aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-06-26 03:27:49 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:38 -0400
commitce25c31bdd3b39266debd86a7732007e05983a67 (patch)
tree1afafa2a68eb71b702db0a24aff2feb52b9f56c7
parentd785a06a0b9d0cd86b3cc1bf8e236e62af7b47ed (diff)
[PATCH] md: Change md/bitmap file handling to use bmap to file blocks-fix
Fix problems with new bmap based access to bitmap files. 1/ When not using a file based bitmap, attach a NULL list of buffers to each page so the common free_buffer routine can cope. 2/ Use submit_bh to read as well as write, rather than vfs_read. This makes read and write more symetric. 3/ sync the file before reading, to ensure that the page cache has no dirty pages that might get written out later. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/md/bitmap.c47
1 files changed, 23 insertions, 24 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index bedd66e9e8ac..ebbd2d856256 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -247,6 +247,8 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
247 247
248 if (sync_page_io(rdev->bdev, target, PAGE_SIZE, page, READ)) { 248 if (sync_page_io(rdev->bdev, target, PAGE_SIZE, page, READ)) {
249 page->index = index; 249 page->index = index;
250 attach_page_buffers(page, NULL); /* so that free_buffer will
251 * quietly no-op */
250 return page; 252 return page;
251 } 253 }
252 } 254 }
@@ -349,11 +351,8 @@ static struct page *read_page(struct file *file, unsigned long index,
349{ 351{
350 struct page *page = NULL; 352 struct page *page = NULL;
351 struct inode *inode = file->f_dentry->d_inode; 353 struct inode *inode = file->f_dentry->d_inode;
352 loff_t pos = index << PAGE_SHIFT;
353 int ret;
354 struct buffer_head *bh; 354 struct buffer_head *bh;
355 sector_t block; 355 sector_t block;
356 mm_segment_t oldfs;
357 356
358 PRINTK("read bitmap file (%dB @ %Lu)\n", (int)PAGE_SIZE, 357 PRINTK("read bitmap file (%dB @ %Lu)\n", (int)PAGE_SIZE,
359 (unsigned long long)index << PAGE_SHIFT); 358 (unsigned long long)index << PAGE_SHIFT);
@@ -364,18 +363,6 @@ static struct page *read_page(struct file *file, unsigned long index,
364 if (IS_ERR(page)) 363 if (IS_ERR(page))
365 goto out; 364 goto out;
366 365
367 oldfs = get_fs();
368 set_fs(KERNEL_DS);
369 ret = vfs_read(file, (char __user*) page_address(page), count, &pos);
370 set_fs(oldfs);
371
372 if (ret >= 0 && ret != count)
373 ret = -EIO;
374 if (ret < 0) {
375 put_page(page);
376 page = ERR_PTR(ret);
377 goto out;
378 }
379 bh = alloc_page_buffers(page, 1<<inode->i_blkbits, 0); 366 bh = alloc_page_buffers(page, 1<<inode->i_blkbits, 0);
380 if (!bh) { 367 if (!bh) {
381 put_page(page); 368 put_page(page);
@@ -403,12 +390,22 @@ static struct page *read_page(struct file *file, unsigned long index,
403 390
404 bh->b_end_io = end_bitmap_write; 391 bh->b_end_io = end_bitmap_write;
405 bh->b_private = bitmap; 392 bh->b_private = bitmap;
393 atomic_inc(&bitmap->pending_writes);
394 set_buffer_locked(bh);
395 set_buffer_mapped(bh);
396 submit_bh(READ, bh);
406 } 397 }
407 block++; 398 block++;
408 bh = bh->b_this_page; 399 bh = bh->b_this_page;
409 } 400 }
410
411 page->index = index; 401 page->index = index;
402
403 wait_event(bitmap->write_wait,
404 atomic_read(&bitmap->pending_writes)==0);
405 if (bitmap->flags & BITMAP_WRITE_ERROR) {
406 free_buffers(page);
407 page = ERR_PTR(-EIO);
408 }
412out: 409out:
413 if (IS_ERR(page)) 410 if (IS_ERR(page))
414 printk(KERN_ALERT "md: bitmap read error: (%dB @ %Lu): %ld\n", 411 printk(KERN_ALERT "md: bitmap read error: (%dB @ %Lu): %ld\n",
@@ -1415,15 +1412,20 @@ int bitmap_create(mddev_t *mddev)
1415 return -ENOMEM; 1412 return -ENOMEM;
1416 1413
1417 spin_lock_init(&bitmap->lock); 1414 spin_lock_init(&bitmap->lock);
1415 atomic_set(&bitmap->pending_writes, 0);
1416 init_waitqueue_head(&bitmap->write_wait);
1417
1418 bitmap->mddev = mddev; 1418 bitmap->mddev = mddev;
1419 1419
1420 bitmap->file = file; 1420 bitmap->file = file;
1421 bitmap->offset = mddev->bitmap_offset; 1421 bitmap->offset = mddev->bitmap_offset;
1422 if (file) get_file(file); 1422 if (file) {
1423 1423 get_file(file);
1424 /* Ensure we read fresh data */ 1424 do_sync_file_range(file, 0, LLONG_MAX,
1425 invalidate_inode_pages(file->f_dentry->d_inode->i_mapping); 1425 SYNC_FILE_RANGE_WAIT_BEFORE |
1426 1426 SYNC_FILE_RANGE_WRITE |
1427 SYNC_FILE_RANGE_WAIT_AFTER);
1428 }
1427 /* read superblock from bitmap file (this sets bitmap->chunksize) */ 1429 /* read superblock from bitmap file (this sets bitmap->chunksize) */
1428 err = bitmap_read_sb(bitmap); 1430 err = bitmap_read_sb(bitmap);
1429 if (err) 1431 if (err)
@@ -1446,9 +1448,6 @@ int bitmap_create(mddev_t *mddev)
1446 1448
1447 bitmap->syncchunk = ~0UL; 1449 bitmap->syncchunk = ~0UL;
1448 1450
1449 atomic_set(&bitmap->pending_writes, 0);
1450 init_waitqueue_head(&bitmap->write_wait);
1451
1452#ifdef INJECT_FATAL_FAULT_1 1451#ifdef INJECT_FATAL_FAULT_1
1453 bitmap->bp = NULL; 1452 bitmap->bp = NULL;
1454#else 1453#else