Linux RAID subsystem development
 help / color / mirror / Atom feed
* Re: 4.11.2: reshape raid5 -> raid6 atop bcache deadlocks at start on md_attr_store / raid5_make_request
From: NeilBrown @ 2017-05-25  1:30 UTC (permalink / raw)
  To: Shaohua Li; +Cc: Nix, linux-raid
In-Reply-To: <20170524225735.555dpfe24mi6yxrb@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 3449 bytes --]

On Wed, May 24 2017, Shaohua Li wrote:

> On Wed, May 24, 2017 at 11:24:21AM +1000, Neil Brown wrote:
>> 
>> 
>> 
>> diff --git a/drivers/md/md.c b/drivers/md/md.c
>> index 10367ffe92e3..a7b9c0576479 100644
>> --- a/drivers/md/md.c
>> +++ b/drivers/md/md.c
>> @@ -324,8 +324,12 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio)
>>  void mddev_suspend(struct mddev *mddev)
>>  {
>>  	WARN_ON_ONCE(mddev->thread && current == mddev->thread->tsk);
>> +
>>  	if (mddev->suspended++)
>>  		return;
>> +#ifdef CONFIG_LOCKDEP
>> +	WARN_ON_ONCE(debug_locks && lockdep_is_held(&mddev->reconfig_mutex));
>> +#endif
>>  	synchronize_rcu();
>>  	wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
>>  	mddev->pers->quiesce(mddev, 1);
>> @@ -3594,9 +3598,12 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
>>  	if (slen == 0 || slen >= sizeof(clevel))
>>  		return -EINVAL;
>>  
>> +	mddev_suspend(mddev);
>>  	rv = mddev_lock(mddev);
>> -	if (rv)
>> +	if (rv) {
>> +		mddev_resume(mddev);
>>  		return rv;
>> +	}
>>  
>>  	if (mddev->pers == NULL) {
>>  		strncpy(mddev->clevel, buf, slen);
>> @@ -3687,7 +3694,6 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
>>  	}
>>  
>>  	/* Looks like we have a winner */
>> -	mddev_suspend(mddev);
>>  	mddev_detach(mddev);
>>  
>>  	spin_lock(&mddev->lock);
>> @@ -3771,13 +3777,13 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
>>  	blk_set_stacking_limits(&mddev->queue->limits);
>>  	pers->run(mddev);
>>  	set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags);
>> -	mddev_resume(mddev);
>>  	if (!mddev->thread)
>>  		md_update_sb(mddev, 1);
>>  	sysfs_notify(&mddev->kobj, NULL, "level");
>>  	md_new_event(mddev);
>>  	rv = len;
>>  out_unlock:
>> +	mddev_resume(mddev);
>>  	mddev_unlock(mddev);
>>  	return rv;
>>  }
>> @@ -4490,6 +4496,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
>>  		int err;
>>  		if (mddev->pers->start_reshape == NULL)
>>  			return -EINVAL;
>> +		mddev_suspend(mddev);
>>  		err = mddev_lock(mddev);
>>  		if (!err) {
>>  			if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
>> @@ -4500,6 +4507,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
>>  			}
>>  			mddev_unlock(mddev);
>>  		}
>> +		mddev_resume(mddev);
>>  		if (err)
>>  			return err;
>>  		sysfs_notify(&mddev->kobj, NULL, "degraded");
>
> The analysis makes a lot of sense, thanks! The patch looks not solving the
> problem though, because check_recovery will not write super if suspended isn't
> 0.

Why does that matter?  In what case do you need the superblock to be
written, but it doesn't happen.

check_recovery won't write the superblock while the mddev is locked
either, and it is locked for most of level_store().
When level_store() finished, it unlocks the device and that will trigger
md_check_recovery() to be run, and the metadata will be written then.
I don't think there is a particular need to update it before then.

Thanks,
NeilBrown


>
> I'm thinking of alternative wayt to fix this issue. A request which stalls in
> md_write_start reallys isn't an active IO. We could add another counter in
> md_write_start to record stalled request there. Then in mddev_suspend, wait
> event will wait for atomic_read(&mddev->active_io) == the_new_counter.
>
> Thanks,
> Shaohua

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply

* Re: [PATCH v4] super1: fix sb->max_dev when adding a new disk in linear array
From: NeilBrown @ 2017-05-25  0:32 UTC (permalink / raw)
  To: Lidong Zhong, linux-raid; +Cc: colyli, Jes.Sorensen
In-Reply-To: <65768bfe-b94c-0382-4085-c46ff5aeb732@suse.com>

[-- Attachment #1: Type: text/plain, Size: 6407 bytes --]

On Wed, May 24 2017, Lidong Zhong wrote:

> On 05/24/2017 09:57 AM, NeilBrown wrote:
>>>>
>>> I think it's also pointless to assign MD_DISK_ROLE_SPARE
>>> since there is no SPARE in dev_roles when we need to update
>>> sb->max_dev. The newly added device will not meet the condition
>>> as max_dev has already been updated, that's saying, we only
>>> need to update the max_dev value for original disks.
>>> The following code should work
>>>
>>> 1297     } else if (strcmp(update, "linear-grow-update") == 0) {
>>> 1298         unsigned int max = __le32_to_cpu(sb->max_dev);
>>> 1299         sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
>>> 1300         sb->dev_roles[info->disk.number] =
>>> 1301             __cpu_to_le16(info->disk.raid_disk);
>>> 1302         if (info->array.raid_disks > max) {
>>>
>>>
>>> 1303             sb->max_dev = __cpu_to_le32(max+1);
>>> 1304         }
>>
>> Increasing max_dev and not initializing will leave the last entry in
>> dev_roles[] uninitialised.  That isn't good.
>>
> Hi Neil,
>
> As I can see, the dev_roles[] value has already been set by line 1300,
> because only one disk could be added to the linear array at one time.
> When info->array.raid_disks is large than max,
> info->disk.number should be equal to max now.
> If changing the source into
>
> 1297     } else if (strcmp(update, "linear-grow-update") == 0) {
> 1298         unsigned int max = __le32_to_cpu(sb->max_dev);
> 1299         sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
> 1300         if (info->array.raid_disks > max) {
> 1301             sb->dev_roles[max] = __cpu_to_le16(MD_DISK_ROLE_SPARE);
> 1302             sb->max_dev = __cpu_to_le32(max+1);
> 1303         }
> 1304         sb->dev_roles[info->disk.number] = 
>  
>
> 1305             __cpu_to_le16(info->disk.raid_disk);
>
> it still works, but I don't see it as necessary.

Yes, you are right, sorry.  My mistake.
No need to change dev_roles in linear-grow-update other than
info->disk.number.
Only changed needed there is to make sure max_dev is correct.

>> MD_DISK_ROLE_SPARE doesn't mean there is a spare device in that slot.
>> It means that if there is a device in that slot, it must be spare.
>> If you leave it uninitialised, it will probably be zero, and then
>> you will get "?" in the mdadm output again.
>>
>
> I did a test with growing a linear array to 129 devices

Thanks for doing that!!  Testing like this helps confirm our understanding.

Thanks,
NeilBrown

>
> /dev/dm-128:
>            Magic : a92b4efc
>          Version : 1.2
>      Feature Map : 0x0
>       Array UUID : 8bed7e5c:1acea7d9:9087c183:77f44fc0
>             Name : sles12sp2-clone1:0  (local to host sles12sp2-clone1)
>    Creation Time : Wed May 24 16:56:10 2017
>       Raid Level : linear
>     Raid Devices : 129
>
>   Avail Dev Size : 106400 (51.95 MiB 54.48 MB)
>    Used Dev Size : 0
>      Data Offset : 96 sectors
>     Super Offset : 8 sectors
>     Unused Space : before=8 sectors, after=0 sectors
>            State : clean
>      Device UUID : 47dec6cb:e84ddc52:35f7290b:7c47a1c6
>
>      Update Time : Wed May 24 16:56:10 2017
>    Bad Block Log : 512 entries available at offset 72 sectors
>         Checksum : 57c7a375 - correct
>           Events : 0
>
>         Rounding : 0K
>
>     Device Role : Active device 128
>     Array State : 
> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
> ('A' == active, '.' == missing, 'R' == replacing)
> Debug Array State (raid_disks 129, delta_extra 0) :
> dev_roles[0]:0 dev_roles[1]:1 dev_roles[2]:2 dev_roles[3]:3 
> dev_roles[4]:4 dev_roles[5]:5 dev_roles[6]:6 dev_roles[7]:7 
> dev_roles[8]:8 dev_roles[9]:9 dev_roles[10]:a dev_roles[11]:b 
> dev_roles[12]:c dev_roles[13]:d dev_roles[14]:e dev_roles[15]:f 
> dev_roles[16]:10 dev_roles[17]:11 dev_roles[18]:12 dev_roles[19]:13 
> dev_roles[20]:14 dev_roles[21]:15 dev_roles[22]:16 dev_roles[23]:17 
> dev_roles[24]:18 dev_roles[25]:19 dev_roles[26]:1a dev_roles[27]:1b 
> dev_roles[28]:1c dev_roles[29]:1d dev_roles[30]:1e dev_roles[31]:1f 
> dev_roles[32]:20 dev_roles[33]:21 dev_roles[34]:22 dev_roles[35]:23 
> dev_roles[36]:24 dev_roles[37]:25 dev_roles[38]:26 dev_roles[39]:27 
> dev_roles[40]:28 dev_roles[41]:29 dev_roles[42]:2a dev_roles[43]:2b 
> dev_roles[44]:2c dev_roles[45]:2d dev_roles[46]:2e dev_roles[47]:2f 
> dev_roles[48]:30 dev_roles[49]:31 dev_roles[50]:32 dev_roles[51]:33 
> dev_roles[52]:34 dev_roles[53]:35 dev_roles[54]:36 dev_roles[55]:37 
> dev_roles[56]:38 dev_roles[57]:39 dev_roles[58]:3a dev_roles[59]:3b 
> dev_roles[60]:3c dev_roles[61]:3d dev_roles[62]:3e dev_roles[63]:3f 
> dev_roles[64]:40 dev_roles[65]:41 dev_roles[66]:42 dev_roles[67]:43 
> dev_roles[68]:44 dev_roles[69]:45 dev_roles[70]:46 dev_roles[71]:47 
> dev_roles[72]:48 dev_roles[73]:49 dev_roles[74]:4a dev_roles[75]:4b 
> dev_roles[76]:4c dev_roles[77]:4d dev_roles[78]:4e dev_roles[79]:4f 
> dev_roles[80]:50 dev_roles[81]:51 dev_roles[82]:52 dev_roles[83]:53 
> dev_roles[84]:54 dev_roles[85]:55 dev_roles[86]:56 dev_roles[87]:57 
> dev_roles[88]:58 dev_roles[89]:59 dev_roles[90]:5a dev_roles[91]:5b 
> dev_roles[92]:5c dev_roles[93]:5d dev_roles[94]:5e dev_roles[95]:5f 
> dev_roles[96]:60 dev_roles[97]:61 dev_roles[98]:62 dev_roles[99]:63 
> dev_roles[100]:64 dev_roles[101]:65 dev_roles[102]:66 dev_roles[103]:67 
> dev_roles[104]:68 dev_roles[105]:69 dev_roles[106]:6a dev_roles[107]:6b 
> dev_roles[108]:6c dev_roles[109]:6d dev_roles[110]:6e dev_roles[111]:6f 
> dev_roles[112]:70 dev_roles[113]:71 dev_roles[114]:72 dev_roles[115]:73 
> dev_roles[116]:74 dev_roles[117]:75 dev_roles[118]:76 dev_roles[119]:77 
> dev_roles[120]:78 dev_roles[121]:79 dev_roles[122]:7a dev_roles[123]:7b 
> dev_roles[124]:7c dev_roles[125]:7d dev_roles[126]:7e dev_roles[127]:7f 
> dev_roles[128]:80
>
> And there is no problem showing the status.
>
> Thanks,
> Lidong
>> NeilBrown
>>
>>
>>>
>>> Thank you for your patient review.
>>>
>>> Lidong
>>>
>>>> NeilBrown
>>>>
>>>>
>>>>> +			sb->max_dev = __cpu_to_le32(max+1);
>>>>> +		}
>>>>>  	} else if (strcmp(update, "resync") == 0) {
>>>>>  		/* make sure resync happens */
>>>>>  		sb->resync_offset = 0ULL;
>>>>> --
>>>>> 2.12.0

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply

* Re: [PATCH RESEND] md: Make flush bios explicitely sync
From: Shaohua Li @ 2017-05-24 23:22 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-raid, Mike Snitzer, dm-devel
In-Reply-To: <20170524114013.14130-1-jack@suse.cz>

On Wed, May 24, 2017 at 01:40:13PM +0200, Jan Kara wrote:
> Commit b685d3d65ac7 "block: treat REQ_FUA and REQ_PREFLUSH as
> synchronous" removed REQ_SYNC flag from WRITE_{FUA|PREFLUSH|...}
> definitions.  generic_make_request_checks() however strips REQ_FUA and
> REQ_PREFLUSH flags from a bio when the storage doesn't report volatile
> write cache and thus write effectively becomes asynchronous which can
> lead to performance regressions
> 
> Fix the problem by making sure all bios which are synchronous are
> properly marked with REQ_SYNC.

Hi,

DM and MD are different trees, so probably you should separate them to 2
patches. For the md part (md.c, raid5-cache.c), some placed which use REQ_FUA
are missed, like raid5.c and raid5-ppl.c

Can't remember if others asked the question in your first post, sorry, but why
we don't add REQ_SYNC in generic_make_request_checks() if we are going to
stripe REQ_FUA, REQ_PREFLUSH. That will be less error prone.

Thanks,
Shaohua

> CC: linux-raid@vger.kernel.org
> CC: Shaohua Li <shli@kernel.org>
> CC: Mike Snitzer <snitzer@redhat.com>
> CC: dm-devel@redhat.com
> Fixes: b685d3d65ac791406e0dfd8779cc9b3707fea5a3
> Signed-off-by: Jan Kara <jack@suse.cz>
> ---
>  drivers/md/dm-snap-persistent.c | 3 ++-
>  drivers/md/md.c                 | 2 +-
>  drivers/md/raid5-cache.c        | 4 ++--
>  3 files changed, 5 insertions(+), 4 deletions(-)
> 
> Guys, I don't know enough about DM/MD to judge whether I've identified all the
> places that want REQ_SYNC right. Can you please have a look?
> 
> diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
> index b93476c3ba3f..b92ab4cb0710 100644
> --- a/drivers/md/dm-snap-persistent.c
> +++ b/drivers/md/dm-snap-persistent.c
> @@ -741,7 +741,8 @@ static void persistent_commit_exception(struct dm_exception_store *store,
>  	/*
>  	 * Commit exceptions to disk.
>  	 */
> -	if (ps->valid && area_io(ps, REQ_OP_WRITE, REQ_PREFLUSH | REQ_FUA))
> +	if (ps->valid && area_io(ps, REQ_OP_WRITE,
> +				 REQ_SYNC | REQ_PREFLUSH | REQ_FUA))
>  		ps->valid = 0;
>  
>  	/*
> diff --git a/drivers/md/md.c b/drivers/md/md.c
> index 10367ffe92e3..212a6777ff31 100644
> --- a/drivers/md/md.c
> +++ b/drivers/md/md.c
> @@ -765,7 +765,7 @@ void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
>  	    test_bit(FailFast, &rdev->flags) &&
>  	    !test_bit(LastDev, &rdev->flags))
>  		ff = MD_FAILFAST;
> -	bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_FUA | ff;
> +	bio->bi_opf = REQ_OP_WRITE | REQ_SYNC | REQ_PREFLUSH | REQ_FUA | ff;
>  
>  	atomic_inc(&mddev->pending_writes);
>  	submit_bio(bio);
> diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
> index 4c00bc248287..0a7af8b0a80a 100644
> --- a/drivers/md/raid5-cache.c
> +++ b/drivers/md/raid5-cache.c
> @@ -1782,7 +1782,7 @@ static int r5l_log_write_empty_meta_block(struct r5l_log *log, sector_t pos,
>  	mb->checksum = cpu_to_le32(crc32c_le(log->uuid_checksum,
>  					     mb, PAGE_SIZE));
>  	if (!sync_page_io(log->rdev, pos, PAGE_SIZE, page, REQ_OP_WRITE,
> -			  REQ_FUA, false)) {
> +			  REQ_SYNC | REQ_FUA, false)) {
>  		__free_page(page);
>  		return -EIO;
>  	}
> @@ -2388,7 +2388,7 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
>  		mb->checksum = cpu_to_le32(crc32c_le(log->uuid_checksum,
>  						     mb, PAGE_SIZE));
>  		sync_page_io(log->rdev, ctx->pos, PAGE_SIZE, page,
> -			     REQ_OP_WRITE, REQ_FUA, false);
> +			     REQ_OP_WRITE, REQ_SYNC | REQ_FUA, false);
>  		sh->log_start = ctx->pos;
>  		list_add_tail(&sh->r5c, &log->stripe_in_journal_list);
>  		atomic_inc(&log->stripe_in_journal_count);
> -- 
> 2.12.0
> 

^ permalink raw reply

* Re: [PATCH] md: uuid debug statement now in processor byte order.
From: Shaohua Li @ 2017-05-24 23:17 UTC (permalink / raw)
  To: Kyungchan Koh; +Cc: linux-raid, Kernel-team
In-Reply-To: <b8df704c40a411e783200002c9dfb610-1a1976b0@d534dd3d68affa13903f5fb3ca3863d112c51930cd4dca1fc26760790e4487f4>

On Wed, May 24, 2017 at 10:16:27AM -0700, Kyungchan Koh wrote:
> Previously, the uuid debug statements were printed in little-endian
> format, which wasn't consistent in machines that might not be in
> little-endian byte order. With this change, the output will be
> consistent for all machines with different byte-ordering.

applied, thanks!
 
> Signed-off-by: Kyungchan Koh <kkc6196@fb.com>
> ---
>  drivers/md/bitmap.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
> index bf7419a..f4eace5 100644
> --- a/drivers/md/bitmap.c
> +++ b/drivers/md/bitmap.c
> @@ -485,10 +485,10 @@ void bitmap_print_sb(struct bitmap *bitmap)
>  	pr_debug("         magic: %08x\n", le32_to_cpu(sb->magic));
>  	pr_debug("       version: %d\n", le32_to_cpu(sb->version));
>  	pr_debug("          uuid: %08x.%08x.%08x.%08x\n",
> -		 *(__u32 *)(sb->uuid+0),
> -		 *(__u32 *)(sb->uuid+4),
> -		 *(__u32 *)(sb->uuid+8),
> -		 *(__u32 *)(sb->uuid+12));
> +		 le32_to_cpu(*(__u32 *)(sb->uuid+0)),
> +		 le32_to_cpu(*(__u32 *)(sb->uuid+4)),
> +		 le32_to_cpu(*(__u32 *)(sb->uuid+8)),
> +		 le32_to_cpu(*(__u32 *)(sb->uuid+12)));
>  	pr_debug("        events: %llu\n",
>  		 (unsigned long long) le64_to_cpu(sb->events));
>  	pr_debug("events cleared: %llu\n",
> -- 
> 2.9.3
> 

^ permalink raw reply

* Re: 4.11.2: reshape raid5 -> raid6 atop bcache deadlocks at start on md_attr_store / raid5_make_request
From: Shaohua Li @ 2017-05-24 22:57 UTC (permalink / raw)
  To: NeilBrown; +Cc: Nix, linux-raid
In-Reply-To: <87poezhwsa.fsf@notabene.neil.brown.name>

On Wed, May 24, 2017 at 11:24:21AM +1000, Neil Brown wrote:
> On Mon, May 22 2017, Nix wrote:
> 
> > On 22 May 2017, NeilBrown told this:
> >
> >> Probably something like this:
> >>
> >> diff --git a/drivers/md/md.c b/drivers/md/md.c
> >> index f6ae1d67bcd0..dbca31be22a1 100644
> >> --- a/drivers/md/md.c
> >> +++ b/drivers/md/md.c
> >> @@ -8364,8 +8364,6 @@ static void md_start_sync(struct work_struct *ws)
> >>   */
> >>  void md_check_recovery(struct mddev *mddev)
> >>  {
> >> -	if (mddev->suspended)
> >> -		return;
> >>  
> >>  	if (mddev->bitmap)
> >>  		bitmap_daemon_work(mddev);
> >> @@ -8484,6 +8482,7 @@ void md_check_recovery(struct mddev *mddev)
> >>  		clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
> >>  
> >>  		if (!test_and_clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
> >> +		    mddev->suspended ||
> >>  		    test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
> >>  			goto not_running;
> >>  		/* no recovery is running.
> >>
> >> though it's late so don't trust anything I write.
> >>
> >> If you try again it will almost certainly succeed.  I suspect this is a
> >> hard race to hit - well done!!!
> >
> > Definitely not a hard race to hit :( I just hit it again with this
> > patch.
> >
> > Absolutely identical hang:
> >
> > [  495.833520] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> > [  495.840618] mdadm           D    0  2700   2537 0x00000000
> > [  495.847762] Call Trace:
> > [  495.854825]  __schedule+0x290/0x810
> > [  495.861905]  schedule+0x36/0x80
> > [  495.868934]  mddev_suspend+0xb3/0xe0
> > [  495.875926]  ? wake_atomic_t_function+0x60/0x60
> > [  495.882976]  level_store+0x1a7/0x6c0
> > [  495.889953]  ? md_ioctl+0xb7/0x1c10
> > [  495.896901]  ? putname+0x53/0x60
> > [  495.903807]  md_attr_store+0x83/0xc0
> > [  495.910684]  sysfs_kf_write+0x37/0x40
> > [  495.917547]  kernfs_fop_write+0x110/0x1a0
> > [  495.924429]  __vfs_write+0x28/0x120
> > [  495.931270]  ? kernfs_iop_get_link+0x172/0x1e0
> > [  495.938126]  ? __alloc_fd+0x3f/0x170
> > [  495.944906]  vfs_write+0xb6/0x1d0
> > [  495.951646]  SyS_write+0x46/0xb0
> > [  495.958338]  entry_SYSCALL_64_fastpath+0x13/0x94
> >
> > Everything else hangs the same way, too. This was surprising enough that
> > I double-checked to be sure the patch was applied: it was. I suspect the
> > deadlock is somewhat different than you supposed... (and quite possibly
> > not a race at all, or I wouldn't be hitting it so consistently, every
> > time. I mean, I only need to miss it *once* and I'll have reshaped... :) )
> >
> > It seems I can reproduce this on demand, so if you want to throw a patch
> > with piles of extra printks my way, feel free.
> 
> Did you have md_write_start being called by syslog-ng again?
> I wonder what syslog is logging - presumably something about the reshape
> starting.
> If you kill syslog-ng, can you start the reshape?
> 
> Alternately, this might do it.
> I think the root problem is that it isn't safe to call mddev_suspend()
> while holding the reconfig_mutex.
> For complete safety I probably need to move the request_module() call
> earlier, as that could block if a device was suspended (no memory
> allocation allowed while device is suspended).
> 
> Thanks,
> NeilBrown
> 
> 
> 
> diff --git a/drivers/md/md.c b/drivers/md/md.c
> index 10367ffe92e3..a7b9c0576479 100644
> --- a/drivers/md/md.c
> +++ b/drivers/md/md.c
> @@ -324,8 +324,12 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio)
>  void mddev_suspend(struct mddev *mddev)
>  {
>  	WARN_ON_ONCE(mddev->thread && current == mddev->thread->tsk);
> +
>  	if (mddev->suspended++)
>  		return;
> +#ifdef CONFIG_LOCKDEP
> +	WARN_ON_ONCE(debug_locks && lockdep_is_held(&mddev->reconfig_mutex));
> +#endif
>  	synchronize_rcu();
>  	wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
>  	mddev->pers->quiesce(mddev, 1);
> @@ -3594,9 +3598,12 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
>  	if (slen == 0 || slen >= sizeof(clevel))
>  		return -EINVAL;
>  
> +	mddev_suspend(mddev);
>  	rv = mddev_lock(mddev);
> -	if (rv)
> +	if (rv) {
> +		mddev_resume(mddev);
>  		return rv;
> +	}
>  
>  	if (mddev->pers == NULL) {
>  		strncpy(mddev->clevel, buf, slen);
> @@ -3687,7 +3694,6 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
>  	}
>  
>  	/* Looks like we have a winner */
> -	mddev_suspend(mddev);
>  	mddev_detach(mddev);
>  
>  	spin_lock(&mddev->lock);
> @@ -3771,13 +3777,13 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
>  	blk_set_stacking_limits(&mddev->queue->limits);
>  	pers->run(mddev);
>  	set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags);
> -	mddev_resume(mddev);
>  	if (!mddev->thread)
>  		md_update_sb(mddev, 1);
>  	sysfs_notify(&mddev->kobj, NULL, "level");
>  	md_new_event(mddev);
>  	rv = len;
>  out_unlock:
> +	mddev_resume(mddev);
>  	mddev_unlock(mddev);
>  	return rv;
>  }
> @@ -4490,6 +4496,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
>  		int err;
>  		if (mddev->pers->start_reshape == NULL)
>  			return -EINVAL;
> +		mddev_suspend(mddev);
>  		err = mddev_lock(mddev);
>  		if (!err) {
>  			if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
> @@ -4500,6 +4507,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
>  			}
>  			mddev_unlock(mddev);
>  		}
> +		mddev_resume(mddev);
>  		if (err)
>  			return err;
>  		sysfs_notify(&mddev->kobj, NULL, "degraded");

The analysis makes a lot of sense, thanks! The patch looks not solving the
problem though, because check_recovery will not write super if suspended isn't
0.

I'm thinking of alternative wayt to fix this issue. A request which stalls in
md_write_start reallys isn't an active IO. We could add another counter in
md_write_start to record stalled request there. Then in mddev_suspend, wait
event will wait for atomic_read(&mddev->active_io) == the_new_counter.

Thanks,
Shaohua

^ permalink raw reply

* Re: 4.11.2: reshape raid5 -> raid6 atop bcache deadlocks at start on md_attr_store / raid5_make_request
From: Nix @ 2017-05-24 19:42 UTC (permalink / raw)
  To: NeilBrown; +Cc: linux-raid
In-Reply-To: <87poezhwsa.fsf@notabene.neil.brown.name>

On 24 May 2017, NeilBrown said:
> Alternately, this might do it.

Bingo! Ticking away nicely:

[  147.538274] md/raid:md125: device sda3 operational as raid disk 0
[  147.574356] md/raid:md125: device sdd3 operational as raid disk 3
[  147.586482] md/raid:md125: device sdc3 operational as raid disk 2
[  147.598571] md/raid:md125: device sdb3 operational as raid disk 1
[  147.613949] md/raid:md125: raid level 6 active with 4 out of 5 devices, algorithm 18
[  147.776155] md: reshape of RAID array md125

md125 : active raid6 sda3[0] sdf3[5] sdd3[4] sdc3[2] sdb3[1]
      15391689216 blocks super 1.2 level 6, 512k chunk, algorithm 18 [5/4] [UUUU_]
      [>....................]  reshape =  0.0% (2669056/5130563072) finish=1363.5min speed=62678K/sec

(wow, this is a lot faster: only 1363 min / 70MiB/s, versus the
--backup-file one, for an array half the size, that was >2500 min,
12MiB/s. I mean, yes, it was at the slow end of the disk, but they don't
differ in speed *that* much.)

Machine still perfectly responsive, as if on reshape was happening at
all. (But then, I've got used to that. The last time I saw any md resync-
induced delays was long ago when I had a sym53c75 in the loop with an
I/O rate of 10MiB/s. I think delays are unavoidable with something
that slow in there.)

^ permalink raw reply

* Re: [PATCH] Detail: don't exit if ioctl has been successful
From: Jes Sorensen @ 2017-05-24 17:28 UTC (permalink / raw)
  To: Tomasz Majchrzak, linux-raid
In-Reply-To: <1495618462-23016-1-git-send-email-tomasz.majchrzak@intel.com>

On 05/24/2017 05:34 AM, Tomasz Majchrzak wrote:
> When GET_ARRAY_INFO ioctl is successful, mdadm exits with an error.
> It breaks udev and no links in /dev/md are created.
> 
> Also change debug print to error print in the message indicating lack
> of the link to facilitate debugging similar issues in the future.
> 
> Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
> ---
>   Detail.c | 27 +++++++++++++++------------
>   util.c   |  2 +-
>   2 files changed, 16 insertions(+), 13 deletions(-)

Applied!

Thanks,
Jes


^ permalink raw reply

* [PATCH] md: uuid debug statement now in processor byte order.
From: Kyungchan Koh @ 2017-05-24 17:16 UTC (permalink / raw)
  To: linux-raid; +Cc: shli, Kernel-team

Previously, the uuid debug statements were printed in little-endian
format, which wasn't consistent in machines that might not be in
little-endian byte order. With this change, the output will be
consistent for all machines with different byte-ordering.

Signed-off-by: Kyungchan Koh <kkc6196@fb.com>
---
 drivers/md/bitmap.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index bf7419a..f4eace5 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -485,10 +485,10 @@ void bitmap_print_sb(struct bitmap *bitmap)
 	pr_debug("         magic: %08x\n", le32_to_cpu(sb->magic));
 	pr_debug("       version: %d\n", le32_to_cpu(sb->version));
 	pr_debug("          uuid: %08x.%08x.%08x.%08x\n",
-		 *(__u32 *)(sb->uuid+0),
-		 *(__u32 *)(sb->uuid+4),
-		 *(__u32 *)(sb->uuid+8),
-		 *(__u32 *)(sb->uuid+12));
+		 le32_to_cpu(*(__u32 *)(sb->uuid+0)),
+		 le32_to_cpu(*(__u32 *)(sb->uuid+4)),
+		 le32_to_cpu(*(__u32 *)(sb->uuid+8)),
+		 le32_to_cpu(*(__u32 *)(sb->uuid+12)));
 	pr_debug("        events: %llu\n",
 		 (unsigned long long) le64_to_cpu(sb->events));
 	pr_debug("events cleared: %llu\n",
-- 
2.9.3


^ permalink raw reply related

* Re: 4.11.2: reshape raid5 -> raid6 atop bcache deadlocks at start on md_attr_store / raid5_make_request
From: Nix @ 2017-05-24 13:28 UTC (permalink / raw)
  To: NeilBrown; +Cc: linux-raid
In-Reply-To: <87poezhwsa.fsf@notabene.neil.brown.name>

On 24 May 2017, NeilBrown uttered the following:

> On Mon, May 22 2017, Nix wrote:
>
>> Everything else hangs the same way, too. This was surprising enough that
>> I double-checked to be sure the patch was applied: it was. I suspect the
>> deadlock is somewhat different than you supposed... (and quite possibly
>> not a race at all, or I wouldn't be hitting it so consistently, every
>> time. I mean, I only need to miss it *once* and I'll have reshaped... :) )
>>
>> It seems I can reproduce this on demand, so if you want to throw a patch
>> with piles of extra printks my way, feel free.
>
> Did you have md_write_start being called by syslog-ng again?

Yeah.

> I wonder what syslog is logging - presumably something about the reshape
> starting.

Almost certainly.

> If you kill syslog-ng, can you start the reshape?

If I kill syslog-ng the entire network gets very unhappy and most of
userspace across all of it blocks solid waiting for a syslog-ng that
isn't there in very little time. It's the primary log host... :/ I might
switch back to the old log host (primary until three weeks ago) and try
again, but honestly the amount of ongoing traffic on this array is such
that I suspect *something* will creep in no matter what you do. (The
only reason process accounting's not going there is because I'm dumping
it on the RAID-0 array I already reshaped.)

(e.g. this time I also saw write traffic from mysqld. God knows what it
was doing: the database there is about the most idle database ever --
which is why I don't care about its being on RAID-5/6 -- and I know for
sure that it currently has a grand total of zero clients connected.)

Plus there's the usual pile of ongoing "you are still breathing so I'll
do more backlogged stuff" XFS metadata updates, rmap traffic, etc.

> Alternately, this might do it.
> I think the root problem is that it isn't safe to call mddev_suspend()
> while holding the reconfig_mutex.
> For complete safety I probably need to move the request_module() call
> earlier, as that could block if a device was suspended (no memory
> allocation allowed while device is suspended).

I'll give this a try!

(I'm not sure what to do if it *works* -- how do I test any later
changes? I might reshape back to RAID-5 + spare again just so I can test
later stuff, but that would take ages: the array is over 14TiB...)

-- 
NULL && (void)

^ permalink raw reply

* [PATCH RESEND] md: Make flush bios explicitely sync
From: Jan Kara @ 2017-05-24 11:40 UTC (permalink / raw)
  To: Shaohua Li; +Cc: Jan Kara, linux-raid, Mike Snitzer, dm-devel

Commit b685d3d65ac7 "block: treat REQ_FUA and REQ_PREFLUSH as
synchronous" removed REQ_SYNC flag from WRITE_{FUA|PREFLUSH|...}
definitions.  generic_make_request_checks() however strips REQ_FUA and
REQ_PREFLUSH flags from a bio when the storage doesn't report volatile
write cache and thus write effectively becomes asynchronous which can
lead to performance regressions

Fix the problem by making sure all bios which are synchronous are
properly marked with REQ_SYNC.

CC: linux-raid@vger.kernel.org
CC: Shaohua Li <shli@kernel.org>
CC: Mike Snitzer <snitzer@redhat.com>
CC: dm-devel@redhat.com
Fixes: b685d3d65ac791406e0dfd8779cc9b3707fea5a3
Signed-off-by: Jan Kara <jack@suse.cz>
---
 drivers/md/dm-snap-persistent.c | 3 ++-
 drivers/md/md.c                 | 2 +-
 drivers/md/raid5-cache.c        | 4 ++--
 3 files changed, 5 insertions(+), 4 deletions(-)

Guys, I don't know enough about DM/MD to judge whether I've identified all the
places that want REQ_SYNC right. Can you please have a look?

diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index b93476c3ba3f..b92ab4cb0710 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -741,7 +741,8 @@ static void persistent_commit_exception(struct dm_exception_store *store,
 	/*
 	 * Commit exceptions to disk.
 	 */
-	if (ps->valid && area_io(ps, REQ_OP_WRITE, REQ_PREFLUSH | REQ_FUA))
+	if (ps->valid && area_io(ps, REQ_OP_WRITE,
+				 REQ_SYNC | REQ_PREFLUSH | REQ_FUA))
 		ps->valid = 0;
 
 	/*
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 10367ffe92e3..212a6777ff31 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -765,7 +765,7 @@ void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
 	    test_bit(FailFast, &rdev->flags) &&
 	    !test_bit(LastDev, &rdev->flags))
 		ff = MD_FAILFAST;
-	bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_FUA | ff;
+	bio->bi_opf = REQ_OP_WRITE | REQ_SYNC | REQ_PREFLUSH | REQ_FUA | ff;
 
 	atomic_inc(&mddev->pending_writes);
 	submit_bio(bio);
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 4c00bc248287..0a7af8b0a80a 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -1782,7 +1782,7 @@ static int r5l_log_write_empty_meta_block(struct r5l_log *log, sector_t pos,
 	mb->checksum = cpu_to_le32(crc32c_le(log->uuid_checksum,
 					     mb, PAGE_SIZE));
 	if (!sync_page_io(log->rdev, pos, PAGE_SIZE, page, REQ_OP_WRITE,
-			  REQ_FUA, false)) {
+			  REQ_SYNC | REQ_FUA, false)) {
 		__free_page(page);
 		return -EIO;
 	}
@@ -2388,7 +2388,7 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
 		mb->checksum = cpu_to_le32(crc32c_le(log->uuid_checksum,
 						     mb, PAGE_SIZE));
 		sync_page_io(log->rdev, ctx->pos, PAGE_SIZE, page,
-			     REQ_OP_WRITE, REQ_FUA, false);
+			     REQ_OP_WRITE, REQ_SYNC | REQ_FUA, false);
 		sh->log_start = ctx->pos;
 		list_add_tail(&sh->r5c, &log->stripe_in_journal_list);
 		atomic_inc(&log->stripe_in_journal_count);
-- 
2.12.0


^ permalink raw reply related

* [PATCH] Detail: don't exit if ioctl has been successful
From: Tomasz Majchrzak @ 2017-05-24  9:34 UTC (permalink / raw)
  To: linux-raid; +Cc: jes.sorensen, Tomasz Majchrzak

When GET_ARRAY_INFO ioctl is successful, mdadm exits with an error.
It breaks udev and no links in /dev/md are created.

Also change debug print to error print in the message indicating lack
of the link to facilitate debugging similar issues in the future.

Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
---
 Detail.c | 27 +++++++++++++++------------
 util.c   |  2 +-
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/Detail.c b/Detail.c
index ef2370c..0adccb7 100644
--- a/Detail.c
+++ b/Detail.c
@@ -99,21 +99,24 @@ int Detail(char *dev, struct context *c)
 	inactive = (sra->array_state == ARRAY_ACTIVE ||
 		    sra->array_state == ARRAY_CLEAR);
 	st = super_by_fd(fd, &subarray);
-	if (md_get_array_info(fd, &array) && errno == ENODEV) {
-		if (sra->array.major_version == -1 &&
-		    sra->array.minor_version == -1 &&
-		    sra->devs == NULL) {
-			pr_err("Array associated with md device %s does not exist.\n", dev);
+	if (md_get_array_info(fd, &array)) {
+		if (errno == ENODEV) {
+			if (sra->array.major_version == -1 &&
+			    sra->array.minor_version == -1 &&
+			    sra->devs == NULL) {
+				pr_err("Array associated with md device %s does not exist.\n",
+				       dev);
+				close(fd);
+				sysfs_free(sra);
+				return rv;
+			}
+			array = sra->array;
+		} else {
+			pr_err("cannot get array detail for %s: %s\n",
+			       dev, strerror(errno));
 			close(fd);
-			sysfs_free(sra);
 			return rv;
 		}
-		array = sra->array;
-	} else {
-		pr_err("cannot get array detail for %s: %s\n",
-		       dev, strerror(errno));
-		close(fd);
-		return rv;
 	}
 
 	if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
diff --git a/util.c b/util.c
index 11ff2cc..2e148ef 100644
--- a/util.c
+++ b/util.c
@@ -1173,7 +1173,7 @@ void wait_for(char *dev, int fd)
 			delay *= 2;
 	}
 	if (i == 25)
-		dprintf("timeout waiting for %s\n", dev);
+		pr_err("timeout waiting for %s\n", dev);
 }
 
 struct superswitch *superlist[] =
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH v4] super1: fix sb->max_dev when adding a new disk in linear array
From: Lidong Zhong @ 2017-05-24  9:24 UTC (permalink / raw)
  To: NeilBrown, linux-raid; +Cc: colyli, Jes.Sorensen
In-Reply-To: <87k257hv9t.fsf@notabene.neil.brown.name>



On 05/24/2017 09:57 AM, NeilBrown wrote:
>>>
>> I think it's also pointless to assign MD_DISK_ROLE_SPARE
>> since there is no SPARE in dev_roles when we need to update
>> sb->max_dev. The newly added device will not meet the condition
>> as max_dev has already been updated, that's saying, we only
>> need to update the max_dev value for original disks.
>> The following code should work
>>
>> 1297     } else if (strcmp(update, "linear-grow-update") == 0) {
>> 1298         unsigned int max = __le32_to_cpu(sb->max_dev);
>> 1299         sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
>> 1300         sb->dev_roles[info->disk.number] =
>> 1301             __cpu_to_le16(info->disk.raid_disk);
>> 1302         if (info->array.raid_disks > max) {
>>
>>
>> 1303             sb->max_dev = __cpu_to_le32(max+1);
>> 1304         }
>
> Increasing max_dev and not initializing will leave the last entry in
> dev_roles[] uninitialised.  That isn't good.
>
Hi Neil,

As I can see, the dev_roles[] value has already been set by line 1300,
because only one disk could be added to the linear array at one time.
When info->array.raid_disks is large than max,
info->disk.number should be equal to max now.
If changing the source into

1297     } else if (strcmp(update, "linear-grow-update") == 0) {
1298         unsigned int max = __le32_to_cpu(sb->max_dev);
1299         sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
1300         if (info->array.raid_disks > max) {
1301             sb->dev_roles[max] = __cpu_to_le16(MD_DISK_ROLE_SPARE);
1302             sb->max_dev = __cpu_to_le32(max+1);
1303         }
1304         sb->dev_roles[info->disk.number] = 
 

1305             __cpu_to_le16(info->disk.raid_disk);

it still works, but I don't see it as necessary.
> MD_DISK_ROLE_SPARE doesn't mean there is a spare device in that slot.
> It means that if there is a device in that slot, it must be spare.
> If you leave it uninitialised, it will probably be zero, and then
> you will get "?" in the mdadm output again.
>

I did a test with growing a linear array to 129 devices

/dev/dm-128:
           Magic : a92b4efc
         Version : 1.2
     Feature Map : 0x0
      Array UUID : 8bed7e5c:1acea7d9:9087c183:77f44fc0
            Name : sles12sp2-clone1:0  (local to host sles12sp2-clone1)
   Creation Time : Wed May 24 16:56:10 2017
      Raid Level : linear
    Raid Devices : 129

  Avail Dev Size : 106400 (51.95 MiB 54.48 MB)
   Used Dev Size : 0
     Data Offset : 96 sectors
    Super Offset : 8 sectors
    Unused Space : before=8 sectors, after=0 sectors
           State : clean
     Device UUID : 47dec6cb:e84ddc52:35f7290b:7c47a1c6

     Update Time : Wed May 24 16:56:10 2017
   Bad Block Log : 512 entries available at offset 72 sectors
        Checksum : 57c7a375 - correct
          Events : 0

        Rounding : 0K

    Device Role : Active device 128
    Array State : 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
('A' == active, '.' == missing, 'R' == replacing)
Debug Array State (raid_disks 129, delta_extra 0) :
dev_roles[0]:0 dev_roles[1]:1 dev_roles[2]:2 dev_roles[3]:3 
dev_roles[4]:4 dev_roles[5]:5 dev_roles[6]:6 dev_roles[7]:7 
dev_roles[8]:8 dev_roles[9]:9 dev_roles[10]:a dev_roles[11]:b 
dev_roles[12]:c dev_roles[13]:d dev_roles[14]:e dev_roles[15]:f 
dev_roles[16]:10 dev_roles[17]:11 dev_roles[18]:12 dev_roles[19]:13 
dev_roles[20]:14 dev_roles[21]:15 dev_roles[22]:16 dev_roles[23]:17 
dev_roles[24]:18 dev_roles[25]:19 dev_roles[26]:1a dev_roles[27]:1b 
dev_roles[28]:1c dev_roles[29]:1d dev_roles[30]:1e dev_roles[31]:1f 
dev_roles[32]:20 dev_roles[33]:21 dev_roles[34]:22 dev_roles[35]:23 
dev_roles[36]:24 dev_roles[37]:25 dev_roles[38]:26 dev_roles[39]:27 
dev_roles[40]:28 dev_roles[41]:29 dev_roles[42]:2a dev_roles[43]:2b 
dev_roles[44]:2c dev_roles[45]:2d dev_roles[46]:2e dev_roles[47]:2f 
dev_roles[48]:30 dev_roles[49]:31 dev_roles[50]:32 dev_roles[51]:33 
dev_roles[52]:34 dev_roles[53]:35 dev_roles[54]:36 dev_roles[55]:37 
dev_roles[56]:38 dev_roles[57]:39 dev_roles[58]:3a dev_roles[59]:3b 
dev_roles[60]:3c dev_roles[61]:3d dev_roles[62]:3e dev_roles[63]:3f 
dev_roles[64]:40 dev_roles[65]:41 dev_roles[66]:42 dev_roles[67]:43 
dev_roles[68]:44 dev_roles[69]:45 dev_roles[70]:46 dev_roles[71]:47 
dev_roles[72]:48 dev_roles[73]:49 dev_roles[74]:4a dev_roles[75]:4b 
dev_roles[76]:4c dev_roles[77]:4d dev_roles[78]:4e dev_roles[79]:4f 
dev_roles[80]:50 dev_roles[81]:51 dev_roles[82]:52 dev_roles[83]:53 
dev_roles[84]:54 dev_roles[85]:55 dev_roles[86]:56 dev_roles[87]:57 
dev_roles[88]:58 dev_roles[89]:59 dev_roles[90]:5a dev_roles[91]:5b 
dev_roles[92]:5c dev_roles[93]:5d dev_roles[94]:5e dev_roles[95]:5f 
dev_roles[96]:60 dev_roles[97]:61 dev_roles[98]:62 dev_roles[99]:63 
dev_roles[100]:64 dev_roles[101]:65 dev_roles[102]:66 dev_roles[103]:67 
dev_roles[104]:68 dev_roles[105]:69 dev_roles[106]:6a dev_roles[107]:6b 
dev_roles[108]:6c dev_roles[109]:6d dev_roles[110]:6e dev_roles[111]:6f 
dev_roles[112]:70 dev_roles[113]:71 dev_roles[114]:72 dev_roles[115]:73 
dev_roles[116]:74 dev_roles[117]:75 dev_roles[118]:76 dev_roles[119]:77 
dev_roles[120]:78 dev_roles[121]:79 dev_roles[122]:7a dev_roles[123]:7b 
dev_roles[124]:7c dev_roles[125]:7d dev_roles[126]:7e dev_roles[127]:7f 
dev_roles[128]:80

And there is no problem showing the status.

Thanks,
Lidong
> NeilBrown
>
>
>>
>> Thank you for your patient review.
>>
>> Lidong
>>
>>> NeilBrown
>>>
>>>
>>>> +			sb->max_dev = __cpu_to_le32(max+1);
>>>> +		}
>>>>  	} else if (strcmp(update, "resync") == 0) {
>>>>  		/* make sure resync happens */
>>>>  		sb->resync_offset = 0ULL;
>>>> --
>>>> 2.12.0

^ permalink raw reply

* Re: Reducing the number of devices in a degraded RAID-5
From: NeilBrown @ 2017-05-24  2:12 UTC (permalink / raw)
  To: Andreas Klauer, linux-raid
In-Reply-To: <20170522125332.GA18406@metamorpher.de>

[-- Attachment #1: Type: text/plain, Size: 2523 bytes --]

On Mon, May 22 2017, Andreas Klauer wrote:

> Hi,
>
> this is not a recovery question, no real data involved. Thanks for helping!
>
> Suppose you have a failing drive in RAID-5 but you wanted to move to 
> fewer drives anyway, so one way or another you're going to reduce 
> the number of drives in your RAID.
>
> Given a RAID 5 with 5 drives            [UUUUU]
> Reducing it by one drive results in     [UUUU] + Spare
> Okay.
>
> Given a degraded RAID 5 with 5 drives   [_UUUU]
> Reducing it by one drive results in     [_UUU] + Spare
> Still okay? Rebuild must be started manually.
>
> It seems reducing a degraded RAID is a bad idea, 
> since there is no redundancy for a very long time.
>
> So what you might end up doing is a three step process:
>
> -> [_UUUU] (Degraded)
>
> Step 1: Add another drive (redundancy first)
>
> -> [UUUUU]
>     ^ added drive
>
> Step 2: Reduce by one drive
>
> -> [UUUU] + Spare
>
> Step 3: --replace the previously added drive
>         (if the spare happened to be one of the drives you wanted to keep)
>
> -> [UUUU]
>     ^ former spare
>
> This way the process is redundant but it takes a very long time, 
> three separate reshape/rebuilds instead of just one.
>
> Steps to reproduce the [_UUUU] -> [_UUU] + Spare case:
> (using linux 4.10, mdadm 4.0)
>
> # truncate -s 100M 1.img 2.img 3.img 4.img
> # devices=$(for f in ?.img; do losetup --find --show "$f"; done)
> # mdadm --create /dev/md42 --level=5 --raid-devices=5 missing $devices
> md42 : active raid5 loop4[4] loop3[3] loop2[2] loop1[1]
>       405504 blocks super 1.2 level 5, 512k chunk, algorithm 2 [5/4] [_UUUU]
> # mdadm --grow /dev/md42 --array-size 304128
> # mdadm --grow /dev/md42 --backup-file=md42.backup --raid-devices=4
> md42 : active raid5 loop4[4](S) loop3[3] loop2[2] loop1[1]
>       304128 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/3] [_UUU]
> # not rebuilding until you re-add the spare
>
> Is it possible to do [_UUUU] -> [UUUU] in a single step?
> I haven't found a way. Any ideas?

I hoped that
  mdadm --grow /dev/md42 --backup-file=... --raid-device=4 --add /dev/loop4

would have worked, but it doesn't.
What does work is:
 # start with a degraded array, device 0 missing
 mdadm --grow /dev/md42 --array-size=.....
 echo frozen > /sys/block/md42/md/sync_action
 mdadm /dev/md42 --add /dev/loop0
 echo 0 > /sys/block/md42/md/dev-loop0/slot
 mdadm --grow /dev/md42 --backup-file=... --raid-devices=4


NeilBrown


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply

* Re: [PATCH v4] super1: fix sb->max_dev when adding a new disk in linear array
From: NeilBrown @ 2017-05-24  1:57 UTC (permalink / raw)
  To: Lidong Zhong, linux-raid; +Cc: colyli, Jes.Sorensen
In-Reply-To: <20e71aa6-e9e0-312f-747a-d25b872d2af8@suse.com>

[-- Attachment #1: Type: text/plain, Size: 4558 bytes --]

On Tue, May 23 2017, Lidong Zhong wrote:

> On 05/22/2017 07:07 PM, NeilBrown wrote:
>> On Mon, May 22 2017, Lidong Zhong wrote:
>>
>>> The value of sb->max_dev will always be increased by 1 when adding
>>> a new disk in linear array. It causes an inconsistence between each
>>> disk in the array and the "Array State" value of "mdadm --examine DISK"
>>> is wrong. For example, when adding the first new disk into linear array
>>> it will be:
>>>
>>> Array State : RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
>>> ('A' == active, '.' == missing, 'R' == replacing)
>>>
>>> Adding the second disk into linear array it will be
>>>
>>> Array State : .AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
>>> ('A' == active, '.' == missing, 'R' == replacing)
>>>
>>> Signed-off-by: Lidong Zhong <lzhong@suse.com>
>>> ---
>>>  super1.c | 9 ++++++++-
>>>  1 file changed, 8 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/super1.c b/super1.c
>>> index 2fcb814..03cea72 100644
>>> --- a/super1.c
>>> +++ b/super1.c
>>> @@ -1267,8 +1267,10 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
>>>  				break;
>>>  		sb->dev_number = __cpu_to_le32(i);
>>>  		info->disk.number = i;
>>> -		if (max >= __le32_to_cpu(sb->max_dev))
>>> +		if (i >= max) {
>>> +			sb->dev_roles[max] = __cpu_to_le16(MD_DISK_ROLE_SPARE);
>>
>
> Hi Neil,
>
>> Why do you assign to dev_roles[max]?
>
> I meant to assure there will always be a spare spot in dev_roles[],
> that is sb->max_dev at least is at lease 1 more than raid_disks.
> Now I see what you mean in your reply to my last version patch.
>
>> max must equal i here, and a few lines later:
>> 		sb->dev_roles[i] = __cpu_to_le16(info->disk.raid_disk);
>>
>> your assignment is over-written.  So it is pointless.
>> If i was greater than max (which should be impossible), you assignment
>> here would corrupt the dev_roles table.
>>
>> Please drop this assignment.
>
> Yes, just increase the max_dev value is enough.
>
>>
>>>  			sb->max_dev = __cpu_to_le32(max+1);
>>> +		}
>>>
>>>  		random_uuid(sb->device_uuid);
>>>
>>> @@ -1293,9 +1295,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
>>>  			}
>>>  		}
>>>  	} else if (strcmp(update, "linear-grow-update") == 0) {
>>> +		unsigned int max = __le32_to_cpu(sb->max_dev);
>>>  		sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
>>>  		sb->dev_roles[info->disk.number] =
>>>  			__cpu_to_le16(info->disk.raid_disk);
>>> +		if (info->array.raid_disks >= max) {
>>
>> if raid_disks == max there is no need to change anything.
>> It is only when raid_disks > max that you need to increase max.
>>
>
> Yes, the max_dev should only be updated when raid_disks > max.
>
>>> +			sb->dev_roles[max] = __cpu_to_le16(MD_DISK_ROLE_SPARE);
>>
>> When you increase max, you do need to assign MD_DISK_ROLE_SPARE to the
>> new element, but you need to do that *before* disk.raid_disk is
>> assigned, in case info->disk.number == max (as it could be for the
>> recently added device).
>>
> I think it's also pointless to assign MD_DISK_ROLE_SPARE
> since there is no SPARE in dev_roles when we need to update
> sb->max_dev. The newly added device will not meet the condition
> as max_dev has already been updated, that's saying, we only
> need to update the max_dev value for original disks.
> The following code should work
>
> 1297     } else if (strcmp(update, "linear-grow-update") == 0) {
> 1298         unsigned int max = __le32_to_cpu(sb->max_dev);
> 1299         sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
> 1300         sb->dev_roles[info->disk.number] =
> 1301             __cpu_to_le16(info->disk.raid_disk);
> 1302         if (info->array.raid_disks > max) { 
>  
>
> 1303             sb->max_dev = __cpu_to_le32(max+1);
> 1304         }

Increasing max_dev and not initializing will leave the last entry in
dev_roles[] uninitialised.  That isn't good.

MD_DISK_ROLE_SPARE doesn't mean there is a spare device in that slot.
It means that if there is a device in that slot, it must be spare.
If you leave it uninitialised, it will probably be zero, and then
you will get "?" in the mdadm output again.

NeilBrown


>
> Thank you for your patient review.
>
> Lidong
>
>> NeilBrown
>>
>>
>>> +			sb->max_dev = __cpu_to_le32(max+1);
>>> +		}
>>>  	} else if (strcmp(update, "resync") == 0) {
>>>  		/* make sure resync happens */
>>>  		sb->resync_offset = 0ULL;
>>> --
>>> 2.12.0

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply

* Re: 4.11.2: reshape raid5 -> raid6 atop bcache deadlocks at start on md_attr_store / raid5_make_request
From: NeilBrown @ 2017-05-24  1:50 UTC (permalink / raw)
  To: Wols Lists, Nix; +Cc: linux-raid
In-Reply-To: <59244B95.4080600@youngman.org.uk>

[-- Attachment #1: Type: text/plain, Size: 1239 bytes --]

On Tue, May 23 2017, Wols Lists wrote:

> Thanks. I've updated the section. I've taken pretty much everything
> you've said, but rewritten it in my own words, so that the page remains
> consistent in style. I hope I haven't missed anything.
>
> It's thrown up two little points I've noted on the page - if a v1.0
> mirror has its offset changed, does this break the linux boot? (that's
> the "without an initramfs" boot that doesn't assemble the mirror until
> after the kernel is running).

Yes, if a v1.0 has a data offset that wasn't zero, you wouldn't be able
to boot of a member device.
But there is no good reason that I can think of to change the data
offset of a device in a RAID1.

>
> And if you shut down cleanly during a backup-file reshape, is this fact
> noted or does mdadm just assume any shutdown is dirty and use the backup
> file anyway?

The backup file contains UUID and version info.
When mdadm determines that part of the backup is no longer needed, it
invalidates the backup before enabling writes to that region of the
array.
So it only uses the file is there is good reason to suspect that it is
both necessary and safe. (It may not always be necessary.  It should
always be safe).

NeilBrown


>
> Cheers,
> Wol

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply

* Re: 4.11.2: reshape raid5 -> raid6 atop bcache deadlocks at start on md_attr_store / raid5_make_request
From: NeilBrown @ 2017-05-24  1:24 UTC (permalink / raw)
  To: Nix; +Cc: linux-raid
In-Reply-To: <87fufwy3lr.fsf@esperi.org.uk>

[-- Attachment #1: Type: text/plain, Size: 5259 bytes --]

On Mon, May 22 2017, Nix wrote:

> On 22 May 2017, NeilBrown told this:
>
>> Probably something like this:
>>
>> diff --git a/drivers/md/md.c b/drivers/md/md.c
>> index f6ae1d67bcd0..dbca31be22a1 100644
>> --- a/drivers/md/md.c
>> +++ b/drivers/md/md.c
>> @@ -8364,8 +8364,6 @@ static void md_start_sync(struct work_struct *ws)
>>   */
>>  void md_check_recovery(struct mddev *mddev)
>>  {
>> -	if (mddev->suspended)
>> -		return;
>>  
>>  	if (mddev->bitmap)
>>  		bitmap_daemon_work(mddev);
>> @@ -8484,6 +8482,7 @@ void md_check_recovery(struct mddev *mddev)
>>  		clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
>>  
>>  		if (!test_and_clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
>> +		    mddev->suspended ||
>>  		    test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
>>  			goto not_running;
>>  		/* no recovery is running.
>>
>> though it's late so don't trust anything I write.
>>
>> If you try again it will almost certainly succeed.  I suspect this is a
>> hard race to hit - well done!!!
>
> Definitely not a hard race to hit :( I just hit it again with this
> patch.
>
> Absolutely identical hang:
>
> [  495.833520] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  495.840618] mdadm           D    0  2700   2537 0x00000000
> [  495.847762] Call Trace:
> [  495.854825]  __schedule+0x290/0x810
> [  495.861905]  schedule+0x36/0x80
> [  495.868934]  mddev_suspend+0xb3/0xe0
> [  495.875926]  ? wake_atomic_t_function+0x60/0x60
> [  495.882976]  level_store+0x1a7/0x6c0
> [  495.889953]  ? md_ioctl+0xb7/0x1c10
> [  495.896901]  ? putname+0x53/0x60
> [  495.903807]  md_attr_store+0x83/0xc0
> [  495.910684]  sysfs_kf_write+0x37/0x40
> [  495.917547]  kernfs_fop_write+0x110/0x1a0
> [  495.924429]  __vfs_write+0x28/0x120
> [  495.931270]  ? kernfs_iop_get_link+0x172/0x1e0
> [  495.938126]  ? __alloc_fd+0x3f/0x170
> [  495.944906]  vfs_write+0xb6/0x1d0
> [  495.951646]  SyS_write+0x46/0xb0
> [  495.958338]  entry_SYSCALL_64_fastpath+0x13/0x94
>
> Everything else hangs the same way, too. This was surprising enough that
> I double-checked to be sure the patch was applied: it was. I suspect the
> deadlock is somewhat different than you supposed... (and quite possibly
> not a race at all, or I wouldn't be hitting it so consistently, every
> time. I mean, I only need to miss it *once* and I'll have reshaped... :) )
>
> It seems I can reproduce this on demand, so if you want to throw a patch
> with piles of extra printks my way, feel free.

Did you have md_write_start being called by syslog-ng again?
I wonder what syslog is logging - presumably something about the reshape
starting.
If you kill syslog-ng, can you start the reshape?

Alternately, this might do it.
I think the root problem is that it isn't safe to call mddev_suspend()
while holding the reconfig_mutex.
For complete safety I probably need to move the request_module() call
earlier, as that could block if a device was suspended (no memory
allocation allowed while device is suspended).

Thanks,
NeilBrown



diff --git a/drivers/md/md.c b/drivers/md/md.c
index 10367ffe92e3..a7b9c0576479 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -324,8 +324,12 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio)
 void mddev_suspend(struct mddev *mddev)
 {
 	WARN_ON_ONCE(mddev->thread && current == mddev->thread->tsk);
+
 	if (mddev->suspended++)
 		return;
+#ifdef CONFIG_LOCKDEP
+	WARN_ON_ONCE(debug_locks && lockdep_is_held(&mddev->reconfig_mutex));
+#endif
 	synchronize_rcu();
 	wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
 	mddev->pers->quiesce(mddev, 1);
@@ -3594,9 +3598,12 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
 	if (slen == 0 || slen >= sizeof(clevel))
 		return -EINVAL;
 
+	mddev_suspend(mddev);
 	rv = mddev_lock(mddev);
-	if (rv)
+	if (rv) {
+		mddev_resume(mddev);
 		return rv;
+	}
 
 	if (mddev->pers == NULL) {
 		strncpy(mddev->clevel, buf, slen);
@@ -3687,7 +3694,6 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
 	}
 
 	/* Looks like we have a winner */
-	mddev_suspend(mddev);
 	mddev_detach(mddev);
 
 	spin_lock(&mddev->lock);
@@ -3771,13 +3777,13 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
 	blk_set_stacking_limits(&mddev->queue->limits);
 	pers->run(mddev);
 	set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags);
-	mddev_resume(mddev);
 	if (!mddev->thread)
 		md_update_sb(mddev, 1);
 	sysfs_notify(&mddev->kobj, NULL, "level");
 	md_new_event(mddev);
 	rv = len;
 out_unlock:
+	mddev_resume(mddev);
 	mddev_unlock(mddev);
 	return rv;
 }
@@ -4490,6 +4496,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
 		int err;
 		if (mddev->pers->start_reshape == NULL)
 			return -EINVAL;
+		mddev_suspend(mddev);
 		err = mddev_lock(mddev);
 		if (!err) {
 			if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
@@ -4500,6 +4507,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
 			}
 			mddev_unlock(mddev);
 		}
+		mddev_resume(mddev);
 		if (err)
 			return err;
 		sysfs_notify(&mddev->kobj, NULL, "degraded");

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply related

* Re: 4.11.2: reshape raid5 -> raid6 atop bcache deadlocks at start on md_attr_store / raid5_make_request
From: Nix @ 2017-05-23 15:00 UTC (permalink / raw)
  To: Wols Lists; +Cc: NeilBrown, linux-raid
In-Reply-To: <59244428.4050001@youngman.org.uk>

On 23 May 2017, Wols Lists told this:

> On 22/05/17 22:38, Nix wrote:
>> Everything else hangs the same way, too. This was surprising enough that
>> I double-checked to be sure the patch was applied: it was. I suspect the
>> deadlock is somewhat different than you supposed... (and quite possibly
>> not a race at all, or I wouldn't be hitting it so consistently, every
>> time. I mean, I only need to miss it *once* and I'll have reshaped... :) )
>> 
>> It seems I can reproduce this on demand, so if you want to throw a patch
>> with piles of extra printks my way, feel free.
>
> Could this be the long-standing bug that hangs raid5 and raid6 reshapes?
> I don't remember it being found and fixed. iirc (it's too long ago) it
> hit people adding a drive to a raid5 (occasionally a raid6), and was
> fairly easy to get round. Again it's too long ago but stopping and
> starting the reshape fixed it usually iirc.

It hangs access to the whole drive irretrievably, immediately on
starting the reshape (it can't happen at any later time because it is
associated with writing out the level change itself: thank goodness, it
happens *before* the write, not afterwards). I don't know if the hangs
you refer to have similar symptoms.

-- 
NULL && (void)

^ permalink raw reply

* Re: 4.11.2: reshape raid5 -> raid6 atop bcache deadlocks at start on md_attr_store / raid5_make_request
From: Wols Lists @ 2017-05-23 14:47 UTC (permalink / raw)
  To: NeilBrown, Nix; +Cc: linux-raid
In-Reply-To: <87y3toic67.fsf@notabene.neil.brown.name>

On 23/05/17 02:39, NeilBrown wrote:
> On Mon, May 22 2017, Wols Lists wrote:
> 
>> On 22/05/17 16:30, Nix wrote:
>>> I'll give it a try -- I hit it twice in succession, once with a
>>> --backup-file, once without. Since mdadm does not warn about the lack of
>>> a --backup-file, I guess the statement in the manual that it is
>>> essential to provide one when changing RAID levels is untrue: I suspect
>>> that it's necessary *if* you're not increasing the number of disks at
>>> the same time, but since I'm growing into a spare, adding a
>>> --backup-file only slows it down?
>>
>> I did discuss this with Neil while I wrote it, so I hope I got it right :-)
>>
>> https://raid.wiki.kernel.org/index.php/A_guide_to_mdadm#Array_internals_and_how_it_affects_mdadm
>>
>> aiui, provided you're using a v1 superblock, the data offset means there
>> is spare space on the drives precisely for the purpose (one of then at
>> least) of keeping a backup. So the reshape will start reshaping into the
>> spare space and eliminate the need for the backup - the new version of
>> the stripe will be safely written before the space occupied by the old
>> stripe is required.
>>
>> Cheers,
>> Wol
> 
> Proof-reading time.  I'll be very picky.  You'll ignore places where you
> think my pickiness isn't helpful.
> 
>> The first arrays did not have a superblock, and were declared in
>> mdadm.conf.
> 
> The first arrays (linear and raid0 only) did not have a superblock and
> were declared in "raidtab" which was managed by the deprecated
> "raid-tools" which have been replaced by mdadm.
> 
> mdadm does now allow you to declare no-superblock arrays in mdadm.
> You can build them with "mdadm --build .....", but that is all.
> 
>> and the backup area when reshaping an array.
> 
> Not quite.  The whole point of being able to move the data offset
> is that backup isn't needed.  Maybe it could read:
> 
>  ... and some extra space so that the data areas can be moved forward or
>  backward on the device by several stripes.  This is useful when
>  reshaping.
> 
>> All operations that involve moving data around are called reshapes,
>> and require some form of backup.
> 
>  All operations that involve moving data around are called reshapes and
>  need to be careful only to write to a region of the device which
>  can safely be corrupted.  If a system crash happens during a reshape,
>  the region that was being written to must be considered to contain
>  garbage.
>  The preferred mechanism is to relocate the data by a few stripes,
>  reading data from a region of the disk that contains live data, and
>  writing it into a sliding window that is otherwise unused.  After a few
>  stripes have been copied, the metadata in the superblock is updated, so
>  that the newly written data is now "live" and the location it was
>  copied from is now "unused" and can have more stripes copied into it.
>  This process results in the Data Offset being moved by several
>  megabytes, either forward or backward, and it is to allow for this to
>  happen that the Data Offset is set to several to many megabytes when an
>  array is created.
> 
>  If it is not possible to move the Data Offset, either because there is
>  no room or because the v0.90 superblock is in use, mdadm will take a
>  backup of the region of data being reshaped before it allows the
>  reshape to progress.  In the event of a crash, mdadm will restore this
>  data over the potentially corrupted region of the array before starting
>  the array.
> 
> Your current text already covers some of this, and there probably isn't a
> need to replace it all.
> But I think it is important not to talk about the reserved space in the
> devices a backup space.
> 
Thanks. I've updated the section. I've taken pretty much everything
you've said, but rewritten it in my own words, so that the page remains
consistent in style. I hope I haven't missed anything.

It's thrown up two little points I've noted on the page - if a v1.0
mirror has its offset changed, does this break the linux boot? (that's
the "without an initramfs" boot that doesn't assemble the mirror until
after the kernel is running).

And if you shut down cleanly during a backup-file reshape, is this fact
noted or does mdadm just assume any shutdown is dirty and use the backup
file anyway?

Cheers,
Wol


^ permalink raw reply

* Re: 4.11.2: reshape raid5 -> raid6 atop bcache deadlocks at start on md_attr_store / raid5_make_request
From: Wols Lists @ 2017-05-23 14:16 UTC (permalink / raw)
  To: Nix, NeilBrown; +Cc: linux-raid
In-Reply-To: <87fufwy3lr.fsf@esperi.org.uk>

On 22/05/17 22:38, Nix wrote:
> Everything else hangs the same way, too. This was surprising enough that
> I double-checked to be sure the patch was applied: it was. I suspect the
> deadlock is somewhat different than you supposed... (and quite possibly
> not a race at all, or I wouldn't be hitting it so consistently, every
> time. I mean, I only need to miss it *once* and I'll have reshaped... :) )
> 
> It seems I can reproduce this on demand, so if you want to throw a patch
> with piles of extra printks my way, feel free.

Could this be the long-standing bug that hangs raid5 and raid6 reshapes?
I don't remember it being found and fixed. iirc (it's too long ago) it
hit people adding a drive to a raid5 (occasionally a raid6), and was
fairly easy to get round. Again it's too long ago but stopping and
starting the reshape fixed it usually iirc.

Cheers,
Wol

^ permalink raw reply

* Ciao
From: xbtpnxoh @ 2017-05-23 13:22 UTC (permalink / raw)
  To: lesabati

come va
Vendiamo principalmente gli occhiali da sole di Ray Ban, soltanto 24.99euro, trasporto libero. Benvenuto al nostro deposito
www . rbewpt .com

^ permalink raw reply

* Re: [PATCH 10/23] afs: switch to use uuid_t and uuid_gen
From: Andy Shevchenko @ 2017-05-23 13:11 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-xfs-u79uwXL29TY76Z2rM5mHXA,
	linux-raid-u79uwXL29TY76Z2rM5mHXA,
	linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw, Mimi Zohar, Amir Goldstein,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Howells,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Shaohua Li,
	Steven Whitehouse
In-Reply-To: <20170523084956.GB20121-jcswGhMUV9g@public.gmane.org>

On Tue, 2017-05-23 at 10:49 +0200, Christoph Hellwig wrote:
> On Mon, May 22, 2017 at 09:49:17PM +0300, Andy Shevchenko wrote:
> > >  	struct afs_call *call = container_of(work, struct
> > > afs_call,
> > > work);
> > > -	struct uuid_v1 *r = call->request;
> > > +	uuid_t *r = call->request;
> > >  
> > >  	struct {
> > >  		__be32	match;
> > > 
> > 
> > Just to double check that this doesn't create a union aliasing.
> 
> What do you mean with that?

Since we introduced a union it's possible that we might access the
member which wasn't last modified one. So, my comment is to give an
attention on such possibility and avoid if there is an aliasing
happened.

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply

* Re: 4.11.2: reshape raid5 -> raid6 atop bcache deadlocks at start on md_attr_store / raid5_make_request
From: Nix @ 2017-05-23 10:10 UTC (permalink / raw)
  To: NeilBrown; +Cc: Wols Lists, linux-raid
In-Reply-To: <871srgjrnf.fsf@notabene.neil.brown.name>

On 23 May 2017, NeilBrown outgrape:

> On Mon, May 22 2017, Nix wrote:
>
>> On 22 May 2017, Wols Lists verbalised:
>>
>> But it's only a few KiB by default! The amount of seeking needed to
>> reshape with such a small intermediate would be fairly horrific. (It was
>> bad enough as it was: the reshape of 7TiB took more than two days,
>> running at under 15MiB/s, though the component drives can all handle
>> 220MiB/s easily. The extra time was spent seeking to and from the
>> backup, it seems.)
>
> If the space before were "only a few KiB", it wouldn't be used.
> You need at least 1 full stripe, typically more.
> Current mdadm leaves several megabytes I think.

I was about to protest and say "oh but it doesn't"... but it helps if
I'm looking at the right machine. It does, but it didn't in 2009 :)

>> spindles will move the data offset such that it is (still) on a chunk or
>> stripe multiple? That's neat, if so, and means I wasted 128MiB on this,
>> uh, 12TiB array. OK I'm not terribly blown away by this, particularly
>> given that I'm wasting the same again inside the bcache partition for
>> the same reason: I'm sure mdadm won't move *that* data offset.)
>
> Data offset is always moved by a multiple of the chunk size.

Right, so the overlying fs might not be doing full-stripe writes after a
reshape, even if it thinks it is, but it will certainly be doing
chunk-multiple writes.

> When I create a 12-device raid5 on 1TB devices, then examine one of them,
> it says:
>
>     Data Offset : 262144 sectors
>    Unused Space : before=262064 sectors, after=0 sectors
>      Chunk Size : 512K

(which is 21.3... stripes.)

> so there is 130Megabytes of space per device, enough for 255 chunks.
> When mdadm moves the Data Offset to allow a reshape to happen without a
> backup file, it aims to use half the available space.  So it would use
> about 60Meg in about 120 chunks or 720Meg total across all devices.
> This is more than the 500MiB backup file you saw.

Right. The message in the manpage saying that backup files are required
for a level change is obsolete, then (and I probably slowed down my last
reshape by specifying one, since seeking to the backup file at the other
end of the disk would have been *much* slower than seeking to that slack
space before the data offset).

^ permalink raw reply

* Re: [PATCH 10/23] afs: switch to use uuid_t and uuid_gen
From: Christoph Hellwig @ 2017-05-23  8:49 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-xfs-u79uwXL29TY76Z2rM5mHXA,
	linux-raid-u79uwXL29TY76Z2rM5mHXA,
	linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw, Mimi Zohar, Amir Goldstein,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Steven Whitehouse,
	David Howells, linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Shaohua Li,
	Christoph Hellwig
In-Reply-To: <1495478957.6967.69.camel-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

On Mon, May 22, 2017 at 09:49:17PM +0300, Andy Shevchenko wrote:
> >  	struct afs_call *call = container_of(work, struct afs_call,
> > work);
> > -	struct uuid_v1 *r = call->request;
> > +	uuid_t *r = call->request;
> >  
> >  	struct {
> >  		__be32	match;
> > 
> 
> Just to double check that this doesn't create a union aliasing.

What do you mean with that?

^ permalink raw reply

* Re: [PATCH 13/23] md: namespace private helper names
From: Christoph Hellwig @ 2017-05-23  8:41 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Christoph Hellwig, Amir Goldstein, linux-fsdevel, Shaohua Li,
	Dan Williams, David Howells, Steven Whitehouse, Mimi Zohar,
	linux-xfs, linux-raid, linux-nvdimm, linux-kernel
In-Reply-To: <1495479147.6967.70.camel@linux.intel.com>

On Mon, May 22, 2017 at 09:52:27PM +0300, Andy Shevchenko wrote:
> On Thu, 2017-05-18 at 08:26 +0200, Christoph Hellwig wrote:
> > From: Amir Goldstein <amir73il@gmail.com>
> > 
> > The md private helper uuid_equal() collides with a generic helper
> > of the same name.
> > 
> > Rename the md private helper to md_uuid_equal() and do the same for
> > md_sb_equal().
> > 
> 
> While patch is good, shouldn't it go before we introduce those helpers?

Yes, I'll move it to the beginning of the series.

^ permalink raw reply

* Re: [PATCH v4] super1: fix sb->max_dev when adding a new disk in linear array
From: Lidong Zhong @ 2017-05-23  3:55 UTC (permalink / raw)
  To: NeilBrown, linux-raid; +Cc: colyli, Jes.Sorensen
In-Reply-To: <87d1b1jgju.fsf@notabene.neil.brown.name>



On 05/22/2017 07:07 PM, NeilBrown wrote:
> On Mon, May 22 2017, Lidong Zhong wrote:
>
>> The value of sb->max_dev will always be increased by 1 when adding
>> a new disk in linear array. It causes an inconsistence between each
>> disk in the array and the "Array State" value of "mdadm --examine DISK"
>> is wrong. For example, when adding the first new disk into linear array
>> it will be:
>>
>> Array State : RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
>> ('A' == active, '.' == missing, 'R' == replacing)
>>
>> Adding the second disk into linear array it will be
>>
>> Array State : .AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
>> ('A' == active, '.' == missing, 'R' == replacing)
>>
>> Signed-off-by: Lidong Zhong <lzhong@suse.com>
>> ---
>>  super1.c | 9 ++++++++-
>>  1 file changed, 8 insertions(+), 1 deletion(-)
>>
>> diff --git a/super1.c b/super1.c
>> index 2fcb814..03cea72 100644
>> --- a/super1.c
>> +++ b/super1.c
>> @@ -1267,8 +1267,10 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
>>  				break;
>>  		sb->dev_number = __cpu_to_le32(i);
>>  		info->disk.number = i;
>> -		if (max >= __le32_to_cpu(sb->max_dev))
>> +		if (i >= max) {
>> +			sb->dev_roles[max] = __cpu_to_le16(MD_DISK_ROLE_SPARE);
>

Hi Neil,

> Why do you assign to dev_roles[max]?

I meant to assure there will always be a spare spot in dev_roles[],
that is sb->max_dev at least is at lease 1 more than raid_disks.
Now I see what you mean in your reply to my last version patch.

> max must equal i here, and a few lines later:
> 		sb->dev_roles[i] = __cpu_to_le16(info->disk.raid_disk);
>
> your assignment is over-written.  So it is pointless.
> If i was greater than max (which should be impossible), you assignment
> here would corrupt the dev_roles table.
>
> Please drop this assignment.

Yes, just increase the max_dev value is enough.

>
>>  			sb->max_dev = __cpu_to_le32(max+1);
>> +		}
>>
>>  		random_uuid(sb->device_uuid);
>>
>> @@ -1293,9 +1295,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
>>  			}
>>  		}
>>  	} else if (strcmp(update, "linear-grow-update") == 0) {
>> +		unsigned int max = __le32_to_cpu(sb->max_dev);
>>  		sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
>>  		sb->dev_roles[info->disk.number] =
>>  			__cpu_to_le16(info->disk.raid_disk);
>> +		if (info->array.raid_disks >= max) {
>
> if raid_disks == max there is no need to change anything.
> It is only when raid_disks > max that you need to increase max.
>

Yes, the max_dev should only be updated when raid_disks > max.

>> +			sb->dev_roles[max] = __cpu_to_le16(MD_DISK_ROLE_SPARE);
>
> When you increase max, you do need to assign MD_DISK_ROLE_SPARE to the
> new element, but you need to do that *before* disk.raid_disk is
> assigned, in case info->disk.number == max (as it could be for the
> recently added device).
>
I think it's also pointless to assign MD_DISK_ROLE_SPARE
since there is no SPARE in dev_roles when we need to update
sb->max_dev. The newly added device will not meet the condition
as max_dev has already been updated, that's saying, we only
need to update the max_dev value for original disks.
The following code should work

1297     } else if (strcmp(update, "linear-grow-update") == 0) {
1298         unsigned int max = __le32_to_cpu(sb->max_dev);
1299         sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
1300         sb->dev_roles[info->disk.number] =
1301             __cpu_to_le16(info->disk.raid_disk);
1302         if (info->array.raid_disks > max) { 
 

1303             sb->max_dev = __cpu_to_le32(max+1);
1304         }

Thank you for your patient review.

Lidong

> NeilBrown
>
>
>> +			sb->max_dev = __cpu_to_le32(max+1);
>> +		}
>>  	} else if (strcmp(update, "resync") == 0) {
>>  		/* make sure resync happens */
>>  		sb->resync_offset = 0ULL;
>> --
>> 2.12.0

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox