block: genhd: Replace rcu_assign_pointer() with RCU_INIT_POINTER()
PATCH 1/1 block: genhd: Replace rcu_assign_pointer() with RCU_INIT_POINTER()
According to RCU_INIT_POINTER()'s block comment 3.a, it can be used if
"3. The referenced data structure has already been exposed to readers either
at compile time or via rcu_assign_pointer() -and-
a. You have not made -any- reader-visible changes to this structure since
then".
This case fulfills the conditions above because between the rcu_dereference() call and the rcu_assign_pointer() call there is no update of the "part" variable.
Therefore, this patch makes the replacement.
The following Coccinelle semantic patch was used:
@@
identifier v;
@@
v = rcu_dereference(...);
... when != rcu_dereference(...);
when != v = ...;
when != (<+...v...+>)++;
when != \(memcpy\|memset\)(...);(
- rcu_assign_pointer
+ RCU_INIT_POINTER
(..., v);
|
if(...) {
... when != v = ...;
- rcu_assign_pointer
+ RCU_INIT_POINTER
(..., v);
... when any
}
)
Because there are cases where between a “rcu_dereference()” call and a “rcu_assign_pointer()” call might be updates of the value that interests us, the Coccinelle semantic patch ignores them and replaces with "RCU_INIT_POINTER()" only when the update is not happening.
--- block/genhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
block/genhd.c +1 -1
@@ -228,7 +228,7 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector) part =rcu_dereference (ptbl->part[i]);if (part &§or_in_part (part, sector)) { -rcu_assign_pointer (ptbl->last_lookup, part); +RCU_INIT_POINTER (ptbl->last_lookup, part);return part; } }
Signature · 1 line
1.9.1