Commit b48dbb99 authored by Dominique Martinet's avatar Dominique Martinet Committed by Dominique Martinet

9p fid refcount: add p9_fid_get/put wrappers

I was recently reminded that it is not clear that p9_client_clunk()
was actually just decrementing refcount and clunking only when that
reaches zero: make it clear through a set of helpers.

This will also allow instrumenting refcounting better for debugging
next patch

Link: https://lkml.kernel.org/r/20220612085330.1451496-5-asmadeus@codewreck.orgReviewed-by: default avatarTyler Hicks <tyhicks@linux.microsoft.com>
Reviewed-by: default avatarChristian Schoenebeck <linux_oss@crudebyte.com>
Signed-off-by: default avatarDominique Martinet <asmadeus@codewreck.org>
parent b296d057
...@@ -56,7 +56,7 @@ static struct p9_fid *v9fs_fid_find_inode(struct inode *inode, kuid_t uid) ...@@ -56,7 +56,7 @@ static struct p9_fid *v9fs_fid_find_inode(struct inode *inode, kuid_t uid)
h = (struct hlist_head *)&inode->i_private; h = (struct hlist_head *)&inode->i_private;
hlist_for_each_entry(fid, h, ilist) { hlist_for_each_entry(fid, h, ilist) {
if (uid_eq(fid->uid, uid)) { if (uid_eq(fid->uid, uid)) {
refcount_inc(&fid->count); p9_fid_get(fid);
ret = fid; ret = fid;
break; break;
} }
...@@ -104,7 +104,7 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any) ...@@ -104,7 +104,7 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
hlist_for_each_entry(fid, h, dlist) { hlist_for_each_entry(fid, h, dlist) {
if (any || uid_eq(fid->uid, uid)) { if (any || uid_eq(fid->uid, uid)) {
ret = fid; ret = fid;
refcount_inc(&ret->count); p9_fid_get(ret);
break; break;
} }
} }
...@@ -172,7 +172,7 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry, ...@@ -172,7 +172,7 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
old_fid = fid; old_fid = fid;
fid = p9_client_walk(old_fid, 1, &dentry->d_name.name, 1); fid = p9_client_walk(old_fid, 1, &dentry->d_name.name, 1);
p9_client_clunk(old_fid); p9_fid_put(old_fid);
goto fid_out; goto fid_out;
} }
up_read(&v9ses->rename_sem); up_read(&v9ses->rename_sem);
...@@ -194,7 +194,7 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry, ...@@ -194,7 +194,7 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
if (IS_ERR(root_fid)) if (IS_ERR(root_fid))
return root_fid; return root_fid;
refcount_inc(&root_fid->count); p9_fid_get(root_fid);
v9fs_fid_add(dentry->d_sb->s_root, root_fid); v9fs_fid_add(dentry->d_sb->s_root, root_fid);
} }
/* If we are root ourself just return that */ /* If we are root ourself just return that */
...@@ -225,7 +225,7 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry, ...@@ -225,7 +225,7 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
old_fid == root_fid /* clone */); old_fid == root_fid /* clone */);
/* non-cloning walk will return the same fid */ /* non-cloning walk will return the same fid */
if (fid != old_fid) { if (fid != old_fid) {
p9_client_clunk(old_fid); p9_fid_put(old_fid);
old_fid = fid; old_fid = fid;
} }
if (IS_ERR(fid)) { if (IS_ERR(fid)) {
...@@ -240,11 +240,11 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry, ...@@ -240,11 +240,11 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
spin_lock(&dentry->d_lock); spin_lock(&dentry->d_lock);
if (d_unhashed(dentry)) { if (d_unhashed(dentry)) {
spin_unlock(&dentry->d_lock); spin_unlock(&dentry->d_lock);
p9_client_clunk(fid); p9_fid_put(fid);
fid = ERR_PTR(-ENOENT); fid = ERR_PTR(-ENOENT);
} else { } else {
__add_fid(dentry, fid); __add_fid(dentry, fid);
refcount_inc(&fid->count); p9_fid_get(fid);
spin_unlock(&dentry->d_lock); spin_unlock(&dentry->d_lock);
} }
} }
...@@ -301,7 +301,7 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry) ...@@ -301,7 +301,7 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
fid = clone_fid(ofid); fid = clone_fid(ofid);
if (IS_ERR(fid)) if (IS_ERR(fid))
goto error_out; goto error_out;
p9_client_clunk(ofid); p9_fid_put(ofid);
/* /*
* writeback fid will only be used to write back the * writeback fid will only be used to write back the
* dirty pages. We always request for the open fid in read-write * dirty pages. We always request for the open fid in read-write
...@@ -310,7 +310,7 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry) ...@@ -310,7 +310,7 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
*/ */
err = p9_client_open(fid, O_RDWR); err = p9_client_open(fid, O_RDWR);
if (err < 0) { if (err < 0) {
p9_client_clunk(fid); p9_fid_put(fid);
fid = ERR_PTR(err); fid = ERR_PTR(err);
goto error_out; goto error_out;
} }
......
...@@ -29,7 +29,7 @@ static inline struct p9_fid *v9fs_fid_clone(struct dentry *dentry) ...@@ -29,7 +29,7 @@ static inline struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
return fid; return fid;
nfid = clone_fid(fid); nfid = clone_fid(fid);
p9_client_clunk(fid); p9_fid_put(fid);
return nfid; return nfid;
} }
#endif #endif
...@@ -73,7 +73,7 @@ static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file) ...@@ -73,7 +73,7 @@ static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file)
BUG_ON(!fid); BUG_ON(!fid);
} }
refcount_inc(&fid->count); p9_fid_get(fid);
rreq->netfs_priv = fid; rreq->netfs_priv = fid;
return 0; return 0;
} }
...@@ -86,7 +86,7 @@ static void v9fs_free_request(struct netfs_io_request *rreq) ...@@ -86,7 +86,7 @@ static void v9fs_free_request(struct netfs_io_request *rreq)
{ {
struct p9_fid *fid = rreq->netfs_priv; struct p9_fid *fid = rreq->netfs_priv;
p9_client_clunk(fid); p9_fid_put(fid);
} }
/** /**
......
...@@ -54,7 +54,7 @@ static void v9fs_dentry_release(struct dentry *dentry) ...@@ -54,7 +54,7 @@ static void v9fs_dentry_release(struct dentry *dentry)
p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n", p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n",
dentry, dentry); dentry, dentry);
hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata) hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata)
p9_client_clunk(hlist_entry(p, struct p9_fid, dlist)); p9_fid_put(hlist_entry(p, struct p9_fid, dlist));
dentry->d_fsdata = NULL; dentry->d_fsdata = NULL;
} }
...@@ -85,7 +85,7 @@ static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags) ...@@ -85,7 +85,7 @@ static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
retval = v9fs_refresh_inode_dotl(fid, inode); retval = v9fs_refresh_inode_dotl(fid, inode);
else else
retval = v9fs_refresh_inode(fid, inode); retval = v9fs_refresh_inode(fid, inode);
p9_client_clunk(fid); p9_fid_put(fid);
if (retval == -ENOENT) if (retval == -ENOENT)
return 0; return 0;
......
...@@ -218,7 +218,7 @@ int v9fs_dir_release(struct inode *inode, struct file *filp) ...@@ -218,7 +218,7 @@ int v9fs_dir_release(struct inode *inode, struct file *filp)
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
hlist_del(&fid->ilist); hlist_del(&fid->ilist);
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
p9_client_clunk(fid); p9_fid_put(fid);
} }
if ((filp->f_mode & FMODE_WRITE)) { if ((filp->f_mode & FMODE_WRITE)) {
......
...@@ -63,7 +63,7 @@ int v9fs_file_open(struct inode *inode, struct file *file) ...@@ -63,7 +63,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
err = p9_client_open(fid, omode); err = p9_client_open(fid, omode);
if (err < 0) { if (err < 0) {
p9_client_clunk(fid); p9_fid_put(fid);
return err; return err;
} }
if ((file->f_flags & O_APPEND) && if ((file->f_flags & O_APPEND) &&
...@@ -98,7 +98,7 @@ int v9fs_file_open(struct inode *inode, struct file *file) ...@@ -98,7 +98,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
v9fs_open_fid_add(inode, fid); v9fs_open_fid_add(inode, fid);
return 0; return 0;
out_error: out_error:
p9_client_clunk(file->private_data); p9_fid_put(file->private_data);
file->private_data = NULL; file->private_data = NULL;
return err; return err;
} }
......
...@@ -400,7 +400,7 @@ void v9fs_evict_inode(struct inode *inode) ...@@ -400,7 +400,7 @@ void v9fs_evict_inode(struct inode *inode)
fscache_relinquish_cookie(v9fs_inode_cookie(v9inode), false); fscache_relinquish_cookie(v9fs_inode_cookie(v9inode), false);
/* clunk the fid stashed in writeback_fid */ /* clunk the fid stashed in writeback_fid */
if (v9inode->writeback_fid) { if (v9inode->writeback_fid) {
p9_client_clunk(v9inode->writeback_fid); p9_fid_put(v9inode->writeback_fid);
v9inode->writeback_fid = NULL; v9inode->writeback_fid = NULL;
} }
} }
...@@ -569,7 +569,7 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags) ...@@ -569,7 +569,7 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
if (v9fs_proto_dotl(v9ses)) if (v9fs_proto_dotl(v9ses))
retval = p9_client_unlinkat(dfid, dentry->d_name.name, retval = p9_client_unlinkat(dfid, dentry->d_name.name,
v9fs_at_to_dotl_flags(flags)); v9fs_at_to_dotl_flags(flags));
p9_client_clunk(dfid); p9_fid_put(dfid);
if (retval == -EOPNOTSUPP) { if (retval == -EOPNOTSUPP) {
/* Try the one based on path */ /* Try the one based on path */
v9fid = v9fs_fid_clone(dentry); v9fid = v9fs_fid_clone(dentry);
...@@ -633,14 +633,14 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, ...@@ -633,14 +633,14 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
if (IS_ERR(ofid)) { if (IS_ERR(ofid)) {
err = PTR_ERR(ofid); err = PTR_ERR(ofid);
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
p9_client_clunk(dfid); p9_fid_put(dfid);
return ERR_PTR(err); return ERR_PTR(err);
} }
err = p9_client_fcreate(ofid, name, perm, mode, extension); err = p9_client_fcreate(ofid, name, perm, mode, extension);
if (err < 0) { if (err < 0) {
p9_debug(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err); p9_debug(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err);
p9_client_clunk(dfid); p9_fid_put(dfid);
goto error; goto error;
} }
...@@ -652,7 +652,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, ...@@ -652,7 +652,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
p9_debug(P9_DEBUG_VFS, p9_debug(P9_DEBUG_VFS,
"p9_client_walk failed %d\n", err); "p9_client_walk failed %d\n", err);
fid = NULL; fid = NULL;
p9_client_clunk(dfid); p9_fid_put(dfid);
goto error; goto error;
} }
/* /*
...@@ -663,20 +663,20 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, ...@@ -663,20 +663,20 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
err = PTR_ERR(inode); err = PTR_ERR(inode);
p9_debug(P9_DEBUG_VFS, p9_debug(P9_DEBUG_VFS,
"inode creation failed %d\n", err); "inode creation failed %d\n", err);
p9_client_clunk(dfid); p9_fid_put(dfid);
goto error; goto error;
} }
v9fs_fid_add(dentry, fid); v9fs_fid_add(dentry, fid);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
} }
p9_client_clunk(dfid); p9_fid_put(dfid);
return ofid; return ofid;
error: error:
if (ofid) if (ofid)
p9_client_clunk(ofid); p9_fid_put(ofid);
if (fid) if (fid)
p9_client_clunk(fid); p9_fid_put(fid);
return ERR_PTR(err); return ERR_PTR(err);
} }
...@@ -708,7 +708,7 @@ v9fs_vfs_create(struct user_namespace *mnt_userns, struct inode *dir, ...@@ -708,7 +708,7 @@ v9fs_vfs_create(struct user_namespace *mnt_userns, struct inode *dir,
return PTR_ERR(fid); return PTR_ERR(fid);
v9fs_invalidate_inode_attr(dir); v9fs_invalidate_inode_attr(dir);
p9_client_clunk(fid); p9_fid_put(fid);
return 0; return 0;
} }
...@@ -744,7 +744,7 @@ static int v9fs_vfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, ...@@ -744,7 +744,7 @@ static int v9fs_vfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
} }
if (fid) if (fid)
p9_client_clunk(fid); p9_fid_put(fid);
return err; return err;
} }
...@@ -785,7 +785,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, ...@@ -785,7 +785,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
*/ */
name = dentry->d_name.name; name = dentry->d_name.name;
fid = p9_client_walk(dfid, 1, &name, 1); fid = p9_client_walk(dfid, 1, &name, 1);
p9_client_clunk(dfid); p9_fid_put(dfid);
if (fid == ERR_PTR(-ENOENT)) if (fid == ERR_PTR(-ENOENT))
inode = NULL; inode = NULL;
else if (IS_ERR(fid)) else if (IS_ERR(fid))
...@@ -808,7 +808,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, ...@@ -808,7 +808,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
else if (!IS_ERR(res)) else if (!IS_ERR(res))
v9fs_fid_add(res, fid); v9fs_fid_add(res, fid);
else else
p9_client_clunk(fid); p9_fid_put(fid);
} }
return res; return res;
} }
...@@ -891,7 +891,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, ...@@ -891,7 +891,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
error: error:
if (fid) if (fid)
p9_client_clunk(fid); p9_fid_put(fid);
goto out; goto out;
} }
...@@ -959,7 +959,7 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, ...@@ -959,7 +959,7 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
dfid = v9fs_parent_fid(old_dentry); dfid = v9fs_parent_fid(old_dentry);
olddirfid = clone_fid(dfid); olddirfid = clone_fid(dfid);
if (dfid && !IS_ERR(dfid)) if (dfid && !IS_ERR(dfid))
p9_client_clunk(dfid); p9_fid_put(dfid);
if (IS_ERR(olddirfid)) { if (IS_ERR(olddirfid)) {
retval = PTR_ERR(olddirfid); retval = PTR_ERR(olddirfid);
...@@ -968,7 +968,7 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, ...@@ -968,7 +968,7 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
dfid = v9fs_parent_fid(new_dentry); dfid = v9fs_parent_fid(new_dentry);
newdirfid = clone_fid(dfid); newdirfid = clone_fid(dfid);
p9_client_clunk(dfid); p9_fid_put(dfid);
if (IS_ERR(newdirfid)) { if (IS_ERR(newdirfid)) {
retval = PTR_ERR(newdirfid); retval = PTR_ERR(newdirfid);
...@@ -1020,13 +1020,13 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, ...@@ -1020,13 +1020,13 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
d_move(old_dentry, new_dentry); d_move(old_dentry, new_dentry);
} }
up_write(&v9ses->rename_sem); up_write(&v9ses->rename_sem);
p9_client_clunk(newdirfid); p9_fid_put(newdirfid);
clunk_olddir: clunk_olddir:
p9_client_clunk(olddirfid); p9_fid_put(olddirfid);
done: done:
p9_client_clunk(oldfid); p9_fid_put(oldfid);
return retval; return retval;
} }
...@@ -1060,7 +1060,7 @@ v9fs_vfs_getattr(struct user_namespace *mnt_userns, const struct path *path, ...@@ -1060,7 +1060,7 @@ v9fs_vfs_getattr(struct user_namespace *mnt_userns, const struct path *path,
return PTR_ERR(fid); return PTR_ERR(fid);
st = p9_client_stat(fid); st = p9_client_stat(fid);
p9_client_clunk(fid); p9_fid_put(fid);
if (IS_ERR(st)) if (IS_ERR(st))
return PTR_ERR(st); return PTR_ERR(st);
...@@ -1136,7 +1136,7 @@ static int v9fs_vfs_setattr(struct user_namespace *mnt_userns, ...@@ -1136,7 +1136,7 @@ static int v9fs_vfs_setattr(struct user_namespace *mnt_userns,
retval = p9_client_wstat(fid, &wstat); retval = p9_client_wstat(fid, &wstat);
if (use_dentry) if (use_dentry)
p9_client_clunk(fid); p9_fid_put(fid);
if (retval < 0) if (retval < 0)
return retval; return retval;
...@@ -1261,7 +1261,7 @@ static const char *v9fs_vfs_get_link(struct dentry *dentry, ...@@ -1261,7 +1261,7 @@ static const char *v9fs_vfs_get_link(struct dentry *dentry,
return ERR_CAST(fid); return ERR_CAST(fid);
st = p9_client_stat(fid); st = p9_client_stat(fid);
p9_client_clunk(fid); p9_fid_put(fid);
if (IS_ERR(st)) if (IS_ERR(st))
return ERR_CAST(st); return ERR_CAST(st);
...@@ -1308,7 +1308,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, ...@@ -1308,7 +1308,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
return PTR_ERR(fid); return PTR_ERR(fid);
v9fs_invalidate_inode_attr(dir); v9fs_invalidate_inode_attr(dir);
p9_client_clunk(fid); p9_fid_put(fid);
return 0; return 0;
} }
...@@ -1364,7 +1364,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, ...@@ -1364,7 +1364,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
v9fs_refresh_inode(oldfid, d_inode(old_dentry)); v9fs_refresh_inode(oldfid, d_inode(old_dentry));
v9fs_invalidate_inode_attr(dir); v9fs_invalidate_inode_attr(dir);
} }
p9_client_clunk(oldfid); p9_fid_put(oldfid);
return retval; return retval;
} }
......
...@@ -274,7 +274,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, ...@@ -274,7 +274,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
if (IS_ERR(ofid)) { if (IS_ERR(ofid)) {
err = PTR_ERR(ofid); err = PTR_ERR(ofid);
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
p9_client_clunk(dfid); p9_fid_put(dfid);
goto out; goto out;
} }
...@@ -286,7 +286,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, ...@@ -286,7 +286,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
if (err) { if (err) {
p9_debug(P9_DEBUG_VFS, "Failed to get acl values in creat %d\n", p9_debug(P9_DEBUG_VFS, "Failed to get acl values in creat %d\n",
err); err);
p9_client_clunk(dfid); p9_fid_put(dfid);
goto error; goto error;
} }
err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags), err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags),
...@@ -294,14 +294,14 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, ...@@ -294,14 +294,14 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
if (err < 0) { if (err < 0) {
p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in creat %d\n", p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in creat %d\n",
err); err);
p9_client_clunk(dfid); p9_fid_put(dfid);
goto error; goto error;
} }
v9fs_invalidate_inode_attr(dir); v9fs_invalidate_inode_attr(dir);
/* instantiate inode and assign the unopened fid to the dentry */ /* instantiate inode and assign the unopened fid to the dentry */
fid = p9_client_walk(dfid, 1, &name, 1); fid = p9_client_walk(dfid, 1, &name, 1);
p9_client_clunk(dfid); p9_fid_put(dfid);
if (IS_ERR(fid)) { if (IS_ERR(fid)) {
err = PTR_ERR(fid); err = PTR_ERR(fid);
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
...@@ -358,10 +358,10 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, ...@@ -358,10 +358,10 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
error: error:
if (fid) if (fid)
p9_client_clunk(fid); p9_fid_put(fid);
err_clunk_old_fid: err_clunk_old_fid:
if (ofid) if (ofid)
p9_client_clunk(ofid); p9_fid_put(ofid);
goto out; goto out;
} }
...@@ -458,9 +458,9 @@ static int v9fs_vfs_mkdir_dotl(struct user_namespace *mnt_userns, ...@@ -458,9 +458,9 @@ static int v9fs_vfs_mkdir_dotl(struct user_namespace *mnt_userns,
v9fs_invalidate_inode_attr(dir); v9fs_invalidate_inode_attr(dir);
error: error:
if (fid) if (fid)
p9_client_clunk(fid); p9_fid_put(fid);
v9fs_put_acl(dacl, pacl); v9fs_put_acl(dacl, pacl);
p9_client_clunk(dfid); p9_fid_put(dfid);
return err; return err;
} }
...@@ -489,7 +489,7 @@ v9fs_vfs_getattr_dotl(struct user_namespace *mnt_userns, ...@@ -489,7 +489,7 @@ v9fs_vfs_getattr_dotl(struct user_namespace *mnt_userns,
*/ */
st = p9_client_getattr_dotl(fid, P9_STATS_ALL); st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
p9_client_clunk(fid); p9_fid_put(fid);
if (IS_ERR(st)) if (IS_ERR(st))
return PTR_ERR(st); return PTR_ERR(st);
...@@ -603,7 +603,7 @@ int v9fs_vfs_setattr_dotl(struct user_namespace *mnt_userns, ...@@ -603,7 +603,7 @@ int v9fs_vfs_setattr_dotl(struct user_namespace *mnt_userns,
retval = p9_client_setattr(fid, &p9attr); retval = p9_client_setattr(fid, &p9attr);
if (retval < 0) { if (retval < 0) {
if (use_dentry) if (use_dentry)
p9_client_clunk(fid); p9_fid_put(fid);
return retval; return retval;
} }
...@@ -619,12 +619,12 @@ int v9fs_vfs_setattr_dotl(struct user_namespace *mnt_userns, ...@@ -619,12 +619,12 @@ int v9fs_vfs_setattr_dotl(struct user_namespace *mnt_userns,
retval = v9fs_acl_chmod(inode, fid); retval = v9fs_acl_chmod(inode, fid);
if (retval < 0) { if (retval < 0) {
if (use_dentry) if (use_dentry)
p9_client_clunk(fid); p9_fid_put(fid);
return retval; return retval;
} }
} }
if (use_dentry) if (use_dentry)
p9_client_clunk(fid); p9_fid_put(fid);
return 0; return 0;
} }
...@@ -771,9 +771,9 @@ v9fs_vfs_symlink_dotl(struct user_namespace *mnt_userns, struct inode *dir, ...@@ -771,9 +771,9 @@ v9fs_vfs_symlink_dotl(struct user_namespace *mnt_userns, struct inode *dir,
error: error:
if (fid) if (fid)
p9_client_clunk(fid); p9_fid_put(fid);
p9_client_clunk(dfid); p9_fid_put(dfid);
return err; return err;
} }
...@@ -803,14 +803,14 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir, ...@@ -803,14 +803,14 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
oldfid = v9fs_fid_lookup(old_dentry); oldfid = v9fs_fid_lookup(old_dentry);
if (IS_ERR(oldfid)) { if (IS_ERR(oldfid)) {
p9_client_clunk(dfid); p9_fid_put(dfid);
return PTR_ERR(oldfid); return PTR_ERR(oldfid);
} }
err = p9_client_link(dfid, oldfid, dentry->d_name.name); err = p9_client_link(dfid, oldfid, dentry->d_name.name);
p9_client_clunk(dfid); p9_fid_put(dfid);
p9_client_clunk(oldfid); p9_fid_put(oldfid);
if (err < 0) { if (err < 0) {
p9_debug(P9_DEBUG_VFS, "p9_client_link failed %d\n", err); p9_debug(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
return err; return err;
...@@ -826,7 +826,7 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir, ...@@ -826,7 +826,7 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
return PTR_ERR(fid); return PTR_ERR(fid);
v9fs_refresh_inode_dotl(fid, d_inode(old_dentry)); v9fs_refresh_inode_dotl(fid, d_inode(old_dentry));
p9_client_clunk(fid); p9_fid_put(fid);
} }
ihold(d_inode(old_dentry)); ihold(d_inode(old_dentry));
d_instantiate(dentry, d_inode(old_dentry)); d_instantiate(dentry, d_inode(old_dentry));
...@@ -924,9 +924,9 @@ v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir, ...@@ -924,9 +924,9 @@ v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir,
} }
error: error:
if (fid) if (fid)
p9_client_clunk(fid); p9_fid_put(fid);
v9fs_put_acl(dacl, pacl); v9fs_put_acl(dacl, pacl);
p9_client_clunk(dfid); p9_fid_put(dfid);
return err; return err;
} }
...@@ -956,7 +956,7 @@ v9fs_vfs_get_link_dotl(struct dentry *dentry, ...@@ -956,7 +956,7 @@ v9fs_vfs_get_link_dotl(struct dentry *dentry,
if (IS_ERR(fid)) if (IS_ERR(fid))
return ERR_CAST(fid); return ERR_CAST(fid);
retval = p9_client_readlink(fid, &target); retval = p9_client_readlink(fid, &target);
p9_client_clunk(fid); p9_fid_put(fid);
if (retval) if (retval)
return ERR_PTR(retval); return ERR_PTR(retval);
set_delayed_call(done, kfree_link, target); set_delayed_call(done, kfree_link, target);
......
...@@ -190,7 +190,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, ...@@ -190,7 +190,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
return dget(sb->s_root); return dget(sb->s_root);
clunk_fid: clunk_fid:
p9_client_clunk(fid); p9_fid_put(fid);
v9fs_session_close(v9ses); v9fs_session_close(v9ses);
free_session: free_session:
kfree(v9ses); kfree(v9ses);
...@@ -203,7 +203,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, ...@@ -203,7 +203,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
* attached the fid to dentry so it won't get clunked * attached the fid to dentry so it won't get clunked
* automatically. * automatically.
*/ */
p9_client_clunk(fid); p9_fid_put(fid);
deactivate_locked_super(sb); deactivate_locked_super(sb);
return ERR_PTR(retval); return ERR_PTR(retval);
} }
...@@ -270,7 +270,7 @@ static int v9fs_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -270,7 +270,7 @@ static int v9fs_statfs(struct dentry *dentry, struct kstatfs *buf)
} }
res = simple_statfs(dentry, buf); res = simple_statfs(dentry, buf);
done: done:
p9_client_clunk(fid); p9_fid_put(fid);
return res; return res;
} }
......
...@@ -44,7 +44,7 @@ ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name, ...@@ -44,7 +44,7 @@ ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
if (err) if (err)
retval = err; retval = err;
} }
p9_client_clunk(attr_fid); p9_fid_put(attr_fid);
return retval; return retval;
} }
...@@ -71,7 +71,7 @@ ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name, ...@@ -71,7 +71,7 @@ ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name,
if (IS_ERR(fid)) if (IS_ERR(fid))
return PTR_ERR(fid); return PTR_ERR(fid);
ret = v9fs_fid_xattr_get(fid, name, buffer, buffer_size); ret = v9fs_fid_xattr_get(fid, name, buffer, buffer_size);
p9_client_clunk(fid); p9_fid_put(fid);
return ret; return ret;
} }
...@@ -98,7 +98,7 @@ int v9fs_xattr_set(struct dentry *dentry, const char *name, ...@@ -98,7 +98,7 @@ int v9fs_xattr_set(struct dentry *dentry, const char *name,
if (IS_ERR(fid)) if (IS_ERR(fid))
return PTR_ERR(fid); return PTR_ERR(fid);
ret = v9fs_fid_xattr_set(fid, name, value, value_len, flags); ret = v9fs_fid_xattr_set(fid, name, value, value_len, flags);
p9_client_clunk(fid); p9_fid_put(fid);
return ret; return ret;
} }
...@@ -128,7 +128,7 @@ int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name, ...@@ -128,7 +128,7 @@ int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
retval); retval);
else else
p9_client_write(fid, 0, &from, &retval); p9_client_write(fid, 0, &from, &retval);
err = p9_client_clunk(fid); err = p9_fid_put(fid);
if (!retval && err) if (!retval && err)
retval = err; retval = err;
return retval; return retval;
......
...@@ -237,6 +237,34 @@ static inline int p9_req_try_get(struct p9_req_t *r) ...@@ -237,6 +237,34 @@ static inline int p9_req_try_get(struct p9_req_t *r)
int p9_req_put(struct p9_req_t *r); int p9_req_put(struct p9_req_t *r);
/* fid reference counting helpers:
* - fids used for any length of time should always be referenced through
* p9_fid_get(), and released with p9_fid_put()
* - v9fs_fid_lookup() or similar will automatically call get for you
* and also require a put
* - the *_fid_add() helpers will stash the fid in the inode,
* at which point it is the responsibility of evict_inode()
* to call the put
* - the last put will automatically send a clunk to the server
*/
static inline struct p9_fid *p9_fid_get(struct p9_fid *fid)
{
refcount_inc(&fid->count);
return fid;
}
static inline int p9_fid_put(struct p9_fid *fid)
{
if (!fid || IS_ERR(fid))
return 0;
if (!refcount_dec_and_test(&fid->count))
return 0;
return p9_client_clunk(fid);
}
void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status); void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status);
int p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type, int p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type,
......
...@@ -1228,7 +1228,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname, ...@@ -1228,7 +1228,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
clunk_fid: clunk_fid:
kfree(wqids); kfree(wqids);
p9_client_clunk(fid); p9_fid_put(fid);
fid = NULL; fid = NULL;
error: error:
...@@ -1459,15 +1459,6 @@ int p9_client_clunk(struct p9_fid *fid) ...@@ -1459,15 +1459,6 @@ int p9_client_clunk(struct p9_fid *fid)
struct p9_req_t *req; struct p9_req_t *req;
int retries = 0; int retries = 0;
if (!fid || IS_ERR(fid)) {
pr_warn("%s (%d): Trying to clunk with invalid fid\n",
__func__, task_pid_nr(current));
dump_stack();
return 0;
}
if (!refcount_dec_and_test(&fid->count))
return 0;
again: again:
p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n", p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n",
fid->fid, retries); fid->fid, retries);
...@@ -1519,7 +1510,7 @@ int p9_client_remove(struct p9_fid *fid) ...@@ -1519,7 +1510,7 @@ int p9_client_remove(struct p9_fid *fid)
p9_tag_remove(clnt, req); p9_tag_remove(clnt, req);
error: error:
if (err == -ERESTARTSYS) if (err == -ERESTARTSYS)
p9_client_clunk(fid); p9_fid_put(fid);
else else
p9_fid_destroy(fid); p9_fid_destroy(fid);
return err; return err;
...@@ -2042,7 +2033,7 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid, ...@@ -2042,7 +2033,7 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
attr_fid->fid, *attr_size); attr_fid->fid, *attr_size);
return attr_fid; return attr_fid;
clunk_fid: clunk_fid:
p9_client_clunk(attr_fid); p9_fid_put(attr_fid);
attr_fid = NULL; attr_fid = NULL;
error: error:
if (attr_fid && attr_fid != file_fid) if (attr_fid && attr_fid != file_fid)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment