From 1060488a84e56262f375909d94762ff42bf81385 Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Sun, 30 Oct 2005 15:03:05 -0800 Subject: [PATCH] --- yaml --- r: 11871 b: refs/heads/master c: 7f04c26d715a2467a49a2384268de8f70f787b51 h: refs/heads/master i: 11869: 8fddd42c69c1cc84544685bdadbe3bfcc06e3ed0 11867: f1b25d851d3b8f8333ffd70a48576ea9df5d2042 11863: 2518c602ae0ad17a9815702c62410cd81809e382 11855: 77fd29217990b793a292c57323103eb0249dbc44 11839: c30a76aadf8f09de0bb4531a2bd137f63caa765c v: v3 --- [refs] | 2 +- trunk/fs/fs-writeback.c | 28 ++++++++++++++++------------ trunk/fs/inode.c | 1 + 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/[refs] b/[refs] index ffc94e79a8a5..32039325a365 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 52303e8b5f8aa234865d40d76ea16b0ff4b27022 +refs/heads/master: 7f04c26d715a2467a49a2384268de8f70f787b51 diff --git a/trunk/fs/fs-writeback.c b/trunk/fs/fs-writeback.c index e94ab398b717..ffab4783ac64 100644 --- a/trunk/fs/fs-writeback.c +++ b/trunk/fs/fs-writeback.c @@ -230,7 +230,6 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc) * The inode is clean, unused */ list_move(&inode->i_list, &inode_unused); - inodes_stat.nr_unused++; } } wake_up_inode(inode); @@ -238,14 +237,20 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc) } /* - * Write out an inode's dirty pages. Called under inode_lock. + * Write out an inode's dirty pages. Called under inode_lock. Either the + * caller has ref on the inode (either via __iget or via syscall against an fd) + * or the inode has I_WILL_FREE set (via generic_forget_inode) */ static int -__writeback_single_inode(struct inode *inode, - struct writeback_control *wbc) +__writeback_single_inode(struct inode *inode, struct writeback_control *wbc) { wait_queue_head_t *wqh; + if (!atomic_read(&inode->i_count)) + WARN_ON(!(inode->i_state & I_WILL_FREE)); + else + WARN_ON(inode->i_state & I_WILL_FREE); + if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) { list_move(&inode->i_list, &inode->i_sb->s_dirty); return 0; @@ -259,11 +264,9 @@ __writeback_single_inode(struct inode *inode, wqh = bit_waitqueue(&inode->i_state, __I_LOCK); do { - __iget(inode); spin_unlock(&inode_lock); __wait_on_bit(wqh, &wq, inode_wait, TASK_UNINTERRUPTIBLE); - iput(inode); spin_lock(&inode_lock); } while (inode->i_state & I_LOCK); } @@ -541,14 +544,15 @@ void sync_inodes(int wait) } /** - * write_inode_now - write an inode to disk - * @inode: inode to write to disk - * @sync: whether the write should be synchronous or not + * write_inode_now - write an inode to disk + * @inode: inode to write to disk + * @sync: whether the write should be synchronous or not + * + * This function commits an inode to disk immediately if it is dirty. This is + * primarily needed by knfsd. * - * This function commits an inode to disk immediately if it is - * dirty. This is primarily needed by knfsd. + * The caller must either have a ref on the inode or must have set I_WILL_FREE. */ - int write_inode_now(struct inode *inode, int sync) { int ret; diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index 7d3316527767..d8d04bd72b59 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -1088,6 +1088,7 @@ static void generic_forget_inode(struct inode *inode) if (inode->i_data.nrpages) truncate_inode_pages(&inode->i_data, 0); clear_inode(inode); + wake_up_inode(inode); destroy_inode(inode); }