All of lore.kernel.org
 help / color / mirror / Atom feed
From: Donald Buczek <buczek@molgen.mpg.de>
To: Logan Gunthorpe <logang@deltatee.com>,
	linux-kernel@vger.kernel.org, linux-raid@vger.kernel.org,
	Song Liu <song@kernel.org>
Cc: Christoph Hellwig <hch@infradead.org>,
	Guoqing Jiang <guoqing.jiang@linux.dev>, Xiao Ni <xni@redhat.com>,
	Stephen Bates <sbates@raithlin.com>,
	Martin Oliveira <Martin.Oliveira@eideticom.com>,
	David Sloan <David.Sloan@eideticom.com>
Subject: Re: [PATCH v1 12/15] md/raid5-cache: Add RCU protection to conf->log accesses
Date: Sun, 22 May 2022 09:31:46 +0200	[thread overview]
Message-ID: <62b09487-9223-db3d-2165-789a51230060@molgen.mpg.de> (raw)
In-Reply-To: <20220519191311.17119-13-logang@deltatee.com>

On 19.05.22 21:13, Logan Gunthorpe wrote:
> The mdadm test 21raid5cache randomly fails with NULL pointer accesses
> conf->log when run repeatedly. conf->log was sort of protected with
> a RCU, but most dereferences were not done with the correct functions.
> 
> Add rcu_read_locks() and rcu_access_pointers() to the appropriate
> places.
> 
> Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
> ---
>   drivers/md/raid5-cache.c | 135 +++++++++++++++++++++++++++------------
>   drivers/md/raid5-log.h   |  14 ++--
>   drivers/md/raid5.c       |   4 +-
>   drivers/md/raid5.h       |   2 +-
>   4 files changed, 104 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
> index f7b402138d16..1dbc7c4b9a15 100644
> --- a/drivers/md/raid5-cache.c
> +++ b/drivers/md/raid5-cache.c
> @@ -254,7 +254,14 @@ static bool __r5c_is_writeback(struct r5l_log *log)
>   
>   bool r5c_is_writeback(struct r5conf *conf)
>   {
> -	return __r5c_is_writeback(conf->log);
> +	struct r5l_log *log;
> +	bool ret;
> +
> +	rcu_read_lock();
> +	log = rcu_dereference(conf->log);
> +	ret = __r5c_is_writeback(log);
> +	rcu_read_unlock();
> +	return ret;
>   }
>   
>   static sector_t r5l_ring_add(struct r5l_log *log, sector_t start, sector_t inc)
> @@ -340,12 +347,23 @@ static void __r5l_wake_reclaim(struct r5l_log *log, sector_t space)
>   	md_wakeup_thread(log->reclaim_thread);
>   }
>   
> +static struct r5l_log *get_log_for_io(struct r5conf *conf)
> +{
> +	/*
> +	 * rcu_dereference_protected is safe because the array will be
> +	 * quiesced before log_exit() so it can't be called while
> +	 * an IO is in progress.
> +	 */
> +	return rcu_dereference_protected(conf->log, 1);
> +}
> +
>   /* Check whether we should flush some stripes to free up stripe cache */
>   void r5c_check_stripe_cache_usage(struct r5conf *conf)
>   {
> +	struct r5l_log *log = get_log_for_io(conf);
>   	int total_cached;
>   
> -	if (!r5c_is_writeback(conf))
> +	if (!__r5c_is_writeback(log))
>   		return;
>   
>   	total_cached = atomic_read(&conf->r5c_cached_partial_stripes) +
> @@ -361,7 +379,7 @@ void r5c_check_stripe_cache_usage(struct r5conf *conf)
>   	 */
>   	if (total_cached > conf->min_nr_stripes * 1 / 2 ||
>   	    atomic_read(&conf->empty_inactive_list_nr) > 0)
> -		__r5l_wake_reclaim(conf->log, 0);
> +		__r5l_wake_reclaim(log, 0);
>   }
>   
>   /*
> @@ -370,8 +388,7 @@ void r5c_check_stripe_cache_usage(struct r5conf *conf)
>    */
>   void r5c_check_cached_full_stripe(struct r5conf *conf)
>   {
> -	if (!r5c_is_writeback(conf))
> -		return;
> +	struct r5l_log *log = get_log_for_io(conf);
>   
>   	/*
>   	 * wake up reclaim for R5C_FULL_STRIPE_FLUSH_BATCH cached stripes
> @@ -380,7 +397,7 @@ void r5c_check_cached_full_stripe(struct r5conf *conf)
>   	if (atomic_read(&conf->r5c_cached_full_stripes) >=
>   	    min(R5C_FULL_STRIPE_FLUSH_BATCH(conf),
>   		conf->chunk_sectors >> RAID5_STRIPE_SHIFT(conf)))
> -		__r5l_wake_reclaim(conf->log, 0);
> +		__r5l_wake_reclaim(log, 0);
>   }
>   
>   /*
> @@ -703,7 +720,7 @@ static void r5c_disable_writeback_async(struct work_struct *work)
>   
>   	/* wait superblock change before suspend */
>   	wait_event(mddev->sb_wait,
> -		   conf->log == NULL ||
> +		   rcu_access_pointer(conf->log) ||
>   		   (!test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags) &&
>   		    (locked = mddev_trylock(mddev))));
>   	if (locked) {
> @@ -1001,7 +1018,7 @@ static inline void r5l_add_no_space_stripe(struct r5l_log *log,
>    */
>   int r5l_write_stripe(struct r5conf *conf, struct stripe_head *sh)
>   {
> -	struct r5l_log *log = conf->log;
> +	struct r5l_log *log = get_log_for_io(conf);
>   	int write_disks = 0;
>   	int data_pages, parity_pages;
>   	int reserve;
> @@ -1099,7 +1116,8 @@ int r5l_write_stripe(struct r5conf *conf, struct stripe_head *sh)
>   
>   void r5l_write_stripe_run(struct r5conf *conf)
>   {
> -	struct r5l_log *log = conf->log;
> +	struct r5l_log *log = get_log_for_io(conf);
> +
>   	if (!log)
>   		return;
>   	mutex_lock(&log->io_mutex);
> @@ -1109,7 +1127,7 @@ void r5l_write_stripe_run(struct r5conf *conf)
>   
>   int r5l_handle_flush_request(struct r5conf *conf, struct bio *bio)
>   {
> -	struct r5l_log *log = conf->log;
> +	struct r5l_log *log = get_log_for_io(conf);
>   
>   	if (log->r5c_journal_mode == R5C_JOURNAL_MODE_WRITE_THROUGH) {
>   		/*
> @@ -1297,7 +1315,7 @@ static void r5l_log_flush_endio(struct bio *bio)
>    */
>   void r5l_flush_stripe_to_raid(struct r5conf *conf)
>   {
> -	struct r5l_log *log = conf->log;
> +	struct r5l_log *log = get_log_for_io(conf);
>   	bool do_flush;
>   
>   	if (!log || !log->need_cache_flush)
> @@ -1412,7 +1430,7 @@ void r5c_flush_cache(struct r5conf *conf, int num)
>   	struct stripe_head *sh, *next;
>   
>   	lockdep_assert_held(&conf->device_lock);
> -	if (!conf->log)
> +	if (!rcu_access_pointer(conf->log))
>   		return;
>   
>   	count = 0;
> @@ -1431,9 +1449,8 @@ void r5c_flush_cache(struct r5conf *conf, int num)
>   	}
>   }
>   
> -static void r5c_do_reclaim(struct r5conf *conf)
> +static void r5c_do_reclaim(struct r5conf *conf, struct r5l_log *log)
>   {
> -	struct r5l_log *log = conf->log;
>   	struct stripe_head *sh;
>   	int count = 0;
>   	unsigned long flags;
> @@ -1441,7 +1458,7 @@ static void r5c_do_reclaim(struct r5conf *conf)
>   	int stripes_to_flush;
>   	int flushing_partial, flushing_full;
>   
> -	if (!r5c_is_writeback(conf))
> +	if (!__r5c_is_writeback(log))
>   		return;
>   
>   	flushing_partial = atomic_read(&conf->r5c_flushing_partial_stripes);
> @@ -1561,22 +1578,30 @@ static void r5l_reclaim_thread(struct md_thread *thread)
>   {
>   	struct mddev *mddev = thread->mddev;
>   	struct r5conf *conf = mddev->private;
> -	struct r5l_log *log = conf->log;
> +	struct r5l_log *log;
>   
> +	/*
> +	 * This is safe, because the reclaim thread will be stopped before
> +	 * the log is freed in log_exit()
> +	 */
> +	log = rcu_dereference_protected(conf->log, 1);
>   	if (!log)
>   		return;
> -	r5c_do_reclaim(conf);
> +
> +	r5c_do_reclaim(conf, log);
>   	r5l_do_reclaim(log);
>   }
>   
>   void r5l_wake_reclaim(struct r5conf *conf, sector_t space)
>   {
> -	__r5l_wake_reclaim(conf->log, space);
> +	struct r5l_log *log = get_log_for_io(conf);
> +
> +	__r5l_wake_reclaim(log, space);
>   }
>   
>   void r5l_quiesce(struct r5conf *conf, int quiesce)
>   {
> -	struct r5l_log *log = conf->log;
> +	struct r5l_log *log = get_log_for_io(conf);
>   	struct mddev *mddev;
>   
>   	if (quiesce) {
> @@ -2534,16 +2559,20 @@ static void r5l_write_super(struct r5l_log *log, sector_t cp)
>   static ssize_t r5c_journal_mode_show(struct mddev *mddev, char *page)
>   {
>   	struct r5conf *conf;
> -	int ret;
> +	struct r5l_log *log;
> +	int ret = 0;
>   
>   	spin_lock(&mddev->lock);
>   	conf = mddev->private;
> -	if (!conf || !conf->log) {
> -		spin_unlock(&mddev->lock);
> -		return 0;
> -	}
> +	if (!conf)
> +		goto out_spin_unlock;
> +
> +	rcu_read_lock();
> +	log = rcu_dereference(conf->log);
> +	if (!log)
> +		goto out;
>   
> -	switch (conf->log->r5c_journal_mode) {
> +	switch (log->r5c_journal_mode) {
>   	case R5C_JOURNAL_MODE_WRITE_THROUGH:
>   		ret = snprintf(
>   			page, PAGE_SIZE, "[%s] %s\n",
> @@ -2559,6 +2588,10 @@ static ssize_t r5c_journal_mode_show(struct mddev *mddev, char *page)
>   	default:
>   		ret = 0;
>   	}
> +
> +out:
> +	rcu_read_unlock();
> +out_spin_unlock:
>   	spin_unlock(&mddev->lock);
>   	return ret;
>   }
> @@ -2572,13 +2605,15 @@ static ssize_t r5c_journal_mode_show(struct mddev *mddev, char *page)
>   int r5c_journal_mode_set(struct mddev *mddev, int mode)
>   {
>   	struct r5conf *conf;
> +	struct r5l_log *log;
> +	int ret = 0;
>   
>   	if (mode < R5C_JOURNAL_MODE_WRITE_THROUGH ||
>   	    mode > R5C_JOURNAL_MODE_WRITE_BACK)
>   		return -EINVAL;
>   
>   	conf = mddev->private;
> -	if (!conf || !conf->log)
> +	if (!conf || !rcu_access_pointer(conf->log))
>   		return -ENODEV;
>   
>   	if (raid5_calc_degraded(conf) > 0 &&
> @@ -2586,12 +2621,19 @@ int r5c_journal_mode_set(struct mddev *mddev, int mode)
>   		return -EINVAL;
>   
>   	mddev_suspend(mddev);
> -	conf->log->r5c_journal_mode = mode;
> +	rcu_read_lock();
> +	log = rcu_dereference(conf->log);
> +	if (log) {
> +		log->r5c_journal_mode = mode;
> +		pr_debug("md/raid:%s: setting r5c cache mode to %d: %s\n",
> +			 mdname(mddev), mode, r5c_journal_mode_str[mode]);
> +	} else {
> +		ret = -ENODEV;
> +	}
> +	rcu_read_unlock();
>   	mddev_resume(mddev);
>   
> -	pr_debug("md/raid:%s: setting r5c cache mode to %d: %s\n",
> -		 mdname(mddev), mode, r5c_journal_mode_str[mode]);
> -	return 0;
> +	return ret;
>   }
>   EXPORT_SYMBOL(r5c_journal_mode_set);
>   
> @@ -2637,7 +2679,7 @@ int r5c_try_caching_write(struct r5conf *conf,
>   			  struct stripe_head_state *s,
>   			  int disks)
>   {
> -	struct r5l_log *log = conf->log;
> +	struct r5l_log *log = get_log_for_io(conf);
>   	int i;
>   	struct r5dev *dev;
>   	int to_cache = 0;
> @@ -2804,7 +2846,7 @@ void r5c_finish_stripe_write_out(struct r5conf *conf,
>   				 struct stripe_head *sh,
>   				 struct stripe_head_state *s)
>   {
> -	struct r5l_log *log = conf->log;
> +	struct r5l_log *log = get_log_for_io(conf);
>   	int i;
>   	int do_wakeup = 0;
>   	sector_t tree_index;
> @@ -2887,7 +2929,7 @@ void r5c_finish_stripe_write_out(struct r5conf *conf,
>   
>   int r5c_cache_data(struct r5conf *conf, struct stripe_head *sh)
>   {
> -	struct r5l_log *log = conf->log;
> +	struct r5l_log *log = get_log_for_io(conf);
>   	int pages = 0;
>   	int reserve;
>   	int i;
> @@ -2943,7 +2985,7 @@ int r5c_cache_data(struct r5conf *conf, struct stripe_head *sh)
>   /* check whether this big stripe is in write back cache. */
>   bool r5c_big_stripe_cached(struct r5conf *conf, sector_t sect)
>   {
> -	struct r5l_log *log = conf->log;
> +	struct r5l_log *log = get_log_for_io(conf);
>   	sector_t tree_index;
>   	void *slot;
>   
> @@ -2953,6 +2995,7 @@ bool r5c_big_stripe_cached(struct r5conf *conf, sector_t sect)
>   	WARN_ON_ONCE(!rcu_read_lock_held());
>   	tree_index = r5c_tree_index(conf, sect);
>   	slot = radix_tree_lookup(&log->big_stripe_tree, tree_index);
> +
>   	return slot != NULL;
>   }
>   
> @@ -3033,30 +3076,38 @@ static int r5l_load_log(struct r5l_log *log)
>   
>   int r5l_start(struct r5conf *conf)
>   {
> -	struct r5l_log *log = conf->log;
> +	struct r5l_log *log;
>   	int ret;
>   
> +	log = rcu_dereference_protected(conf->log,
> +			lockdep_is_held(&conf->mddev->reconfig_mutex));
>   	if (!log)
>   		return 0;
>   
>   	ret = r5l_load_log(log);
>   	if (ret)
>   		r5l_exit_log(conf);
> +
>   	return ret;
>   }
>   
>   void r5c_update_on_rdev_error(struct mddev *mddev, struct md_rdev *rdev)
>   {
>   	struct r5conf *conf = mddev->private;
> -	struct r5l_log *log = conf->log;
> +	struct r5l_log *log;
>   
> +	rcu_read_lock();
> +	log = rcu_dereference(conf->log);
>   	if (!log)
> -		return;
> +		goto out;
>   
>   	if ((raid5_calc_degraded(conf) > 0 ||
>   	     test_bit(Journal, &rdev->flags)) &&
> -	    conf->log->r5c_journal_mode == R5C_JOURNAL_MODE_WRITE_BACK)
> +	    log->r5c_journal_mode == R5C_JOURNAL_MODE_WRITE_BACK)
>   		schedule_work(&log->disable_writeback_work);
> +
> +out:
> +	rcu_read_unlock();
>   }
>   
>   int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev)
> @@ -3164,15 +3215,17 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev)
>   
>   void r5l_exit_log(struct r5conf *conf)
>   {
> -	struct r5l_log *log = conf->log;
> +	struct r5l_log *log;
>   
> -	conf->log = NULL;
> -	synchronize_rcu();
> +	lockdep_assert_held(&conf->mddev->reconfig_mutex);
> +	log = rcu_replace_pointer(conf->log, NULL, 1);
>   
>   	/* Ensure disable_writeback_work wakes up and exits */
>   	wake_up(&conf->mddev->sb_wait);
>   	flush_work(&log->disable_writeback_work);
>   	md_unregister_thread(&log->reclaim_thread);
> +	synchronize_rcu();
> +
>   	mempool_exit(&log->meta_pool);
>   	bioset_exit(&log->bs);
>   	mempool_exit(&log->io_pool);
> diff --git a/drivers/md/raid5-log.h b/drivers/md/raid5-log.h
> index f26e6f4c7f9a..24b4dbd5b25c 100644
> --- a/drivers/md/raid5-log.h
> +++ b/drivers/md/raid5-log.h
> @@ -58,7 +58,7 @@ static inline int log_stripe(struct stripe_head *sh, struct stripe_head_state *s
>   {
>   	struct r5conf *conf = sh->raid_conf;
>   
> -	if (conf->log) {
> +	if (rcu_access_pointer(conf->log)) {


A problem here is that `struct r5l_log` of `conf->log` is private to raid5-cache.c and gcc below version 10 (wrongly) regards the `typeof(*p) *local` declaration of __rcu_access_pointer as a dereference:

   CC      drivers/md/raid5.o

In file included from ./include/linux/rculist.h:11:0,

                  from ./include/linux/dcache.h:8,

                  from ./include/linux/fs.h:8,

                  from ./include/linux/highmem.h:5,

                  from ./include/linux/bvec.h:10,

                  from ./include/linux/blk_types.h:10,

                  from ./include/linux/blkdev.h:9,

                  from drivers/md/raid5.c:38:

drivers/md/raid5-log.h: In function ‘log_stripe’:

./include/linux/rcupdate.h:384:9: error: dereferencing pointer to incomplete type ‘struct r5l_log’

   typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \

          ^

./include/linux/rcupdate.h:495:31: note: in expansion of macro ‘__rcu_access_pointer’

  #define rcu_access_pointer(p) __rcu_access_pointer((p), __UNIQUE_ID(rcu), __rcu)

                                ^~~~~~~~~~~~~~~~~~~~

drivers/md/raid5-log.h:61:6: note: in expansion of macro ‘rcu_access_pointer’

   if (rcu_access_pointer(conf->log)) {

       ^~~~~~~~~~~~~~~~~~

make[2]: *** [scripts/Makefile.build:288: drivers/md/raid5.o] Error 1

make[1]: *** [scripts/Makefile.build:550: drivers/md] Error 2

make: *** [Makefile:1834: drivers] Error 2


See https://godbolt.org/z/TPP8MdKbc to test compiler versions with this construct.

Best

   Donald


>   		if (!test_bit(STRIPE_R5C_CACHING, &sh->state)) {
>   			/* writing out phase */
>   			if (s->waiting_extra_page)
> @@ -79,7 +79,7 @@ static inline void log_stripe_write_finished(struct stripe_head *sh)
>   {
>   	struct r5conf *conf = sh->raid_conf;
>   
> -	if (conf->log)
> +	if (rcu_access_pointer(conf->log))
>   		r5l_stripe_write_finished(sh);
>   	else if (raid5_has_ppl(conf))
>   		ppl_stripe_write_finished(sh);
> @@ -87,7 +87,7 @@ static inline void log_stripe_write_finished(struct stripe_head *sh)
>   
>   static inline void log_write_stripe_run(struct r5conf *conf)
>   {
> -	if (conf->log)
> +	if (rcu_access_pointer(conf->log))
>   		r5l_write_stripe_run(conf);
>   	else if (raid5_has_ppl(conf))
>   		ppl_write_stripe_run(conf);
> @@ -95,7 +95,7 @@ static inline void log_write_stripe_run(struct r5conf *conf)
>   
>   static inline void log_flush_stripe_to_raid(struct r5conf *conf)
>   {
> -	if (conf->log)
> +	if (rcu_access_pointer(conf->log))
>   		r5l_flush_stripe_to_raid(conf);
>   	else if (raid5_has_ppl(conf))
>   		ppl_write_stripe_run(conf);
> @@ -105,7 +105,7 @@ static inline int log_handle_flush_request(struct r5conf *conf, struct bio *bio)
>   {
>   	int ret = -ENODEV;
>   
> -	if (conf->log)
> +	if (rcu_access_pointer(conf->log))
>   		ret = r5l_handle_flush_request(conf, bio);
>   	else if (raid5_has_ppl(conf))
>   		ret = ppl_handle_flush_request(bio);
> @@ -115,7 +115,7 @@ static inline int log_handle_flush_request(struct r5conf *conf, struct bio *bio)
>   
>   static inline void log_quiesce(struct r5conf *conf, int quiesce)
>   {
> -	if (conf->log)
> +	if (rcu_access_pointer(conf->log))
>   		r5l_quiesce(conf, quiesce);
>   	else if (raid5_has_ppl(conf))
>   		ppl_quiesce(conf, quiesce);
> @@ -123,7 +123,7 @@ static inline void log_quiesce(struct r5conf *conf, int quiesce)
>   
>   static inline void log_exit(struct r5conf *conf)
>   {
> -	if (conf->log)
> +	if (rcu_access_pointer(conf->log))
>   		r5l_exit_log(conf);
>   	else if (raid5_has_ppl(conf))
>   		ppl_exit_log(conf);
> diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
> index 37fe2af77c93..c06c9ef88417 100644
> --- a/drivers/md/raid5.c
> +++ b/drivers/md/raid5.c
> @@ -7937,7 +7937,7 @@ static int raid5_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
>   	struct md_rdev *tmp;
>   
>   	print_raid5_conf(conf);
> -	if (test_bit(Journal, &rdev->flags) && conf->log) {
> +	if (test_bit(Journal, &rdev->flags) && rcu_access_pointer(conf->log)) {
>   		mddev_suspend(mddev);
>   		log_exit(conf);
>   		mddev_resume(mddev);
> @@ -8019,7 +8019,7 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev)
>   	int last = conf->raid_disks - 1;
>   
>   	if (test_bit(Journal, &rdev->flags)) {
> -		if (conf->log)
> +		if (rcu_access_pointer(conf->log))
>   			return -EBUSY;
>   
>   		rdev->raid_disk = 0;
> diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
> index 638d29863503..04fe5b6f679c 100644
> --- a/drivers/md/raid5.h
> +++ b/drivers/md/raid5.h
> @@ -684,7 +684,7 @@ struct r5conf {
>   	struct r5worker_group	*worker_groups;
>   	int			group_cnt;
>   	int			worker_cnt_per_group;
> -	struct r5l_log		*log;
> +	struct r5l_log		__rcu *log;
>   	void			*log_private;
>   
>   	spinlock_t		pending_bios_lock;

-- 
Donald Buczek
buczek@molgen.mpg.de
Tel: +49 30 8413 1433

  parent reply	other threads:[~2022-05-22  7:31 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-19 19:12 [PATCH v1 00/15] Bug fixes for mdadm tests Logan Gunthorpe
2022-05-19 19:12 ` [PATCH v1 01/15] md/raid5-log: Drop extern decorators for function prototypes Logan Gunthorpe
2022-05-21 11:36   ` Christoph Hellwig
2022-05-19 19:12 ` [PATCH v1 02/15] md/raid5-cache: Refactor r5c_is_writeback() to take a struct r5conf Logan Gunthorpe
2022-05-21 11:37   ` Christoph Hellwig
2022-05-19 19:12 ` [PATCH v1 03/15] md/raid5-cache: Refactor r5l_start() " Logan Gunthorpe
2022-05-21 11:37   ` Christoph Hellwig
2022-05-19 19:13 ` [PATCH v1 04/15] md/raid5-cache: Refactor r5l_flush_stripe_to_raid() " Logan Gunthorpe
2022-05-21 11:38   ` Christoph Hellwig
2022-05-19 19:13 ` [PATCH v1 05/15] md/raid5-cache: Refactor r5l_wake_reclaim() " Logan Gunthorpe
2022-05-21 11:38   ` Christoph Hellwig
2022-05-19 19:13 ` [PATCH v1 06/15] md/raid5-cache: Refactor remaining functions to take a r5conf Logan Gunthorpe
2022-05-21 11:40   ` Christoph Hellwig
2022-05-19 19:13 ` [PATCH v1 07/15] md/raid5-ppl: Drop unused argument from ppl_handle_flush_request() Logan Gunthorpe
2022-05-21 11:41   ` Christoph Hellwig
2022-05-19 19:13 ` [PATCH v1 08/15] md/raid5-cache: Pass the log through to r5c_finish_cache_stripe() Logan Gunthorpe
2022-05-21 11:42   ` Christoph Hellwig
2022-05-19 19:13 ` [PATCH v1 09/15] md/raid5-cache: Don't pass conf to r5c_calculate_new_cp() Logan Gunthorpe
2022-05-21 11:42   ` Christoph Hellwig
2022-05-19 19:13 ` [PATCH v1 10/15] md/raid5-cache: Take struct r5l_log in r5c_log_required_to_flush_cache() Logan Gunthorpe
2022-05-21 11:43   ` Christoph Hellwig
2022-05-19 19:13 ` [PATCH v1 11/15] md/raid5: Ensure array is suspended for calls to log_exit() Logan Gunthorpe
2022-05-21 11:44   ` Christoph Hellwig
2022-05-19 19:13 ` [PATCH v1 12/15] md/raid5-cache: Add RCU protection to conf->log accesses Logan Gunthorpe
2022-05-21 11:50   ` Christoph Hellwig
2022-05-22  7:31   ` Donald Buczek [this message]
2022-05-23  6:47     ` Song Liu
2022-05-23 18:15       ` Song Liu
2022-05-24 16:14         ` Logan Gunthorpe
2022-05-24 15:59       ` Logan Gunthorpe
2022-05-24 18:13         ` Song Liu
2022-05-22  7:32   ` Donald Buczek
2022-05-24 15:55     ` Logan Gunthorpe
2022-05-19 19:13 ` [PATCH v1 13/15] md/raid5-cache: Annotate pslot with __rcu notation Logan Gunthorpe
2022-05-21 11:51   ` Christoph Hellwig
2022-05-19 19:13 ` [PATCH v1 14/15] md: Ensure resync is reported after it starts Logan Gunthorpe
2022-05-21 11:51   ` Christoph Hellwig
2022-05-24 15:45     ` Logan Gunthorpe
2022-05-19 19:13 ` [PATCH v1 15/15] md: Notify sysfs sync_completed in md_reap_sync_thread() Logan Gunthorpe
2022-05-21 11:52   ` Christoph Hellwig
2022-05-23  6:28 ` [PATCH v1 00/15] Bug fixes for mdadm tests Song Liu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=62b09487-9223-db3d-2165-789a51230060@molgen.mpg.de \
    --to=buczek@molgen.mpg.de \
    --cc=David.Sloan@eideticom.com \
    --cc=Martin.Oliveira@eideticom.com \
    --cc=guoqing.jiang@linux.dev \
    --cc=hch@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-raid@vger.kernel.org \
    --cc=logang@deltatee.com \
    --cc=sbates@raithlin.com \
    --cc=song@kernel.org \
    --cc=xni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.