Merge branch 'work.iget' into work.misc
[sfrench/cifs-2.6.git] / fs / inode.c
index ad445542c2858f5d622386bb58e725c4c11ae38d..691c00747e725918cdc98e1f1414a42047f1baee 100644 (file)
@@ -1021,13 +1021,17 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
 {
        struct hlist_head *head = inode_hashtable + hash(sb, hashval);
        struct inode *inode;
-
+again:
        spin_lock(&inode_hash_lock);
        inode = find_inode(sb, head, test, data);
        spin_unlock(&inode_hash_lock);
 
        if (inode) {
                wait_on_inode(inode);
+               if (unlikely(inode_unhashed(inode))) {
+                       iput(inode);
+                       goto again;
+               }
                return inode;
        }
 
@@ -1064,6 +1068,10 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
                destroy_inode(inode);
                inode = old;
                wait_on_inode(inode);
+               if (unlikely(inode_unhashed(inode))) {
+                       iput(inode);
+                       goto again;
+               }
        }
        return inode;
 
@@ -1091,12 +1099,16 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino)
 {
        struct hlist_head *head = inode_hashtable + hash(sb, ino);
        struct inode *inode;
-
+again:
        spin_lock(&inode_hash_lock);
        inode = find_inode_fast(sb, head, ino);
        spin_unlock(&inode_hash_lock);
        if (inode) {
                wait_on_inode(inode);
+               if (unlikely(inode_unhashed(inode))) {
+                       iput(inode);
+                       goto again;
+               }
                return inode;
        }
 
@@ -1131,6 +1143,10 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino)
                destroy_inode(inode);
                inode = old;
                wait_on_inode(inode);
+               if (unlikely(inode_unhashed(inode))) {
+                       iput(inode);
+                       goto again;
+               }
        }
        return inode;
 }
@@ -1266,10 +1282,16 @@ EXPORT_SYMBOL(ilookup5_nowait);
 struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
                int (*test)(struct inode *, void *), void *data)
 {
-       struct inode *inode = ilookup5_nowait(sb, hashval, test, data);
-
-       if (inode)
+       struct inode *inode;
+again:
+       inode = ilookup5_nowait(sb, hashval, test, data);
+       if (inode) {
                wait_on_inode(inode);
+               if (unlikely(inode_unhashed(inode))) {
+                       iput(inode);
+                       goto again;
+               }
+       }
        return inode;
 }
 EXPORT_SYMBOL(ilookup5);
@@ -1286,13 +1308,18 @@ struct inode *ilookup(struct super_block *sb, unsigned long ino)
 {
        struct hlist_head *head = inode_hashtable + hash(sb, ino);
        struct inode *inode;
-
+again:
        spin_lock(&inode_hash_lock);
        inode = find_inode_fast(sb, head, ino);
        spin_unlock(&inode_hash_lock);
 
-       if (inode)
+       if (inode) {
                wait_on_inode(inode);
+               if (unlikely(inode_unhashed(inode))) {
+                       iput(inode);
+                       goto again;
+               }
+       }
        return inode;
 }
 EXPORT_SYMBOL(ilookup);
@@ -1729,7 +1756,6 @@ int dentry_needs_remove_privs(struct dentry *dentry)
                mask |= ATTR_KILL_PRIV;
        return mask;
 }
-EXPORT_SYMBOL(dentry_needs_remove_privs);
 
 static int __remove_privs(struct dentry *dentry, int kill)
 {
@@ -1749,8 +1775,8 @@ static int __remove_privs(struct dentry *dentry, int kill)
  */
 int file_remove_privs(struct file *file)
 {
-       struct dentry *dentry = file->f_path.dentry;
-       struct inode *inode = d_inode(dentry);
+       struct dentry *dentry = file_dentry(file);
+       struct inode *inode = file_inode(file);
        int kill;
        int error = 0;
 
@@ -1758,7 +1784,7 @@ int file_remove_privs(struct file *file)
        if (IS_NOSEC(inode))
                return 0;
 
-       kill = file_needs_remove_privs(file);
+       kill = dentry_needs_remove_privs(dentry);
        if (kill < 0)
                return kill;
        if (kill)