On Wed, Aug 30 2017, Zhilong Liu wrote: > > Hi, Neil; > I have tested the following patch, I still got the call-trace after > I built with it. > If you need other infos, I would append. Ok, one more try. If this doesn't work I do the testing myself to avoid the back-and-forth. Thanks, NeilBrown diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 40f3cd7eab0f..05ba9c7d33b4 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<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) @@ -616,9 +611,16 @@ static int bitmap_read_sb(struct bitmap *bitmap) } if (bitmap->storage.file) { - loff_t isize = i_size_read(bitmap->storage.file->f_mapping->host); + struct inode *inode = bitmap->storage.file->f_mapping->host; + loff_t isize = i_size_read(inode); int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize; + struct buffer_head *bh; + bh = alloc_page_buffers(sb_page, 1 << inode->i_blkbits, 0); + if (bh) + attach_page_buffers(sb_page, bh); + else + return -ENOMEM; err = read_page(bitmap->storage.file, 0, bitmap, bytes, sb_page); } else { @@ -771,12 +773,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 +809,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 +2117,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);