Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2785b52 authored by NeilBrown's avatar NeilBrown Committed by Shaohua Li
Browse files

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: default avatarNeilBrown <neilb@suse.com>
Signed-off-by: default avatarShaohua Li <sh.li@alibaba-inc.com>
parent 4b6c1060
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -26,6 +26,18 @@
#define BARRIER_BUCKETS_NR_BITS		(PAGE_SHIFT - ilog2(sizeof(atomic_t)))
#define BARRIER_BUCKETS_NR		(1<<BARRIER_BUCKETS_NR_BITS)

/* Note: raid1_info.rdev can be set to NULL asynchronously by raid1_remove_disk.
 * There are three safe ways to access raid1_info.rdev.
 * 1/ when holding mddev->reconfig_mutex
 * 2/ when resync/recovery is known to be happening - i.e. in code that is
 *    called as part of performing resync/recovery.
 * 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 raid1_info {
	struct md_rdev	*rdev;
	sector_t	head_position;
+13 −0
Original line number Diff line number Diff line
@@ -2,6 +2,19 @@
#ifndef _RAID10_H
#define _RAID10_H

/* Note: raid10_info.rdev can be set to NULL asynchronously by
 * raid10_remove_disk.
 * There are three safe ways to access raid10_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 raid10_info {
	struct md_rdev	*rdev, *replacement;
	sector_t	head_position;
+12 −0
Original line number Diff line number Diff line
@@ -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 */