From f3ddd4272cb8a8f272480b586747afcd74a93611 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 6 Feb 2008 01:37:36 -0800 Subject: [PATCH] --- yaml --- r: 83455 b: refs/heads/master c: 941d2380e979dfefb6c824452e9f42be3ef948ee h: refs/heads/master i: 83453: 4912f45b191f550eb5abf7f4447173414ea471a4 83451: 481d08a91d54d387b27ca35eb11560af39adc746 83447: b3bb3152aadbe610c2050c9f77bc514697f356f6 83439: 891af3214d7bc6a190f1d69be4edc348ae247938 83423: f28ac45b945173a28a4406f5cf639109d1c83312 83391: 12674d51df45eec62dec544202960ce7e79ba72b 83327: e1a0a8d7d62a69bc7e18c9a05881f9058cfdd33d 83199: c9fbca14f9a8d49316d64b6916c94aaf8f730ebc 82943: 2f1e9e69810b4b85cc9c90e4852db93481f91f1d v: v3 --- [refs] | 2 +- trunk/fs/dquot.c | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index 6e15413ee7c6..75ead8a0df2f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bed9759b2e6bd938097389f6bd2ac8d622fa3884 +refs/heads/master: 941d2380e979dfefb6c824452e9f42be3ef948ee diff --git a/trunk/fs/dquot.c b/trunk/fs/dquot.c index cee7c6f428f0..def4e969df77 100644 --- a/trunk/fs/dquot.c +++ b/trunk/fs/dquot.c @@ -696,9 +696,8 @@ static int dqinit_needed(struct inode *inode, int type) /* This routine is guarded by dqonoff_mutex mutex */ static void add_dquot_ref(struct super_block *sb, int type) { - struct inode *inode; + struct inode *inode, *old_inode = NULL; -restart: spin_lock(&inode_lock); list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { if (!atomic_read(&inode->i_writecount)) @@ -711,12 +710,18 @@ static void add_dquot_ref(struct super_block *sb, int type) __iget(inode); spin_unlock(&inode_lock); + iput(old_inode); sb->dq_op->initialize(inode, type); - iput(inode); - /* As we may have blocked we had better restart... */ - goto restart; + /* We hold a reference to 'inode' so it couldn't have been + * removed from s_inodes list while we dropped the inode_lock. + * We cannot iput the inode now as we can be holding the last + * reference and we cannot iput it under inode_lock. So we + * keep the reference and iput it later. */ + old_inode = inode; + spin_lock(&inode_lock); } spin_unlock(&inode_lock); + iput(old_inode); } /* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */