summaryrefslogtreecommitdiffstats
path: root/drivers/md/bitmap.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-05-21 23:55:08 -0400
committerNeilBrown <neilb@suse.de>2012-05-21 23:55:08 -0400
commit27581e5ae01f77b5472dc5c2368b41063fed7f37 (patch)
tree202d2ee37bcfb82ce09bc72c0d3d81045a941637 /drivers/md/bitmap.c
parentef99bf480de9bde9d3b2afdf05324670fab4e571 (diff)
md/bitmap: centralise allocation of bitmap file pages.
Instead of allocating pages in read_sb_page, read_page and bitmap_read_sb, allocate them all in bitmap_init_from disk. Also replace the hack of calling "attach_page_buffers(page, NULL)" to ensure that free_buffer() won't complain, by putting a test for PagePrivate in free_buffer(). Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r--drivers/md/bitmap.c149
1 files changed, 68 insertions, 81 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index c042efd019c3..324a198e8be7 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -130,22 +130,14 @@ static void bitmap_checkfree(struct bitmap *bitmap, unsigned long page)
130 */ 130 */
131 131
132/* IO operations when bitmap is stored near all superblocks */ 132/* IO operations when bitmap is stored near all superblocks */
133static struct page *read_sb_page(struct mddev *mddev, loff_t offset, 133static int read_sb_page(struct mddev *mddev, loff_t offset,
134 struct page *page, 134 struct page *page,
135 unsigned long index, int size) 135 unsigned long index, int size)
136{ 136{
137 /* choose a good rdev and read the page from there */ 137 /* choose a good rdev and read the page from there */
138 138
139 struct md_rdev *rdev; 139 struct md_rdev *rdev;
140 sector_t target; 140 sector_t target;
141 int did_alloc = 0;
142
143 if (!page) {
144 page = alloc_page(GFP_KERNEL);
145 if (!page)
146 return ERR_PTR(-ENOMEM);
147 did_alloc = 1;
148 }
149 141
150 rdev_for_each(rdev, mddev) { 142 rdev_for_each(rdev, mddev) {
151 if (! test_bit(In_sync, &rdev->flags) 143 if (! test_bit(In_sync, &rdev->flags)
@@ -158,15 +150,10 @@ static struct page *read_sb_page(struct mddev *mddev, loff_t offset,
158 roundup(size, bdev_logical_block_size(rdev->bdev)), 150 roundup(size, bdev_logical_block_size(rdev->bdev)),
159 page, READ, true)) { 151 page, READ, true)) {
160 page->index = index; 152 page->index = index;
161 attach_page_buffers(page, NULL); /* so that free_buffer will 153 return 0;
162 * quietly no-op */
163 return page;
164 } 154 }
165 } 155 }
166 if (did_alloc) 156 return -EIO;
167 put_page(page);
168 return ERR_PTR(-EIO);
169
170} 157}
171 158
172static struct md_rdev *next_active_rdev(struct md_rdev *rdev, struct mddev *mddev) 159static struct md_rdev *next_active_rdev(struct md_rdev *rdev, struct mddev *mddev)
@@ -325,8 +312,12 @@ __clear_page_buffers(struct page *page)
325} 312}
326static void free_buffers(struct page *page) 313static void free_buffers(struct page *page)
327{ 314{
328 struct buffer_head *bh = page_buffers(page); 315 struct buffer_head *bh;
329 316
317 if (!PagePrivate(page))
318 return;
319
320 bh = page_buffers(page);
330 while (bh) { 321 while (bh) {
331 struct buffer_head *next = bh->b_this_page; 322 struct buffer_head *next = bh->b_this_page;
332 free_buffer_head(bh); 323 free_buffer_head(bh);
@@ -343,11 +334,12 @@ static void free_buffers(struct page *page)
343 * This usage is similar to how swap files are handled, and allows us 334 * This usage is similar to how swap files are handled, and allows us
344 * to write to a file with no concerns of memory allocation failing. 335 * to write to a file with no concerns of memory allocation failing.
345 */ 336 */
346static struct page *read_page(struct file *file, unsigned long index, 337static int read_page(struct file *file, unsigned long index,
347 struct bitmap *bitmap, 338 struct bitmap *bitmap,
348 unsigned long count) 339 unsigned long count,
340 struct page *page)
349{ 341{
350 struct page *page = NULL; 342 int ret = 0;
351 struct inode *inode = file->f_path.dentry->d_inode; 343 struct inode *inode = file->f_path.dentry->d_inode;
352 struct buffer_head *bh; 344 struct buffer_head *bh;
353 sector_t block; 345 sector_t block;
@@ -355,16 +347,9 @@ static struct page *read_page(struct file *file, unsigned long index,
355 pr_debug("read bitmap file (%dB @ %llu)\n", (int)PAGE_SIZE, 347 pr_debug("read bitmap file (%dB @ %llu)\n", (int)PAGE_SIZE,
356 (unsigned long long)index << PAGE_SHIFT); 348 (unsigned long long)index << PAGE_SHIFT);
357 349
358 page = alloc_page(GFP_KERNEL);
359 if (!page)
360 page = ERR_PTR(-ENOMEM);
361 if (IS_ERR(page))
362 goto out;
363
364 bh = alloc_page_buffers(page, 1<<inode->i_blkbits, 0); 350 bh = alloc_page_buffers(page, 1<<inode->i_blkbits, 0);
365 if (!bh) { 351 if (!bh) {
366 put_page(page); 352 ret = -ENOMEM;
367 page = ERR_PTR(-ENOMEM);
368 goto out; 353 goto out;
369 } 354 }
370 attach_page_buffers(page, bh); 355 attach_page_buffers(page, bh);
@@ -376,8 +361,7 @@ static struct page *read_page(struct file *file, unsigned long index,
376 bh->b_blocknr = bmap(inode, block); 361 bh->b_blocknr = bmap(inode, block);
377 if (bh->b_blocknr == 0) { 362 if (bh->b_blocknr == 0) {
378 /* Cannot use this file! */ 363 /* Cannot use this file! */
379 free_buffers(page); 364 ret = -EINVAL;
380 page = ERR_PTR(-EINVAL);
381 goto out; 365 goto out;
382 } 366 }
383 bh->b_bdev = inode->i_sb->s_bdev; 367 bh->b_bdev = inode->i_sb->s_bdev;
@@ -400,17 +384,15 @@ static struct page *read_page(struct file *file, unsigned long index,
400 384
401 wait_event(bitmap->write_wait, 385 wait_event(bitmap->write_wait,
402 atomic_read(&bitmap->pending_writes)==0); 386 atomic_read(&bitmap->pending_writes)==0);
403 if (bitmap->flags & BITMAP_WRITE_ERROR) { 387 if (bitmap->flags & BITMAP_WRITE_ERROR)
404 free_buffers(page); 388 ret = -EIO;
405 page = ERR_PTR(-EIO);
406 }
407out: 389out:
408 if (IS_ERR(page)) 390 if (ret)
409 printk(KERN_ALERT "md: bitmap read error: (%dB @ %llu): %ld\n", 391 printk(KERN_ALERT "md: bitmap read error: (%dB @ %llu): %d\n",
410 (int)PAGE_SIZE, 392 (int)PAGE_SIZE,
411 (unsigned long long)index << PAGE_SHIFT, 393 (unsigned long long)index << PAGE_SHIFT,
412 PTR_ERR(page)); 394 ret);
413 return page; 395 return ret;
414} 396}
415 397
416/* 398/*
@@ -552,6 +534,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
552 unsigned long chunksize, daemon_sleep, write_behind; 534 unsigned long chunksize, daemon_sleep, write_behind;
553 unsigned long long events; 535 unsigned long long events;
554 int err = -EINVAL; 536 int err = -EINVAL;
537 struct page *sb_page;
555 538
556 if (!bitmap->file && !bitmap->mddev->bitmap_info.offset) { 539 if (!bitmap->file && !bitmap->mddev->bitmap_info.offset) {
557 chunksize = 128 * 1024 * 1024; 540 chunksize = 128 * 1024 * 1024;
@@ -562,24 +545,27 @@ static int bitmap_read_sb(struct bitmap *bitmap)
562 goto out_no_sb; 545 goto out_no_sb;
563 } 546 }
564 /* page 0 is the superblock, read it... */ 547 /* page 0 is the superblock, read it... */
548 sb_page = alloc_page(GFP_KERNEL);
549 if (!sb_page)
550 return -ENOMEM;
551 bitmap->sb_page = sb_page;
552
565 if (bitmap->file) { 553 if (bitmap->file) {
566 loff_t isize = i_size_read(bitmap->file->f_mapping->host); 554 loff_t isize = i_size_read(bitmap->file->f_mapping->host);
567 int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize; 555 int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize;
568 556
569 bitmap->sb_page = read_page(bitmap->file, 0, bitmap, bytes); 557 err = read_page(bitmap->file, 0,
558 bitmap, bytes, sb_page);
570 } else { 559 } else {
571 bitmap->sb_page = read_sb_page(bitmap->mddev, 560 err = read_sb_page(bitmap->mddev,
572 bitmap->mddev->bitmap_info.offset, 561 bitmap->mddev->bitmap_info.offset,
573 NULL, 562 sb_page,
574 0, sizeof(bitmap_super_t)); 563 0, sizeof(bitmap_super_t));
575 } 564 }
576 if (IS_ERR(bitmap->sb_page)) { 565 if (err)
577 err = PTR_ERR(bitmap->sb_page);
578 bitmap->sb_page = NULL;
579 return err; 566 return err;
580 }
581 567
582 sb = kmap_atomic(bitmap->sb_page); 568 sb = kmap_atomic(sb_page);
583 569
584 chunksize = le32_to_cpu(sb->chunksize); 570 chunksize = le32_to_cpu(sb->chunksize);
585 daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ; 571 daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ;
@@ -948,7 +934,8 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n
948static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) 934static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
949{ 935{
950 unsigned long i, chunks, index, oldindex, bit; 936 unsigned long i, chunks, index, oldindex, bit;
951 struct page *page = NULL, *oldpage = NULL; 937 int pnum;
938 struct page *page = NULL;
952 unsigned long num_pages, bit_cnt = 0; 939 unsigned long num_pages, bit_cnt = 0;
953 struct file *file; 940 struct file *file;
954 unsigned long bytes, offset; 941 unsigned long bytes, offset;
@@ -999,6 +986,22 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
999 if (!bitmap->filemap) 986 if (!bitmap->filemap)
1000 goto err; 987 goto err;
1001 988
989 pnum = 0;
990 offset = 0;
991 if (bitmap->sb_page) {
992 bitmap->filemap[0] = bitmap->sb_page;
993 pnum = 1;
994 offset = sizeof(bitmap_super_t);
995 }
996 for ( ; pnum < num_pages; pnum++) {
997 bitmap->filemap[pnum] = alloc_page(GFP_KERNEL);
998 if (!bitmap->filemap[pnum]) {
999 bitmap->file_pages = pnum;
1000 goto err;
1001 }
1002 }
1003 bitmap->file_pages = pnum;
1004
1002 /* We need 4 bits per page, rounded up to a multiple of sizeof(unsigned long) */ 1005 /* We need 4 bits per page, rounded up to a multiple of sizeof(unsigned long) */
1003 bitmap->filemap_attr = kzalloc( 1006 bitmap->filemap_attr = kzalloc(
1004 roundup(DIV_ROUND_UP(num_pages*4, 8), sizeof(unsigned long)), 1007 roundup(DIV_ROUND_UP(num_pages*4, 8), sizeof(unsigned long)),
@@ -1019,39 +1022,22 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
1019 count = bytes - index * PAGE_SIZE; 1022 count = bytes - index * PAGE_SIZE;
1020 else 1023 else
1021 count = PAGE_SIZE; 1024 count = PAGE_SIZE;
1022 if (index == 0 && bitmap->sb_page) { 1025 page = bitmap->filemap[index];
1023 /* 1026 if (file)
1024 * if we're here then the superblock page 1027 ret = read_page(file, index, bitmap,
1025 * contains some bits (PAGE_SIZE != sizeof sb) 1028 count, page);
1026 * we've already read it in, so just use it 1029 else
1027 */ 1030 ret = read_sb_page(
1028 page = bitmap->sb_page; 1031 bitmap->mddev,
1029 offset = sizeof(bitmap_super_t); 1032 bitmap->mddev->bitmap_info.offset,
1030 if (!file) 1033 page,
1031 page = read_sb_page( 1034 index, count);
1032 bitmap->mddev, 1035
1033 bitmap->mddev->bitmap_info.offset, 1036 if (ret)
1034 page,
1035 index, count);
1036 } else if (file) {
1037 page = read_page(file, index, bitmap, count);
1038 offset = 0;
1039 } else {
1040 page = read_sb_page(bitmap->mddev,
1041 bitmap->mddev->bitmap_info.offset,
1042 NULL,
1043 index, count);
1044 offset = 0;
1045 }
1046 if (IS_ERR(page)) { /* read error */
1047 ret = PTR_ERR(page);
1048 goto err; 1037 goto err;
1049 }
1050 1038
1051 oldindex = index; 1039 oldindex = index;
1052 oldpage = page;
1053 1040
1054 bitmap->filemap[bitmap->file_pages++] = page;
1055 bitmap->last_page_size = count; 1041 bitmap->last_page_size = count;
1056 1042
1057 if (outofdate) { 1043 if (outofdate) {
@@ -1085,6 +1071,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
1085 needed); 1071 needed);
1086 bit_cnt++; 1072 bit_cnt++;
1087 } 1073 }
1074 offset = 0;
1088 } 1075 }
1089 1076
1090 printk(KERN_INFO "%s: bitmap initialized from disk: " 1077 printk(KERN_INFO "%s: bitmap initialized from disk: "