aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dquot.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dquot.c')
-rw-r--r--fs/dquot.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/fs/dquot.c b/fs/dquot.c
index cee7c6f428f0..9c7feb62eed1 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -696,9 +696,8 @@ static int dqinit_needed(struct inode *inode, int type)
696/* This routine is guarded by dqonoff_mutex mutex */ 696/* This routine is guarded by dqonoff_mutex mutex */
697static void add_dquot_ref(struct super_block *sb, int type) 697static void add_dquot_ref(struct super_block *sb, int type)
698{ 698{
699 struct inode *inode; 699 struct inode *inode, *old_inode = NULL;
700 700
701restart:
702 spin_lock(&inode_lock); 701 spin_lock(&inode_lock);
703 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { 702 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
704 if (!atomic_read(&inode->i_writecount)) 703 if (!atomic_read(&inode->i_writecount))
@@ -711,12 +710,18 @@ restart:
711 __iget(inode); 710 __iget(inode);
712 spin_unlock(&inode_lock); 711 spin_unlock(&inode_lock);
713 712
713 iput(old_inode);
714 sb->dq_op->initialize(inode, type); 714 sb->dq_op->initialize(inode, type);
715 iput(inode); 715 /* We hold a reference to 'inode' so it couldn't have been
716 /* As we may have blocked we had better restart... */ 716 * removed from s_inodes list while we dropped the inode_lock.
717 goto restart; 717 * We cannot iput the inode now as we can be holding the last
718 * reference and we cannot iput it under inode_lock. So we
719 * keep the reference and iput it later. */
720 old_inode = inode;
721 spin_lock(&inode_lock);
718 } 722 }
719 spin_unlock(&inode_lock); 723 spin_unlock(&inode_lock);
724 iput(old_inode);
720} 725}
721 726
722/* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */ 727/* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */
@@ -1628,16 +1633,17 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
1628 error = path_lookup(path, LOOKUP_FOLLOW, &nd); 1633 error = path_lookup(path, LOOKUP_FOLLOW, &nd);
1629 if (error < 0) 1634 if (error < 0)
1630 return error; 1635 return error;
1631 error = security_quota_on(nd.dentry); 1636 error = security_quota_on(nd.path.dentry);
1632 if (error) 1637 if (error)
1633 goto out_path; 1638 goto out_path;
1634 /* Quota file not on the same filesystem? */ 1639 /* Quota file not on the same filesystem? */
1635 if (nd.mnt->mnt_sb != sb) 1640 if (nd.path.mnt->mnt_sb != sb)
1636 error = -EXDEV; 1641 error = -EXDEV;
1637 else 1642 else
1638 error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id); 1643 error = vfs_quota_on_inode(nd.path.dentry->d_inode, type,
1644 format_id);
1639out_path: 1645out_path:
1640 path_release(&nd); 1646 path_put(&nd.path);
1641 return error; 1647 return error;
1642} 1648}
1643 1649