aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-04-09 14:50:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-04-09 14:50:29 -0400
commit2f4084209adc77f9a1c9f38db3019a509e167882 (patch)
tree775657114c885505ecc46605e29ea1470e986f76 /fs
parent2f10ffcfb28beb35137d9e86992c771b4a6c5f2a (diff)
parent3440c49f5c5ecb4f29b0544aa87da71888404f8f (diff)
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block: (34 commits) cfq-iosched: Fix the incorrect timeslice accounting with forced_dispatch loop: Update mtime when writing using aops block: expose the statistics in blkio.time and blkio.sectors for the root cgroup backing-dev: Handle class_create() failure Block: Fix block/elevator.c elevator_get() off-by-one error drbd: lc_element_by_index() never returns NULL cciss: unlock on error path cfq-iosched: Do not merge queues of BE and IDLE classes cfq-iosched: Add additional blktrace log messages in CFQ for easier debugging i2o: Remove the dangerous kobj_to_i2o_device macro block: remove 16 bytes of padding from struct request on 64bits cfq-iosched: fix a kbuild regression block: make CONFIG_BLK_CGROUP visible Remove GENHD_FL_DRIVERFS block: Export max number of segments and max segment size in sysfs block: Finalize conversion of block limits functions block: Fix overrun in lcm() and move it to lib vfs: improve writeback_inodes_wb() paride: fix off-by-one test drbd: fix al-to-on-disk-bitmap for 4k logical_block_size ...
Diffstat (limited to 'fs')
-rw-r--r--fs/bio.c4
-rw-r--r--fs/fs-writeback.c133
2 files changed, 75 insertions, 62 deletions
diff --git a/fs/bio.c b/fs/bio.c
index e1f922184b45..e7bf6ca64dcf 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -554,7 +554,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
554 .bi_rw = bio->bi_rw, 554 .bi_rw = bio->bi_rw,
555 }; 555 };
556 556
557 if (q->merge_bvec_fn(q, &bvm, prev) < len) { 557 if (q->merge_bvec_fn(q, &bvm, prev) < prev->bv_len) {
558 prev->bv_len -= len; 558 prev->bv_len -= len;
559 return 0; 559 return 0;
560 } 560 }
@@ -607,7 +607,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
607 * merge_bvec_fn() returns number of bytes it can accept 607 * merge_bvec_fn() returns number of bytes it can accept
608 * at this offset 608 * at this offset
609 */ 609 */
610 if (q->merge_bvec_fn(q, &bvm, bvec) < len) { 610 if (q->merge_bvec_fn(q, &bvm, bvec) < bvec->bv_len) {
611 bvec->bv_page = NULL; 611 bvec->bv_page = NULL;
612 bvec->bv_len = 0; 612 bvec->bv_len = 0;
613 bvec->bv_offset = 0; 613 bvec->bv_offset = 0;
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 781a322ccb45..4b37f7cea4dd 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -554,108 +554,85 @@ select_queue:
554 return ret; 554 return ret;
555} 555}
556 556
557static void unpin_sb_for_writeback(struct super_block **psb) 557static void unpin_sb_for_writeback(struct super_block *sb)
558{ 558{
559 struct super_block *sb = *psb; 559 up_read(&sb->s_umount);
560 560 put_super(sb);
561 if (sb) {
562 up_read(&sb->s_umount);
563 put_super(sb);
564 *psb = NULL;
565 }
566} 561}
567 562
563enum sb_pin_state {
564 SB_PINNED,
565 SB_NOT_PINNED,
566 SB_PIN_FAILED
567};
568
568/* 569/*
569 * For WB_SYNC_NONE writeback, the caller does not have the sb pinned 570 * For WB_SYNC_NONE writeback, the caller does not have the sb pinned
570 * before calling writeback. So make sure that we do pin it, so it doesn't 571 * before calling writeback. So make sure that we do pin it, so it doesn't
571 * go away while we are writing inodes from it. 572 * go away while we are writing inodes from it.
572 *
573 * Returns 0 if the super was successfully pinned (or pinning wasn't needed),
574 * 1 if we failed.
575 */ 573 */
576static int pin_sb_for_writeback(struct writeback_control *wbc, 574static enum sb_pin_state pin_sb_for_writeback(struct writeback_control *wbc,
577 struct inode *inode, struct super_block **psb) 575 struct super_block *sb)
578{ 576{
579 struct super_block *sb = inode->i_sb;
580
581 /*
582 * If this sb is already pinned, nothing more to do. If not and
583 * *psb is non-NULL, unpin the old one first
584 */
585 if (sb == *psb)
586 return 0;
587 else if (*psb)
588 unpin_sb_for_writeback(psb);
589
590 /* 577 /*
591 * Caller must already hold the ref for this 578 * Caller must already hold the ref for this
592 */ 579 */
593 if (wbc->sync_mode == WB_SYNC_ALL) { 580 if (wbc->sync_mode == WB_SYNC_ALL) {
594 WARN_ON(!rwsem_is_locked(&sb->s_umount)); 581 WARN_ON(!rwsem_is_locked(&sb->s_umount));
595 return 0; 582 return SB_NOT_PINNED;
596 } 583 }
597
598 spin_lock(&sb_lock); 584 spin_lock(&sb_lock);
599 sb->s_count++; 585 sb->s_count++;
600 if (down_read_trylock(&sb->s_umount)) { 586 if (down_read_trylock(&sb->s_umount)) {
601 if (sb->s_root) { 587 if (sb->s_root) {
602 spin_unlock(&sb_lock); 588 spin_unlock(&sb_lock);
603 goto pinned; 589 return SB_PINNED;
604 } 590 }
605 /* 591 /*
606 * umounted, drop rwsem again and fall through to failure 592 * umounted, drop rwsem again and fall through to failure
607 */ 593 */
608 up_read(&sb->s_umount); 594 up_read(&sb->s_umount);
609 } 595 }
610
611 sb->s_count--; 596 sb->s_count--;
612 spin_unlock(&sb_lock); 597 spin_unlock(&sb_lock);
613 return 1; 598 return SB_PIN_FAILED;
614pinned:
615 *psb = sb;
616 return 0;
617} 599}
618 600
619static void writeback_inodes_wb(struct bdi_writeback *wb, 601/*
620 struct writeback_control *wbc) 602 * Write a portion of b_io inodes which belong to @sb.
603 * If @wbc->sb != NULL, then find and write all such
604 * inodes. Otherwise write only ones which go sequentially
605 * in reverse order.
606 * Return 1, if the caller writeback routine should be
607 * interrupted. Otherwise return 0.
608 */
609static int writeback_sb_inodes(struct super_block *sb,
610 struct bdi_writeback *wb,
611 struct writeback_control *wbc)
621{ 612{
622 struct super_block *sb = wbc->sb, *pin_sb = NULL;
623 const unsigned long start = jiffies; /* livelock avoidance */
624
625 spin_lock(&inode_lock);
626
627 if (!wbc->for_kupdate || list_empty(&wb->b_io))
628 queue_io(wb, wbc->older_than_this);
629
630 while (!list_empty(&wb->b_io)) { 613 while (!list_empty(&wb->b_io)) {
631 struct inode *inode = list_entry(wb->b_io.prev,
632 struct inode, i_list);
633 long pages_skipped; 614 long pages_skipped;
634 615 struct inode *inode = list_entry(wb->b_io.prev,
635 /* 616 struct inode, i_list);
636 * super block given and doesn't match, skip this inode 617 if (wbc->sb && sb != inode->i_sb) {
637 */ 618 /* super block given and doesn't
638 if (sb && sb != inode->i_sb) { 619 match, skip this inode */
639 redirty_tail(inode); 620 redirty_tail(inode);
640 continue; 621 continue;
641 } 622 }
642 623 if (sb != inode->i_sb)
624 /* finish with this superblock */
625 return 0;
643 if (inode->i_state & (I_NEW | I_WILL_FREE)) { 626 if (inode->i_state & (I_NEW | I_WILL_FREE)) {
644 requeue_io(inode); 627 requeue_io(inode);
645 continue; 628 continue;
646 } 629 }
647
648 /* 630 /*
649 * Was this inode dirtied after sync_sb_inodes was called? 631 * Was this inode dirtied after sync_sb_inodes was called?
650 * This keeps sync from extra jobs and livelock. 632 * This keeps sync from extra jobs and livelock.
651 */ 633 */
652 if (inode_dirtied_after(inode, start)) 634 if (inode_dirtied_after(inode, wbc->wb_start))
653 break; 635 return 1;
654
655 if (pin_sb_for_writeback(wbc, inode, &pin_sb)) {
656 requeue_io(inode);
657 continue;
658 }
659 636
660 BUG_ON(inode->i_state & (I_FREEING | I_CLEAR)); 637 BUG_ON(inode->i_state & (I_FREEING | I_CLEAR));
661 __iget(inode); 638 __iget(inode);
@@ -674,14 +651,50 @@ static void writeback_inodes_wb(struct bdi_writeback *wb,
674 spin_lock(&inode_lock); 651 spin_lock(&inode_lock);
675 if (wbc->nr_to_write <= 0) { 652 if (wbc->nr_to_write <= 0) {
676 wbc->more_io = 1; 653 wbc->more_io = 1;
677 break; 654 return 1;
678 } 655 }
679 if (!list_empty(&wb->b_more_io)) 656 if (!list_empty(&wb->b_more_io))
680 wbc->more_io = 1; 657 wbc->more_io = 1;
681 } 658 }
659 /* b_io is empty */
660 return 1;
661}
662
663static void writeback_inodes_wb(struct bdi_writeback *wb,
664 struct writeback_control *wbc)
665{
666 int ret = 0;
682 667
683 unpin_sb_for_writeback(&pin_sb); 668 wbc->wb_start = jiffies; /* livelock avoidance */
669 spin_lock(&inode_lock);
670 if (!wbc->for_kupdate || list_empty(&wb->b_io))
671 queue_io(wb, wbc->older_than_this);
672
673 while (!list_empty(&wb->b_io)) {
674 struct inode *inode = list_entry(wb->b_io.prev,
675 struct inode, i_list);
676 struct super_block *sb = inode->i_sb;
677 enum sb_pin_state state;
678
679 if (wbc->sb && sb != wbc->sb) {
680 /* super block given and doesn't
681 match, skip this inode */
682 redirty_tail(inode);
683 continue;
684 }
685 state = pin_sb_for_writeback(wbc, sb);
686
687 if (state == SB_PIN_FAILED) {
688 requeue_io(inode);
689 continue;
690 }
691 ret = writeback_sb_inodes(sb, wb, wbc);
684 692
693 if (state == SB_PINNED)
694 unpin_sb_for_writeback(sb);
695 if (ret)
696 break;
697 }
685 spin_unlock(&inode_lock); 698 spin_unlock(&inode_lock);
686 /* Leave any unwritten inodes on b_io */ 699 /* Leave any unwritten inodes on b_io */
687} 700}