aboutsummaryrefslogtreecommitdiffstats
path: root/fs/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-28 12:54:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-28 12:54:45 -0400
commit90324cc1b11a211e37eabd8cb863e1a1561d6b1d (patch)
treec8b79c6850420a114ca6660c1b44fc486b1ba86d /fs/inode.c
parentfb8b00675eb6462aacab56bca31ed6107bda5314 (diff)
parent169ebd90131b2ffca74bb2dbe7eeacd39fb83714 (diff)
Merge tag 'writeback' of git://git.kernel.org/pub/scm/linux/kernel/git/wfg/linux
Pull writeback tree from Wu Fengguang: "Mainly from Jan Kara to avoid iput() in the flusher threads." * tag 'writeback' of git://git.kernel.org/pub/scm/linux/kernel/git/wfg/linux: writeback: Avoid iput() from flusher thread vfs: Rename end_writeback() to clear_inode() vfs: Move waiting for inode writeback from end_writeback() to evict_inode() writeback: Refactor writeback_single_inode() writeback: Remove wb->list_lock from writeback_single_inode() writeback: Separate inode requeueing after writeback writeback: Move I_DIRTY_PAGES handling writeback: Move requeueing when I_SYNC set to writeback_sb_inodes() writeback: Move clearing of I_SYNC into inode_sync_complete() writeback: initialize global_dirty_limit fs: remove 8 bytes of padding from struct writeback_control on 64 bit builds mm: page-writeback.c: local functions should not be exposed globally
Diffstat (limited to 'fs/inode.c')
-rw-r--r--fs/inode.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/inode.c b/fs/inode.c
index da93f7d160d4..6bc8761cc333 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -486,7 +486,7 @@ void __remove_inode_hash(struct inode *inode)
486} 486}
487EXPORT_SYMBOL(__remove_inode_hash); 487EXPORT_SYMBOL(__remove_inode_hash);
488 488
489void end_writeback(struct inode *inode) 489void clear_inode(struct inode *inode)
490{ 490{
491 might_sleep(); 491 might_sleep();
492 /* 492 /*
@@ -500,11 +500,10 @@ void end_writeback(struct inode *inode)
500 BUG_ON(!list_empty(&inode->i_data.private_list)); 500 BUG_ON(!list_empty(&inode->i_data.private_list));
501 BUG_ON(!(inode->i_state & I_FREEING)); 501 BUG_ON(!(inode->i_state & I_FREEING));
502 BUG_ON(inode->i_state & I_CLEAR); 502 BUG_ON(inode->i_state & I_CLEAR);
503 inode_sync_wait(inode);
504 /* don't need i_lock here, no concurrent mods to i_state */ 503 /* don't need i_lock here, no concurrent mods to i_state */
505 inode->i_state = I_FREEING | I_CLEAR; 504 inode->i_state = I_FREEING | I_CLEAR;
506} 505}
507EXPORT_SYMBOL(end_writeback); 506EXPORT_SYMBOL(clear_inode);
508 507
509/* 508/*
510 * Free the inode passed in, removing it from the lists it is still connected 509 * Free the inode passed in, removing it from the lists it is still connected
@@ -531,12 +530,20 @@ static void evict(struct inode *inode)
531 530
532 inode_sb_list_del(inode); 531 inode_sb_list_del(inode);
533 532
533 /*
534 * Wait for flusher thread to be done with the inode so that filesystem
535 * does not start destroying it while writeback is still running. Since
536 * the inode has I_FREEING set, flusher thread won't start new work on
537 * the inode. We just have to wait for running writeback to finish.
538 */
539 inode_wait_for_writeback(inode);
540
534 if (op->evict_inode) { 541 if (op->evict_inode) {
535 op->evict_inode(inode); 542 op->evict_inode(inode);
536 } else { 543 } else {
537 if (inode->i_data.nrpages) 544 if (inode->i_data.nrpages)
538 truncate_inode_pages(&inode->i_data, 0); 545 truncate_inode_pages(&inode->i_data, 0);
539 end_writeback(inode); 546 clear_inode(inode);
540 } 547 }
541 if (S_ISBLK(inode->i_mode) && inode->i_bdev) 548 if (S_ISBLK(inode->i_mode) && inode->i_bdev)
542 bd_forget(inode); 549 bd_forget(inode);