NFS: Protect inode->i_nlink updates using inode->i_lock
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 11 Jun 2008 19:44:04 +0000 (15:44 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 15 Jul 2008 22:10:50 +0000 (18:10 -0400)
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/dir.c

index b1940660502f4b432812a1dda74afcf8855b54f5..d6ec1c85995a59171852a08f8062c5b0ef550d5f 100644 (file)
@@ -870,6 +870,14 @@ static int nfs_dentry_delete(struct dentry *dentry)
 
 }
 
+static void nfs_drop_nlink(struct inode *inode)
+{
+       spin_lock(&inode->i_lock);
+       if (inode->i_nlink > 0)
+               drop_nlink(inode);
+       spin_unlock(&inode->i_lock);
+}
+
 /*
  * Called when the dentry loses inode.
  * We use it to clean up silly-renamed files.
@@ -1420,7 +1428,7 @@ static int nfs_safe_remove(struct dentry *dentry)
                error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
                /* The VFS may want to delete this inode */
                if (error == 0)
-                       drop_nlink(inode);
+                       nfs_drop_nlink(inode);
                nfs_mark_for_revalidate(inode);
        } else
                error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
@@ -1647,7 +1655,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                        /* dentry still busy? */
                        goto out;
        } else
-               drop_nlink(new_inode);
+               nfs_drop_nlink(new_inode);
 
 go_ahead:
        /*