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 | ||