All of lore.kernel.org
 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 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.