diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-05 14:53:53 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-05 14:53:53 -0500 |
commit | 9467c4fdd66f6810cecef0f1173330f3c6e67d45 (patch) | |
tree | 5fea180a10127c893b288dff2c8788b72d2eaea3 | |
parent | 35c2e967d067ff02dc944f2434f024419c2fe83a (diff) | |
parent | a9185b41a4f84971b930c519f0c63bd450c4810d (diff) |
Merge branch 'write_inode2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'write_inode2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
pass writeback_control to ->write_inode
make sure data is on disk before calling ->write_inode
48 files changed, 123 insertions, 107 deletions
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h index 9cc18775b832..2ff622f6f547 100644 --- a/fs/adfs/adfs.h +++ b/fs/adfs/adfs.h | |||
@@ -121,7 +121,7 @@ struct adfs_discmap { | |||
121 | 121 | ||
122 | /* Inode stuff */ | 122 | /* Inode stuff */ |
123 | struct inode *adfs_iget(struct super_block *sb, struct object_info *obj); | 123 | struct inode *adfs_iget(struct super_block *sb, struct object_info *obj); |
124 | int adfs_write_inode(struct inode *inode,int unused); | 124 | int adfs_write_inode(struct inode *inode, struct writeback_control *wbc); |
125 | int adfs_notify_change(struct dentry *dentry, struct iattr *attr); | 125 | int adfs_notify_change(struct dentry *dentry, struct iattr *attr); |
126 | 126 | ||
127 | /* map.c */ | 127 | /* map.c */ |
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c index 3f57ce4bee5d..0f5e30978135 100644 --- a/fs/adfs/inode.c +++ b/fs/adfs/inode.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/smp_lock.h> | 10 | #include <linux/smp_lock.h> |
11 | #include <linux/buffer_head.h> | 11 | #include <linux/buffer_head.h> |
12 | #include <linux/writeback.h> | ||
12 | #include "adfs.h" | 13 | #include "adfs.h" |
13 | 14 | ||
14 | /* | 15 | /* |
@@ -360,7 +361,7 @@ out: | |||
360 | * The adfs-specific inode data has already been updated by | 361 | * The adfs-specific inode data has already been updated by |
361 | * adfs_notify_change() | 362 | * adfs_notify_change() |
362 | */ | 363 | */ |
363 | int adfs_write_inode(struct inode *inode, int wait) | 364 | int adfs_write_inode(struct inode *inode, struct writeback_control *wbc) |
364 | { | 365 | { |
365 | struct super_block *sb = inode->i_sb; | 366 | struct super_block *sb = inode->i_sb; |
366 | struct object_info obj; | 367 | struct object_info obj; |
@@ -375,7 +376,7 @@ int adfs_write_inode(struct inode *inode, int wait) | |||
375 | obj.attr = ADFS_I(inode)->attr; | 376 | obj.attr = ADFS_I(inode)->attr; |
376 | obj.size = inode->i_size; | 377 | obj.size = inode->i_size; |
377 | 378 | ||
378 | ret = adfs_dir_update(sb, &obj, wait); | 379 | ret = adfs_dir_update(sb, &obj, wbc->sync_mode == WB_SYNC_ALL); |
379 | unlock_kernel(); | 380 | unlock_kernel(); |
380 | return ret; | 381 | return ret; |
381 | } | 382 | } |
diff --git a/fs/affs/affs.h b/fs/affs/affs.h index 0e40caaba456..861dae68ac12 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h | |||
@@ -175,7 +175,8 @@ extern void affs_delete_inode(struct inode *inode); | |||
175 | extern void affs_clear_inode(struct inode *inode); | 175 | extern void affs_clear_inode(struct inode *inode); |
176 | extern struct inode *affs_iget(struct super_block *sb, | 176 | extern struct inode *affs_iget(struct super_block *sb, |
177 | unsigned long ino); | 177 | unsigned long ino); |
178 | extern int affs_write_inode(struct inode *inode, int); | 178 | extern int affs_write_inode(struct inode *inode, |
179 | struct writeback_control *wbc); | ||
179 | extern int affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type); | 180 | extern int affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type); |
180 | 181 | ||
181 | /* file.c */ | 182 | /* file.c */ |
diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 3c4ec7d864c4..c9744d771d98 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c | |||
@@ -166,7 +166,7 @@ bad_inode: | |||
166 | } | 166 | } |
167 | 167 | ||
168 | int | 168 | int |
169 | affs_write_inode(struct inode *inode, int unused) | 169 | affs_write_inode(struct inode *inode, struct writeback_control *wbc) |
170 | { | 170 | { |
171 | struct super_block *sb = inode->i_sb; | 171 | struct super_block *sb = inode->i_sb; |
172 | struct buffer_head *bh; | 172 | struct buffer_head *bh; |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 6ece2a13bf71..c54dad4e6063 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -733,7 +733,6 @@ extern int afs_write_end(struct file *file, struct address_space *mapping, | |||
733 | struct page *page, void *fsdata); | 733 | struct page *page, void *fsdata); |
734 | extern int afs_writepage(struct page *, struct writeback_control *); | 734 | extern int afs_writepage(struct page *, struct writeback_control *); |
735 | extern int afs_writepages(struct address_space *, struct writeback_control *); | 735 | extern int afs_writepages(struct address_space *, struct writeback_control *); |
736 | extern int afs_write_inode(struct inode *, int); | ||
737 | extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *); | 736 | extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *); |
738 | extern ssize_t afs_file_write(struct kiocb *, const struct iovec *, | 737 | extern ssize_t afs_file_write(struct kiocb *, const struct iovec *, |
739 | unsigned long, loff_t); | 738 | unsigned long, loff_t); |
diff --git a/fs/afs/super.c b/fs/afs/super.c index e1ea1c240b6a..14f6431598ad 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -48,7 +48,6 @@ struct file_system_type afs_fs_type = { | |||
48 | static const struct super_operations afs_super_ops = { | 48 | static const struct super_operations afs_super_ops = { |
49 | .statfs = afs_statfs, | 49 | .statfs = afs_statfs, |
50 | .alloc_inode = afs_alloc_inode, | 50 | .alloc_inode = afs_alloc_inode, |
51 | .write_inode = afs_write_inode, | ||
52 | .destroy_inode = afs_destroy_inode, | 51 | .destroy_inode = afs_destroy_inode, |
53 | .clear_inode = afs_clear_inode, | 52 | .clear_inode = afs_clear_inode, |
54 | .put_super = afs_put_super, | 53 | .put_super = afs_put_super, |
diff --git a/fs/afs/write.c b/fs/afs/write.c index 5e15a21dbf9f..3bed54a294d4 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c | |||
@@ -585,27 +585,6 @@ int afs_writepages(struct address_space *mapping, | |||
585 | } | 585 | } |
586 | 586 | ||
587 | /* | 587 | /* |
588 | * write an inode back | ||
589 | */ | ||
590 | int afs_write_inode(struct inode *inode, int sync) | ||
591 | { | ||
592 | struct afs_vnode *vnode = AFS_FS_I(inode); | ||
593 | int ret; | ||
594 | |||
595 | _enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode); | ||
596 | |||
597 | ret = 0; | ||
598 | if (sync) { | ||
599 | ret = filemap_fdatawait(inode->i_mapping); | ||
600 | if (ret < 0) | ||
601 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); | ||
602 | } | ||
603 | |||
604 | _leave(" = %d", ret); | ||
605 | return ret; | ||
606 | } | ||
607 | |||
608 | /* | ||
609 | * completion of write to server | 588 | * completion of write to server |
610 | */ | 589 | */ |
611 | void afs_pages_written_back(struct afs_vnode *vnode, struct afs_call *call) | 590 | void afs_pages_written_back(struct afs_vnode *vnode, struct afs_call *call) |
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 8f3d9fd89604..f22a7d3dc362 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/smp_lock.h> | 15 | #include <linux/smp_lock.h> |
16 | #include <linux/buffer_head.h> | 16 | #include <linux/buffer_head.h> |
17 | #include <linux/vfs.h> | 17 | #include <linux/vfs.h> |
18 | #include <linux/writeback.h> | ||
18 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
19 | #include "bfs.h" | 20 | #include "bfs.h" |
20 | 21 | ||
@@ -98,7 +99,7 @@ error: | |||
98 | return ERR_PTR(-EIO); | 99 | return ERR_PTR(-EIO); |
99 | } | 100 | } |
100 | 101 | ||
101 | static int bfs_write_inode(struct inode *inode, int wait) | 102 | static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc) |
102 | { | 103 | { |
103 | struct bfs_sb_info *info = BFS_SB(inode->i_sb); | 104 | struct bfs_sb_info *info = BFS_SB(inode->i_sb); |
104 | unsigned int ino = (u16)inode->i_ino; | 105 | unsigned int ino = (u16)inode->i_ino; |
@@ -147,7 +148,7 @@ static int bfs_write_inode(struct inode *inode, int wait) | |||
147 | di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1); | 148 | di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1); |
148 | 149 | ||
149 | mark_buffer_dirty(bh); | 150 | mark_buffer_dirty(bh); |
150 | if (wait) { | 151 | if (wbc->sync_mode == WB_SYNC_ALL) { |
151 | sync_dirty_buffer(bh); | 152 | sync_dirty_buffer(bh); |
152 | if (buffer_req(bh) && !buffer_uptodate(bh)) | 153 | if (buffer_req(bh) && !buffer_uptodate(bh)) |
153 | err = -EIO; | 154 | err = -EIO; |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 2aa8ec6a0981..8b5cfdd4bfc1 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -2326,7 +2326,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); | |||
2326 | int btrfs_readpage(struct file *file, struct page *page); | 2326 | int btrfs_readpage(struct file *file, struct page *page); |
2327 | void btrfs_delete_inode(struct inode *inode); | 2327 | void btrfs_delete_inode(struct inode *inode); |
2328 | void btrfs_put_inode(struct inode *inode); | 2328 | void btrfs_put_inode(struct inode *inode); |
2329 | int btrfs_write_inode(struct inode *inode, int wait); | 2329 | int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc); |
2330 | void btrfs_dirty_inode(struct inode *inode); | 2330 | void btrfs_dirty_inode(struct inode *inode); |
2331 | struct inode *btrfs_alloc_inode(struct super_block *sb); | 2331 | struct inode *btrfs_alloc_inode(struct super_block *sb); |
2332 | void btrfs_destroy_inode(struct inode *inode); | 2332 | void btrfs_destroy_inode(struct inode *inode); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4deb280f8969..c41db6d45ab6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -3968,7 +3968,7 @@ err: | |||
3968 | return ret; | 3968 | return ret; |
3969 | } | 3969 | } |
3970 | 3970 | ||
3971 | int btrfs_write_inode(struct inode *inode, int wait) | 3971 | int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc) |
3972 | { | 3972 | { |
3973 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3973 | struct btrfs_root *root = BTRFS_I(inode)->root; |
3974 | struct btrfs_trans_handle *trans; | 3974 | struct btrfs_trans_handle *trans; |
@@ -3977,7 +3977,7 @@ int btrfs_write_inode(struct inode *inode, int wait) | |||
3977 | if (root->fs_info->btree_inode == inode) | 3977 | if (root->fs_info->btree_inode == inode) |
3978 | return 0; | 3978 | return 0; |
3979 | 3979 | ||
3980 | if (wait) { | 3980 | if (wbc->sync_mode == WB_SYNC_ALL) { |
3981 | trans = btrfs_join_transaction(root, 1); | 3981 | trans = btrfs_join_transaction(root, 1); |
3982 | btrfs_set_trans_block_group(trans, inode); | 3982 | btrfs_set_trans_block_group(trans, inode); |
3983 | ret = btrfs_commit_transaction(trans, root); | 3983 | ret = btrfs_commit_transaction(trans, root); |
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h index 59b8bf2825c7..8442e353309f 100644 --- a/fs/exofs/exofs.h +++ b/fs/exofs/exofs.h | |||
@@ -261,7 +261,7 @@ int exofs_write_begin(struct file *file, struct address_space *mapping, | |||
261 | struct page **pagep, void **fsdata); | 261 | struct page **pagep, void **fsdata); |
262 | extern struct inode *exofs_iget(struct super_block *, unsigned long); | 262 | extern struct inode *exofs_iget(struct super_block *, unsigned long); |
263 | struct inode *exofs_new_inode(struct inode *, int); | 263 | struct inode *exofs_new_inode(struct inode *, int); |
264 | extern int exofs_write_inode(struct inode *, int); | 264 | extern int exofs_write_inode(struct inode *, struct writeback_control *wbc); |
265 | extern void exofs_delete_inode(struct inode *); | 265 | extern void exofs_delete_inode(struct inode *); |
266 | 266 | ||
267 | /* dir.c: */ | 267 | /* dir.c: */ |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 5514f3c2c2f4..a17e4b733e35 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -1280,9 +1280,9 @@ out: | |||
1280 | return ret; | 1280 | return ret; |
1281 | } | 1281 | } |
1282 | 1282 | ||
1283 | int exofs_write_inode(struct inode *inode, int wait) | 1283 | int exofs_write_inode(struct inode *inode, struct writeback_control *wbc) |
1284 | { | 1284 | { |
1285 | return exofs_update_inode(inode, wait); | 1285 | return exofs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); |
1286 | } | 1286 | } |
1287 | 1287 | ||
1288 | /* | 1288 | /* |
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 061914add3cf..0b038e47ad2f 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
@@ -118,7 +118,7 @@ extern unsigned long ext2_count_free (struct buffer_head *, unsigned); | |||
118 | 118 | ||
119 | /* inode.c */ | 119 | /* inode.c */ |
120 | extern struct inode *ext2_iget (struct super_block *, unsigned long); | 120 | extern struct inode *ext2_iget (struct super_block *, unsigned long); |
121 | extern int ext2_write_inode (struct inode *, int); | 121 | extern int ext2_write_inode (struct inode *, struct writeback_control *); |
122 | extern void ext2_delete_inode (struct inode *); | 122 | extern void ext2_delete_inode (struct inode *); |
123 | extern int ext2_sync_inode (struct inode *); | 123 | extern int ext2_sync_inode (struct inode *); |
124 | extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int); | 124 | extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int); |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 71b032c65a02..36ae1cac767c 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -41,6 +41,8 @@ MODULE_AUTHOR("Remy Card and others"); | |||
41 | MODULE_DESCRIPTION("Second Extended Filesystem"); | 41 | MODULE_DESCRIPTION("Second Extended Filesystem"); |
42 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
43 | 43 | ||
44 | static int __ext2_write_inode(struct inode *inode, int do_sync); | ||
45 | |||
44 | /* | 46 | /* |
45 | * Test whether an inode is a fast symlink. | 47 | * Test whether an inode is a fast symlink. |
46 | */ | 48 | */ |
@@ -64,7 +66,7 @@ void ext2_delete_inode (struct inode * inode) | |||
64 | goto no_delete; | 66 | goto no_delete; |
65 | EXT2_I(inode)->i_dtime = get_seconds(); | 67 | EXT2_I(inode)->i_dtime = get_seconds(); |
66 | mark_inode_dirty(inode); | 68 | mark_inode_dirty(inode); |
67 | ext2_write_inode(inode, inode_needs_sync(inode)); | 69 | __ext2_write_inode(inode, inode_needs_sync(inode)); |
68 | 70 | ||
69 | inode->i_size = 0; | 71 | inode->i_size = 0; |
70 | if (inode->i_blocks) | 72 | if (inode->i_blocks) |
@@ -1335,7 +1337,7 @@ bad_inode: | |||
1335 | return ERR_PTR(ret); | 1337 | return ERR_PTR(ret); |
1336 | } | 1338 | } |
1337 | 1339 | ||
1338 | int ext2_write_inode(struct inode *inode, int do_sync) | 1340 | static int __ext2_write_inode(struct inode *inode, int do_sync) |
1339 | { | 1341 | { |
1340 | struct ext2_inode_info *ei = EXT2_I(inode); | 1342 | struct ext2_inode_info *ei = EXT2_I(inode); |
1341 | struct super_block *sb = inode->i_sb; | 1343 | struct super_block *sb = inode->i_sb; |
@@ -1440,6 +1442,11 @@ int ext2_write_inode(struct inode *inode, int do_sync) | |||
1440 | return err; | 1442 | return err; |
1441 | } | 1443 | } |
1442 | 1444 | ||
1445 | int ext2_write_inode(struct inode *inode, struct writeback_control *wbc) | ||
1446 | { | ||
1447 | return __ext2_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); | ||
1448 | } | ||
1449 | |||
1443 | int ext2_sync_inode(struct inode *inode) | 1450 | int ext2_sync_inode(struct inode *inode) |
1444 | { | 1451 | { |
1445 | struct writeback_control wbc = { | 1452 | struct writeback_control wbc = { |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 455e6e6e5cb9..7aca55fcc976 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -3096,7 +3096,7 @@ out_brelse: | |||
3096 | * `stuff()' is running, and the new i_size will be lost. Plus the inode | 3096 | * `stuff()' is running, and the new i_size will be lost. Plus the inode |
3097 | * will no longer be on the superblock's dirty inode list. | 3097 | * will no longer be on the superblock's dirty inode list. |
3098 | */ | 3098 | */ |
3099 | int ext3_write_inode(struct inode *inode, int wait) | 3099 | int ext3_write_inode(struct inode *inode, struct writeback_control *wbc) |
3100 | { | 3100 | { |
3101 | if (current->flags & PF_MEMALLOC) | 3101 | if (current->flags & PF_MEMALLOC) |
3102 | return 0; | 3102 | return 0; |
@@ -3107,7 +3107,7 @@ int ext3_write_inode(struct inode *inode, int wait) | |||
3107 | return -EIO; | 3107 | return -EIO; |
3108 | } | 3108 | } |
3109 | 3109 | ||
3110 | if (!wait) | 3110 | if (wbc->sync_mode != WB_SYNC_ALL) |
3111 | return 0; | 3111 | return 0; |
3112 | 3112 | ||
3113 | return ext3_force_commit(inode->i_sb); | 3113 | return ext3_force_commit(inode->i_sb); |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 6e5787a29b90..bf938cf7c5f0 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1446,7 +1446,7 @@ int ext4_get_block(struct inode *inode, sector_t iblock, | |||
1446 | struct buffer_head *bh_result, int create); | 1446 | struct buffer_head *bh_result, int create); |
1447 | 1447 | ||
1448 | extern struct inode *ext4_iget(struct super_block *, unsigned long); | 1448 | extern struct inode *ext4_iget(struct super_block *, unsigned long); |
1449 | extern int ext4_write_inode(struct inode *, int); | 1449 | extern int ext4_write_inode(struct inode *, struct writeback_control *); |
1450 | extern int ext4_setattr(struct dentry *, struct iattr *); | 1450 | extern int ext4_setattr(struct dentry *, struct iattr *); |
1451 | extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, | 1451 | extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, |
1452 | struct kstat *stat); | 1452 | struct kstat *stat); |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index f55df7192b95..f977aade0d1b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -5348,7 +5348,7 @@ out_brelse: | |||
5348 | * `stuff()' is running, and the new i_size will be lost. Plus the inode | 5348 | * `stuff()' is running, and the new i_size will be lost. Plus the inode |
5349 | * will no longer be on the superblock's dirty inode list. | 5349 | * will no longer be on the superblock's dirty inode list. |
5350 | */ | 5350 | */ |
5351 | int ext4_write_inode(struct inode *inode, int wait) | 5351 | int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) |
5352 | { | 5352 | { |
5353 | int err; | 5353 | int err; |
5354 | 5354 | ||
@@ -5362,7 +5362,7 @@ int ext4_write_inode(struct inode *inode, int wait) | |||
5362 | return -EIO; | 5362 | return -EIO; |
5363 | } | 5363 | } |
5364 | 5364 | ||
5365 | if (!wait) | 5365 | if (wbc->sync_mode != WB_SYNC_ALL) |
5366 | return 0; | 5366 | return 0; |
5367 | 5367 | ||
5368 | err = ext4_force_commit(inode->i_sb); | 5368 | err = ext4_force_commit(inode->i_sb); |
@@ -5372,7 +5372,7 @@ int ext4_write_inode(struct inode *inode, int wait) | |||
5372 | err = ext4_get_inode_loc(inode, &iloc); | 5372 | err = ext4_get_inode_loc(inode, &iloc); |
5373 | if (err) | 5373 | if (err) |
5374 | return err; | 5374 | return err; |
5375 | if (wait) | 5375 | if (wbc->sync_mode == WB_SYNC_ALL) |
5376 | sync_dirty_buffer(iloc.bh); | 5376 | sync_dirty_buffer(iloc.bh); |
5377 | if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) { | 5377 | if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) { |
5378 | ext4_error(inode->i_sb, "IO error syncing inode, " | 5378 | ext4_error(inode->i_sb, "IO error syncing inode, " |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 14da530b05ca..fbeecdc194dc 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -577,7 +577,7 @@ static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi, | |||
577 | return i_pos; | 577 | return i_pos; |
578 | } | 578 | } |
579 | 579 | ||
580 | static int fat_write_inode(struct inode *inode, int wait) | 580 | static int __fat_write_inode(struct inode *inode, int wait) |
581 | { | 581 | { |
582 | struct super_block *sb = inode->i_sb; | 582 | struct super_block *sb = inode->i_sb; |
583 | struct msdos_sb_info *sbi = MSDOS_SB(sb); | 583 | struct msdos_sb_info *sbi = MSDOS_SB(sb); |
@@ -634,9 +634,14 @@ retry: | |||
634 | return err; | 634 | return err; |
635 | } | 635 | } |
636 | 636 | ||
637 | static int fat_write_inode(struct inode *inode, struct writeback_control *wbc) | ||
638 | { | ||
639 | return __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); | ||
640 | } | ||
641 | |||
637 | int fat_sync_inode(struct inode *inode) | 642 | int fat_sync_inode(struct inode *inode) |
638 | { | 643 | { |
639 | return fat_write_inode(inode, 1); | 644 | return __fat_write_inode(inode, 1); |
640 | } | 645 | } |
641 | 646 | ||
642 | EXPORT_SYMBOL_GPL(fat_sync_inode); | 647 | EXPORT_SYMBOL_GPL(fat_sync_inode); |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 1a7c42c64ff4..76fc4d594acb 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -381,10 +381,10 @@ static void queue_io(struct bdi_writeback *wb, unsigned long *older_than_this) | |||
381 | move_expired_inodes(&wb->b_dirty, &wb->b_io, older_than_this); | 381 | move_expired_inodes(&wb->b_dirty, &wb->b_io, older_than_this); |
382 | } | 382 | } |
383 | 383 | ||
384 | static int write_inode(struct inode *inode, int sync) | 384 | static int write_inode(struct inode *inode, struct writeback_control *wbc) |
385 | { | 385 | { |
386 | if (inode->i_sb->s_op->write_inode && !is_bad_inode(inode)) | 386 | if (inode->i_sb->s_op->write_inode && !is_bad_inode(inode)) |
387 | return inode->i_sb->s_op->write_inode(inode, sync); | 387 | return inode->i_sb->s_op->write_inode(inode, wbc); |
388 | return 0; | 388 | return 0; |
389 | } | 389 | } |
390 | 390 | ||
@@ -421,7 +421,6 @@ static int | |||
421 | writeback_single_inode(struct inode *inode, struct writeback_control *wbc) | 421 | writeback_single_inode(struct inode *inode, struct writeback_control *wbc) |
422 | { | 422 | { |
423 | struct address_space *mapping = inode->i_mapping; | 423 | struct address_space *mapping = inode->i_mapping; |
424 | int wait = wbc->sync_mode == WB_SYNC_ALL; | ||
425 | unsigned dirty; | 424 | unsigned dirty; |
426 | int ret; | 425 | int ret; |
427 | 426 | ||
@@ -439,7 +438,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
439 | * We'll have another go at writing back this inode when we | 438 | * We'll have another go at writing back this inode when we |
440 | * completed a full scan of b_io. | 439 | * completed a full scan of b_io. |
441 | */ | 440 | */ |
442 | if (!wait) { | 441 | if (wbc->sync_mode != WB_SYNC_ALL) { |
443 | requeue_io(inode); | 442 | requeue_io(inode); |
444 | return 0; | 443 | return 0; |
445 | } | 444 | } |
@@ -461,15 +460,20 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
461 | 460 | ||
462 | ret = do_writepages(mapping, wbc); | 461 | ret = do_writepages(mapping, wbc); |
463 | 462 | ||
464 | /* Don't write the inode if only I_DIRTY_PAGES was set */ | 463 | /* |
465 | if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { | 464 | * Make sure to wait on the data before writing out the metadata. |
466 | int err = write_inode(inode, wait); | 465 | * This is important for filesystems that modify metadata on data |
466 | * I/O completion. | ||
467 | */ | ||
468 | if (wbc->sync_mode == WB_SYNC_ALL) { | ||
469 | int err = filemap_fdatawait(mapping); | ||
467 | if (ret == 0) | 470 | if (ret == 0) |
468 | ret = err; | 471 | ret = err; |
469 | } | 472 | } |
470 | 473 | ||
471 | if (wait) { | 474 | /* Don't write the inode if only I_DIRTY_PAGES was set */ |
472 | int err = filemap_fdatawait(mapping); | 475 | if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { |
476 | int err = write_inode(inode, wbc); | ||
473 | if (ret == 0) | 477 | if (ret == 0) |
474 | ret = err; | 478 | ret = err; |
475 | } | 479 | } |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index e5e22629da67..ca87598ead7f 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/crc32.h> | 22 | #include <linux/crc32.h> |
23 | #include <linux/time.h> | 23 | #include <linux/time.h> |
24 | #include <linux/wait.h> | 24 | #include <linux/wait.h> |
25 | #include <linux/writeback.h> | ||
25 | 26 | ||
26 | #include "gfs2.h" | 27 | #include "gfs2.h" |
27 | #include "incore.h" | 28 | #include "incore.h" |
@@ -711,7 +712,7 @@ void gfs2_unfreeze_fs(struct gfs2_sbd *sdp) | |||
711 | * Returns: errno | 712 | * Returns: errno |
712 | */ | 713 | */ |
713 | 714 | ||
714 | static int gfs2_write_inode(struct inode *inode, int sync) | 715 | static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc) |
715 | { | 716 | { |
716 | struct gfs2_inode *ip = GFS2_I(inode); | 717 | struct gfs2_inode *ip = GFS2_I(inode); |
717 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 718 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
@@ -745,7 +746,7 @@ static int gfs2_write_inode(struct inode *inode, int sync) | |||
745 | do_unlock: | 746 | do_unlock: |
746 | gfs2_glock_dq_uninit(&gh); | 747 | gfs2_glock_dq_uninit(&gh); |
747 | do_flush: | 748 | do_flush: |
748 | if (sync != 0) | 749 | if (wbc->sync_mode == WB_SYNC_ALL) |
749 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); | 750 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); |
750 | return ret; | 751 | return ret; |
751 | } | 752 | } |
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h index 052387e11671..fe35e3b626c4 100644 --- a/fs/hfs/hfs_fs.h +++ b/fs/hfs/hfs_fs.h | |||
@@ -188,7 +188,7 @@ extern const struct address_space_operations hfs_btree_aops; | |||
188 | 188 | ||
189 | extern struct inode *hfs_new_inode(struct inode *, struct qstr *, int); | 189 | extern struct inode *hfs_new_inode(struct inode *, struct qstr *, int); |
190 | extern void hfs_inode_write_fork(struct inode *, struct hfs_extent *, __be32 *, __be32 *); | 190 | extern void hfs_inode_write_fork(struct inode *, struct hfs_extent *, __be32 *, __be32 *); |
191 | extern int hfs_write_inode(struct inode *, int); | 191 | extern int hfs_write_inode(struct inode *, struct writeback_control *); |
192 | extern int hfs_inode_setattr(struct dentry *, struct iattr *); | 192 | extern int hfs_inode_setattr(struct dentry *, struct iattr *); |
193 | extern void hfs_inode_read_fork(struct inode *inode, struct hfs_extent *ext, | 193 | extern void hfs_inode_read_fork(struct inode *inode, struct hfs_extent *ext, |
194 | __be32 log_size, __be32 phys_size, u32 clump_size); | 194 | __be32 log_size, __be32 phys_size, u32 clump_size); |
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index a1cbff2b4d99..14f5cb1b9fdc 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
@@ -381,7 +381,7 @@ void hfs_inode_write_fork(struct inode *inode, struct hfs_extent *ext, | |||
381 | HFS_SB(inode->i_sb)->alloc_blksz); | 381 | HFS_SB(inode->i_sb)->alloc_blksz); |
382 | } | 382 | } |
383 | 383 | ||
384 | int hfs_write_inode(struct inode *inode, int unused) | 384 | int hfs_write_inode(struct inode *inode, struct writeback_control *wbc) |
385 | { | 385 | { |
386 | struct inode *main_inode = inode; | 386 | struct inode *main_inode = inode; |
387 | struct hfs_find_data fd; | 387 | struct hfs_find_data fd; |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 43022f3d5148..74b473a8ef92 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -87,7 +87,8 @@ bad_inode: | |||
87 | return ERR_PTR(err); | 87 | return ERR_PTR(err); |
88 | } | 88 | } |
89 | 89 | ||
90 | static int hfsplus_write_inode(struct inode *inode, int unused) | 90 | static int hfsplus_write_inode(struct inode *inode, |
91 | struct writeback_control *wbc) | ||
91 | { | 92 | { |
92 | struct hfsplus_vh *vhdr; | 93 | struct hfsplus_vh *vhdr; |
93 | int ret = 0; | 94 | int ret = 0; |
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index b2ae190a77ba..182b78cc3e62 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/buffer_head.h> | 22 | #include <linux/buffer_head.h> |
23 | #include <linux/pagemap.h> | 23 | #include <linux/pagemap.h> |
24 | #include <linux/quotaops.h> | 24 | #include <linux/quotaops.h> |
25 | #include <linux/writeback.h> | ||
25 | #include "jfs_incore.h" | 26 | #include "jfs_incore.h" |
26 | #include "jfs_inode.h" | 27 | #include "jfs_inode.h" |
27 | #include "jfs_filsys.h" | 28 | #include "jfs_filsys.h" |
@@ -120,8 +121,10 @@ int jfs_commit_inode(struct inode *inode, int wait) | |||
120 | return rc; | 121 | return rc; |
121 | } | 122 | } |
122 | 123 | ||
123 | int jfs_write_inode(struct inode *inode, int wait) | 124 | int jfs_write_inode(struct inode *inode, struct writeback_control *wbc) |
124 | { | 125 | { |
126 | int wait = wbc->sync_mode == WB_SYNC_ALL; | ||
127 | |||
125 | if (test_cflag(COMMIT_Nolink, inode)) | 128 | if (test_cflag(COMMIT_Nolink, inode)) |
126 | return 0; | 129 | return 0; |
127 | /* | 130 | /* |
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 1eff7db34d63..15902b03c2a7 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h | |||
@@ -26,7 +26,7 @@ extern long jfs_ioctl(struct file *, unsigned int, unsigned long); | |||
26 | extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long); | 26 | extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long); |
27 | extern struct inode *jfs_iget(struct super_block *, unsigned long); | 27 | extern struct inode *jfs_iget(struct super_block *, unsigned long); |
28 | extern int jfs_commit_inode(struct inode *, int); | 28 | extern int jfs_commit_inode(struct inode *, int); |
29 | extern int jfs_write_inode(struct inode*, int); | 29 | extern int jfs_write_inode(struct inode *, struct writeback_control *); |
30 | extern void jfs_delete_inode(struct inode *); | 30 | extern void jfs_delete_inode(struct inode *); |
31 | extern void jfs_dirty_inode(struct inode *); | 31 | extern void jfs_dirty_inode(struct inode *); |
32 | extern void jfs_truncate(struct inode *); | 32 | extern void jfs_truncate(struct inode *); |
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 74ea82d72164..756f8c93780c 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
@@ -17,8 +17,10 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/highuid.h> | 18 | #include <linux/highuid.h> |
19 | #include <linux/vfs.h> | 19 | #include <linux/vfs.h> |
20 | #include <linux/writeback.h> | ||
20 | 21 | ||
21 | static int minix_write_inode(struct inode * inode, int wait); | 22 | static int minix_write_inode(struct inode *inode, |
23 | struct writeback_control *wbc); | ||
22 | static int minix_statfs(struct dentry *dentry, struct kstatfs *buf); | 24 | static int minix_statfs(struct dentry *dentry, struct kstatfs *buf); |
23 | static int minix_remount (struct super_block * sb, int * flags, char * data); | 25 | static int minix_remount (struct super_block * sb, int * flags, char * data); |
24 | 26 | ||
@@ -552,7 +554,7 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode) | |||
552 | return bh; | 554 | return bh; |
553 | } | 555 | } |
554 | 556 | ||
555 | static int minix_write_inode(struct inode *inode, int wait) | 557 | static int minix_write_inode(struct inode *inode, struct writeback_control *wbc) |
556 | { | 558 | { |
557 | int err = 0; | 559 | int err = 0; |
558 | struct buffer_head *bh; | 560 | struct buffer_head *bh; |
@@ -563,7 +565,7 @@ static int minix_write_inode(struct inode *inode, int wait) | |||
563 | bh = V2_minix_update_inode(inode); | 565 | bh = V2_minix_update_inode(inode); |
564 | if (!bh) | 566 | if (!bh) |
565 | return -EIO; | 567 | return -EIO; |
566 | if (wait && buffer_dirty(bh)) { | 568 | if (wbc->sync_mode == WB_SYNC_ALL && buffer_dirty(bh)) { |
567 | sync_dirty_buffer(bh); | 569 | sync_dirty_buffer(bh); |
568 | if (buffer_req(bh) && !buffer_uptodate(bh)) { | 570 | if (buffer_req(bh) && !buffer_uptodate(bh)) { |
569 | printk("IO error syncing minix inode [%s:%08lx]\n", | 571 | printk("IO error syncing minix inode [%s:%08lx]\n", |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 7570573bdb30..7f9ecc46f3fb 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -97,16 +97,12 @@ u64 nfs_compat_user_ino64(u64 fileid) | |||
97 | return ino; | 97 | return ino; |
98 | } | 98 | } |
99 | 99 | ||
100 | int nfs_write_inode(struct inode *inode, int sync) | 100 | int nfs_write_inode(struct inode *inode, struct writeback_control *wbc) |
101 | { | 101 | { |
102 | int ret; | 102 | int ret; |
103 | 103 | ||
104 | if (sync) { | 104 | ret = nfs_commit_inode(inode, |
105 | ret = filemap_fdatawait(inode->i_mapping); | 105 | wbc->sync_mode == WB_SYNC_ALL ? FLUSH_SYNC : 0); |
106 | if (ret == 0) | ||
107 | ret = nfs_commit_inode(inode, FLUSH_SYNC); | ||
108 | } else | ||
109 | ret = nfs_commit_inode(inode, 0); | ||
110 | if (ret >= 0) | 106 | if (ret >= 0) |
111 | return 0; | 107 | return 0; |
112 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); | 108 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 29e464d23b32..11f82f03c5de 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -211,7 +211,7 @@ extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask); | |||
211 | extern struct workqueue_struct *nfsiod_workqueue; | 211 | extern struct workqueue_struct *nfsiod_workqueue; |
212 | extern struct inode *nfs_alloc_inode(struct super_block *sb); | 212 | extern struct inode *nfs_alloc_inode(struct super_block *sb); |
213 | extern void nfs_destroy_inode(struct inode *); | 213 | extern void nfs_destroy_inode(struct inode *); |
214 | extern int nfs_write_inode(struct inode *,int); | 214 | extern int nfs_write_inode(struct inode *, struct writeback_control *); |
215 | extern void nfs_clear_inode(struct inode *); | 215 | extern void nfs_clear_inode(struct inode *); |
216 | #ifdef CONFIG_NFS_V4 | 216 | #ifdef CONFIG_NFS_V4 |
217 | extern void nfs4_clear_inode(struct inode *); | 217 | extern void nfs4_clear_inode(struct inode *); |
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c index 5a9e34475e37..9173e82a45d1 100644 --- a/fs/ntfs/dir.c +++ b/fs/ntfs/dir.c | |||
@@ -1545,7 +1545,7 @@ static int ntfs_dir_fsync(struct file *filp, struct dentry *dentry, | |||
1545 | write_inode_now(bmp_vi, !datasync); | 1545 | write_inode_now(bmp_vi, !datasync); |
1546 | iput(bmp_vi); | 1546 | iput(bmp_vi); |
1547 | } | 1547 | } |
1548 | ret = ntfs_write_inode(vi, 1); | 1548 | ret = __ntfs_write_inode(vi, 1); |
1549 | write_inode_now(vi, !datasync); | 1549 | write_inode_now(vi, !datasync); |
1550 | err = sync_blockdev(vi->i_sb->s_bdev); | 1550 | err = sync_blockdev(vi->i_sb->s_bdev); |
1551 | if (unlikely(err && !ret)) | 1551 | if (unlikely(err && !ret)) |
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 43179ddd336f..b681c71d7069 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c | |||
@@ -2182,7 +2182,7 @@ static int ntfs_file_fsync(struct file *filp, struct dentry *dentry, | |||
2182 | ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); | 2182 | ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); |
2183 | BUG_ON(S_ISDIR(vi->i_mode)); | 2183 | BUG_ON(S_ISDIR(vi->i_mode)); |
2184 | if (!datasync || !NInoNonResident(NTFS_I(vi))) | 2184 | if (!datasync || !NInoNonResident(NTFS_I(vi))) |
2185 | ret = ntfs_write_inode(vi, 1); | 2185 | ret = __ntfs_write_inode(vi, 1); |
2186 | write_inode_now(vi, !datasync); | 2186 | write_inode_now(vi, !datasync); |
2187 | /* | 2187 | /* |
2188 | * NOTE: If we were to use mapping->private_list (see ext2 and | 2188 | * NOTE: If we were to use mapping->private_list (see ext2 and |
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index dc2505abb6d7..4b57fb1eac2a 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
@@ -2957,7 +2957,7 @@ out: | |||
2957 | * | 2957 | * |
2958 | * Return 0 on success and -errno on error. | 2958 | * Return 0 on success and -errno on error. |
2959 | */ | 2959 | */ |
2960 | int ntfs_write_inode(struct inode *vi, int sync) | 2960 | int __ntfs_write_inode(struct inode *vi, int sync) |
2961 | { | 2961 | { |
2962 | sle64 nt; | 2962 | sle64 nt; |
2963 | ntfs_inode *ni = NTFS_I(vi); | 2963 | ntfs_inode *ni = NTFS_I(vi); |
diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h index 117eaf8032a3..9a113544605d 100644 --- a/fs/ntfs/inode.h +++ b/fs/ntfs/inode.h | |||
@@ -307,12 +307,12 @@ extern void ntfs_truncate_vfs(struct inode *vi); | |||
307 | 307 | ||
308 | extern int ntfs_setattr(struct dentry *dentry, struct iattr *attr); | 308 | extern int ntfs_setattr(struct dentry *dentry, struct iattr *attr); |
309 | 309 | ||
310 | extern int ntfs_write_inode(struct inode *vi, int sync); | 310 | extern int __ntfs_write_inode(struct inode *vi, int sync); |
311 | 311 | ||
312 | static inline void ntfs_commit_inode(struct inode *vi) | 312 | static inline void ntfs_commit_inode(struct inode *vi) |
313 | { | 313 | { |
314 | if (!is_bad_inode(vi)) | 314 | if (!is_bad_inode(vi)) |
315 | ntfs_write_inode(vi, 1); | 315 | __ntfs_write_inode(vi, 1); |
316 | return; | 316 | return; |
317 | } | 317 | } |
318 | 318 | ||
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 80b04770e8e9..1cf39dfaee7a 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include "dir.h" | 39 | #include "dir.h" |
40 | #include "debug.h" | 40 | #include "debug.h" |
41 | #include "index.h" | 41 | #include "index.h" |
42 | #include "inode.h" | ||
42 | #include "aops.h" | 43 | #include "aops.h" |
43 | #include "layout.h" | 44 | #include "layout.h" |
44 | #include "malloc.h" | 45 | #include "malloc.h" |
@@ -2662,6 +2663,13 @@ static int ntfs_statfs(struct dentry *dentry, struct kstatfs *sfs) | |||
2662 | return 0; | 2663 | return 0; |
2663 | } | 2664 | } |
2664 | 2665 | ||
2666 | #ifdef NTFS_RW | ||
2667 | static int ntfs_write_inode(struct inode *vi, struct writeback_control *wbc) | ||
2668 | { | ||
2669 | return __ntfs_write_inode(vi, wbc->sync_mode == WB_SYNC_ALL); | ||
2670 | } | ||
2671 | #endif | ||
2672 | |||
2665 | /** | 2673 | /** |
2666 | * The complete super operations. | 2674 | * The complete super operations. |
2667 | */ | 2675 | */ |
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index f3b7c1541f3a..75d9b5ba1d45 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/parser.h> | 11 | #include <linux/parser.h> |
12 | #include <linux/buffer_head.h> | 12 | #include <linux/buffer_head.h> |
13 | #include <linux/vmalloc.h> | 13 | #include <linux/vmalloc.h> |
14 | #include <linux/writeback.h> | ||
14 | #include <linux/crc-itu-t.h> | 15 | #include <linux/crc-itu-t.h> |
15 | #include "omfs.h" | 16 | #include "omfs.h" |
16 | 17 | ||
@@ -89,7 +90,7 @@ static void omfs_update_checksums(struct omfs_inode *oi) | |||
89 | oi->i_head.h_check_xor = xor; | 90 | oi->i_head.h_check_xor = xor; |
90 | } | 91 | } |
91 | 92 | ||
92 | static int omfs_write_inode(struct inode *inode, int wait) | 93 | static int __omfs_write_inode(struct inode *inode, int wait) |
93 | { | 94 | { |
94 | struct omfs_inode *oi; | 95 | struct omfs_inode *oi; |
95 | struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); | 96 | struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); |
@@ -162,9 +163,14 @@ out: | |||
162 | return ret; | 163 | return ret; |
163 | } | 164 | } |
164 | 165 | ||
166 | static int omfs_write_inode(struct inode *inode, struct writeback_control *wbc) | ||
167 | { | ||
168 | return __omfs_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); | ||
169 | } | ||
170 | |||
165 | int omfs_sync_inode(struct inode *inode) | 171 | int omfs_sync_inode(struct inode *inode) |
166 | { | 172 | { |
167 | return omfs_write_inode(inode, 1); | 173 | return __omfs_write_inode(inode, 1); |
168 | } | 174 | } |
169 | 175 | ||
170 | /* | 176 | /* |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 2df0f5c7c60b..0d651f980a8d 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -1615,7 +1615,7 @@ int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp, | |||
1615 | ** to properly mark inodes for datasync and such, but only actually | 1615 | ** to properly mark inodes for datasync and such, but only actually |
1616 | ** does something when called for a synchronous update. | 1616 | ** does something when called for a synchronous update. |
1617 | */ | 1617 | */ |
1618 | int reiserfs_write_inode(struct inode *inode, int do_sync) | 1618 | int reiserfs_write_inode(struct inode *inode, struct writeback_control *wbc) |
1619 | { | 1619 | { |
1620 | struct reiserfs_transaction_handle th; | 1620 | struct reiserfs_transaction_handle th; |
1621 | int jbegin_count = 1; | 1621 | int jbegin_count = 1; |
@@ -1627,7 +1627,7 @@ int reiserfs_write_inode(struct inode *inode, int do_sync) | |||
1627 | ** inode needs to reach disk for safety, and they can safely be | 1627 | ** inode needs to reach disk for safety, and they can safely be |
1628 | ** ignored because the altered inode has already been logged. | 1628 | ** ignored because the altered inode has already been logged. |
1629 | */ | 1629 | */ |
1630 | if (do_sync && !(current->flags & PF_MEMALLOC)) { | 1630 | if (wbc->sync_mode == WB_SYNC_ALL && !(current->flags & PF_MEMALLOC)) { |
1631 | reiserfs_write_lock(inode->i_sb); | 1631 | reiserfs_write_lock(inode->i_sb); |
1632 | if (!journal_begin(&th, inode->i_sb, jbegin_count)) { | 1632 | if (!journal_begin(&th, inode->i_sb, jbegin_count)) { |
1633 | reiserfs_update_sd(&th, inode); | 1633 | reiserfs_update_sd(&th, inode); |
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 9824743832a7..4573734d723d 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
28 | #include <linux/vfs.h> | 28 | #include <linux/vfs.h> |
29 | #include <linux/writeback.h> | ||
29 | #include <linux/namei.h> | 30 | #include <linux/namei.h> |
30 | #include <asm/byteorder.h> | 31 | #include <asm/byteorder.h> |
31 | #include "sysv.h" | 32 | #include "sysv.h" |
@@ -246,7 +247,7 @@ bad_inode: | |||
246 | return ERR_PTR(-EIO); | 247 | return ERR_PTR(-EIO); |
247 | } | 248 | } |
248 | 249 | ||
249 | int sysv_write_inode(struct inode *inode, int wait) | 250 | static int __sysv_write_inode(struct inode *inode, int wait) |
250 | { | 251 | { |
251 | struct super_block * sb = inode->i_sb; | 252 | struct super_block * sb = inode->i_sb; |
252 | struct sysv_sb_info * sbi = SYSV_SB(sb); | 253 | struct sysv_sb_info * sbi = SYSV_SB(sb); |
@@ -296,9 +297,14 @@ int sysv_write_inode(struct inode *inode, int wait) | |||
296 | return 0; | 297 | return 0; |
297 | } | 298 | } |
298 | 299 | ||
300 | int sysv_write_inode(struct inode *inode, struct writeback_control *wbc) | ||
301 | { | ||
302 | return __sysv_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); | ||
303 | } | ||
304 | |||
299 | int sysv_sync_inode(struct inode *inode) | 305 | int sysv_sync_inode(struct inode *inode) |
300 | { | 306 | { |
301 | return sysv_write_inode(inode, 1); | 307 | return __sysv_write_inode(inode, 1); |
302 | } | 308 | } |
303 | 309 | ||
304 | static void sysv_delete_inode(struct inode *inode) | 310 | static void sysv_delete_inode(struct inode *inode) |
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h index 53786eb5cf60..94cb9b4d76c2 100644 --- a/fs/sysv/sysv.h +++ b/fs/sysv/sysv.h | |||
@@ -142,7 +142,7 @@ extern int __sysv_write_begin(struct file *file, struct address_space *mapping, | |||
142 | 142 | ||
143 | /* inode.c */ | 143 | /* inode.c */ |
144 | extern struct inode *sysv_iget(struct super_block *, unsigned int); | 144 | extern struct inode *sysv_iget(struct super_block *, unsigned int); |
145 | extern int sysv_write_inode(struct inode *, int); | 145 | extern int sysv_write_inode(struct inode *, struct writeback_control *wbc); |
146 | extern int sysv_sync_inode(struct inode *); | 146 | extern int sysv_sync_inode(struct inode *); |
147 | extern void sysv_set_inode(struct inode *, dev_t); | 147 | extern void sysv_set_inode(struct inode *, dev_t); |
148 | extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *); | 148 | extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *); |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 552fb0111fff..401e503d44a1 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -1120,7 +1120,7 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1120 | if (release) | 1120 | if (release) |
1121 | ubifs_release_budget(c, &ino_req); | 1121 | ubifs_release_budget(c, &ino_req); |
1122 | if (IS_SYNC(old_inode)) | 1122 | if (IS_SYNC(old_inode)) |
1123 | err = old_inode->i_sb->s_op->write_inode(old_inode, 1); | 1123 | err = old_inode->i_sb->s_op->write_inode(old_inode, NULL); |
1124 | return err; | 1124 | return err; |
1125 | 1125 | ||
1126 | out_cancel: | 1126 | out_cancel: |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 16a6444330ec..e26c02ab6cd5 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -1011,7 +1011,7 @@ static int ubifs_writepage(struct page *page, struct writeback_control *wbc) | |||
1011 | /* Is the page fully inside @i_size? */ | 1011 | /* Is the page fully inside @i_size? */ |
1012 | if (page->index < end_index) { | 1012 | if (page->index < end_index) { |
1013 | if (page->index >= synced_i_size >> PAGE_CACHE_SHIFT) { | 1013 | if (page->index >= synced_i_size >> PAGE_CACHE_SHIFT) { |
1014 | err = inode->i_sb->s_op->write_inode(inode, 1); | 1014 | err = inode->i_sb->s_op->write_inode(inode, NULL); |
1015 | if (err) | 1015 | if (err) |
1016 | goto out_unlock; | 1016 | goto out_unlock; |
1017 | /* | 1017 | /* |
@@ -1039,7 +1039,7 @@ static int ubifs_writepage(struct page *page, struct writeback_control *wbc) | |||
1039 | kunmap_atomic(kaddr, KM_USER0); | 1039 | kunmap_atomic(kaddr, KM_USER0); |
1040 | 1040 | ||
1041 | if (i_size > synced_i_size) { | 1041 | if (i_size > synced_i_size) { |
1042 | err = inode->i_sb->s_op->write_inode(inode, 1); | 1042 | err = inode->i_sb->s_op->write_inode(inode, NULL); |
1043 | if (err) | 1043 | if (err) |
1044 | goto out_unlock; | 1044 | goto out_unlock; |
1045 | } | 1045 | } |
@@ -1242,7 +1242,7 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode, | |||
1242 | if (release) | 1242 | if (release) |
1243 | ubifs_release_budget(c, &req); | 1243 | ubifs_release_budget(c, &req); |
1244 | if (IS_SYNC(inode)) | 1244 | if (IS_SYNC(inode)) |
1245 | err = inode->i_sb->s_op->write_inode(inode, 1); | 1245 | err = inode->i_sb->s_op->write_inode(inode, NULL); |
1246 | return err; | 1246 | return err; |
1247 | 1247 | ||
1248 | out: | 1248 | out: |
@@ -1316,7 +1316,7 @@ int ubifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1316 | * the inode unless this is a 'datasync()' call. | 1316 | * the inode unless this is a 'datasync()' call. |
1317 | */ | 1317 | */ |
1318 | if (!datasync || (inode->i_state & I_DIRTY_DATASYNC)) { | 1318 | if (!datasync || (inode->i_state & I_DIRTY_DATASYNC)) { |
1319 | err = inode->i_sb->s_op->write_inode(inode, 1); | 1319 | err = inode->i_sb->s_op->write_inode(inode, NULL); |
1320 | if (err) | 1320 | if (err) |
1321 | return err; | 1321 | return err; |
1322 | } | 1322 | } |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 43f9d19a6f33..4d2f2157dd3f 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -283,7 +283,7 @@ static void ubifs_destroy_inode(struct inode *inode) | |||
283 | /* | 283 | /* |
284 | * Note, Linux write-back code calls this without 'i_mutex'. | 284 | * Note, Linux write-back code calls this without 'i_mutex'. |
285 | */ | 285 | */ |
286 | static int ubifs_write_inode(struct inode *inode, int wait) | 286 | static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc) |
287 | { | 287 | { |
288 | int err = 0; | 288 | int err = 0; |
289 | struct ubifs_info *c = inode->i_sb->s_fs_info; | 289 | struct ubifs_info *c = inode->i_sb->s_fs_info; |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 378a7592257c..b02089247296 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -1373,12 +1373,12 @@ static mode_t udf_convert_permissions(struct fileEntry *fe) | |||
1373 | return mode; | 1373 | return mode; |
1374 | } | 1374 | } |
1375 | 1375 | ||
1376 | int udf_write_inode(struct inode *inode, int sync) | 1376 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) |
1377 | { | 1377 | { |
1378 | int ret; | 1378 | int ret; |
1379 | 1379 | ||
1380 | lock_kernel(); | 1380 | lock_kernel(); |
1381 | ret = udf_update_inode(inode, sync); | 1381 | ret = udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); |
1382 | unlock_kernel(); | 1382 | unlock_kernel(); |
1383 | 1383 | ||
1384 | return ret; | 1384 | return ret; |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 8d46f4294ee7..4223ac855da9 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -142,7 +142,7 @@ extern void udf_truncate(struct inode *); | |||
142 | extern void udf_read_inode(struct inode *); | 142 | extern void udf_read_inode(struct inode *); |
143 | extern void udf_delete_inode(struct inode *); | 143 | extern void udf_delete_inode(struct inode *); |
144 | extern void udf_clear_inode(struct inode *); | 144 | extern void udf_clear_inode(struct inode *); |
145 | extern int udf_write_inode(struct inode *, int); | 145 | extern int udf_write_inode(struct inode *, struct writeback_control *wbc); |
146 | extern long udf_block_map(struct inode *, sector_t); | 146 | extern long udf_block_map(struct inode *, sector_t); |
147 | extern int udf_extend_file(struct inode *, struct extent_position *, | 147 | extern int udf_extend_file(struct inode *, struct extent_position *, |
148 | struct kernel_long_ad *, sector_t); | 148 | struct kernel_long_ad *, sector_t); |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 7cf33379fd46..0a627e08610b 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/mm.h> | 36 | #include <linux/mm.h> |
37 | #include <linux/smp_lock.h> | 37 | #include <linux/smp_lock.h> |
38 | #include <linux/buffer_head.h> | 38 | #include <linux/buffer_head.h> |
39 | #include <linux/writeback.h> | ||
39 | 40 | ||
40 | #include "ufs_fs.h" | 41 | #include "ufs_fs.h" |
41 | #include "ufs.h" | 42 | #include "ufs.h" |
@@ -890,11 +891,11 @@ static int ufs_update_inode(struct inode * inode, int do_sync) | |||
890 | return 0; | 891 | return 0; |
891 | } | 892 | } |
892 | 893 | ||
893 | int ufs_write_inode (struct inode * inode, int wait) | 894 | int ufs_write_inode(struct inode *inode, struct writeback_control *wbc) |
894 | { | 895 | { |
895 | int ret; | 896 | int ret; |
896 | lock_kernel(); | 897 | lock_kernel(); |
897 | ret = ufs_update_inode (inode, wait); | 898 | ret = ufs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); |
898 | unlock_kernel(); | 899 | unlock_kernel(); |
899 | return ret; | 900 | return ret; |
900 | } | 901 | } |
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h index 01d0e2a3b230..43f9f5d5670e 100644 --- a/fs/ufs/ufs.h +++ b/fs/ufs/ufs.h | |||
@@ -106,7 +106,7 @@ extern struct inode * ufs_new_inode (struct inode *, int); | |||
106 | 106 | ||
107 | /* inode.c */ | 107 | /* inode.c */ |
108 | extern struct inode *ufs_iget(struct super_block *, unsigned long); | 108 | extern struct inode *ufs_iget(struct super_block *, unsigned long); |
109 | extern int ufs_write_inode (struct inode *, int); | 109 | extern int ufs_write_inode (struct inode *, struct writeback_control *); |
110 | extern int ufs_sync_inode (struct inode *); | 110 | extern int ufs_sync_inode (struct inode *); |
111 | extern void ufs_delete_inode (struct inode *); | 111 | extern void ufs_delete_inode (struct inode *); |
112 | extern struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *); | 112 | extern struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *); |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 25ea2408118f..71345a370d9f 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -1063,7 +1063,7 @@ xfs_log_inode( | |||
1063 | STATIC int | 1063 | STATIC int |
1064 | xfs_fs_write_inode( | 1064 | xfs_fs_write_inode( |
1065 | struct inode *inode, | 1065 | struct inode *inode, |
1066 | int sync) | 1066 | struct writeback_control *wbc) |
1067 | { | 1067 | { |
1068 | struct xfs_inode *ip = XFS_I(inode); | 1068 | struct xfs_inode *ip = XFS_I(inode); |
1069 | struct xfs_mount *mp = ip->i_mount; | 1069 | struct xfs_mount *mp = ip->i_mount; |
@@ -1074,11 +1074,7 @@ xfs_fs_write_inode( | |||
1074 | if (XFS_FORCED_SHUTDOWN(mp)) | 1074 | if (XFS_FORCED_SHUTDOWN(mp)) |
1075 | return XFS_ERROR(EIO); | 1075 | return XFS_ERROR(EIO); |
1076 | 1076 | ||
1077 | if (sync) { | 1077 | if (wbc->sync_mode == WB_SYNC_ALL) { |
1078 | error = xfs_wait_on_pages(ip, 0, -1); | ||
1079 | if (error) | ||
1080 | goto out; | ||
1081 | |||
1082 | /* | 1078 | /* |
1083 | * Make sure the inode has hit stable storage. By using the | 1079 | * Make sure the inode has hit stable storage. By using the |
1084 | * log and the fsync transactions we reduce the IOs we have | 1080 | * log and the fsync transactions we reduce the IOs we have |
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 6b049030fbe6..deac2566450e 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h | |||
@@ -877,7 +877,7 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
877 | int create); | 877 | int create); |
878 | 878 | ||
879 | extern struct inode *ext3_iget(struct super_block *, unsigned long); | 879 | extern struct inode *ext3_iget(struct super_block *, unsigned long); |
880 | extern int ext3_write_inode (struct inode *, int); | 880 | extern int ext3_write_inode (struct inode *, struct writeback_control *); |
881 | extern int ext3_setattr (struct dentry *, struct iattr *); | 881 | extern int ext3_setattr (struct dentry *, struct iattr *); |
882 | extern void ext3_delete_inode (struct inode *); | 882 | extern void ext3_delete_inode (struct inode *); |
883 | extern int ext3_sync_inode (handle_t *, struct inode *); | 883 | extern int ext3_sync_inode (handle_t *, struct inode *); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 5b3182c7eb5f..45689621a851 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1557,7 +1557,7 @@ struct super_operations { | |||
1557 | void (*destroy_inode)(struct inode *); | 1557 | void (*destroy_inode)(struct inode *); |
1558 | 1558 | ||
1559 | void (*dirty_inode) (struct inode *); | 1559 | void (*dirty_inode) (struct inode *); |
1560 | int (*write_inode) (struct inode *, int); | 1560 | int (*write_inode) (struct inode *, struct writeback_control *wbc); |
1561 | void (*drop_inode) (struct inode *); | 1561 | void (*drop_inode) (struct inode *); |
1562 | void (*delete_inode) (struct inode *); | 1562 | void (*delete_inode) (struct inode *); |
1563 | void (*put_super) (struct super_block *); | 1563 | void (*put_super) (struct super_block *); |
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 1ba3cf6edfbb..3b603f474186 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h | |||
@@ -2034,7 +2034,7 @@ void reiserfs_read_locked_inode(struct inode *inode, | |||
2034 | int reiserfs_find_actor(struct inode *inode, void *p); | 2034 | int reiserfs_find_actor(struct inode *inode, void *p); |
2035 | int reiserfs_init_locked_inode(struct inode *inode, void *p); | 2035 | int reiserfs_init_locked_inode(struct inode *inode, void *p); |
2036 | void reiserfs_delete_inode(struct inode *inode); | 2036 | void reiserfs_delete_inode(struct inode *inode); |
2037 | int reiserfs_write_inode(struct inode *inode, int); | 2037 | int reiserfs_write_inode(struct inode *inode, struct writeback_control *wbc); |
2038 | int reiserfs_get_block(struct inode *inode, sector_t block, | 2038 | int reiserfs_get_block(struct inode *inode, sector_t block, |
2039 | struct buffer_head *bh_result, int create); | 2039 | struct buffer_head *bh_result, int create); |
2040 | struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid, | 2040 | struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid, |