]> Pileus Git - ~andy/linux/blobdiff - fs/9p/vfs_inode_dotl.c
Merge tag 'imx-fixes' of git://git.pengutronix.de/git/imx/linux-2.6 into fixes
[~andy/linux] / fs / 9p / vfs_inode_dotl.c
index e3dd2a1e2bfc18e47abae82bce7ee60238527c08..40895546e103e3e9b35e9542e23ac929d74de348 100644 (file)
@@ -230,20 +230,25 @@ int v9fs_open_to_dotl_flags(int flags)
  * @dir: directory inode that is being created
  * @dentry:  dentry that is being deleted
  * @mode: create permissions
- * @nd: path information
  *
  */
 
 static int
 v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
-               struct nameidata *nd)
+               bool excl)
+{
+       return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
+}
+
+static int
+v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
+                         struct file *file, unsigned flags, umode_t omode,
+                         int *opened)
 {
        int err = 0;
        gid_t gid;
-       int flags;
        umode_t mode;
        char *name = NULL;
-       struct file *filp;
        struct p9_qid qid;
        struct inode *inode;
        struct p9_fid *fid = NULL;
@@ -251,19 +256,23 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
        struct p9_fid *dfid, *ofid, *inode_fid;
        struct v9fs_session_info *v9ses;
        struct posix_acl *pacl = NULL, *dacl = NULL;
+       struct dentry *res = NULL;
 
-       v9ses = v9fs_inode2v9ses(dir);
-       if (nd)
-               flags = nd->intent.open.flags;
-       else {
-               /*
-                * create call without LOOKUP_OPEN is due
-                * to mknod of regular files. So use mknod
-                * operation.
-                */
-               return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
+       if (d_unhashed(dentry)) {
+               res = v9fs_vfs_lookup(dir, dentry, 0);
+               if (IS_ERR(res))
+                       return PTR_ERR(res);
+
+               if (res)
+                       dentry = res;
        }
 
+       /* Only creates */
+       if (!(flags & O_CREAT) || dentry->d_inode)
+               return finish_no_open(file, res);
+
+       v9ses = v9fs_inode2v9ses(dir);
+
        name = (char *) dentry->d_name.name;
        p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%hx\n",
                 name, flags, omode);
@@ -272,7 +281,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
        if (IS_ERR(dfid)) {
                err = PTR_ERR(dfid);
                p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
-               return err;
+               goto out;
        }
 
        /* clone a fid to use for creation */
@@ -280,7 +289,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
        if (IS_ERR(ofid)) {
                err = PTR_ERR(ofid);
                p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
-               return err;
+               goto out;
        }
 
        gid = v9fs_get_fsgid_for_create(dir);
@@ -345,17 +354,18 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
        }
        mutex_unlock(&v9inode->v_mutex);
        /* Since we are opening a file, assign the open fid to the file */
-       filp = lookup_instantiate_filp(nd, dentry, generic_file_open);
-       if (IS_ERR(filp)) {
-               err = PTR_ERR(filp);
+       err = finish_open(file, dentry, generic_file_open, opened);
+       if (err)
                goto err_clunk_old_fid;
-       }
-       filp->private_data = ofid;
+       file->private_data = ofid;
 #ifdef CONFIG_9P_FSCACHE
        if (v9ses->cache)
-               v9fs_cache_inode_set_cookie(inode, filp);
+               v9fs_cache_inode_set_cookie(inode, file);
 #endif
-       return 0;
+       *opened |= FILE_CREATED;
+out:
+       dput(res);
+       return err;
 
 error:
        if (fid)
@@ -364,7 +374,7 @@ err_clunk_old_fid:
        if (ofid)
                p9_client_clunk(ofid);
        v9fs_set_create_acl(NULL, &dacl, &pacl);
-       return err;
+       goto out;
 }
 
 /**
@@ -982,6 +992,7 @@ out:
 
 const struct inode_operations v9fs_dir_inode_operations_dotl = {
        .create = v9fs_vfs_create_dotl,
+       .atomic_open = v9fs_vfs_atomic_open_dotl,
        .lookup = v9fs_vfs_lookup,
        .link = v9fs_vfs_link_dotl,
        .symlink = v9fs_vfs_symlink_dotl,