diff options
50 files changed, 147 insertions, 65 deletions
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index fe2b7ae6f962..0f3a1390bf00 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting | |||
| @@ -295,9 +295,9 @@ in the beginning of ->setattr unconditionally. | |||
| 295 | ->clear_inode() and ->delete_inode() are gone; ->evict_inode() should | 295 | ->clear_inode() and ->delete_inode() are gone; ->evict_inode() should |
| 296 | be used instead. It gets called whenever the inode is evicted, whether it has | 296 | be used instead. It gets called whenever the inode is evicted, whether it has |
| 297 | remaining links or not. Caller does *not* evict the pagecache or inode-associated | 297 | remaining links or not. Caller does *not* evict the pagecache or inode-associated |
| 298 | metadata buffers; getting rid of those is responsibility of method, as it had | 298 | metadata buffers; the method has to use truncate_inode_pages_final() to get rid |
| 299 | been for ->delete_inode(). Caller makes sure async writeback cannot be running | 299 | of those. Caller makes sure async writeback cannot be running for the inode while |
| 300 | for the inode while (or after) ->evict_inode() is called. | 300 | (or after) ->evict_inode() is called. |
| 301 | 301 | ||
| 302 | ->drop_inode() returns int now; it's called on final iput() with | 302 | ->drop_inode() returns int now; it's called on final iput() with |
| 303 | inode->i_lock held and it returns true if filesystems wants the inode to be | 303 | inode->i_lock held and it returns true if filesystems wants the inode to be |
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 26003d3c1be7..7c4fd97a7fa0 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c | |||
| @@ -1877,7 +1877,7 @@ void ll_delete_inode(struct inode *inode) | |||
| 1877 | cl_sync_file_range(inode, 0, OBD_OBJECT_EOF, | 1877 | cl_sync_file_range(inode, 0, OBD_OBJECT_EOF, |
| 1878 | CL_FSYNC_DISCARD, 1); | 1878 | CL_FSYNC_DISCARD, 1); |
| 1879 | 1879 | ||
| 1880 | truncate_inode_pages(&inode->i_data, 0); | 1880 | truncate_inode_pages_final(&inode->i_data); |
| 1881 | 1881 | ||
| 1882 | /* Workaround for LU-118 */ | 1882 | /* Workaround for LU-118 */ |
| 1883 | if (inode->i_data.nrpages) { | 1883 | if (inode->i_data.nrpages) { |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index bb7991c7e5c7..53161ec058a7 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
| @@ -451,7 +451,7 @@ void v9fs_evict_inode(struct inode *inode) | |||
| 451 | { | 451 | { |
| 452 | struct v9fs_inode *v9inode = V9FS_I(inode); | 452 | struct v9fs_inode *v9inode = V9FS_I(inode); |
| 453 | 453 | ||
| 454 | truncate_inode_pages(inode->i_mapping, 0); | 454 | truncate_inode_pages_final(inode->i_mapping); |
| 455 | clear_inode(inode); | 455 | clear_inode(inode); |
| 456 | filemap_fdatawrite(inode->i_mapping); | 456 | filemap_fdatawrite(inode->i_mapping); |
| 457 | 457 | ||
diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 0e092d08680e..96df91e8c334 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c | |||
| @@ -259,7 +259,7 @@ affs_evict_inode(struct inode *inode) | |||
| 259 | { | 259 | { |
| 260 | unsigned long cache_page; | 260 | unsigned long cache_page; |
| 261 | pr_debug("AFFS: evict_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); | 261 | pr_debug("AFFS: evict_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); |
| 262 | truncate_inode_pages(&inode->i_data, 0); | 262 | truncate_inode_pages_final(&inode->i_data); |
| 263 | 263 | ||
| 264 | if (!inode->i_nlink) { | 264 | if (!inode->i_nlink) { |
| 265 | inode->i_size = 0; | 265 | inode->i_size = 0; |
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index ce25d755b7aa..294671288449 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
| @@ -422,7 +422,7 @@ void afs_evict_inode(struct inode *inode) | |||
| 422 | 422 | ||
| 423 | ASSERTCMP(inode->i_ino, ==, vnode->fid.vnode); | 423 | ASSERTCMP(inode->i_ino, ==, vnode->fid.vnode); |
| 424 | 424 | ||
| 425 | truncate_inode_pages(&inode->i_data, 0); | 425 | truncate_inode_pages_final(&inode->i_data); |
| 426 | clear_inode(inode); | 426 | clear_inode(inode); |
| 427 | 427 | ||
| 428 | afs_give_up_callback(vnode); | 428 | afs_give_up_callback(vnode); |
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 8defc6b3f9a2..29aa5cf6639b 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c | |||
| @@ -172,7 +172,7 @@ static void bfs_evict_inode(struct inode *inode) | |||
| 172 | 172 | ||
| 173 | dprintf("ino=%08lx\n", ino); | 173 | dprintf("ino=%08lx\n", ino); |
| 174 | 174 | ||
| 175 | truncate_inode_pages(&inode->i_data, 0); | 175 | truncate_inode_pages_final(&inode->i_data); |
| 176 | invalidate_inode_buffers(inode); | 176 | invalidate_inode_buffers(inode); |
| 177 | clear_inode(inode); | 177 | clear_inode(inode); |
| 178 | 178 | ||
diff --git a/fs/block_dev.c b/fs/block_dev.c index e4cba21a627e..ba0d2b05bb78 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
| @@ -83,7 +83,7 @@ void kill_bdev(struct block_device *bdev) | |||
| 83 | { | 83 | { |
| 84 | struct address_space *mapping = bdev->bd_inode->i_mapping; | 84 | struct address_space *mapping = bdev->bd_inode->i_mapping; |
| 85 | 85 | ||
| 86 | if (mapping->nrpages == 0) | 86 | if (mapping->nrpages == 0 && mapping->nrshadows == 0) |
| 87 | return; | 87 | return; |
| 88 | 88 | ||
| 89 | invalidate_bh_lrus(); | 89 | invalidate_bh_lrus(); |
| @@ -419,7 +419,7 @@ static void bdev_evict_inode(struct inode *inode) | |||
| 419 | { | 419 | { |
| 420 | struct block_device *bdev = &BDEV_I(inode)->bdev; | 420 | struct block_device *bdev = &BDEV_I(inode)->bdev; |
| 421 | struct list_head *p; | 421 | struct list_head *p; |
| 422 | truncate_inode_pages(&inode->i_data, 0); | 422 | truncate_inode_pages_final(&inode->i_data); |
| 423 | invalidate_inode_buffers(inode); /* is it needed here? */ | 423 | invalidate_inode_buffers(inode); /* is it needed here? */ |
| 424 | clear_inode(inode); | 424 | clear_inode(inode); |
| 425 | spin_lock(&bdev_lock); | 425 | spin_lock(&bdev_lock); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d3d44486290b..49ec1398879f 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -4593,7 +4593,7 @@ static void evict_inode_truncate_pages(struct inode *inode) | |||
| 4593 | struct rb_node *node; | 4593 | struct rb_node *node; |
| 4594 | 4594 | ||
| 4595 | ASSERT(inode->i_state & I_FREEING); | 4595 | ASSERT(inode->i_state & I_FREEING); |
| 4596 | truncate_inode_pages(&inode->i_data, 0); | 4596 | truncate_inode_pages_final(&inode->i_data); |
| 4597 | 4597 | ||
| 4598 | write_lock(&map_tree->lock); | 4598 | write_lock(&map_tree->lock); |
| 4599 | while (!RB_EMPTY_ROOT(&map_tree->map)) { | 4599 | while (!RB_EMPTY_ROOT(&map_tree->map)) { |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index e8ae8323c058..ab8ad2546c3e 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -286,7 +286,7 @@ cifs_destroy_inode(struct inode *inode) | |||
| 286 | static void | 286 | static void |
| 287 | cifs_evict_inode(struct inode *inode) | 287 | cifs_evict_inode(struct inode *inode) |
| 288 | { | 288 | { |
| 289 | truncate_inode_pages(&inode->i_data, 0); | 289 | truncate_inode_pages_final(&inode->i_data); |
| 290 | clear_inode(inode); | 290 | clear_inode(inode); |
| 291 | cifs_fscache_release_inode_cookie(inode); | 291 | cifs_fscache_release_inode_cookie(inode); |
| 292 | } | 292 | } |
diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 506de34a4ef3..62618ec9356c 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c | |||
| @@ -250,7 +250,7 @@ static void coda_put_super(struct super_block *sb) | |||
| 250 | 250 | ||
| 251 | static void coda_evict_inode(struct inode *inode) | 251 | static void coda_evict_inode(struct inode *inode) |
| 252 | { | 252 | { |
| 253 | truncate_inode_pages(&inode->i_data, 0); | 253 | truncate_inode_pages_final(&inode->i_data); |
| 254 | clear_inode(inode); | 254 | clear_inode(inode); |
| 255 | coda_cache_clear_inode(inode); | 255 | coda_cache_clear_inode(inode); |
| 256 | } | 256 | } |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index e879cf8ff0b1..afa1b81c3418 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
| @@ -132,7 +132,7 @@ static int ecryptfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
| 132 | */ | 132 | */ |
| 133 | static void ecryptfs_evict_inode(struct inode *inode) | 133 | static void ecryptfs_evict_inode(struct inode *inode) |
| 134 | { | 134 | { |
| 135 | truncate_inode_pages(&inode->i_data, 0); | 135 | truncate_inode_pages_final(&inode->i_data); |
| 136 | clear_inode(inode); | 136 | clear_inode(inode); |
| 137 | iput(ecryptfs_inode_to_lower(inode)); | 137 | iput(ecryptfs_inode_to_lower(inode)); |
| 138 | } | 138 | } |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index ee4317faccb1..d1c244d67667 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
| @@ -1486,7 +1486,7 @@ void exofs_evict_inode(struct inode *inode) | |||
| 1486 | struct ore_io_state *ios; | 1486 | struct ore_io_state *ios; |
| 1487 | int ret; | 1487 | int ret; |
| 1488 | 1488 | ||
| 1489 | truncate_inode_pages(&inode->i_data, 0); | 1489 | truncate_inode_pages_final(&inode->i_data); |
| 1490 | 1490 | ||
| 1491 | /* TODO: should do better here */ | 1491 | /* TODO: should do better here */ |
| 1492 | if (inode->i_nlink || is_bad_inode(inode)) | 1492 | if (inode->i_nlink || is_bad_inode(inode)) |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 94ed36849b71..b1d2a4675d42 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
| @@ -78,7 +78,7 @@ void ext2_evict_inode(struct inode * inode) | |||
| 78 | dquot_drop(inode); | 78 | dquot_drop(inode); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | truncate_inode_pages(&inode->i_data, 0); | 81 | truncate_inode_pages_final(&inode->i_data); |
| 82 | 82 | ||
| 83 | if (want_delete) { | 83 | if (want_delete) { |
| 84 | sb_start_intwrite(inode->i_sb); | 84 | sb_start_intwrite(inode->i_sb); |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 384b6ebb655f..efce2bbfb5e5 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
| @@ -228,7 +228,7 @@ void ext3_evict_inode (struct inode *inode) | |||
| 228 | log_wait_commit(journal, commit_tid); | 228 | log_wait_commit(journal, commit_tid); |
| 229 | filemap_write_and_wait(&inode->i_data); | 229 | filemap_write_and_wait(&inode->i_data); |
| 230 | } | 230 | } |
| 231 | truncate_inode_pages(&inode->i_data, 0); | 231 | truncate_inode_pages_final(&inode->i_data); |
| 232 | 232 | ||
| 233 | ext3_discard_reservation(inode); | 233 | ext3_discard_reservation(inode); |
| 234 | rsv = ei->i_block_alloc_info; | 234 | rsv = ei->i_block_alloc_info; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 24bfd7ff3049..175c3f933816 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -215,7 +215,7 @@ void ext4_evict_inode(struct inode *inode) | |||
| 215 | jbd2_complete_transaction(journal, commit_tid); | 215 | jbd2_complete_transaction(journal, commit_tid); |
| 216 | filemap_write_and_wait(&inode->i_data); | 216 | filemap_write_and_wait(&inode->i_data); |
| 217 | } | 217 | } |
| 218 | truncate_inode_pages(&inode->i_data, 0); | 218 | truncate_inode_pages_final(&inode->i_data); |
| 219 | 219 | ||
| 220 | WARN_ON(atomic_read(&EXT4_I(inode)->i_ioend_count)); | 220 | WARN_ON(atomic_read(&EXT4_I(inode)->i_ioend_count)); |
| 221 | goto no_delete; | 221 | goto no_delete; |
| @@ -226,7 +226,7 @@ void ext4_evict_inode(struct inode *inode) | |||
| 226 | 226 | ||
| 227 | if (ext4_should_order_data(inode)) | 227 | if (ext4_should_order_data(inode)) |
| 228 | ext4_begin_ordered_truncate(inode, 0); | 228 | ext4_begin_ordered_truncate(inode, 0); |
| 229 | truncate_inode_pages(&inode->i_data, 0); | 229 | truncate_inode_pages_final(&inode->i_data); |
| 230 | 230 | ||
| 231 | WARN_ON(atomic_read(&EXT4_I(inode)->i_ioend_count)); | 231 | WARN_ON(atomic_read(&EXT4_I(inode)->i_ioend_count)); |
| 232 | if (is_bad_inode(inode)) | 232 | if (is_bad_inode(inode)) |
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 4d67ed736dca..28cea76d78c6 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c | |||
| @@ -260,7 +260,7 @@ void f2fs_evict_inode(struct inode *inode) | |||
| 260 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); | 260 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); |
| 261 | 261 | ||
| 262 | trace_f2fs_evict_inode(inode); | 262 | trace_f2fs_evict_inode(inode); |
| 263 | truncate_inode_pages(&inode->i_data, 0); | 263 | truncate_inode_pages_final(&inode->i_data); |
| 264 | 264 | ||
| 265 | if (inode->i_ino == F2FS_NODE_INO(sbi) || | 265 | if (inode->i_ino == F2FS_NODE_INO(sbi) || |
| 266 | inode->i_ino == F2FS_META_INO(sbi)) | 266 | inode->i_ino == F2FS_META_INO(sbi)) |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 854b578f6695..c68d9f27135e 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
| @@ -490,7 +490,7 @@ EXPORT_SYMBOL_GPL(fat_build_inode); | |||
| 490 | 490 | ||
| 491 | static void fat_evict_inode(struct inode *inode) | 491 | static void fat_evict_inode(struct inode *inode) |
| 492 | { | 492 | { |
| 493 | truncate_inode_pages(&inode->i_data, 0); | 493 | truncate_inode_pages_final(&inode->i_data); |
| 494 | if (!inode->i_nlink) { | 494 | if (!inode->i_nlink) { |
| 495 | inode->i_size = 0; | 495 | inode->i_size = 0; |
| 496 | fat_truncate_blocks(inode, 0); | 496 | fat_truncate_blocks(inode, 0); |
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c index f47df72cef17..363e3ae25f6b 100644 --- a/fs/freevxfs/vxfs_inode.c +++ b/fs/freevxfs/vxfs_inode.c | |||
| @@ -354,7 +354,7 @@ static void vxfs_i_callback(struct rcu_head *head) | |||
| 354 | void | 354 | void |
| 355 | vxfs_evict_inode(struct inode *ip) | 355 | vxfs_evict_inode(struct inode *ip) |
| 356 | { | 356 | { |
| 357 | truncate_inode_pages(&ip->i_data, 0); | 357 | truncate_inode_pages_final(&ip->i_data); |
| 358 | clear_inode(ip); | 358 | clear_inode(ip); |
| 359 | call_rcu(&ip->i_rcu, vxfs_i_callback); | 359 | call_rcu(&ip->i_rcu, vxfs_i_callback); |
| 360 | } | 360 | } |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index d468643a68b2..9c761b611c54 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
| @@ -123,7 +123,7 @@ static void fuse_destroy_inode(struct inode *inode) | |||
| 123 | 123 | ||
| 124 | static void fuse_evict_inode(struct inode *inode) | 124 | static void fuse_evict_inode(struct inode *inode) |
| 125 | { | 125 | { |
| 126 | truncate_inode_pages(&inode->i_data, 0); | 126 | truncate_inode_pages_final(&inode->i_data); |
| 127 | clear_inode(inode); | 127 | clear_inode(inode); |
| 128 | if (inode->i_sb->s_flags & MS_ACTIVE) { | 128 | if (inode->i_sb->s_flags & MS_ACTIVE) { |
| 129 | struct fuse_conn *fc = get_fuse_conn(inode); | 129 | struct fuse_conn *fc = get_fuse_conn(inode); |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 60f60f6181f3..24410cd9a82a 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
| @@ -1558,7 +1558,7 @@ out_unlock: | |||
| 1558 | fs_warn(sdp, "gfs2_evict_inode: %d\n", error); | 1558 | fs_warn(sdp, "gfs2_evict_inode: %d\n", error); |
| 1559 | out: | 1559 | out: |
| 1560 | /* Case 3 starts here */ | 1560 | /* Case 3 starts here */ |
| 1561 | truncate_inode_pages(&inode->i_data, 0); | 1561 | truncate_inode_pages_final(&inode->i_data); |
| 1562 | gfs2_rs_delete(ip, NULL); | 1562 | gfs2_rs_delete(ip, NULL); |
| 1563 | gfs2_ordered_del_inode(ip); | 1563 | gfs2_ordered_del_inode(ip); |
| 1564 | clear_inode(inode); | 1564 | clear_inode(inode); |
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 380ab31b5e0f..9e2fecd62f62 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
| @@ -547,7 +547,7 @@ out: | |||
| 547 | 547 | ||
| 548 | void hfs_evict_inode(struct inode *inode) | 548 | void hfs_evict_inode(struct inode *inode) |
| 549 | { | 549 | { |
| 550 | truncate_inode_pages(&inode->i_data, 0); | 550 | truncate_inode_pages_final(&inode->i_data); |
| 551 | clear_inode(inode); | 551 | clear_inode(inode); |
| 552 | if (HFS_IS_RSRC(inode) && HFS_I(inode)->rsrc_inode) { | 552 | if (HFS_IS_RSRC(inode) && HFS_I(inode)->rsrc_inode) { |
| 553 | HFS_I(HFS_I(inode)->rsrc_inode)->rsrc_inode = NULL; | 553 | HFS_I(HFS_I(inode)->rsrc_inode)->rsrc_inode = NULL; |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 80875aa640ef..a6abf87d79d0 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
| @@ -161,7 +161,7 @@ static int hfsplus_write_inode(struct inode *inode, | |||
| 161 | static void hfsplus_evict_inode(struct inode *inode) | 161 | static void hfsplus_evict_inode(struct inode *inode) |
| 162 | { | 162 | { |
| 163 | hfs_dbg(INODE, "hfsplus_evict_inode: %lu\n", inode->i_ino); | 163 | hfs_dbg(INODE, "hfsplus_evict_inode: %lu\n", inode->i_ino); |
| 164 | truncate_inode_pages(&inode->i_data, 0); | 164 | truncate_inode_pages_final(&inode->i_data); |
| 165 | clear_inode(inode); | 165 | clear_inode(inode); |
| 166 | if (HFSPLUS_IS_RSRC(inode)) { | 166 | if (HFSPLUS_IS_RSRC(inode)) { |
| 167 | HFSPLUS_I(HFSPLUS_I(inode)->rsrc_inode)->rsrc_inode = NULL; | 167 | HFSPLUS_I(HFSPLUS_I(inode)->rsrc_inode)->rsrc_inode = NULL; |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index fe649d325b1f..9c470fde9878 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
| @@ -230,7 +230,7 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb) | |||
| 230 | 230 | ||
| 231 | static void hostfs_evict_inode(struct inode *inode) | 231 | static void hostfs_evict_inode(struct inode *inode) |
| 232 | { | 232 | { |
| 233 | truncate_inode_pages(&inode->i_data, 0); | 233 | truncate_inode_pages_final(&inode->i_data); |
| 234 | clear_inode(inode); | 234 | clear_inode(inode); |
| 235 | if (HOSTFS_I(inode)->fd != -1) { | 235 | if (HOSTFS_I(inode)->fd != -1) { |
| 236 | close_file(&HOSTFS_I(inode)->fd); | 236 | close_file(&HOSTFS_I(inode)->fd); |
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index 9edeeb0ea97e..50a427313835 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c | |||
| @@ -304,7 +304,7 @@ void hpfs_write_if_changed(struct inode *inode) | |||
| 304 | 304 | ||
| 305 | void hpfs_evict_inode(struct inode *inode) | 305 | void hpfs_evict_inode(struct inode *inode) |
| 306 | { | 306 | { |
| 307 | truncate_inode_pages(&inode->i_data, 0); | 307 | truncate_inode_pages_final(&inode->i_data); |
| 308 | clear_inode(inode); | 308 | clear_inode(inode); |
| 309 | if (!inode->i_nlink) { | 309 | if (!inode->i_nlink) { |
| 310 | hpfs_lock(inode->i_sb); | 310 | hpfs_lock(inode->i_sb); |
diff --git a/fs/inode.c b/fs/inode.c index 4bcdad3c9361..e6905152c39f 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
| @@ -503,6 +503,7 @@ void clear_inode(struct inode *inode) | |||
| 503 | */ | 503 | */ |
| 504 | spin_lock_irq(&inode->i_data.tree_lock); | 504 | spin_lock_irq(&inode->i_data.tree_lock); |
| 505 | BUG_ON(inode->i_data.nrpages); | 505 | BUG_ON(inode->i_data.nrpages); |
| 506 | BUG_ON(inode->i_data.nrshadows); | ||
| 506 | spin_unlock_irq(&inode->i_data.tree_lock); | 507 | spin_unlock_irq(&inode->i_data.tree_lock); |
| 507 | BUG_ON(!list_empty(&inode->i_data.private_list)); | 508 | BUG_ON(!list_empty(&inode->i_data.private_list)); |
| 508 | BUG_ON(!(inode->i_state & I_FREEING)); | 509 | BUG_ON(!(inode->i_state & I_FREEING)); |
| @@ -548,8 +549,7 @@ static void evict(struct inode *inode) | |||
| 548 | if (op->evict_inode) { | 549 | if (op->evict_inode) { |
| 549 | op->evict_inode(inode); | 550 | op->evict_inode(inode); |
| 550 | } else { | 551 | } else { |
| 551 | if (inode->i_data.nrpages) | 552 | truncate_inode_pages_final(&inode->i_data); |
| 552 | truncate_inode_pages(&inode->i_data, 0); | ||
| 553 | clear_inode(inode); | 553 | clear_inode(inode); |
| 554 | } | 554 | } |
| 555 | if (S_ISBLK(inode->i_mode) && inode->i_bdev) | 555 | if (S_ISBLK(inode->i_mode) && inode->i_bdev) |
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index a69e426435dd..a012e16a8bb3 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
| @@ -242,7 +242,7 @@ void jffs2_evict_inode (struct inode *inode) | |||
| 242 | 242 | ||
| 243 | jffs2_dbg(1, "%s(): ino #%lu mode %o\n", | 243 | jffs2_dbg(1, "%s(): ino #%lu mode %o\n", |
| 244 | __func__, inode->i_ino, inode->i_mode); | 244 | __func__, inode->i_ino, inode->i_mode); |
| 245 | truncate_inode_pages(&inode->i_data, 0); | 245 | truncate_inode_pages_final(&inode->i_data); |
| 246 | clear_inode(inode); | 246 | clear_inode(inode); |
| 247 | jffs2_do_clear_inode(c, f); | 247 | jffs2_do_clear_inode(c, f); |
| 248 | } | 248 | } |
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index f4aab719add5..6f8fe72c2a7a 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
| @@ -154,7 +154,7 @@ void jfs_evict_inode(struct inode *inode) | |||
| 154 | dquot_initialize(inode); | 154 | dquot_initialize(inode); |
| 155 | 155 | ||
| 156 | if (JFS_IP(inode)->fileset == FILESYSTEM_I) { | 156 | if (JFS_IP(inode)->fileset == FILESYSTEM_I) { |
| 157 | truncate_inode_pages(&inode->i_data, 0); | 157 | truncate_inode_pages_final(&inode->i_data); |
| 158 | 158 | ||
| 159 | if (test_cflag(COMMIT_Freewmap, inode)) | 159 | if (test_cflag(COMMIT_Freewmap, inode)) |
| 160 | jfs_free_zero_link(inode); | 160 | jfs_free_zero_link(inode); |
| @@ -168,7 +168,7 @@ void jfs_evict_inode(struct inode *inode) | |||
| 168 | dquot_free_inode(inode); | 168 | dquot_free_inode(inode); |
| 169 | } | 169 | } |
| 170 | } else { | 170 | } else { |
| 171 | truncate_inode_pages(&inode->i_data, 0); | 171 | truncate_inode_pages_final(&inode->i_data); |
| 172 | } | 172 | } |
| 173 | clear_inode(inode); | 173 | clear_inode(inode); |
| 174 | dquot_drop(inode); | 174 | dquot_drop(inode); |
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index e55126f85bd2..abb0f1f53d93 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c | |||
| @@ -355,7 +355,7 @@ void kernfs_evict_inode(struct inode *inode) | |||
| 355 | { | 355 | { |
| 356 | struct kernfs_node *kn = inode->i_private; | 356 | struct kernfs_node *kn = inode->i_private; |
| 357 | 357 | ||
| 358 | truncate_inode_pages(&inode->i_data, 0); | 358 | truncate_inode_pages_final(&inode->i_data); |
| 359 | clear_inode(inode); | 359 | clear_inode(inode); |
| 360 | kernfs_put(kn); | 360 | kernfs_put(kn); |
| 361 | } | 361 | } |
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index 9a59cbade2fb..48140315f627 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c | |||
| @@ -2180,7 +2180,7 @@ void logfs_evict_inode(struct inode *inode) | |||
| 2180 | do_delete_inode(inode); | 2180 | do_delete_inode(inode); |
| 2181 | } | 2181 | } |
| 2182 | } | 2182 | } |
| 2183 | truncate_inode_pages(&inode->i_data, 0); | 2183 | truncate_inode_pages_final(&inode->i_data); |
| 2184 | clear_inode(inode); | 2184 | clear_inode(inode); |
| 2185 | 2185 | ||
| 2186 | /* Cheaper version of write_inode. All changes are concealed in | 2186 | /* Cheaper version of write_inode. All changes are concealed in |
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 0332109162a5..03aaeb1a694a 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
| @@ -26,7 +26,7 @@ static int minix_remount (struct super_block * sb, int * flags, char * data); | |||
| 26 | 26 | ||
| 27 | static void minix_evict_inode(struct inode *inode) | 27 | static void minix_evict_inode(struct inode *inode) |
| 28 | { | 28 | { |
| 29 | truncate_inode_pages(&inode->i_data, 0); | 29 | truncate_inode_pages_final(&inode->i_data); |
| 30 | if (!inode->i_nlink) { | 30 | if (!inode->i_nlink) { |
| 31 | inode->i_size = 0; | 31 | inode->i_size = 0; |
| 32 | minix_truncate(inode); | 32 | minix_truncate(inode); |
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 2cf2ebecb55f..ee59d35ff069 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
| @@ -296,7 +296,7 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info) | |||
| 296 | static void | 296 | static void |
| 297 | ncp_evict_inode(struct inode *inode) | 297 | ncp_evict_inode(struct inode *inode) |
| 298 | { | 298 | { |
| 299 | truncate_inode_pages(&inode->i_data, 0); | 299 | truncate_inode_pages_final(&inode->i_data); |
| 300 | clear_inode(inode); | 300 | clear_inode(inode); |
| 301 | 301 | ||
| 302 | if (S_ISDIR(inode->i_mode)) { | 302 | if (S_ISDIR(inode->i_mode)) { |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 360114ae8b82..c4702baa22b8 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
| @@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(nfs_clear_inode); | |||
| 128 | 128 | ||
| 129 | void nfs_evict_inode(struct inode *inode) | 129 | void nfs_evict_inode(struct inode *inode) |
| 130 | { | 130 | { |
| 131 | truncate_inode_pages(&inode->i_data, 0); | 131 | truncate_inode_pages_final(&inode->i_data); |
| 132 | clear_inode(inode); | 132 | clear_inode(inode); |
| 133 | nfs_clear_inode(inode); | 133 | nfs_clear_inode(inode); |
| 134 | } | 134 | } |
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 808f29574412..6f340f02f2ba 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c | |||
| @@ -90,7 +90,7 @@ static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
| 90 | */ | 90 | */ |
| 91 | static void nfs4_evict_inode(struct inode *inode) | 91 | static void nfs4_evict_inode(struct inode *inode) |
| 92 | { | 92 | { |
| 93 | truncate_inode_pages(&inode->i_data, 0); | 93 | truncate_inode_pages_final(&inode->i_data); |
| 94 | clear_inode(inode); | 94 | clear_inode(inode); |
| 95 | pnfs_return_layout(inode); | 95 | pnfs_return_layout(inode); |
| 96 | pnfs_destroy_layout(NFS_I(inode)); | 96 | pnfs_destroy_layout(NFS_I(inode)); |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 7e350c562e0e..b9c5726120e3 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
| @@ -783,16 +783,14 @@ void nilfs_evict_inode(struct inode *inode) | |||
| 783 | int ret; | 783 | int ret; |
| 784 | 784 | ||
| 785 | if (inode->i_nlink || !ii->i_root || unlikely(is_bad_inode(inode))) { | 785 | if (inode->i_nlink || !ii->i_root || unlikely(is_bad_inode(inode))) { |
| 786 | if (inode->i_data.nrpages) | 786 | truncate_inode_pages_final(&inode->i_data); |
| 787 | truncate_inode_pages(&inode->i_data, 0); | ||
| 788 | clear_inode(inode); | 787 | clear_inode(inode); |
| 789 | nilfs_clear_inode(inode); | 788 | nilfs_clear_inode(inode); |
| 790 | return; | 789 | return; |
| 791 | } | 790 | } |
| 792 | nilfs_transaction_begin(sb, &ti, 0); /* never fails */ | 791 | nilfs_transaction_begin(sb, &ti, 0); /* never fails */ |
| 793 | 792 | ||
| 794 | if (inode->i_data.nrpages) | 793 | truncate_inode_pages_final(&inode->i_data); |
| 795 | truncate_inode_pages(&inode->i_data, 0); | ||
| 796 | 794 | ||
| 797 | /* TODO: some of the following operations may fail. */ | 795 | /* TODO: some of the following operations may fail. */ |
| 798 | nilfs_truncate_bmap(ii, 0); | 796 | nilfs_truncate_bmap(ii, 0); |
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index ffb9b3675736..9d8153ebacfb 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
| @@ -2259,7 +2259,7 @@ void ntfs_evict_big_inode(struct inode *vi) | |||
| 2259 | { | 2259 | { |
| 2260 | ntfs_inode *ni = NTFS_I(vi); | 2260 | ntfs_inode *ni = NTFS_I(vi); |
| 2261 | 2261 | ||
| 2262 | truncate_inode_pages(&vi->i_data, 0); | 2262 | truncate_inode_pages_final(&vi->i_data); |
| 2263 | clear_inode(vi); | 2263 | clear_inode(vi); |
| 2264 | 2264 | ||
| 2265 | #ifdef NTFS_RW | 2265 | #ifdef NTFS_RW |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index d437f3ba90b0..437de7f768c6 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
| @@ -964,7 +964,7 @@ static void ocfs2_cleanup_delete_inode(struct inode *inode, | |||
| 964 | (unsigned long long)OCFS2_I(inode)->ip_blkno, sync_data); | 964 | (unsigned long long)OCFS2_I(inode)->ip_blkno, sync_data); |
| 965 | if (sync_data) | 965 | if (sync_data) |
| 966 | filemap_write_and_wait(inode->i_mapping); | 966 | filemap_write_and_wait(inode->i_mapping); |
| 967 | truncate_inode_pages(&inode->i_data, 0); | 967 | truncate_inode_pages_final(&inode->i_data); |
| 968 | } | 968 | } |
| 969 | 969 | ||
| 970 | static void ocfs2_delete_inode(struct inode *inode) | 970 | static void ocfs2_delete_inode(struct inode *inode) |
| @@ -1181,7 +1181,7 @@ void ocfs2_evict_inode(struct inode *inode) | |||
| 1181 | (OCFS2_I(inode)->ip_flags & OCFS2_INODE_MAYBE_ORPHANED)) { | 1181 | (OCFS2_I(inode)->ip_flags & OCFS2_INODE_MAYBE_ORPHANED)) { |
| 1182 | ocfs2_delete_inode(inode); | 1182 | ocfs2_delete_inode(inode); |
| 1183 | } else { | 1183 | } else { |
| 1184 | truncate_inode_pages(&inode->i_data, 0); | 1184 | truncate_inode_pages_final(&inode->i_data); |
| 1185 | } | 1185 | } |
| 1186 | ocfs2_clear_inode(inode); | 1186 | ocfs2_clear_inode(inode); |
| 1187 | } | 1187 | } |
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index d8b0afde2179..ec58c7659183 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c | |||
| @@ -183,7 +183,7 @@ int omfs_sync_inode(struct inode *inode) | |||
| 183 | */ | 183 | */ |
| 184 | static void omfs_evict_inode(struct inode *inode) | 184 | static void omfs_evict_inode(struct inode *inode) |
| 185 | { | 185 | { |
| 186 | truncate_inode_pages(&inode->i_data, 0); | 186 | truncate_inode_pages_final(&inode->i_data); |
| 187 | clear_inode(inode); | 187 | clear_inode(inode); |
| 188 | 188 | ||
| 189 | if (inode->i_nlink) | 189 | if (inode->i_nlink) |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 124fc43c7090..8f20e3404fd2 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
| @@ -35,7 +35,7 @@ static void proc_evict_inode(struct inode *inode) | |||
| 35 | const struct proc_ns_operations *ns_ops; | 35 | const struct proc_ns_operations *ns_ops; |
| 36 | void *ns; | 36 | void *ns; |
| 37 | 37 | ||
| 38 | truncate_inode_pages(&inode->i_data, 0); | 38 | truncate_inode_pages_final(&inode->i_data); |
| 39 | clear_inode(inode); | 39 | clear_inode(inode); |
| 40 | 40 | ||
| 41 | /* Stop tracking associated processes */ | 41 | /* Stop tracking associated processes */ |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index ad62bdbb451e..bc8b8009897d 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
| @@ -35,7 +35,7 @@ void reiserfs_evict_inode(struct inode *inode) | |||
| 35 | if (!inode->i_nlink && !is_bad_inode(inode)) | 35 | if (!inode->i_nlink && !is_bad_inode(inode)) |
| 36 | dquot_initialize(inode); | 36 | dquot_initialize(inode); |
| 37 | 37 | ||
| 38 | truncate_inode_pages(&inode->i_data, 0); | 38 | truncate_inode_pages_final(&inode->i_data); |
| 39 | if (inode->i_nlink) | 39 | if (inode->i_nlink) |
| 40 | goto no_delete; | 40 | goto no_delete; |
| 41 | 41 | ||
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index c327d4ee1235..5625ca920f5e 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
| @@ -295,7 +295,7 @@ int sysv_sync_inode(struct inode *inode) | |||
| 295 | 295 | ||
| 296 | static void sysv_evict_inode(struct inode *inode) | 296 | static void sysv_evict_inode(struct inode *inode) |
| 297 | { | 297 | { |
| 298 | truncate_inode_pages(&inode->i_data, 0); | 298 | truncate_inode_pages_final(&inode->i_data); |
| 299 | if (!inode->i_nlink) { | 299 | if (!inode->i_nlink) { |
| 300 | inode->i_size = 0; | 300 | inode->i_size = 0; |
| 301 | sysv_truncate(inode); | 301 | sysv_truncate(inode); |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 5ded8490c0c6..48f943f7f5d5 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
| @@ -351,7 +351,7 @@ static void ubifs_evict_inode(struct inode *inode) | |||
| 351 | dbg_gen("inode %lu, mode %#x", inode->i_ino, (int)inode->i_mode); | 351 | dbg_gen("inode %lu, mode %#x", inode->i_ino, (int)inode->i_mode); |
| 352 | ubifs_assert(!atomic_read(&inode->i_count)); | 352 | ubifs_assert(!atomic_read(&inode->i_count)); |
| 353 | 353 | ||
| 354 | truncate_inode_pages(&inode->i_data, 0); | 354 | truncate_inode_pages_final(&inode->i_data); |
| 355 | 355 | ||
| 356 | if (inode->i_nlink) | 356 | if (inode->i_nlink) |
| 357 | goto done; | 357 | goto done; |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 982ce05c87ed..5d643706212f 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
| @@ -146,8 +146,8 @@ void udf_evict_inode(struct inode *inode) | |||
| 146 | want_delete = 1; | 146 | want_delete = 1; |
| 147 | udf_setsize(inode, 0); | 147 | udf_setsize(inode, 0); |
| 148 | udf_update_inode(inode, IS_SYNC(inode)); | 148 | udf_update_inode(inode, IS_SYNC(inode)); |
| 149 | } else | 149 | } |
| 150 | truncate_inode_pages(&inode->i_data, 0); | 150 | truncate_inode_pages_final(&inode->i_data); |
| 151 | invalidate_inode_buffers(inode); | 151 | invalidate_inode_buffers(inode); |
| 152 | clear_inode(inode); | 152 | clear_inode(inode); |
| 153 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && | 153 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index c8ca96086784..61e8a9b021dd 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
| @@ -885,7 +885,7 @@ void ufs_evict_inode(struct inode * inode) | |||
| 885 | if (!inode->i_nlink && !is_bad_inode(inode)) | 885 | if (!inode->i_nlink && !is_bad_inode(inode)) |
| 886 | want_delete = 1; | 886 | want_delete = 1; |
| 887 | 887 | ||
| 888 | truncate_inode_pages(&inode->i_data, 0); | 888 | truncate_inode_pages_final(&inode->i_data); |
| 889 | if (want_delete) { | 889 | if (want_delete) { |
| 890 | loff_t old_i_size; | 890 | loff_t old_i_size; |
| 891 | /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/ | 891 | /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/ |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index d971f4932b5d..0ef599218991 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
| @@ -996,7 +996,7 @@ xfs_fs_evict_inode( | |||
| 996 | 996 | ||
| 997 | trace_xfs_evict_inode(ip); | 997 | trace_xfs_evict_inode(ip); |
| 998 | 998 | ||
| 999 | truncate_inode_pages(&inode->i_data, 0); | 999 | truncate_inode_pages_final(&inode->i_data); |
| 1000 | clear_inode(inode); | 1000 | clear_inode(inode); |
| 1001 | XFS_STATS_INC(vn_rele); | 1001 | XFS_STATS_INC(vn_rele); |
| 1002 | XFS_STATS_INC(vn_remove); | 1002 | XFS_STATS_INC(vn_remove); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 6e765d28841b..3ca9420f627e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -419,6 +419,7 @@ struct address_space { | |||
| 419 | struct mutex i_mmap_mutex; /* protect tree, count, list */ | 419 | struct mutex i_mmap_mutex; /* protect tree, count, list */ |
| 420 | /* Protected by tree_lock together with the radix tree */ | 420 | /* Protected by tree_lock together with the radix tree */ |
| 421 | unsigned long nrpages; /* number of total pages */ | 421 | unsigned long nrpages; /* number of total pages */ |
| 422 | unsigned long nrshadows; /* number of shadow entries */ | ||
| 422 | pgoff_t writeback_index;/* writeback starts here */ | 423 | pgoff_t writeback_index;/* writeback starts here */ |
| 423 | const struct address_space_operations *a_ops; /* methods */ | 424 | const struct address_space_operations *a_ops; /* methods */ |
| 424 | unsigned long flags; /* error bits/gfp mask */ | 425 | unsigned long flags; /* error bits/gfp mask */ |
diff --git a/include/linux/mm.h b/include/linux/mm.h index b1331aff769c..58d6ddba5db3 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -1834,6 +1834,7 @@ vm_unmapped_area(struct vm_unmapped_area_info *info) | |||
| 1834 | extern void truncate_inode_pages(struct address_space *, loff_t); | 1834 | extern void truncate_inode_pages(struct address_space *, loff_t); |
| 1835 | extern void truncate_inode_pages_range(struct address_space *, | 1835 | extern void truncate_inode_pages_range(struct address_space *, |
| 1836 | loff_t lstart, loff_t lend); | 1836 | loff_t lstart, loff_t lend); |
| 1837 | extern void truncate_inode_pages_final(struct address_space *); | ||
| 1837 | 1838 | ||
| 1838 | /* generic vm_area_ops exported for stackable file systems */ | 1839 | /* generic vm_area_ops exported for stackable file systems */ |
| 1839 | extern int filemap_fault(struct vm_area_struct *, struct vm_fault *); | 1840 | extern int filemap_fault(struct vm_area_struct *, struct vm_fault *); |
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 493bfd85214e..ff43253f568a 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h | |||
| @@ -25,6 +25,7 @@ enum mapping_flags { | |||
| 25 | AS_MM_ALL_LOCKS = __GFP_BITS_SHIFT + 2, /* under mm_take_all_locks() */ | 25 | AS_MM_ALL_LOCKS = __GFP_BITS_SHIFT + 2, /* under mm_take_all_locks() */ |
| 26 | AS_UNEVICTABLE = __GFP_BITS_SHIFT + 3, /* e.g., ramdisk, SHM_LOCK */ | 26 | AS_UNEVICTABLE = __GFP_BITS_SHIFT + 3, /* e.g., ramdisk, SHM_LOCK */ |
| 27 | AS_BALLOON_MAP = __GFP_BITS_SHIFT + 4, /* balloon page special map */ | 27 | AS_BALLOON_MAP = __GFP_BITS_SHIFT + 4, /* balloon page special map */ |
| 28 | AS_EXITING = __GFP_BITS_SHIFT + 5, /* final truncate in progress */ | ||
| 28 | }; | 29 | }; |
| 29 | 30 | ||
| 30 | static inline void mapping_set_error(struct address_space *mapping, int error) | 31 | static inline void mapping_set_error(struct address_space *mapping, int error) |
| @@ -69,6 +70,16 @@ static inline int mapping_balloon(struct address_space *mapping) | |||
| 69 | return mapping && test_bit(AS_BALLOON_MAP, &mapping->flags); | 70 | return mapping && test_bit(AS_BALLOON_MAP, &mapping->flags); |
| 70 | } | 71 | } |
| 71 | 72 | ||
| 73 | static inline void mapping_set_exiting(struct address_space *mapping) | ||
| 74 | { | ||
| 75 | set_bit(AS_EXITING, &mapping->flags); | ||
| 76 | } | ||
| 77 | |||
| 78 | static inline int mapping_exiting(struct address_space *mapping) | ||
| 79 | { | ||
| 80 | return test_bit(AS_EXITING, &mapping->flags); | ||
| 81 | } | ||
| 82 | |||
| 72 | static inline gfp_t mapping_gfp_mask(struct address_space * mapping) | 83 | static inline gfp_t mapping_gfp_mask(struct address_space * mapping) |
| 73 | { | 84 | { |
| 74 | return (__force gfp_t)mapping->flags & __GFP_BITS_MASK; | 85 | return (__force gfp_t)mapping->flags & __GFP_BITS_MASK; |
| @@ -547,7 +558,7 @@ int add_to_page_cache_locked(struct page *page, struct address_space *mapping, | |||
| 547 | int add_to_page_cache_lru(struct page *page, struct address_space *mapping, | 558 | int add_to_page_cache_lru(struct page *page, struct address_space *mapping, |
| 548 | pgoff_t index, gfp_t gfp_mask); | 559 | pgoff_t index, gfp_t gfp_mask); |
| 549 | extern void delete_from_page_cache(struct page *page); | 560 | extern void delete_from_page_cache(struct page *page); |
| 550 | extern void __delete_from_page_cache(struct page *page); | 561 | extern void __delete_from_page_cache(struct page *page, void *shadow); |
| 551 | int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask); | 562 | int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask); |
| 552 | 563 | ||
| 553 | /* | 564 | /* |
diff --git a/mm/filemap.c b/mm/filemap.c index efc63876477f..05c44aa44188 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
| @@ -107,12 +107,33 @@ | |||
| 107 | * ->tasklist_lock (memory_failure, collect_procs_ao) | 107 | * ->tasklist_lock (memory_failure, collect_procs_ao) |
| 108 | */ | 108 | */ |
| 109 | 109 | ||
| 110 | static void page_cache_tree_delete(struct address_space *mapping, | ||
| 111 | struct page *page, void *shadow) | ||
| 112 | { | ||
| 113 | if (shadow) { | ||
| 114 | void **slot; | ||
| 115 | |||
| 116 | slot = radix_tree_lookup_slot(&mapping->page_tree, page->index); | ||
| 117 | radix_tree_replace_slot(slot, shadow); | ||
| 118 | mapping->nrshadows++; | ||
| 119 | /* | ||
| 120 | * Make sure the nrshadows update is committed before | ||
| 121 | * the nrpages update so that final truncate racing | ||
| 122 | * with reclaim does not see both counters 0 at the | ||
| 123 | * same time and miss a shadow entry. | ||
| 124 | */ | ||
| 125 | smp_wmb(); | ||
| 126 | } else | ||
| 127 | radix_tree_delete(&mapping->page_tree, page->index); | ||
| 128 | mapping->nrpages--; | ||
| 129 | } | ||
| 130 | |||
| 110 | /* | 131 | /* |
| 111 | * Delete a page from the page cache and free it. Caller has to make | 132 | * Delete a page from the page cache and free it. Caller has to make |
| 112 | * sure the page is locked and that nobody else uses it - or that usage | 133 | * sure the page is locked and that nobody else uses it - or that usage |
| 113 | * is safe. The caller must hold the mapping's tree_lock. | 134 | * is safe. The caller must hold the mapping's tree_lock. |
| 114 | */ | 135 | */ |
| 115 | void __delete_from_page_cache(struct page *page) | 136 | void __delete_from_page_cache(struct page *page, void *shadow) |
| 116 | { | 137 | { |
| 117 | struct address_space *mapping = page->mapping; | 138 | struct address_space *mapping = page->mapping; |
| 118 | 139 | ||
| @@ -127,10 +148,11 @@ void __delete_from_page_cache(struct page *page) | |||
| 127 | else | 148 | else |
| 128 | cleancache_invalidate_page(mapping, page); | 149 | cleancache_invalidate_page(mapping, page); |
| 129 | 150 | ||
| 130 | radix_tree_delete(&mapping->page_tree, page->index); | 151 | page_cache_tree_delete(mapping, page, shadow); |
| 152 | |||
| 131 | page->mapping = NULL; | 153 | page->mapping = NULL; |
| 132 | /* Leave page->index set: truncation lookup relies upon it */ | 154 | /* Leave page->index set: truncation lookup relies upon it */ |
| 133 | mapping->nrpages--; | 155 | |
| 134 | __dec_zone_page_state(page, NR_FILE_PAGES); | 156 | __dec_zone_page_state(page, NR_FILE_PAGES); |
| 135 | if (PageSwapBacked(page)) | 157 | if (PageSwapBacked(page)) |
| 136 | __dec_zone_page_state(page, NR_SHMEM); | 158 | __dec_zone_page_state(page, NR_SHMEM); |
| @@ -166,7 +188,7 @@ void delete_from_page_cache(struct page *page) | |||
| 166 | 188 | ||
| 167 | freepage = mapping->a_ops->freepage; | 189 | freepage = mapping->a_ops->freepage; |
| 168 | spin_lock_irq(&mapping->tree_lock); | 190 | spin_lock_irq(&mapping->tree_lock); |
| 169 | __delete_from_page_cache(page); | 191 | __delete_from_page_cache(page, NULL); |
| 170 | spin_unlock_irq(&mapping->tree_lock); | 192 | spin_unlock_irq(&mapping->tree_lock); |
| 171 | mem_cgroup_uncharge_cache_page(page); | 193 | mem_cgroup_uncharge_cache_page(page); |
| 172 | 194 | ||
| @@ -426,7 +448,7 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask) | |||
| 426 | new->index = offset; | 448 | new->index = offset; |
| 427 | 449 | ||
| 428 | spin_lock_irq(&mapping->tree_lock); | 450 | spin_lock_irq(&mapping->tree_lock); |
| 429 | __delete_from_page_cache(old); | 451 | __delete_from_page_cache(old, NULL); |
| 430 | error = radix_tree_insert(&mapping->page_tree, offset, new); | 452 | error = radix_tree_insert(&mapping->page_tree, offset, new); |
| 431 | BUG_ON(error); | 453 | BUG_ON(error); |
| 432 | mapping->nrpages++; | 454 | mapping->nrpages++; |
| @@ -460,6 +482,7 @@ static int page_cache_tree_insert(struct address_space *mapping, | |||
| 460 | if (!radix_tree_exceptional_entry(p)) | 482 | if (!radix_tree_exceptional_entry(p)) |
| 461 | return -EEXIST; | 483 | return -EEXIST; |
| 462 | radix_tree_replace_slot(slot, page); | 484 | radix_tree_replace_slot(slot, page); |
| 485 | mapping->nrshadows--; | ||
| 463 | mapping->nrpages++; | 486 | mapping->nrpages++; |
| 464 | return 0; | 487 | return 0; |
| 465 | } | 488 | } |
diff --git a/mm/truncate.c b/mm/truncate.c index 2e84fe59190b..0db9258319f0 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
| @@ -35,7 +35,8 @@ static void clear_exceptional_entry(struct address_space *mapping, | |||
| 35 | * without the tree itself locked. These unlocked entries | 35 | * without the tree itself locked. These unlocked entries |
| 36 | * need verification under the tree lock. | 36 | * need verification under the tree lock. |
| 37 | */ | 37 | */ |
| 38 | radix_tree_delete_item(&mapping->page_tree, index, entry); | 38 | if (radix_tree_delete_item(&mapping->page_tree, index, entry) == entry) |
| 39 | mapping->nrshadows--; | ||
| 39 | spin_unlock_irq(&mapping->tree_lock); | 40 | spin_unlock_irq(&mapping->tree_lock); |
| 40 | } | 41 | } |
| 41 | 42 | ||
| @@ -229,7 +230,7 @@ void truncate_inode_pages_range(struct address_space *mapping, | |||
| 229 | int i; | 230 | int i; |
| 230 | 231 | ||
| 231 | cleancache_invalidate_inode(mapping); | 232 | cleancache_invalidate_inode(mapping); |
| 232 | if (mapping->nrpages == 0) | 233 | if (mapping->nrpages == 0 && mapping->nrshadows == 0) |
| 233 | return; | 234 | return; |
| 234 | 235 | ||
| 235 | /* Offsets within partial pages */ | 236 | /* Offsets within partial pages */ |
| @@ -392,6 +393,53 @@ void truncate_inode_pages(struct address_space *mapping, loff_t lstart) | |||
| 392 | EXPORT_SYMBOL(truncate_inode_pages); | 393 | EXPORT_SYMBOL(truncate_inode_pages); |
| 393 | 394 | ||
| 394 | /** | 395 | /** |
| 396 | * truncate_inode_pages_final - truncate *all* pages before inode dies | ||
| 397 | * @mapping: mapping to truncate | ||
| 398 | * | ||
| 399 | * Called under (and serialized by) inode->i_mutex. | ||
| 400 | * | ||
| 401 | * Filesystems have to use this in the .evict_inode path to inform the | ||
| 402 | * VM that this is the final truncate and the inode is going away. | ||
| 403 | */ | ||
| 404 | void truncate_inode_pages_final(struct address_space *mapping) | ||
| 405 | { | ||
| 406 | unsigned long nrshadows; | ||
| 407 | unsigned long nrpages; | ||
| 408 | |||
| 409 | /* | ||
| 410 | * Page reclaim can not participate in regular inode lifetime | ||
| 411 | * management (can't call iput()) and thus can race with the | ||
| 412 | * inode teardown. Tell it when the address space is exiting, | ||
| 413 | * so that it does not install eviction information after the | ||
| 414 | * final truncate has begun. | ||
| 415 | */ | ||
| 416 | mapping_set_exiting(mapping); | ||
| 417 | |||
| 418 | /* | ||
| 419 | * When reclaim installs eviction entries, it increases | ||
| 420 | * nrshadows first, then decreases nrpages. Make sure we see | ||
| 421 | * this in the right order or we might miss an entry. | ||
| 422 | */ | ||
| 423 | nrpages = mapping->nrpages; | ||
| 424 | smp_rmb(); | ||
| 425 | nrshadows = mapping->nrshadows; | ||
| 426 | |||
| 427 | if (nrpages || nrshadows) { | ||
| 428 | /* | ||
| 429 | * As truncation uses a lockless tree lookup, cycle | ||
| 430 | * the tree lock to make sure any ongoing tree | ||
| 431 | * modification that does not see AS_EXITING is | ||
| 432 | * completed before starting the final truncate. | ||
| 433 | */ | ||
| 434 | spin_lock_irq(&mapping->tree_lock); | ||
| 435 | spin_unlock_irq(&mapping->tree_lock); | ||
| 436 | |||
| 437 | truncate_inode_pages(mapping, 0); | ||
| 438 | } | ||
| 439 | } | ||
| 440 | EXPORT_SYMBOL(truncate_inode_pages_final); | ||
| 441 | |||
| 442 | /** | ||
| 395 | * invalidate_mapping_pages - Invalidate all the unlocked pages of one inode | 443 | * invalidate_mapping_pages - Invalidate all the unlocked pages of one inode |
| 396 | * @mapping: the address_space which holds the pages to invalidate | 444 | * @mapping: the address_space which holds the pages to invalidate |
| 397 | * @start: the offset 'from' which to invalidate | 445 | * @start: the offset 'from' which to invalidate |
| @@ -484,7 +532,7 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page) | |||
| 484 | goto failed; | 532 | goto failed; |
| 485 | 533 | ||
| 486 | BUG_ON(page_has_private(page)); | 534 | BUG_ON(page_has_private(page)); |
| 487 | __delete_from_page_cache(page); | 535 | __delete_from_page_cache(page, NULL); |
| 488 | spin_unlock_irq(&mapping->tree_lock); | 536 | spin_unlock_irq(&mapping->tree_lock); |
| 489 | mem_cgroup_uncharge_cache_page(page); | 537 | mem_cgroup_uncharge_cache_page(page); |
| 490 | 538 | ||
diff --git a/mm/vmscan.c b/mm/vmscan.c index c53d1a54964c..2a0bb8fdb259 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
| @@ -572,7 +572,7 @@ static int __remove_mapping(struct address_space *mapping, struct page *page) | |||
| 572 | 572 | ||
| 573 | freepage = mapping->a_ops->freepage; | 573 | freepage = mapping->a_ops->freepage; |
| 574 | 574 | ||
| 575 | __delete_from_page_cache(page); | 575 | __delete_from_page_cache(page, NULL); |
| 576 | spin_unlock_irq(&mapping->tree_lock); | 576 | spin_unlock_irq(&mapping->tree_lock); |
| 577 | mem_cgroup_uncharge_cache_page(page); | 577 | mem_cgroup_uncharge_cache_page(page); |
| 578 | 578 | ||
