linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: NeilBrown <neilb@suse.com>
To: Zhilong Liu <zlliu@suse.com>
Cc: linux-raid@vger.kernel.org
Subject: Re: report a bug that panic when grow size for external bitmap
Date: Tue, 29 Aug 2017 20:47:19 +1000	[thread overview]
Message-ID: <87k21mhcqw.fsf@notabene.neil.brown.name> (raw)
In-Reply-To: <ba801ebe-9c0c-d911-2b18-936495fe0ed3@suse.com>

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

On Tue, Aug 29 2017, Zhilong Liu wrote:

> On 08/29/2017 11:12 AM, NeilBrown wrote:
>> On Tue, Aug 29 2017, Zhilong Liu wrote:
>>
>>> Hi, Neil;
>>>       Thanks for your pointing and sorry for the incorrect dmesg for last
>>> mail.
>>>
>>> Here update the pure steps and paste the dmesg.
>>>
>>> ENV:
>>> OS: 4.13-rc7 upstream
>>> linux-apta:~/mdadm-test # df -T /mnt/
>>> Filesystem     Type 1K-blocks     Used Available Use% Mounted on
>>> /dev/sda2      ext4  44248848 24416952  18778472  57% /
>>>
>>> Reproduce: 100%
>>>
>>> Steps:
>>> linux-apta:~/mdadm-test # ./mdadm -CR /dev/md0 -l1 -b /mnt/3 -n2 -x1
>>> /dev/loop[0-2] --force
>>> mdadm: Note: this array has metadata at the start and
>>>       may not be suitable as a boot device.  If you plan to
>>>       store '/boot' on this device please ensure that
>>>       your boot-loader understands md/v1.x metadata, or use
>>>       --metadata=0.90
>>> mdadm: Defaulting to version 1.2 metadata
>>> mdadm: array /dev/md0 started.
>>> linux-apta:~/mdadm-test # cat /proc/mdstat
>>> Personalities : [raid1]
>>> md0 : active raid1 loop2[2](S) loop1[1] loop0[0]
>>>         18944 blocks super 1.2 [2/2] [UU]
>>>         bitmap: 3/3 pages [12KB], 4KB chunk, file: /mnt/3
>>>
>>> unused devices: <none>
>>> linux-apta:~/mdadm-test # dmesg -c
>>> [  181.378209] md/raid1:md0: not clean -- starting background reconstruction
>>> [  181.378211] md/raid1:md0: active with 2 out of 2 mirrors
>>> [  181.379354] md0: detected capacity change from 0 to 19398656
>>> [  181.379773] md: resync of RAID array md0
>>> [  190.396162] md: md0: resync done.
>>>
>>> linux-apta:~/mdadm-test # ./mdadm --grow /dev/md0 --size 128
>>> Segmentation fault
>>> linux-apta:~/mdadm-test # cat /sys/block/md0/md/component_size
>>> 18944                         "here is incorrect also."
>>> linux-apta:~/mdadm-test # dmesg -c
>>> [  208.027505] ------------[ cut here ]------------
>>> [  208.027508] kernel BUG at drivers/md/bitmap.c:298!
>> Thanks.  Less confusing now.
>>
>> The problem is that when the bitmap is resized, new pages are allocated
>> to store the on-disk copy, but these are not read from the file, the
>> contents are set from the in-memory bitmap.
>> So read_page() isn't called and particularly
>>
>> 	bh = alloc_page_buffers(page, 1<<inode->i_blkbits, 0);
>>          ...
>> 	attach_page_buffers(page, bh);
>>
>> doesn't happen.
>>
>> Maybe something like this will work.
>> Can you test it?
>
> Another panic happens when I built with the below patch.
>
> Steps:
> 1. patching the codes to bitmap.c
> 2. rebuilt the kernel source code.
> 3. reboot and test.
>
> linux-apta:~/mdadm-test # ./mdadm -CR /dev/md0 -l1 -b /mnt/3 -n2 -x1 
> /dev/loop[0-2] --force
> mdadm: Note: this array has metadata at the start and
>      may not be suitable as a boot device.  If you plan to
>      store '/boot' on this device please ensure that
>      your boot-loader understands md/v1.x metadata, or use
>      --metadata=0.90
> mdadm: Defaulting to version 1.2 metadata
> Segmentation fault
> linux-apta:~/mdadm-test # dmesg -c
> [   46.416567] md/raid1:md0: not clean -- starting background reconstruction
> [   46.416570] md/raid1:md0: active with 2 out of 2 mirrors
> [   46.417003] ------------[ cut here ]------------
> [   46.417004] kernel BUG at drivers/md/bitmap.c:371!

Thanks.  I see what I missed. Please try this patch instead.

NeilBrown

diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 40f3cd7eab0f..ca7633a81632 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -368,12 +368,7 @@ static int read_page(struct file *file, unsigned long index,
 	pr_debug("read bitmap file (%dB @ %llu)\n", (int)PAGE_SIZE,
 		 (unsigned long long)index << PAGE_SHIFT);
 
-	bh = alloc_page_buffers(page, 1<<inode->i_blkbits, 0);
-	if (!bh) {
-		ret = -ENOMEM;
-		goto out;
-	}
-	attach_page_buffers(page, bh);
+	bh = page_buffers(page);
 	block = index << (PAGE_SHIFT - inode->i_blkbits);
 	while (bh) {
 		if (count == 0)
@@ -771,12 +766,18 @@ static inline struct page *filemap_get_page(struct bitmap_storage *store,
 }
 
 static int bitmap_storage_alloc(struct bitmap_storage *store,
-				unsigned long chunks, int with_super,
+				unsigned long chunks,
+				struct file *file,
+				int with_super,
 				int slot_number)
 {
 	int pnum, offset = 0;
 	unsigned long num_pages;
 	unsigned long bytes;
+	struct inode *inode = NULL;
+
+	if (file)
+		inode = file_inode(file);
 
 	bytes = DIV_ROUND_UP(chunks, 8);
 	if (with_super)
@@ -801,15 +802,33 @@ static int bitmap_storage_alloc(struct bitmap_storage *store,
 		store->filemap[0] = store->sb_page;
 		pnum = 1;
 		store->sb_page->index = offset;
+		if (inode) {
+			struct buffer_head *bh;
+			struct page *p = store->sb_page;
+			bh = alloc_page_buffers(p, 1 << inode->i_blkbits, 0);
+			if (bh)
+				attach_page_buffers(p, bh);
+			else
+				return -ENOMEM;
+		}
 	}
 
 	for ( ; pnum < num_pages; pnum++) {
-		store->filemap[pnum] = alloc_page(GFP_KERNEL|__GFP_ZERO);
-		if (!store->filemap[pnum]) {
+		struct page *p = alloc_page(GFP_KERNEL|__GFP_ZERO);
+		store->filemap[pnum] = p;
+		if (!p) {
 			store->file_pages = pnum;
 			return -ENOMEM;
 		}
-		store->filemap[pnum]->index = pnum + offset;
+		if (inode) {
+			struct buffer_head *bh;
+			bh = alloc_page_buffers(p, 1 << inode->i_blkbits, 0);
+			if (bh)
+				attach_page_buffers(p, bh);
+			else
+				return -ENOMEM;
+		}
+		p->index = pnum + offset;
 	}
 	store->file_pages = pnum;
 
@@ -2091,7 +2110,7 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
 	chunks = DIV_ROUND_UP_SECTOR_T(blocks, 1 << chunkshift);
 	memset(&store, 0, sizeof(store));
 	if (bitmap->mddev->bitmap_info.offset || bitmap->mddev->bitmap_info.file)
-		ret = bitmap_storage_alloc(&store, chunks,
+		ret = bitmap_storage_alloc(&store, chunks, bitmap->mddev->bitmap_info.file,
 					   !bitmap->mddev->bitmap_info.external,
 					   mddev_is_clustered(bitmap->mddev)
 					   ? bitmap->cluster_slot : 0);

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

  reply	other threads:[~2017-08-29 10:47 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-28  9:37 report a bug that panic when grow size for external bitmap Zhilong Liu
     [not found] ` <87y3q3gq8g.fsf@notabene.neil.brown.name>
2017-08-29  2:37   ` Zhilong Liu
2017-08-29  3:12     ` NeilBrown
2017-08-29  4:39       ` Zhilong Liu
2017-08-29 10:47         ` NeilBrown [this message]
2017-08-30  2:52           ` Zhilong Liu
2017-08-30  4:08             ` NeilBrown
2017-08-30  4:57               ` Zhilong Liu
2017-08-31  0:27             ` NeilBrown
2017-08-31  2:57               ` Zhilong Liu
2017-08-31  3:30                 ` NeilBrown
2017-09-01  9:49                   ` Zhilong 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=87k21mhcqw.fsf@notabene.neil.brown.name \
    --to=neilb@suse.com \
    --cc=linux-raid@vger.kernel.org \
    --cc=zlliu@suse.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).