X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=fs%2Fdquot.c;h=def4e969df77646192eb6ce96d223a1f78ec4544;hb=7f3fbd08976f1d2562d6174d5fe4c85d12bb7d54;hp=cee7c6f428f0fa518e80bda281eb92421a5ac295;hpb=88fb61e4ba263685a0d5b82c7e9cd6f22a9e6a9d;p=powerpc.git diff --git a/fs/dquot.c b/fs/dquot.c index cee7c6f428..def4e969df 100644 --- a/fs/dquot.c +++ b/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 @@ restart: __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) */