Merge tag 'drm-next-2020-12-24' of git://anongit.freedesktop.org/drm/drm
[linux-2.6-microblaze.git] / fs / 9p / vfs_inode_dotl.c
index 0028ecc..823c2eb 100644 (file)
@@ -296,6 +296,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
 
        /* instantiate inode and assign the unopened fid to the dentry */
        fid = p9_client_walk(dfid, 1, &name, 1);
+       p9_client_clunk(dfid);
        if (IS_ERR(fid)) {
                err = PTR_ERR(fid);
                p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
@@ -342,6 +343,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
        file->private_data = ofid;
        if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
                v9fs_cache_inode_set_cookie(inode, file);
+       v9fs_open_fid_add(inode, ofid);
        file->f_mode |= FMODE_CREATED;
 out:
        v9fs_put_acl(dacl, pacl);
@@ -407,7 +409,6 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
        err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
        if (err < 0)
                goto error;
-
        fid = p9_client_walk(dfid, 1, &name, 1);
        if (IS_ERR(fid)) {
                err = PTR_ERR(fid);
@@ -451,6 +452,7 @@ error:
        if (fid)
                p9_client_clunk(fid);
        v9fs_put_acl(dacl, pacl);
+       p9_client_clunk(dfid);
        return err;
 }
 
@@ -478,6 +480,7 @@ v9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat,
         */
 
        st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
+       p9_client_clunk(fid);
        if (IS_ERR(st))
                return PTR_ERR(st);
 
@@ -539,7 +542,7 @@ static int v9fs_mapped_iattr_valid(int iattr_valid)
 
 int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
 {
-       int retval;
+       int retval, use_dentry = 0;
        struct p9_fid *fid = NULL;
        struct p9_iattr_dotl p9attr;
        struct inode *inode = d_inode(dentry);
@@ -564,8 +567,10 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
                fid = iattr->ia_file->private_data;
                WARN_ON(!fid);
        }
-       if (!fid)
+       if (!fid) {
                fid = v9fs_fid_lookup(dentry);
+               use_dentry = 1;
+       }
        if (IS_ERR(fid))
                return PTR_ERR(fid);
 
@@ -574,8 +579,11 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
                filemap_write_and_wait(inode->i_mapping);
 
        retval = p9_client_setattr(fid, &p9attr);
-       if (retval < 0)
+       if (retval < 0) {
+               if (use_dentry)
+                       p9_client_clunk(fid);
                return retval;
+       }
 
        if ((iattr->ia_valid & ATTR_SIZE) &&
            iattr->ia_size != i_size_read(inode))
@@ -587,9 +595,15 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
        if (iattr->ia_valid & ATTR_MODE) {
                /* We also want to update ACL when we update mode bits */
                retval = v9fs_acl_chmod(inode, fid);
-               if (retval < 0)
+               if (retval < 0) {
+                       if (use_dentry)
+                               p9_client_clunk(fid);
                        return retval;
+               }
        }
+       if (use_dentry)
+               p9_client_clunk(fid);
+
        return 0;
 }
 
@@ -741,6 +755,7 @@ error:
        if (fid)
                p9_client_clunk(fid);
 
+       p9_client_clunk(dfid);
        return err;
 }
 
@@ -769,11 +784,15 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
                return PTR_ERR(dfid);
 
        oldfid = v9fs_fid_lookup(old_dentry);
-       if (IS_ERR(oldfid))
+       if (IS_ERR(oldfid)) {
+               p9_client_clunk(dfid);
                return PTR_ERR(oldfid);
+       }
 
        err = p9_client_link(dfid, oldfid, dentry->d_name.name);
 
+       p9_client_clunk(dfid);
+       p9_client_clunk(oldfid);
        if (err < 0) {
                p9_debug(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
                return err;
@@ -788,6 +807,7 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
                        return PTR_ERR(fid);
 
                v9fs_refresh_inode_dotl(fid, d_inode(old_dentry));
+               p9_client_clunk(fid);
        }
        ihold(d_inode(old_dentry));
        d_instantiate(dentry, d_inode(old_dentry));
@@ -886,6 +906,8 @@ error:
        if (fid)
                p9_client_clunk(fid);
        v9fs_put_acl(dacl, pacl);
+       p9_client_clunk(dfid);
+
        return err;
 }
 
@@ -914,6 +936,7 @@ v9fs_vfs_get_link_dotl(struct dentry *dentry,
        if (IS_ERR(fid))
                return ERR_CAST(fid);
        retval = p9_client_readlink(fid, &target);
+       p9_client_clunk(fid);
        if (retval)
                return ERR_PTR(retval);
        set_delayed_call(done, kfree_link, target);