x86/efi: Clean up a minor mistake in comment
[linux-2.6-microblaze.git] / fs / namei.c
index 07e292b..d41fab7 100644 (file)
@@ -3363,13 +3363,50 @@ out:
        return error;
 }
 
+struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, int open_flag)
+{
+       static const struct qstr name = QSTR_INIT("/", 1);
+       struct dentry *child = NULL;
+       struct inode *dir = dentry->d_inode;
+       struct inode *inode;
+       int error;
+
+       /* we want directory to be writable */
+       error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
+       if (error)
+               goto out_err;
+       error = -EOPNOTSUPP;
+       if (!dir->i_op->tmpfile)
+               goto out_err;
+       error = -ENOMEM;
+       child = d_alloc(dentry, &name);
+       if (unlikely(!child))
+               goto out_err;
+       error = dir->i_op->tmpfile(dir, child, mode);
+       if (error)
+               goto out_err;
+       error = -ENOENT;
+       inode = child->d_inode;
+       if (unlikely(!inode))
+               goto out_err;
+       if (!(open_flag & O_EXCL)) {
+               spin_lock(&inode->i_lock);
+               inode->i_state |= I_LINKABLE;
+               spin_unlock(&inode->i_lock);
+       }
+       return child;
+
+out_err:
+       dput(child);
+       return ERR_PTR(error);
+}
+EXPORT_SYMBOL(vfs_tmpfile);
+
 static int do_tmpfile(struct nameidata *nd, unsigned flags,
                const struct open_flags *op,
                struct file *file, int *opened)
 {
-       static const struct qstr name = QSTR_INIT("/", 1);
        struct dentry *child;
-       struct inode *dir;
        struct path path;
        int error = path_lookupat(nd, flags | LOOKUP_DIRECTORY, &path);
        if (unlikely(error))
@@ -3377,25 +3414,12 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags,
        error = mnt_want_write(path.mnt);
        if (unlikely(error))
                goto out;
-       dir = path.dentry->d_inode;
-       /* we want directory to be writable */
-       error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
-       if (error)
-               goto out2;
-       if (!dir->i_op->tmpfile) {
-               error = -EOPNOTSUPP;
-               goto out2;
-       }
-       child = d_alloc(path.dentry, &name);
-       if (unlikely(!child)) {
-               error = -ENOMEM;
+       child = vfs_tmpfile(path.dentry, op->mode, op->open_flag);
+       error = PTR_ERR(child);
+       if (unlikely(IS_ERR(child)))
                goto out2;
-       }
        dput(path.dentry);
        path.dentry = child;
-       error = dir->i_op->tmpfile(dir, child, op->mode);
-       if (error)
-               goto out2;
        audit_inode(nd->name, child, 0);
        /* Don't check for other permissions, the inode was just created */
        error = may_open(&path, 0, op->open_flag);
@@ -3406,14 +3430,8 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags,
        if (error)
                goto out2;
        error = open_check_o_direct(file);
-       if (error) {
+       if (error)
                fput(file);
-       } else if (!(op->open_flag & O_EXCL)) {
-               struct inode *inode = file_inode(file);
-               spin_lock(&inode->i_lock);
-               inode->i_state |= I_LINKABLE;
-               spin_unlock(&inode->i_lock);
-       }
 out2:
        mnt_drop_write(path.mnt);
 out: