Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.25-rc7 /fs/dquot.c

Filename:/fs/dquot.c
Lines Added:16
Lines Deleted:10
Also changed in: (Previous) 2.6.25-rc6-git8  2.6.25-rc6-git7  2.6.25-rc6-git6  2.6.25-rc6-git5  2.6.25-rc6-git4  2.6.25-rc6 
(Following) 2.6.25-rc8  2.6.25-rc9  2.6.25  2.6.25-git12  2.6.25-git13  2.6.25-git14 

Location
[  2.6.25-rc7
  [  fs
     o  dquot.c

Patch

diff --git a/fs/dquot.c b/fs/dquot.c
index cee7c6f..41b9dbd 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) */
@@ -1517,8 +1522,8 @@ int vfs_quota_off(struct super_block *sb, int type)
             truncate_inode_pages(&toputinode[cnt]->i_data, 0);
             mutex_unlock(&toputinode[cnt]->i_mutex);
             mark_inode_dirty(toputinode[cnt]);
-            iput(toputinode[cnt]);
          }
+         iput(toputinode[cnt]);
          mutex_unlock(&dqopt->dqonoff_mutex);
       }
    if (sb->s_bdev)
@@ -1628,16 +1633,17 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
    error = path_lookup(path, LOOKUP_FOLLOW, &nd);
    if (error < 0)
       return error;
-   error = security_quota_on(nd.dentry);
+   error = security_quota_on(nd.path.dentry);
    if (error)
       goto out_path;
    /* Quota file not on the same filesystem? */
-   if (nd.mnt->mnt_sb != sb)
+   if (nd.path.mnt->mnt_sb != sb)
       error = -EXDEV;
    else
-      error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id);
+      error = vfs_quota_on_inode(nd.path.dentry->d_inode, type,
+                  format_id);
 out_path:
-   path_release(&nd);
+   path_put(&nd.path);
    return error;
 }
 


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.