Commit d8a8559cd7a9ccac98d5f6f13297a2ff68a43627
1 parent
0d03d59d9b
Exists in
master
and in
4 other branches
writeback: get rid of generic_sync_sb_inodes() export
This adds two new exported functions: - writeback_inodes_sb(), which only attempts to writeback dirty inodes on this super_block, for WB_SYNC_NONE writeout. - sync_inodes_sb(), which writes out all dirty inodes on this super_block and also waits for the IO to complete. Acked-by: Jan Kara <jack@suse.cz> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Showing 7 changed files with 58 additions and 68 deletions Side-by-side Diff
drivers/staging/pohmelfs/inode.c
... | ... | @@ -1950,14 +1950,7 @@ |
1950 | 1950 | */ |
1951 | 1951 | static void pohmelfs_kill_super(struct super_block *sb) |
1952 | 1952 | { |
1953 | - struct writeback_control wbc = { | |
1954 | - .sync_mode = WB_SYNC_ALL, | |
1955 | - .range_start = 0, | |
1956 | - .range_end = LLONG_MAX, | |
1957 | - .nr_to_write = LONG_MAX, | |
1958 | - }; | |
1959 | - generic_sync_sb_inodes(sb, &wbc); | |
1960 | - | |
1953 | + sync_inodes_sb(sb); | |
1961 | 1954 | kill_anon_super(sb); |
1962 | 1955 | } |
1963 | 1956 |
fs/fs-writeback.c
... | ... | @@ -458,8 +458,8 @@ |
458 | 458 | * on the writer throttling path, and we get decent balancing between many |
459 | 459 | * throttled threads: we don't want them all piling up on inode_sync_wait. |
460 | 460 | */ |
461 | -void generic_sync_sb_inodes(struct super_block *sb, | |
462 | - struct writeback_control *wbc) | |
461 | +static void generic_sync_sb_inodes(struct super_block *sb, | |
462 | + struct writeback_control *wbc) | |
463 | 463 | { |
464 | 464 | const unsigned long start = jiffies; /* livelock avoidance */ |
465 | 465 | int sync = wbc->sync_mode == WB_SYNC_ALL; |
466 | 466 | |
... | ... | @@ -593,14 +593,7 @@ |
593 | 593 | |
594 | 594 | return; /* Leave any unwritten inodes on s_io */ |
595 | 595 | } |
596 | -EXPORT_SYMBOL_GPL(generic_sync_sb_inodes); | |
597 | 596 | |
598 | -static void sync_sb_inodes(struct super_block *sb, | |
599 | - struct writeback_control *wbc) | |
600 | -{ | |
601 | - generic_sync_sb_inodes(sb, wbc); | |
602 | -} | |
603 | - | |
604 | 597 | /* |
605 | 598 | * Start writeback of dirty pagecache data against all unlocked inodes. |
606 | 599 | * |
... | ... | @@ -640,7 +633,7 @@ |
640 | 633 | */ |
641 | 634 | if (down_read_trylock(&sb->s_umount)) { |
642 | 635 | if (sb->s_root) |
643 | - sync_sb_inodes(sb, wbc); | |
636 | + generic_sync_sb_inodes(sb, wbc); | |
644 | 637 | up_read(&sb->s_umount); |
645 | 638 | } |
646 | 639 | spin_lock(&sb_lock); |
647 | 640 | |
648 | 641 | |
649 | 642 | |
650 | 643 | |
651 | 644 | |
652 | 645 | |
653 | 646 | |
654 | 647 | |
... | ... | @@ -653,35 +646,56 @@ |
653 | 646 | spin_unlock(&sb_lock); |
654 | 647 | } |
655 | 648 | |
656 | -/* | |
657 | - * writeback and wait upon the filesystem's dirty inodes. The caller will | |
658 | - * do this in two passes - one to write, and one to wait. | |
649 | +/** | |
650 | + * writeback_inodes_sb - writeback dirty inodes from given super_block | |
651 | + * @sb: the superblock | |
659 | 652 | * |
660 | - * A finite limit is set on the number of pages which will be written. | |
661 | - * To prevent infinite livelock of sys_sync(). | |
662 | - * | |
663 | - * We add in the number of potentially dirty inodes, because each inode write | |
664 | - * can dirty pagecache in the underlying blockdev. | |
653 | + * Start writeback on some inodes on this super_block. No guarantees are made | |
654 | + * on how many (if any) will be written, and this function does not wait | |
655 | + * for IO completion of submitted IO. The number of pages submitted is | |
656 | + * returned. | |
665 | 657 | */ |
666 | -void sync_inodes_sb(struct super_block *sb, int wait) | |
658 | +long writeback_inodes_sb(struct super_block *sb) | |
667 | 659 | { |
668 | 660 | struct writeback_control wbc = { |
669 | - .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_NONE, | |
661 | + .sync_mode = WB_SYNC_NONE, | |
670 | 662 | .range_start = 0, |
671 | 663 | .range_end = LLONG_MAX, |
672 | 664 | }; |
665 | + unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); | |
666 | + unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); | |
667 | + long nr_to_write; | |
673 | 668 | |
674 | - if (!wait) { | |
675 | - unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); | |
676 | - unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); | |
677 | - | |
678 | - wbc.nr_to_write = nr_dirty + nr_unstable + | |
669 | + nr_to_write = nr_dirty + nr_unstable + | |
679 | 670 | (inodes_stat.nr_inodes - inodes_stat.nr_unused); |
680 | - } else | |
681 | - wbc.nr_to_write = LONG_MAX; /* doesn't actually matter */ | |
682 | 671 | |
683 | - sync_sb_inodes(sb, &wbc); | |
672 | + wbc.nr_to_write = nr_to_write; | |
673 | + generic_sync_sb_inodes(sb, &wbc); | |
674 | + return nr_to_write - wbc.nr_to_write; | |
684 | 675 | } |
676 | +EXPORT_SYMBOL(writeback_inodes_sb); | |
677 | + | |
678 | +/** | |
679 | + * sync_inodes_sb - sync sb inode pages | |
680 | + * @sb: the superblock | |
681 | + * | |
682 | + * This function writes and waits on any dirty inode belonging to this | |
683 | + * super_block. The number of pages synced is returned. | |
684 | + */ | |
685 | +long sync_inodes_sb(struct super_block *sb) | |
686 | +{ | |
687 | + struct writeback_control wbc = { | |
688 | + .sync_mode = WB_SYNC_ALL, | |
689 | + .range_start = 0, | |
690 | + .range_end = LLONG_MAX, | |
691 | + }; | |
692 | + long nr_to_write = LONG_MAX; /* doesn't actually matter */ | |
693 | + | |
694 | + wbc.nr_to_write = nr_to_write; | |
695 | + generic_sync_sb_inodes(sb, &wbc); | |
696 | + return nr_to_write - wbc.nr_to_write; | |
697 | +} | |
698 | +EXPORT_SYMBOL(sync_inodes_sb); | |
685 | 699 | |
686 | 700 | /** |
687 | 701 | * write_inode_now - write an inode to disk |
fs/sync.c
... | ... | @@ -19,20 +19,22 @@ |
19 | 19 | SYNC_FILE_RANGE_WAIT_AFTER) |
20 | 20 | |
21 | 21 | /* |
22 | - * Do the filesystem syncing work. For simple filesystems sync_inodes_sb(sb, 0) | |
23 | - * just dirties buffers with inodes so we have to submit IO for these buffers | |
24 | - * via __sync_blockdev(). This also speeds up the wait == 1 case since in that | |
25 | - * case write_inode() functions do sync_dirty_buffer() and thus effectively | |
26 | - * write one block at a time. | |
22 | + * Do the filesystem syncing work. For simple filesystems | |
23 | + * writeback_inodes_sb(sb) just dirties buffers with inodes so we have to | |
24 | + * submit IO for these buffers via __sync_blockdev(). This also speeds up the | |
25 | + * wait == 1 case since in that case write_inode() functions do | |
26 | + * sync_dirty_buffer() and thus effectively write one block at a time. | |
27 | 27 | */ |
28 | 28 | static int __sync_filesystem(struct super_block *sb, int wait) |
29 | 29 | { |
30 | 30 | /* Avoid doing twice syncing and cache pruning for quota sync */ |
31 | - if (!wait) | |
31 | + if (!wait) { | |
32 | 32 | writeout_quota_sb(sb, -1); |
33 | - else | |
33 | + writeback_inodes_sb(sb); | |
34 | + } else { | |
34 | 35 | sync_quota_sb(sb, -1); |
35 | - sync_inodes_sb(sb, wait); | |
36 | + sync_inodes_sb(sb); | |
37 | + } | |
36 | 38 | if (sb->s_op->sync_fs) |
37 | 39 | sb->s_op->sync_fs(sb, wait); |
38 | 40 | return __sync_blockdev(sb->s_bdev, wait); |
fs/ubifs/budget.c
... | ... | @@ -65,26 +65,14 @@ |
65 | 65 | static int shrink_liability(struct ubifs_info *c, int nr_to_write) |
66 | 66 | { |
67 | 67 | int nr_written; |
68 | - struct writeback_control wbc = { | |
69 | - .sync_mode = WB_SYNC_NONE, | |
70 | - .range_end = LLONG_MAX, | |
71 | - .nr_to_write = nr_to_write, | |
72 | - }; | |
73 | 68 | |
74 | - generic_sync_sb_inodes(c->vfs_sb, &wbc); | |
75 | - nr_written = nr_to_write - wbc.nr_to_write; | |
76 | - | |
69 | + nr_written = writeback_inodes_sb(c->vfs_sb); | |
77 | 70 | if (!nr_written) { |
78 | 71 | /* |
79 | 72 | * Re-try again but wait on pages/inodes which are being |
80 | 73 | * written-back concurrently (e.g., by pdflush). |
81 | 74 | */ |
82 | - memset(&wbc, 0, sizeof(struct writeback_control)); | |
83 | - wbc.sync_mode = WB_SYNC_ALL; | |
84 | - wbc.range_end = LLONG_MAX; | |
85 | - wbc.nr_to_write = nr_to_write; | |
86 | - generic_sync_sb_inodes(c->vfs_sb, &wbc); | |
87 | - nr_written = nr_to_write - wbc.nr_to_write; | |
75 | + nr_written = sync_inodes_sb(c->vfs_sb); | |
88 | 76 | } |
89 | 77 | |
90 | 78 | dbg_budg("%d pages were written back", nr_written); |
fs/ubifs/super.c
... | ... | @@ -438,12 +438,6 @@ |
438 | 438 | { |
439 | 439 | int i, err; |
440 | 440 | struct ubifs_info *c = sb->s_fs_info; |
441 | - struct writeback_control wbc = { | |
442 | - .sync_mode = WB_SYNC_ALL, | |
443 | - .range_start = 0, | |
444 | - .range_end = LLONG_MAX, | |
445 | - .nr_to_write = LONG_MAX, | |
446 | - }; | |
447 | 441 | |
448 | 442 | /* |
449 | 443 | * Zero @wait is just an advisory thing to help the file system shove |
... | ... | @@ -462,7 +456,7 @@ |
462 | 456 | * the user be able to get more accurate results of 'statfs()' after |
463 | 457 | * they synchronize the file system. |
464 | 458 | */ |
465 | - generic_sync_sb_inodes(sb, &wbc); | |
459 | + sync_inodes_sb(sb); | |
466 | 460 | |
467 | 461 | /* |
468 | 462 | * Synchronize write buffers, because 'ubifs_run_commit()' does not |
include/linux/fs.h
... | ... | @@ -2071,8 +2071,6 @@ |
2071 | 2071 | extern int invalidate_inode_pages2(struct address_space *mapping); |
2072 | 2072 | extern int invalidate_inode_pages2_range(struct address_space *mapping, |
2073 | 2073 | pgoff_t start, pgoff_t end); |
2074 | -extern void generic_sync_sb_inodes(struct super_block *sb, | |
2075 | - struct writeback_control *wbc); | |
2076 | 2074 | extern int write_inode_now(struct inode *, int); |
2077 | 2075 | extern int filemap_fdatawrite(struct address_space *); |
2078 | 2076 | extern int filemap_flush(struct address_space *); |
include/linux/writeback.h
... | ... | @@ -78,7 +78,8 @@ |
78 | 78 | */ |
79 | 79 | void writeback_inodes(struct writeback_control *wbc); |
80 | 80 | int inode_wait(void *); |
81 | -void sync_inodes_sb(struct super_block *, int wait); | |
81 | +long writeback_inodes_sb(struct super_block *); | |
82 | +long sync_inodes_sb(struct super_block *); | |
82 | 83 | |
83 | 84 | /* writeback.h requires fs.h; it, too, is not included from here. */ |
84 | 85 | static inline void wait_on_inode(struct inode *inode) |