[PATCH] switch all filesystems over to d_obtain_alias
authorChristoph Hellwig <hch@lst.de>
Mon, 11 Aug 2008 13:49:04 +0000 (15:49 +0200)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 23 Oct 2008 09:13:01 +0000 (05:13 -0400)
Switch all users of d_alloc_anon to d_obtain_alias.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
19 files changed:
fs/dcache.c
fs/efs/namei.c
fs/exportfs/expfs.c
fs/ext2/namei.c
fs/ext3/namei.c
fs/ext4/namei.c
fs/fat/inode.c
fs/fuse/inode.c
fs/gfs2/ops_export.c
fs/isofs/export.c
fs/jfs/namei.c
fs/nfs/getroot.c
fs/ntfs/namei.c
fs/ocfs2/export.c
fs/reiserfs/inode.c
fs/reiserfs/namei.c
fs/udf/namei.c
fs/xfs/linux-2.6/xfs_export.c
fs/xfs/linux-2.6/xfs_ioctl.c

index 46fc782..d45ff7f 100644 (file)
@@ -1187,17 +1187,17 @@ struct dentry * d_alloc_anon(struct inode *inode)
  * allocating a new one.
  *
  * On successful return, the reference to the inode has been transferred
- * to the dentry.  If %NULL is returned (indicating kmalloc failure),
- * the reference on the inode has been released.  To make it easier
- * to use in export operations a NULL or IS_ERR inode may be passed in
- * and will be casted to the corresponding NULL or IS_ERR dentry.
+ * to the dentry.  In case of an error the reference on the inode is released.
+ * To make it easier to use in export operations a %NULL or IS_ERR inode may
+ * be passed in and will be the error will be propagate to the return value,
+ * with a %NULL @inode replaced by ERR_PTR(-ESTALE).
  */
 struct dentry *d_obtain_alias(struct inode *inode)
 {
        struct dentry *dentry;
 
        if (!inode)
-               return NULL;
+               return ERR_PTR(-ESTALE);
        if (IS_ERR(inode))
                return ERR_CAST(inode);
 
index 291abb1..c3fb5f9 100644 (file)
@@ -112,35 +112,14 @@ struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
 
 struct dentry *efs_get_parent(struct dentry *child)
 {
-       struct dentry *parent;
-       struct inode *inode;
+       struct dentry *parent = ERR_PTR(-ENOENT);
        efs_ino_t ino;
-       long error;
 
        lock_kernel();
-
-       error = -ENOENT;
        ino = efs_find_entry(child->d_inode, "..", 2);
-       if (!ino)
-               goto fail;
-
-       inode = efs_iget(child->d_inode->i_sb, ino);
-       if (IS_ERR(inode)) {
-               error = PTR_ERR(inode);
-               goto fail;
-       }
-
-       error = -ENOMEM;
-       parent = d_alloc_anon(inode);
-       if (!parent)
-               goto fail_iput;
-
+       if (ino)
+               parent = d_obtain_alias(efs_iget(child->d_inode->i_sb, ino));
        unlock_kernel();
-       return parent;
 
- fail_iput:
-       iput(inode);
- fail:
-       unlock_kernel();
-       return ERR_PTR(error);
+       return parent;
 }
index cc91227..7b0f75d 100644 (file)
@@ -366,8 +366,6 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
         * Try to get any dentry for the given file handle from the filesystem.
         */
        result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
-       if (!result)
-               result = ERR_PTR(-ESTALE);
        if (IS_ERR(result))
                return result;
 
@@ -422,8 +420,6 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
 
                target_dir = nop->fh_to_parent(mnt->mnt_sb, fid,
                                fh_len, fileid_type);
-               if (!target_dir)
-                       goto err_result;
                err = PTR_ERR(target_dir);
                if (IS_ERR(target_dir))
                        goto err_result;
index 80c97fd..a1b328a 100644 (file)
@@ -73,8 +73,6 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, str
 struct dentry *ext2_get_parent(struct dentry *child)
 {
        unsigned long ino;
-       struct dentry *parent;
-       struct inode *inode;
        struct dentry dotdot;
 
        dotdot.d_name.name = "..";
@@ -83,16 +81,7 @@ struct dentry *ext2_get_parent(struct dentry *child)
        ino = ext2_inode_by_name(child->d_inode, &dotdot);
        if (!ino)
                return ERR_PTR(-ENOENT);
-       inode = ext2_iget(child->d_inode->i_sb, ino);
-
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
-       return parent;
+       return d_obtain_alias(ext2_iget(child->d_inode->i_sb, ino));
 } 
 
 /*
index de13e91..880b544 100644 (file)
@@ -1057,8 +1057,6 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, str
 struct dentry *ext3_get_parent(struct dentry *child)
 {
        unsigned long ino;
-       struct dentry *parent;
-       struct inode *inode;
        struct dentry dotdot;
        struct ext3_dir_entry_2 * de;
        struct buffer_head *bh;
@@ -1068,7 +1066,6 @@ struct dentry *ext3_get_parent(struct dentry *child)
        dotdot.d_parent = child; /* confusing, isn't it! */
 
        bh = ext3_find_entry(&dotdot, &de);
-       inode = NULL;
        if (!bh)
                return ERR_PTR(-ENOENT);
        ino = le32_to_cpu(de->inode);
@@ -1080,16 +1077,7 @@ struct dentry *ext3_get_parent(struct dentry *child)
                return ERR_PTR(-EIO);
        }
 
-       inode = ext3_iget(child->d_inode->i_sb, ino);
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
-       return parent;
+       return d_obtain_alias(ext3_iget(child->d_inode->i_sb, ino));
 }
 
 #define S_SHIFT 12
index 92db9e9..5b93a7d 100644 (file)
@@ -1083,16 +1083,7 @@ struct dentry *ext4_get_parent(struct dentry *child)
                return ERR_PTR(-EIO);
        }
 
-       inode = ext4_iget(child->d_inode->i_sb, ino);
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
-       return parent;
+       return d_obtain_alias(ext4_iget(child->d_inode->i_sb, ino));
 }
 
 #define S_SHIFT 12
index d12cdf2..19eafbe 100644 (file)
@@ -681,33 +681,24 @@ static struct dentry *fat_fh_to_dentry(struct super_block *sb,
                        inode = NULL;
                }
        }
-       if (!inode) {
-               /* For now, do nothing
-                * What we could do is:
-                * follow the file starting at fh[4], and record
-                * the ".." entry, and the name of the fh[2] entry.
-                * The follow the ".." file finding the next step up.
-                * This way we build a path to the root of
-                * the tree. If this works, we lookup the path and so
-                * get this inode into the cache.
-                * Finally try the fat_iget lookup again
-                * If that fails, then weare totally out of luck
-                * But all that is for another day
-                */
-       }
-       if (!inode)
-               return ERR_PTR(-ESTALE);
-
 
-       /* now to find a dentry.
-        * If possible, get a well-connected one
+       /*
+        * For now, do nothing if the inode is not found.
+        *
+        * What we could do is:
+        *
+        *      - follow the file starting at fh[4], and record the ".." entry,
+        *        and the name of the fh[2] entry.
+        *      - then follow the ".." file finding the next step up.
+        *
+        * This way we build a path to the root of the tree. If this works, we
+        * lookup the path and so get this inode into the cache.  Finally try
+        * the fat_iget lookup again.  If that fails, then we are totally out
+        * of luck.  But all that is for another day
         */
-       result = d_alloc_anon(inode);
-       if (result == NULL) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       result->d_op = sb->s_root->d_op;
+       result = d_obtain_alias(inode);
+       if (!IS_ERR(result))
+               result->d_op = sb->s_root->d_op;
        return result;
 }
 
@@ -754,15 +745,8 @@ static struct dentry *fat_get_parent(struct dentry *child)
        }
        inode = fat_build_inode(sb, de, i_pos);
        brelse(bh);
-       if (IS_ERR(inode)) {
-               parent = ERR_CAST(inode);
-               goto out;
-       }
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
+
+       parent = d_obtain_alias(inode);
 out:
        unlock_super(sb);
 
index 54b1f0e..2e99f34 100644 (file)
@@ -596,12 +596,8 @@ static struct dentry *fuse_get_dentry(struct super_block *sb,
        if (inode->i_generation != handle->generation)
                goto out_iput;
 
-       entry = d_alloc_anon(inode);
-       err = -ENOMEM;
-       if (!entry)
-               goto out_iput;
-
-       if (get_node_id(inode) != FUSE_ROOT_ID) {
+       entry = d_obtain_alias(inode);
+       if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) {
                entry->d_op = &fuse_dentry_operations;
                fuse_invalidate_entry_cache(entry);
        }
@@ -696,17 +692,14 @@ static struct dentry *fuse_get_parent(struct dentry *child)
        name.name = "..";
        err = fuse_lookup_name(child_inode->i_sb, get_node_id(child_inode),
                               &name, &outarg, &inode);
-       if (err && err != -ENOENT)
+       if (err) {
+               if (err == -ENOENT)
+                       return ERR_PTR(-ESTALE);
                return ERR_PTR(err);
-       if (err || !inode)
-               return ERR_PTR(-ESTALE);
-
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
        }
-       if (get_node_id(inode) != FUSE_ROOT_ID) {
+
+       parent = d_obtain_alias(inode);
+       if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) {
                parent->d_op = &fuse_dentry_operations;
                fuse_invalidate_entry_cache(parent);
        }
index 9cda853..bbb8c36 100644 (file)
@@ -130,28 +130,17 @@ static int gfs2_get_name(struct dentry *parent, char *name,
 static struct dentry *gfs2_get_parent(struct dentry *child)
 {
        struct qstr dotdot;
-       struct inode *inode;
        struct dentry *dentry;
 
-       gfs2_str2qstr(&dotdot, "..");
-       inode = gfs2_lookupi(child->d_inode, &dotdot, 1);
-
-       if (!inode)
-               return ERR_PTR(-ENOENT);
        /*
-        * In case of an error, @inode carries the error value, and we
-        * have to return that as a(n invalid) pointer to dentry.
+        * XXX(hch): it would be a good idea to keep this around as a
+        *           static variable.
         */
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-
-       dentry = d_alloc_anon(inode);
-       if (!dentry) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
+       gfs2_str2qstr(&dotdot, "..");
 
-       dentry->d_op = &gfs2_dops;
+       dentry = d_obtain_alias(gfs2_lookupi(child->d_inode, &dotdot, 1));
+       if (!IS_ERR(dentry))
+               dentry->d_op = &gfs2_dops;
        return dentry;
 }
 
@@ -233,13 +222,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb,
        gfs2_glock_dq_uninit(&i_gh);
 
 out_inode:
-       dentry = d_alloc_anon(inode);
-       if (!dentry) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-
-       dentry->d_op = &gfs2_dops;
+       dentry = d_obtain_alias(inode);
+       if (!IS_ERR(dentry))
+               dentry->d_op = &gfs2_dops;
        return dentry;
 
 fail_rgd:
index bb21913..e81a305 100644 (file)
@@ -22,7 +22,7 @@ isofs_export_iget(struct super_block *sb,
                  __u32 generation)
 {
        struct inode *inode;
-       struct dentry *result;
+
        if (block == 0)
                return ERR_PTR(-ESTALE);
        inode = isofs_iget(sb, block, offset);
@@ -32,12 +32,7 @@ isofs_export_iget(struct super_block *sb,
                iput(inode);
                return ERR_PTR(-ESTALE);
        }
-       result = d_alloc_anon(inode);
-       if (!result) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       return result;
+       return d_obtain_alias(inode);
 }
 
 /* This function is surprisingly simple.  The trick is understanding
@@ -51,7 +46,6 @@ static struct dentry *isofs_export_get_parent(struct dentry *child)
        unsigned long parent_offset = 0;
        struct inode *child_inode = child->d_inode;
        struct iso_inode_info *e_child_inode = ISOFS_I(child_inode);
-       struct inode *parent_inode = NULL;
        struct iso_directory_record *de = NULL;
        struct buffer_head * bh = NULL;
        struct dentry *rv = NULL;
@@ -104,28 +98,11 @@ static struct dentry *isofs_export_get_parent(struct dentry *child)
        /* Normalize */
        isofs_normalize_block_and_offset(de, &parent_block, &parent_offset);
 
-       /* Get the inode. */
-       parent_inode = isofs_iget(child_inode->i_sb,
-                                 parent_block,
-                                 parent_offset);
-       if (IS_ERR(parent_inode)) {
-               rv = ERR_CAST(parent_inode);
-               if (rv != ERR_PTR(-ENOMEM))
-                       rv = ERR_PTR(-EACCES);
-               goto out;
-       }
-
-       /* Allocate the dentry. */
-       rv = d_alloc_anon(parent_inode);
-       if (rv == NULL) {
-               rv = ERR_PTR(-ENOMEM);
-               goto out;
-       }
-
+       rv = d_obtain_alias(isofs_iget(child_inode->i_sb, parent_block,
+                                    parent_offset));
  out:
-       if (bh) {
+       if (bh)
                brelse(bh);
-       }
        return rv;
 }
 
index 2aba823..e199dde 100644 (file)
@@ -1511,25 +1511,12 @@ struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
 
 struct dentry *jfs_get_parent(struct dentry *dentry)
 {
-       struct super_block *sb = dentry->d_inode->i_sb;
-       struct dentry *parent = ERR_PTR(-ENOENT);
-       struct inode *inode;
        unsigned long parent_ino;
 
        parent_ino =
                le32_to_cpu(JFS_IP(dentry->d_inode)->i_dtroot.header.idotdot);
-       inode = jfs_iget(sb, parent_ino);
-       if (IS_ERR(inode)) {
-               parent = ERR_CAST(inode);
-       } else {
-               parent = d_alloc_anon(inode);
-               if (!parent) {
-                       parent = ERR_PTR(-ENOMEM);
-                       iput(inode);
-               }
-       }
 
-       return parent;
+       return d_obtain_alias(jfs_iget(dentry->d_inode->i_sb, parent_ino));
 }
 
 const struct inode_operations jfs_dir_inode_operations = {
index fae9719..b7c9b2d 100644 (file)
@@ -107,11 +107,10 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
         * if the dentry tree reaches them; however if the dentry already
         * exists, we'll pick it up at this point and use it as the root
         */
-       mntroot = d_alloc_anon(inode);
-       if (!mntroot) {
-               iput(inode);
+       mntroot = d_obtain_alias(inode);
+       if (IS_ERR(mntroot)) {
                dprintk("nfs_get_root: get root dentry failed\n");
-               return ERR_PTR(-ENOMEM);
+               return mntroot;
        }
 
        security_d_instantiate(mntroot, inode);
@@ -277,11 +276,10 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
         * if the dentry tree reaches them; however if the dentry already
         * exists, we'll pick it up at this point and use it as the root
         */
-       mntroot = d_alloc_anon(inode);
-       if (!mntroot) {
-               iput(inode);
+       mntroot = d_obtain_alias(inode);
+       if (IS_ERR(mntroot)) {
                dprintk("nfs_get_root: get root dentry failed\n");
-               return ERR_PTR(-ENOMEM);
+               return mntroot;
        }
 
        security_d_instantiate(mntroot, inode);
index 9e8a95b..2ca0015 100644 (file)
@@ -304,8 +304,6 @@ static struct dentry *ntfs_get_parent(struct dentry *child_dent)
        ntfs_attr_search_ctx *ctx;
        ATTR_RECORD *attr;
        FILE_NAME_ATTR *fn;
-       struct inode *parent_vi;
-       struct dentry *parent_dent;
        unsigned long parent_ino;
        int err;
 
@@ -345,24 +343,8 @@ try_next:
        /* Release the search context and the mft record of the child. */
        ntfs_attr_put_search_ctx(ctx);
        unmap_mft_record(ni);
-       /* Get the inode of the parent directory. */
-       parent_vi = ntfs_iget(vi->i_sb, parent_ino);
-       if (IS_ERR(parent_vi) || unlikely(is_bad_inode(parent_vi))) {
-               if (!IS_ERR(parent_vi))
-                       iput(parent_vi);
-               ntfs_error(vi->i_sb, "Failed to get parent directory inode "
-                               "0x%lx of child inode 0x%lx.", parent_ino,
-                               vi->i_ino);
-               return ERR_PTR(-EACCES);
-       }
-       /* Finally get a dentry for the parent directory and return it. */
-       parent_dent = d_alloc_anon(parent_vi);
-       if (unlikely(!parent_dent)) {
-               iput(parent_vi);
-               return ERR_PTR(-ENOMEM);
-       }
-       ntfs_debug("Done for inode 0x%lx.", vi->i_ino);
-       return parent_dent;
+
+       return d_obtain_alias(ntfs_iget(vi->i_sb, parent_ino));
 }
 
 static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
index 67527ce..2f27b33 100644 (file)
@@ -68,14 +68,9 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb,
                return ERR_PTR(-ESTALE);
        }
 
-       result = d_alloc_anon(inode);
-
-       if (!result) {
-               iput(inode);
-               mlog_errno(-ENOMEM);
-               return ERR_PTR(-ENOMEM);
-       }
-       result->d_op = &ocfs2_dentry_ops;
+       result = d_obtain_alias(inode);
+       if (!IS_ERR(result))
+               result->d_op = &ocfs2_dentry_ops;
 
        mlog_exit_ptr(result);
        return result;
@@ -86,7 +81,6 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
        int status;
        u64 blkno;
        struct dentry *parent;
-       struct inode *inode;
        struct inode *dir = child->d_inode;
 
        mlog_entry("(0x%p, '%.*s')\n", child,
@@ -109,21 +103,9 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
                goto bail_unlock;
        }
 
-       inode = ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0);
-       if (IS_ERR(inode)) {
-               mlog(ML_ERROR, "Unable to create inode %llu\n",
-                    (unsigned long long)blkno);
-               parent = ERR_PTR(-EACCES);
-               goto bail_unlock;
-       }
-
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
-
-       parent->d_op = &ocfs2_dentry_ops;
+       parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0));
+       if (!IS_ERR(parent))
+               parent->d_op = &ocfs2_dentry_ops;
 
 bail_unlock:
        ocfs2_inode_unlock(dir, 0);
index 5699171..6c4c2c6 100644 (file)
@@ -1522,7 +1522,6 @@ static struct dentry *reiserfs_get_dentry(struct super_block *sb,
 
 {
        struct cpu_key key;
-       struct dentry *result;
        struct inode *inode;
 
        key.on_disk_key.k_objectid = objectid;
@@ -1535,16 +1534,8 @@ static struct dentry *reiserfs_get_dentry(struct super_block *sb,
                inode = NULL;
        }
        reiserfs_write_unlock(sb);
-       if (!inode)
-               inode = ERR_PTR(-ESTALE);
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-       result = d_alloc_anon(inode);
-       if (!result) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       return result;
+
+       return d_obtain_alias(inode);
 }
 
 struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
index c1add28..f89ebb9 100644 (file)
@@ -383,7 +383,6 @@ struct dentry *reiserfs_get_parent(struct dentry *child)
        struct inode *inode = NULL;
        struct reiserfs_dir_entry de;
        INITIALIZE_PATH(path_to_entry);
-       struct dentry *parent;
        struct inode *dir = child->d_inode;
 
        if (dir->i_nlink == 0) {
@@ -401,15 +400,7 @@ struct dentry *reiserfs_get_parent(struct dentry *child)
        inode = reiserfs_iget(dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
        reiserfs_write_unlock(dir->i_sb);
 
-       if (!inode || IS_ERR(inode)) {
-               return ERR_PTR(-EACCES);
-       }
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
-       return parent;
+       return d_obtain_alias(inode);
 }
 
 /* add entry to the directory (entry can be hidden). 
index d323194..7578fae 100644 (file)
@@ -1243,7 +1243,6 @@ end_rename:
 
 static struct dentry *udf_get_parent(struct dentry *child)
 {
-       struct dentry *parent;
        struct inode *inode = NULL;
        struct dentry dotdot;
        struct fileIdentDesc cfi;
@@ -1266,13 +1265,7 @@ static struct dentry *udf_get_parent(struct dentry *child)
                goto out_unlock;
        unlock_kernel();
 
-       parent = d_alloc_anon(inode);
-       if (!parent) {
-               iput(inode);
-               parent = ERR_PTR(-ENOMEM);
-       }
-
-       return parent;
+       return d_obtain_alias(inode);
 out_unlock:
        unlock_kernel();
        return ERR_PTR(-EACCES);
@@ -1283,7 +1276,6 @@ static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block,
                                        u16 partref, __u32 generation)
 {
        struct inode *inode;
-       struct dentry *result;
        kernel_lb_addr loc;
 
        if (block == 0)
@@ -1300,12 +1292,7 @@ static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block,
                iput(inode);
                return ERR_PTR(-ESTALE);
        }
-       result = d_alloc_anon(inode);
-       if (!result) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       return result;
+       return d_obtain_alias(inode);
 }
 
 static struct dentry *udf_fh_to_dentry(struct super_block *sb,
index 24fd598..7f7abec 100644 (file)
@@ -148,7 +148,6 @@ xfs_fs_fh_to_dentry(struct super_block *sb, struct fid *fid,
 {
        struct xfs_fid64        *fid64 = (struct xfs_fid64 *)fid;
        struct inode            *inode = NULL;
-       struct dentry           *result;
 
        if (fh_len < xfs_fileid_length(fileid_type))
                return NULL;
@@ -164,16 +163,7 @@ xfs_fs_fh_to_dentry(struct super_block *sb, struct fid *fid,
                break;
        }
 
-       if (!inode)
-               return NULL;
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-       result = d_alloc_anon(inode);
-       if (!result) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       return result;
+       return d_obtain_alias(inode);
 }
 
 STATIC struct dentry *
@@ -182,7 +172,6 @@ xfs_fs_fh_to_parent(struct super_block *sb, struct fid *fid,
 {
        struct xfs_fid64        *fid64 = (struct xfs_fid64 *)fid;
        struct inode            *inode = NULL;
-       struct dentry           *result;
 
        switch (fileid_type) {
        case FILEID_INO32_GEN_PARENT:
@@ -195,16 +184,7 @@ xfs_fs_fh_to_parent(struct super_block *sb, struct fid *fid,
                break;
        }
 
-       if (!inode)
-               return NULL;
-       if (IS_ERR(inode))
-               return ERR_CAST(inode);
-       result = d_alloc_anon(inode);
-       if (!result) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       return result;
+       return d_obtain_alias(inode);
 }
 
 STATIC struct dentry *
@@ -213,18 +193,12 @@ xfs_fs_get_parent(
 {
        int                     error;
        struct xfs_inode        *cip;
-       struct dentry           *parent;
 
        error = xfs_lookup(XFS_I(child->d_inode), &xfs_name_dotdot, &cip, NULL);
        if (unlikely(error))
                return ERR_PTR(-error);
 
-       parent = d_alloc_anon(VFS_I(cip));
-       if (unlikely(!parent)) {
-               iput(VFS_I(cip));
-               return ERR_PTR(-ENOMEM);
-       }
-       return parent;
+       return d_obtain_alias(VFS_I(cip));
 }
 
 const struct export_operations xfs_export_operations = {
index 48799ba..d3438c7 100644 (file)
@@ -311,11 +311,10 @@ xfs_open_by_handle(
                return new_fd;
        }
 
-       dentry = d_alloc_anon(inode);
-       if (dentry == NULL) {
-               iput(inode);
+       dentry = d_obtain_alias(inode);
+       if (IS_ERR(dentry)) {
                put_unused_fd(new_fd);
-               return -XFS_ERROR(ENOMEM);
+               return PTR_ERR(dentry);
        }
 
        /* Ensure umount returns EBUSY on umounts while this file is open. */