summaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.h
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2018-02-02 23:19:30 +0100
committerShaohua Li <sh.li@alibaba-inc.com>2018-02-18 19:22:27 +0100
commitf2785b527cda46314805123ddcbc871655b7c4c4 (patch)
tree797db5c31d88db7c308e660356501d1367c4cab8 /drivers/md/raid5.h
parentmd: fix md_write_start() deadlock w/o metadata devices (diff)
downloadlinux-f2785b527cda46314805123ddcbc871655b7c4c4.tar.xz
linux-f2785b527cda46314805123ddcbc871655b7c4c4.zip
md: document lifetime of internal rdev pointer.
The rdev pointer kept in the local 'config' for each for raid1, raid10, raid4/5/6 has non-obvious lifetime rules. Sometimes RCU is needed, sometimes a lock, something nothing. Add documentation to explain this. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Shaohua Li <sh.li@alibaba-inc.com>
Diffstat (limited to 'drivers/md/raid5.h')
-rw-r--r--drivers/md/raid5.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index 2e6123825095..3f8da26032ac 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -450,6 +450,18 @@ enum {
* HANDLE gets cleared if stripe_handle leaves nothing locked.
*/
+/* Note: disk_info.rdev can be set to NULL asynchronously by raid5_remove_disk.
+ * There are three safe ways to access disk_info.rdev.
+ * 1/ when holding mddev->reconfig_mutex
+ * 2/ when resync/recovery/reshape is known to be happening - i.e. in code that
+ * is called as part of performing resync/recovery/reshape.
+ * 3/ while holding rcu_read_lock(), use rcu_dereference to get the pointer
+ * and if it is non-NULL, increment rdev->nr_pending before dropping the RCU
+ * lock.
+ * When .rdev is set to NULL, the nr_pending count checked again and if
+ * it has been incremented, the pointer is put back in .rdev.
+ */
+
struct disk_info {
struct md_rdev *rdev, *replacement;
struct page *extra_page; /* extra page to use in prexor */