mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
9p-for-5.20
- a couple of fixes - add a tracepoint for fid refcounting - some cleanup/followup on fid lookup - some cleanup around req refcounting -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE/IPbcYBuWt0zoYhOq06b7GqY5nAFAmLuKqkACgkQq06b7GqY 5nA+RBAAvuA6AjKQSvsNxHsqSFMahwoE3cCPlF/QlmAnnZa1DzmRI3kKTAuuDKkE Q4c7DjxzDJCWRTlkpNUCGZycHqpu1QQbfoTo43sIqob7W8xlajeemc5Fxqtw5sPM m+0SzN7vvNJpCr+6pxMXwwGHSZmZOvpFjwj7cUjhpF/V1WO8bNxfCGzQdF0hX1Vn 2HoBbFUOmacL9Z/pF3O/ZG9LwCFuRQsH0EmbFBlJy1WdDtlVHTXlzDaGQ7EGaY4D 17UR6iITsj9ozacLhvk094PLIc3/RHDGLrm3C4Ka3zmUI7BsiYWPDmai3Pu/DNqn JJ5sZkdrVowxyBbGxw8GpZ4YDJtGsU5XglFPdkw+ZazxhZLNEIstPXg0HTZybrOe GE+WskWB0qS+RpX0tnYEcX6qOHWm3/63Yq5NG6A9tLQUSFku02jS/bCQSLBrmGWW Js24IWvFSTvl6XytHeldYhJP618pNUxXRSqgYv96vT/LI3mUrIMN+IVBNPujO6p2 jIYXNoaqLoY3efXKW/WQmp7C/52ZP4ly4fOiz7qtHTQsCcIk8Xo6zwHtm/FkNEqc sMZdqgLrxKPNBAlT8iEtt//wU2fB7mFt988p0pc+5lAK5t0h67KZJV6vDwTAMObX wV6Ht+QhOHtJwO779fk8FhZPNRPYZYMutIyFNlRx+4gCpBuqJPc= =941k -----END PGP SIGNATURE----- Merge tag '9p-for-5.20' of https://github.com/martinetd/linux Pull 9p updates from Dominique Martinet: - a couple of fixes - add a tracepoint for fid refcounting - some cleanup/followup on fid lookup - some cleanup around req refcounting * tag '9p-for-5.20' of https://github.com/martinetd/linux: net/9p: Initialize the iounit field during fid creation net: 9p: fix refcount leak in p9_read_work() error handling 9p: roll p9_tag_remove into p9_req_put 9p: Add client parameter to p9_req_put() 9p: Drop kref usage 9p: Fix some kernel-doc comments 9p fid refcount: cleanup p9_fid_put calls 9p fid refcount: add a 9p_fid_ref tracepoint 9p fid refcount: add p9_fid_get/put wrappers 9p: Fix minor typo in code comment 9p: Remove unnecessary variable for old fids while walking from d_parent 9p: Make the path walk logic more clear about when cloning is required 9p: Track the root fid with its own variable during lookups
This commit is contained in:
commit
ea0c39260d
61
fs/9p/fid.c
61
fs/9p/fid.c
@ -28,14 +28,18 @@ static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid)
|
||||
/**
|
||||
* v9fs_fid_add - add a fid to a dentry
|
||||
* @dentry: dentry that the fid is being added to
|
||||
* @fid: fid to add
|
||||
* @pfid: fid to add, NULLed out
|
||||
*
|
||||
*/
|
||||
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
|
||||
void v9fs_fid_add(struct dentry *dentry, struct p9_fid **pfid)
|
||||
{
|
||||
struct p9_fid *fid = *pfid;
|
||||
|
||||
spin_lock(&dentry->d_lock);
|
||||
__add_fid(dentry, fid);
|
||||
spin_unlock(&dentry->d_lock);
|
||||
|
||||
*pfid = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,7 +60,7 @@ static struct p9_fid *v9fs_fid_find_inode(struct inode *inode, kuid_t uid)
|
||||
h = (struct hlist_head *)&inode->i_private;
|
||||
hlist_for_each_entry(fid, h, ilist) {
|
||||
if (uid_eq(fid->uid, uid)) {
|
||||
refcount_inc(&fid->count);
|
||||
p9_fid_get(fid);
|
||||
ret = fid;
|
||||
break;
|
||||
}
|
||||
@ -68,15 +72,19 @@ static struct p9_fid *v9fs_fid_find_inode(struct inode *inode, kuid_t uid)
|
||||
/**
|
||||
* v9fs_open_fid_add - add an open fid to an inode
|
||||
* @inode: inode that the fid is being added to
|
||||
* @fid: fid to add
|
||||
* @pfid: fid to add, NULLed out
|
||||
*
|
||||
*/
|
||||
|
||||
void v9fs_open_fid_add(struct inode *inode, struct p9_fid *fid)
|
||||
void v9fs_open_fid_add(struct inode *inode, struct p9_fid **pfid)
|
||||
{
|
||||
struct p9_fid *fid = *pfid;
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
hlist_add_head(&fid->ilist, (struct hlist_head *)&inode->i_private);
|
||||
spin_unlock(&inode->i_lock);
|
||||
|
||||
*pfid = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -104,7 +112,7 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
|
||||
hlist_for_each_entry(fid, h, dlist) {
|
||||
if (any || uid_eq(fid->uid, uid)) {
|
||||
ret = fid;
|
||||
refcount_inc(&ret->count);
|
||||
p9_fid_get(ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -150,9 +158,9 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
|
||||
{
|
||||
struct dentry *ds;
|
||||
const unsigned char **wnames, *uname;
|
||||
int i, n, l, clone, access;
|
||||
int i, n, l, access;
|
||||
struct v9fs_session_info *v9ses;
|
||||
struct p9_fid *fid, *old_fid;
|
||||
struct p9_fid *fid, *root_fid, *old_fid;
|
||||
|
||||
v9ses = v9fs_dentry2v9ses(dentry);
|
||||
access = v9ses->flags & V9FS_ACCESS_MASK;
|
||||
@ -169,17 +177,17 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
|
||||
fid = v9fs_fid_find(ds, uid, any);
|
||||
if (fid) {
|
||||
/* Found the parent fid do a lookup with that */
|
||||
struct p9_fid *ofid = fid;
|
||||
old_fid = fid;
|
||||
|
||||
fid = p9_client_walk(ofid, 1, &dentry->d_name.name, 1);
|
||||
p9_client_clunk(ofid);
|
||||
fid = p9_client_walk(old_fid, 1, &dentry->d_name.name, 1);
|
||||
p9_fid_put(old_fid);
|
||||
goto fid_out;
|
||||
}
|
||||
up_read(&v9ses->rename_sem);
|
||||
|
||||
/* start from the root and try to do a lookup */
|
||||
fid = v9fs_fid_find(dentry->d_sb->s_root, uid, any);
|
||||
if (!fid) {
|
||||
root_fid = v9fs_fid_find(dentry->d_sb->s_root, uid, any);
|
||||
if (!root_fid) {
|
||||
/* the user is not attached to the fs yet */
|
||||
if (access == V9FS_ACCESS_SINGLE)
|
||||
return ERR_PTR(-EPERM);
|
||||
@ -194,12 +202,13 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
|
||||
if (IS_ERR(fid))
|
||||
return fid;
|
||||
|
||||
refcount_inc(&fid->count);
|
||||
v9fs_fid_add(dentry->d_sb->s_root, fid);
|
||||
root_fid = p9_fid_get(fid);
|
||||
v9fs_fid_add(dentry->d_sb->s_root, &fid);
|
||||
}
|
||||
/* If we are root ourself just return that */
|
||||
if (dentry->d_sb->s_root == dentry)
|
||||
return fid;
|
||||
return root_fid;
|
||||
|
||||
/*
|
||||
* Do a multipath walk with attached root.
|
||||
* When walking parent we need to make sure we
|
||||
@ -211,19 +220,20 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
|
||||
fid = ERR_PTR(n);
|
||||
goto err_out;
|
||||
}
|
||||
old_fid = fid;
|
||||
clone = 1;
|
||||
fid = root_fid;
|
||||
old_fid = root_fid;
|
||||
i = 0;
|
||||
while (i < n) {
|
||||
l = min(n - i, P9_MAXWELEM);
|
||||
/*
|
||||
* We need to hold rename lock when doing a multipath
|
||||
* walk to ensure none of the patch component change
|
||||
* walk to ensure none of the path components change
|
||||
*/
|
||||
fid = p9_client_walk(fid, l, &wnames[i], clone);
|
||||
fid = p9_client_walk(old_fid, l, &wnames[i],
|
||||
old_fid == root_fid /* clone */);
|
||||
/* non-cloning walk will return the same fid */
|
||||
if (fid != old_fid) {
|
||||
p9_client_clunk(old_fid);
|
||||
p9_fid_put(old_fid);
|
||||
old_fid = fid;
|
||||
}
|
||||
if (IS_ERR(fid)) {
|
||||
@ -231,7 +241,6 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
|
||||
goto err_out;
|
||||
}
|
||||
i += l;
|
||||
clone = 0;
|
||||
}
|
||||
kfree(wnames);
|
||||
fid_out:
|
||||
@ -239,11 +248,11 @@ fid_out:
|
||||
spin_lock(&dentry->d_lock);
|
||||
if (d_unhashed(dentry)) {
|
||||
spin_unlock(&dentry->d_lock);
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
fid = ERR_PTR(-ENOENT);
|
||||
} else {
|
||||
__add_fid(dentry, fid);
|
||||
refcount_inc(&fid->count);
|
||||
p9_fid_get(fid);
|
||||
spin_unlock(&dentry->d_lock);
|
||||
}
|
||||
}
|
||||
@ -300,7 +309,7 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
|
||||
fid = clone_fid(ofid);
|
||||
if (IS_ERR(fid))
|
||||
goto error_out;
|
||||
p9_client_clunk(ofid);
|
||||
p9_fid_put(ofid);
|
||||
/*
|
||||
* writeback fid will only be used to write back the
|
||||
* dirty pages. We always request for the open fid in read-write
|
||||
@ -309,7 +318,7 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
|
||||
*/
|
||||
err = p9_client_open(fid, O_RDWR);
|
||||
if (err < 0) {
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
fid = ERR_PTR(err);
|
||||
goto error_out;
|
||||
}
|
||||
|
@ -13,9 +13,9 @@ static inline struct p9_fid *v9fs_parent_fid(struct dentry *dentry)
|
||||
{
|
||||
return v9fs_fid_lookup(dentry->d_parent);
|
||||
}
|
||||
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid);
|
||||
void v9fs_fid_add(struct dentry *dentry, struct p9_fid **fid);
|
||||
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry);
|
||||
void v9fs_open_fid_add(struct inode *inode, struct p9_fid *fid);
|
||||
void v9fs_open_fid_add(struct inode *inode, struct p9_fid **fid);
|
||||
static inline struct p9_fid *clone_fid(struct p9_fid *fid)
|
||||
{
|
||||
return IS_ERR(fid) ? fid : p9_client_walk(fid, 0, NULL, 1);
|
||||
@ -29,7 +29,7 @@ static inline struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
|
||||
return fid;
|
||||
|
||||
nfid = clone_fid(fid);
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
return nfid;
|
||||
}
|
||||
#endif
|
||||
|
@ -73,7 +73,7 @@ static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file)
|
||||
BUG_ON(!fid);
|
||||
}
|
||||
|
||||
refcount_inc(&fid->count);
|
||||
p9_fid_get(fid);
|
||||
rreq->netfs_priv = fid;
|
||||
return 0;
|
||||
}
|
||||
@ -86,7 +86,7 @@ static void v9fs_free_request(struct netfs_io_request *rreq)
|
||||
{
|
||||
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)
|
||||
p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n",
|
||||
dentry, dentry);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
|
||||
retval = v9fs_refresh_inode_dotl(fid, inode);
|
||||
else
|
||||
retval = v9fs_refresh_inode(fid, inode);
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
|
||||
if (retval == -ENOENT)
|
||||
return 0;
|
||||
|
@ -218,7 +218,7 @@ int v9fs_dir_release(struct inode *inode, struct file *filp)
|
||||
spin_lock(&inode->i_lock);
|
||||
hlist_del(&fid->ilist);
|
||||
spin_unlock(&inode->i_lock);
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
}
|
||||
|
||||
if ((filp->f_mode & FMODE_WRITE)) {
|
||||
|
@ -63,15 +63,16 @@ int v9fs_file_open(struct inode *inode, struct file *file)
|
||||
|
||||
err = p9_client_open(fid, omode);
|
||||
if (err < 0) {
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
return err;
|
||||
}
|
||||
if ((file->f_flags & O_APPEND) &&
|
||||
(!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)))
|
||||
generic_file_llseek(file, 0, SEEK_END);
|
||||
|
||||
file->private_data = fid;
|
||||
}
|
||||
|
||||
file->private_data = fid;
|
||||
mutex_lock(&v9inode->v_mutex);
|
||||
if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
|
||||
!v9inode->writeback_fid &&
|
||||
@ -95,10 +96,10 @@ int v9fs_file_open(struct inode *inode, struct file *file)
|
||||
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
|
||||
fscache_use_cookie(v9fs_inode_cookie(v9inode),
|
||||
file->f_mode & FMODE_WRITE);
|
||||
v9fs_open_fid_add(inode, fid);
|
||||
v9fs_open_fid_add(inode, &fid);
|
||||
return 0;
|
||||
out_error:
|
||||
p9_client_clunk(file->private_data);
|
||||
p9_fid_put(file->private_data);
|
||||
file->private_data = NULL;
|
||||
return err;
|
||||
}
|
||||
|
@ -399,10 +399,8 @@ void v9fs_evict_inode(struct inode *inode)
|
||||
|
||||
fscache_relinquish_cookie(v9fs_inode_cookie(v9inode), false);
|
||||
/* clunk the fid stashed in writeback_fid */
|
||||
if (v9inode->writeback_fid) {
|
||||
p9_client_clunk(v9inode->writeback_fid);
|
||||
v9inode->writeback_fid = NULL;
|
||||
}
|
||||
p9_fid_put(v9inode->writeback_fid);
|
||||
v9inode->writeback_fid = NULL;
|
||||
}
|
||||
|
||||
static int v9fs_test_inode(struct inode *inode, void *data)
|
||||
@ -569,7 +567,7 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
|
||||
if (v9fs_proto_dotl(v9ses))
|
||||
retval = p9_client_unlinkat(dfid, dentry->d_name.name,
|
||||
v9fs_at_to_dotl_flags(flags));
|
||||
p9_client_clunk(dfid);
|
||||
p9_fid_put(dfid);
|
||||
if (retval == -EOPNOTSUPP) {
|
||||
/* Try the one based on path */
|
||||
v9fid = v9fs_fid_clone(dentry);
|
||||
@ -633,14 +631,12 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
|
||||
if (IS_ERR(ofid)) {
|
||||
err = PTR_ERR(ofid);
|
||||
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
|
||||
p9_client_clunk(dfid);
|
||||
return ERR_PTR(err);
|
||||
goto error;
|
||||
}
|
||||
|
||||
err = p9_client_fcreate(ofid, name, perm, mode, extension);
|
||||
if (err < 0) {
|
||||
p9_debug(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err);
|
||||
p9_client_clunk(dfid);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -651,8 +647,6 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
|
||||
err = PTR_ERR(fid);
|
||||
p9_debug(P9_DEBUG_VFS,
|
||||
"p9_client_walk failed %d\n", err);
|
||||
fid = NULL;
|
||||
p9_client_clunk(dfid);
|
||||
goto error;
|
||||
}
|
||||
/*
|
||||
@ -663,21 +657,17 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
|
||||
err = PTR_ERR(inode);
|
||||
p9_debug(P9_DEBUG_VFS,
|
||||
"inode creation failed %d\n", err);
|
||||
p9_client_clunk(dfid);
|
||||
goto error;
|
||||
}
|
||||
v9fs_fid_add(dentry, fid);
|
||||
v9fs_fid_add(dentry, &fid);
|
||||
d_instantiate(dentry, inode);
|
||||
}
|
||||
p9_client_clunk(dfid);
|
||||
p9_fid_put(dfid);
|
||||
return ofid;
|
||||
error:
|
||||
if (ofid)
|
||||
p9_client_clunk(ofid);
|
||||
|
||||
if (fid)
|
||||
p9_client_clunk(fid);
|
||||
|
||||
p9_fid_put(dfid);
|
||||
p9_fid_put(ofid);
|
||||
p9_fid_put(fid);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
@ -708,7 +698,7 @@ v9fs_vfs_create(struct user_namespace *mnt_userns, struct inode *dir,
|
||||
return PTR_ERR(fid);
|
||||
|
||||
v9fs_invalidate_inode_attr(dir);
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -744,7 +734,7 @@ static int v9fs_vfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
|
||||
}
|
||||
|
||||
if (fid)
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -785,7 +775,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
||||
*/
|
||||
name = dentry->d_name.name;
|
||||
fid = p9_client_walk(dfid, 1, &name, 1);
|
||||
p9_client_clunk(dfid);
|
||||
p9_fid_put(dfid);
|
||||
if (fid == ERR_PTR(-ENOENT))
|
||||
inode = NULL;
|
||||
else if (IS_ERR(fid))
|
||||
@ -804,11 +794,11 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
||||
res = d_splice_alias(inode, dentry);
|
||||
if (!IS_ERR(fid)) {
|
||||
if (!res)
|
||||
v9fs_fid_add(dentry, fid);
|
||||
v9fs_fid_add(dentry, &fid);
|
||||
else if (!IS_ERR(res))
|
||||
v9fs_fid_add(res, fid);
|
||||
v9fs_fid_add(res, &fid);
|
||||
else
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -847,7 +837,6 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||
v9fs_proto_dotu(v9ses)));
|
||||
if (IS_ERR(fid)) {
|
||||
err = PTR_ERR(fid);
|
||||
fid = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -882,7 +871,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
|
||||
fscache_use_cookie(v9fs_inode_cookie(v9inode),
|
||||
file->f_mode & FMODE_WRITE);
|
||||
v9fs_open_fid_add(inode, fid);
|
||||
v9fs_open_fid_add(inode, &fid);
|
||||
|
||||
file->f_mode |= FMODE_CREATED;
|
||||
out:
|
||||
@ -890,8 +879,7 @@ out:
|
||||
return err;
|
||||
|
||||
error:
|
||||
if (fid)
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -939,9 +927,9 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
|
||||
struct inode *old_inode;
|
||||
struct inode *new_inode;
|
||||
struct v9fs_session_info *v9ses;
|
||||
struct p9_fid *oldfid, *dfid;
|
||||
struct p9_fid *olddirfid;
|
||||
struct p9_fid *newdirfid;
|
||||
struct p9_fid *oldfid = NULL, *dfid = NULL;
|
||||
struct p9_fid *olddirfid = NULL;
|
||||
struct p9_fid *newdirfid = NULL;
|
||||
struct p9_wstat wstat;
|
||||
|
||||
if (flags)
|
||||
@ -958,21 +946,22 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
|
||||
|
||||
dfid = v9fs_parent_fid(old_dentry);
|
||||
olddirfid = clone_fid(dfid);
|
||||
if (dfid && !IS_ERR(dfid))
|
||||
p9_client_clunk(dfid);
|
||||
p9_fid_put(dfid);
|
||||
dfid = NULL;
|
||||
|
||||
if (IS_ERR(olddirfid)) {
|
||||
retval = PTR_ERR(olddirfid);
|
||||
goto done;
|
||||
goto error;
|
||||
}
|
||||
|
||||
dfid = v9fs_parent_fid(new_dentry);
|
||||
newdirfid = clone_fid(dfid);
|
||||
p9_client_clunk(dfid);
|
||||
p9_fid_put(dfid);
|
||||
dfid = NULL;
|
||||
|
||||
if (IS_ERR(newdirfid)) {
|
||||
retval = PTR_ERR(newdirfid);
|
||||
goto clunk_olddir;
|
||||
goto error;
|
||||
}
|
||||
|
||||
down_write(&v9ses->rename_sem);
|
||||
@ -983,7 +972,7 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
|
||||
retval = p9_client_rename(oldfid, newdirfid,
|
||||
new_dentry->d_name.name);
|
||||
if (retval != -EOPNOTSUPP)
|
||||
goto clunk_newdir;
|
||||
goto error_locked;
|
||||
}
|
||||
if (old_dentry->d_parent != new_dentry->d_parent) {
|
||||
/*
|
||||
@ -992,14 +981,14 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
|
||||
|
||||
p9_debug(P9_DEBUG_ERROR, "old dir and new dir are different\n");
|
||||
retval = -EXDEV;
|
||||
goto clunk_newdir;
|
||||
goto error_locked;
|
||||
}
|
||||
v9fs_blank_wstat(&wstat);
|
||||
wstat.muid = v9ses->uname;
|
||||
wstat.name = new_dentry->d_name.name;
|
||||
retval = p9_client_wstat(oldfid, &wstat);
|
||||
|
||||
clunk_newdir:
|
||||
error_locked:
|
||||
if (!retval) {
|
||||
if (new_inode) {
|
||||
if (S_ISDIR(new_inode->i_mode))
|
||||
@ -1020,13 +1009,11 @@ clunk_newdir:
|
||||
d_move(old_dentry, new_dentry);
|
||||
}
|
||||
up_write(&v9ses->rename_sem);
|
||||
p9_client_clunk(newdirfid);
|
||||
|
||||
clunk_olddir:
|
||||
p9_client_clunk(olddirfid);
|
||||
|
||||
done:
|
||||
p9_client_clunk(oldfid);
|
||||
error:
|
||||
p9_fid_put(newdirfid);
|
||||
p9_fid_put(olddirfid);
|
||||
p9_fid_put(oldfid);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -1060,7 +1047,7 @@ v9fs_vfs_getattr(struct user_namespace *mnt_userns, const struct path *path,
|
||||
return PTR_ERR(fid);
|
||||
|
||||
st = p9_client_stat(fid);
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
if (IS_ERR(st))
|
||||
return PTR_ERR(st);
|
||||
|
||||
@ -1136,7 +1123,7 @@ static int v9fs_vfs_setattr(struct user_namespace *mnt_userns,
|
||||
retval = p9_client_wstat(fid, &wstat);
|
||||
|
||||
if (use_dentry)
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
@ -1261,7 +1248,7 @@ static const char *v9fs_vfs_get_link(struct dentry *dentry,
|
||||
return ERR_CAST(fid);
|
||||
|
||||
st = p9_client_stat(fid);
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
if (IS_ERR(st))
|
||||
return ERR_CAST(st);
|
||||
|
||||
@ -1308,7 +1295,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
|
||||
return PTR_ERR(fid);
|
||||
|
||||
v9fs_invalidate_inode_attr(dir);
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1364,7 +1351,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
|
||||
v9fs_refresh_inode(oldfid, d_inode(old_dentry));
|
||||
v9fs_invalidate_inode_attr(dir);
|
||||
}
|
||||
p9_client_clunk(oldfid);
|
||||
p9_fid_put(oldfid);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
||||
struct inode *inode;
|
||||
struct p9_fid *fid = NULL;
|
||||
struct v9fs_inode *v9inode;
|
||||
struct p9_fid *dfid, *ofid, *inode_fid;
|
||||
struct p9_fid *dfid = NULL, *ofid = NULL, *inode_fid = NULL;
|
||||
struct v9fs_session_info *v9ses;
|
||||
struct posix_acl *pacl = NULL, *dacl = NULL;
|
||||
struct dentry *res = NULL;
|
||||
@ -274,7 +274,6 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
||||
if (IS_ERR(ofid)) {
|
||||
err = PTR_ERR(ofid);
|
||||
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
|
||||
p9_client_clunk(dfid);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -286,38 +285,34 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
||||
if (err) {
|
||||
p9_debug(P9_DEBUG_VFS, "Failed to get acl values in creat %d\n",
|
||||
err);
|
||||
p9_client_clunk(dfid);
|
||||
goto error;
|
||||
goto out;
|
||||
}
|
||||
err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags),
|
||||
mode, gid, &qid);
|
||||
if (err < 0) {
|
||||
p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in creat %d\n",
|
||||
err);
|
||||
p9_client_clunk(dfid);
|
||||
goto error;
|
||||
goto out;
|
||||
}
|
||||
v9fs_invalidate_inode_attr(dir);
|
||||
|
||||
/* 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);
|
||||
fid = NULL;
|
||||
goto error;
|
||||
goto out;
|
||||
}
|
||||
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err);
|
||||
goto error;
|
||||
goto out;
|
||||
}
|
||||
/* Now set the ACL based on the default value */
|
||||
v9fs_set_create_acl(inode, fid, dacl, pacl);
|
||||
|
||||
v9fs_fid_add(dentry, fid);
|
||||
v9fs_fid_add(dentry, &fid);
|
||||
d_instantiate(dentry, inode);
|
||||
|
||||
v9inode = V9FS_I(inode);
|
||||
@ -336,7 +331,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
||||
if (IS_ERR(inode_fid)) {
|
||||
err = PTR_ERR(inode_fid);
|
||||
mutex_unlock(&v9inode->v_mutex);
|
||||
goto err_clunk_old_fid;
|
||||
goto out;
|
||||
}
|
||||
v9inode->writeback_fid = (void *) inode_fid;
|
||||
}
|
||||
@ -344,25 +339,20 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
||||
/* Since we are opening a file, assign the open fid to the file */
|
||||
err = finish_open(file, dentry, generic_file_open);
|
||||
if (err)
|
||||
goto err_clunk_old_fid;
|
||||
goto out;
|
||||
file->private_data = ofid;
|
||||
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
|
||||
fscache_use_cookie(v9fs_inode_cookie(v9inode),
|
||||
file->f_mode & FMODE_WRITE);
|
||||
v9fs_open_fid_add(inode, ofid);
|
||||
v9fs_open_fid_add(inode, &ofid);
|
||||
file->f_mode |= FMODE_CREATED;
|
||||
out:
|
||||
p9_fid_put(dfid);
|
||||
p9_fid_put(ofid);
|
||||
p9_fid_put(fid);
|
||||
v9fs_put_acl(dacl, pacl);
|
||||
dput(res);
|
||||
return err;
|
||||
|
||||
error:
|
||||
if (fid)
|
||||
p9_client_clunk(fid);
|
||||
err_clunk_old_fid:
|
||||
if (ofid)
|
||||
p9_client_clunk(ofid);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -400,7 +390,6 @@ static int v9fs_vfs_mkdir_dotl(struct user_namespace *mnt_userns,
|
||||
if (IS_ERR(dfid)) {
|
||||
err = PTR_ERR(dfid);
|
||||
p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
|
||||
dfid = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -422,7 +411,6 @@ static int v9fs_vfs_mkdir_dotl(struct user_namespace *mnt_userns,
|
||||
err = PTR_ERR(fid);
|
||||
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
|
||||
err);
|
||||
fid = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -435,10 +423,9 @@ static int v9fs_vfs_mkdir_dotl(struct user_namespace *mnt_userns,
|
||||
err);
|
||||
goto error;
|
||||
}
|
||||
v9fs_fid_add(dentry, fid);
|
||||
v9fs_fid_add(dentry, &fid);
|
||||
v9fs_set_create_acl(inode, fid, dacl, pacl);
|
||||
d_instantiate(dentry, inode);
|
||||
fid = NULL;
|
||||
err = 0;
|
||||
} else {
|
||||
/*
|
||||
@ -457,10 +444,9 @@ static int v9fs_vfs_mkdir_dotl(struct user_namespace *mnt_userns,
|
||||
inc_nlink(dir);
|
||||
v9fs_invalidate_inode_attr(dir);
|
||||
error:
|
||||
if (fid)
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
v9fs_put_acl(dacl, pacl);
|
||||
p9_client_clunk(dfid);
|
||||
p9_fid_put(dfid);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -489,7 +475,7 @@ v9fs_vfs_getattr_dotl(struct user_namespace *mnt_userns,
|
||||
*/
|
||||
|
||||
st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
if (IS_ERR(st))
|
||||
return PTR_ERR(st);
|
||||
|
||||
@ -603,7 +589,7 @@ int v9fs_vfs_setattr_dotl(struct user_namespace *mnt_userns,
|
||||
retval = p9_client_setattr(fid, &p9attr);
|
||||
if (retval < 0) {
|
||||
if (use_dentry)
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -619,12 +605,12 @@ int v9fs_vfs_setattr_dotl(struct user_namespace *mnt_userns,
|
||||
retval = v9fs_acl_chmod(inode, fid);
|
||||
if (retval < 0) {
|
||||
if (use_dentry)
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
if (use_dentry)
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -743,7 +729,6 @@ v9fs_vfs_symlink_dotl(struct user_namespace *mnt_userns, struct inode *dir,
|
||||
err = PTR_ERR(fid);
|
||||
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
|
||||
err);
|
||||
fid = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -755,9 +740,8 @@ v9fs_vfs_symlink_dotl(struct user_namespace *mnt_userns, struct inode *dir,
|
||||
err);
|
||||
goto error;
|
||||
}
|
||||
v9fs_fid_add(dentry, fid);
|
||||
v9fs_fid_add(dentry, &fid);
|
||||
d_instantiate(dentry, inode);
|
||||
fid = NULL;
|
||||
err = 0;
|
||||
} else {
|
||||
/* Not in cached mode. No need to populate inode with stat */
|
||||
@ -770,10 +754,8 @@ v9fs_vfs_symlink_dotl(struct user_namespace *mnt_userns, struct inode *dir,
|
||||
}
|
||||
|
||||
error:
|
||||
if (fid)
|
||||
p9_client_clunk(fid);
|
||||
|
||||
p9_client_clunk(dfid);
|
||||
p9_fid_put(fid);
|
||||
p9_fid_put(dfid);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -803,14 +785,14 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
|
||||
|
||||
oldfid = v9fs_fid_lookup(old_dentry);
|
||||
if (IS_ERR(oldfid)) {
|
||||
p9_client_clunk(dfid);
|
||||
p9_fid_put(dfid);
|
||||
return PTR_ERR(oldfid);
|
||||
}
|
||||
|
||||
err = p9_client_link(dfid, oldfid, dentry->d_name.name);
|
||||
|
||||
p9_client_clunk(dfid);
|
||||
p9_client_clunk(oldfid);
|
||||
p9_fid_put(dfid);
|
||||
p9_fid_put(oldfid);
|
||||
if (err < 0) {
|
||||
p9_debug(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
|
||||
return err;
|
||||
@ -826,7 +808,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);
|
||||
p9_fid_put(fid);
|
||||
}
|
||||
ihold(d_inode(old_dentry));
|
||||
d_instantiate(dentry, d_inode(old_dentry));
|
||||
@ -866,7 +848,6 @@ v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir,
|
||||
if (IS_ERR(dfid)) {
|
||||
err = PTR_ERR(dfid);
|
||||
p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
|
||||
dfid = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -891,7 +872,6 @@ v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir,
|
||||
err = PTR_ERR(fid);
|
||||
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
|
||||
err);
|
||||
fid = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -905,9 +885,8 @@ v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir,
|
||||
goto error;
|
||||
}
|
||||
v9fs_set_create_acl(inode, fid, dacl, pacl);
|
||||
v9fs_fid_add(dentry, fid);
|
||||
v9fs_fid_add(dentry, &fid);
|
||||
d_instantiate(dentry, inode);
|
||||
fid = NULL;
|
||||
err = 0;
|
||||
} else {
|
||||
/*
|
||||
@ -923,10 +902,9 @@ v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir,
|
||||
d_instantiate(dentry, inode);
|
||||
}
|
||||
error:
|
||||
if (fid)
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
v9fs_put_acl(dacl, pacl);
|
||||
p9_client_clunk(dfid);
|
||||
p9_fid_put(dfid);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -956,7 +934,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);
|
||||
p9_fid_put(fid);
|
||||
if (retval)
|
||||
return ERR_PTR(retval);
|
||||
set_delayed_call(done, kfree_link, target);
|
||||
|
@ -184,13 +184,13 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
|
||||
retval = v9fs_get_acl(inode, fid);
|
||||
if (retval)
|
||||
goto release_sb;
|
||||
v9fs_fid_add(root, fid);
|
||||
v9fs_fid_add(root, &fid);
|
||||
|
||||
p9_debug(P9_DEBUG_VFS, " simple set mount, return 0\n");
|
||||
return dget(sb->s_root);
|
||||
|
||||
clunk_fid:
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
v9fs_session_close(v9ses);
|
||||
free_session:
|
||||
kfree(v9ses);
|
||||
@ -203,7 +203,7 @@ release_sb:
|
||||
* attached the fid to dentry so it won't get clunked
|
||||
* automatically.
|
||||
*/
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
deactivate_locked_super(sb);
|
||||
return ERR_PTR(retval);
|
||||
}
|
||||
@ -270,7 +270,7 @@ static int v9fs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
||||
}
|
||||
res = simple_statfs(dentry, buf);
|
||||
done:
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
|
||||
if (err)
|
||||
retval = err;
|
||||
}
|
||||
p9_client_clunk(attr_fid);
|
||||
p9_fid_put(attr_fid);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name,
|
||||
if (IS_ERR(fid))
|
||||
return PTR_ERR(fid);
|
||||
ret = v9fs_fid_xattr_get(fid, name, buffer, buffer_size);
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -98,7 +98,7 @@ int v9fs_xattr_set(struct dentry *dentry, const char *name,
|
||||
if (IS_ERR(fid))
|
||||
return PTR_ERR(fid);
|
||||
ret = v9fs_fid_xattr_set(fid, name, value, value_len, flags);
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
|
||||
retval);
|
||||
else
|
||||
p9_client_write(fid, 0, &from, &retval);
|
||||
err = p9_client_clunk(fid);
|
||||
err = p9_fid_put(fid);
|
||||
if (!retval && err)
|
||||
retval = err;
|
||||
return retval;
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/tracepoint-defs.h>
|
||||
|
||||
/* Number of requests per row */
|
||||
#define P9_ROW_MAXTAG 255
|
||||
@ -76,7 +77,7 @@ enum p9_req_status_t {
|
||||
struct p9_req_t {
|
||||
int status;
|
||||
int t_err;
|
||||
struct kref refcount;
|
||||
refcount_t refcount;
|
||||
wait_queue_head_t wq;
|
||||
struct p9_fcall tc;
|
||||
struct p9_fcall rc;
|
||||
@ -227,15 +228,55 @@ struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag);
|
||||
|
||||
static inline void p9_req_get(struct p9_req_t *r)
|
||||
{
|
||||
kref_get(&r->refcount);
|
||||
refcount_inc(&r->refcount);
|
||||
}
|
||||
|
||||
static inline int p9_req_try_get(struct p9_req_t *r)
|
||||
{
|
||||
return kref_get_unless_zero(&r->refcount);
|
||||
return refcount_inc_not_zero(&r->refcount);
|
||||
}
|
||||
|
||||
int p9_req_put(struct p9_req_t *r);
|
||||
int p9_req_put(struct p9_client *c, struct p9_req_t *r);
|
||||
|
||||
/* We cannot have the real tracepoints in header files,
|
||||
* use a wrapper function */
|
||||
DECLARE_TRACEPOINT(9p_fid_ref);
|
||||
void do_trace_9p_fid_get(struct p9_fid *fid);
|
||||
void do_trace_9p_fid_put(struct p9_fid *fid);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
if (tracepoint_enabled(9p_fid_ref))
|
||||
do_trace_9p_fid_get(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 (tracepoint_enabled(9p_fid_ref))
|
||||
do_trace_9p_fid_put(fid);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -77,6 +77,13 @@
|
||||
EM( P9_TWSTAT, "P9_TWSTAT" ) \
|
||||
EMe(P9_RWSTAT, "P9_RWSTAT" )
|
||||
|
||||
|
||||
#define P9_FID_REFTYPE \
|
||||
EM( P9_FID_REF_CREATE, "create " ) \
|
||||
EM( P9_FID_REF_GET, "get " ) \
|
||||
EM( P9_FID_REF_PUT, "put " ) \
|
||||
EMe(P9_FID_REF_DESTROY, "destroy" )
|
||||
|
||||
/* Define EM() to export the enums to userspace via TRACE_DEFINE_ENUM() */
|
||||
#undef EM
|
||||
#undef EMe
|
||||
@ -84,6 +91,21 @@
|
||||
#define EMe(a, b) TRACE_DEFINE_ENUM(a);
|
||||
|
||||
P9_MSG_T
|
||||
P9_FID_REFTYPE
|
||||
|
||||
/* And also use EM/EMe to define helper enums -- once */
|
||||
#ifndef __9P_DECLARE_TRACE_ENUMS_ONLY_ONCE
|
||||
#define __9P_DECLARE_TRACE_ENUMS_ONLY_ONCE
|
||||
#undef EM
|
||||
#undef EMe
|
||||
#define EM(a, b) a,
|
||||
#define EMe(a, b) a
|
||||
|
||||
enum p9_fid_reftype {
|
||||
P9_FID_REFTYPE
|
||||
} __mode(byte);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Now redefine the EM() and EMe() macros to map the enums to the strings
|
||||
@ -96,6 +118,8 @@ P9_MSG_T
|
||||
|
||||
#define show_9p_op(type) \
|
||||
__print_symbolic(type, P9_MSG_T)
|
||||
#define show_9p_fid_reftype(type) \
|
||||
__print_symbolic(type, P9_FID_REFTYPE)
|
||||
|
||||
TRACE_EVENT(9p_client_req,
|
||||
TP_PROTO(struct p9_client *clnt, int8_t type, int tag),
|
||||
@ -168,6 +192,30 @@ TRACE_EVENT(9p_protocol_dump,
|
||||
__entry->tag, 0, __entry->line, 16, __entry->line + 16)
|
||||
);
|
||||
|
||||
|
||||
TRACE_EVENT(9p_fid_ref,
|
||||
TP_PROTO(struct p9_fid *fid, __u8 type),
|
||||
|
||||
TP_ARGS(fid, type),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field( int, fid )
|
||||
__field( int, refcount )
|
||||
__field( __u8, type )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->fid = fid->fid;
|
||||
__entry->refcount = refcount_read(&fid->count);
|
||||
__entry->type = type;
|
||||
),
|
||||
|
||||
TP_printk("%s fid %d, refcount %d",
|
||||
show_9p_fid_reftype(__entry->type),
|
||||
__entry->fid, __entry->refcount)
|
||||
);
|
||||
|
||||
|
||||
#endif /* _TRACE_9P_H */
|
||||
|
||||
/* This part must be outside protection */
|
||||
|
168
net/9p/client.c
168
net/9p/client.c
@ -298,14 +298,14 @@ p9_tag_alloc(struct p9_client *c, int8_t type, unsigned int max_size)
|
||||
/* Init ref to two because in the general case there is one ref
|
||||
* that is put asynchronously by a writer thread, one ref
|
||||
* temporarily given by p9_tag_lookup and put by p9_client_cb
|
||||
* in the recv thread, and one ref put by p9_tag_remove in the
|
||||
* in the recv thread, and one ref put by p9_req_put in the
|
||||
* main thread. The only exception is virtio that does not use
|
||||
* p9_tag_lookup but does not have a writer thread either
|
||||
* (the write happens synchronously in the request/zc_request
|
||||
* callback), so p9_client_cb eats the second ref there
|
||||
* as the pointer is duplicated directly by virtqueue_add_sgs()
|
||||
*/
|
||||
refcount_set(&req->refcount.refcount, 2);
|
||||
refcount_set(&req->refcount, 2);
|
||||
|
||||
return req;
|
||||
|
||||
@ -341,7 +341,7 @@ again:
|
||||
if (!p9_req_try_get(req))
|
||||
goto again;
|
||||
if (req->tc.tag != tag) {
|
||||
p9_req_put(req);
|
||||
p9_req_put(c, req);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
@ -358,30 +358,28 @@ EXPORT_SYMBOL(p9_tag_lookup);
|
||||
*
|
||||
* Context: Any context.
|
||||
*/
|
||||
static int p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
|
||||
static void p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
|
||||
{
|
||||
unsigned long flags;
|
||||
u16 tag = r->tc.tag;
|
||||
|
||||
p9_debug(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag);
|
||||
p9_debug(P9_DEBUG_MUX, "freeing clnt %p req %p tag: %d\n", c, r, tag);
|
||||
spin_lock_irqsave(&c->lock, flags);
|
||||
idr_remove(&c->reqs, tag);
|
||||
spin_unlock_irqrestore(&c->lock, flags);
|
||||
return p9_req_put(r);
|
||||
}
|
||||
|
||||
static void p9_req_free(struct kref *ref)
|
||||
int p9_req_put(struct p9_client *c, struct p9_req_t *r)
|
||||
{
|
||||
struct p9_req_t *r = container_of(ref, struct p9_req_t, refcount);
|
||||
if (refcount_dec_and_test(&r->refcount)) {
|
||||
p9_tag_remove(c, r);
|
||||
|
||||
p9_fcall_fini(&r->tc);
|
||||
p9_fcall_fini(&r->rc);
|
||||
kmem_cache_free(p9_req_cache, r);
|
||||
}
|
||||
|
||||
int p9_req_put(struct p9_req_t *r)
|
||||
{
|
||||
return kref_put(&r->refcount, p9_req_free);
|
||||
p9_fcall_fini(&r->tc);
|
||||
p9_fcall_fini(&r->rc);
|
||||
kmem_cache_free(p9_req_cache, r);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(p9_req_put);
|
||||
|
||||
@ -400,7 +398,7 @@ static void p9_tag_cleanup(struct p9_client *c)
|
||||
rcu_read_lock();
|
||||
idr_for_each_entry(&c->reqs, req, id) {
|
||||
pr_info("Tag %d still in use\n", id);
|
||||
if (p9_tag_remove(c, req) == 0)
|
||||
if (p9_req_put(c, req) == 0)
|
||||
pr_warn("Packet with tag %d has still references",
|
||||
req->tc.tag);
|
||||
}
|
||||
@ -426,7 +424,7 @@ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
|
||||
|
||||
wake_up(&req->wq);
|
||||
p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc.tag);
|
||||
p9_req_put(req);
|
||||
p9_req_put(c, req);
|
||||
}
|
||||
EXPORT_SYMBOL(p9_client_cb);
|
||||
|
||||
@ -589,7 +587,7 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
|
||||
c->trans_mod->cancelled(c, oldreq);
|
||||
}
|
||||
|
||||
p9_tag_remove(c, req);
|
||||
p9_req_put(c, req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -623,9 +621,9 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
|
||||
trace_9p_client_req(c, type, req->tc.tag);
|
||||
return req;
|
||||
reterr:
|
||||
p9_tag_remove(c, req);
|
||||
p9_req_put(c, req);
|
||||
/* We have to put also the 2nd reference as it won't be used */
|
||||
p9_req_put(req);
|
||||
p9_req_put(c, req);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
@ -635,7 +633,7 @@ reterr:
|
||||
* @type: type of request
|
||||
* @fmt: protocol format string (see protocol.c)
|
||||
*
|
||||
* Returns request structure (which client must free using p9_tag_remove)
|
||||
* Returns request structure (which client must free using p9_req_put)
|
||||
*/
|
||||
|
||||
static struct p9_req_t *
|
||||
@ -662,7 +660,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
|
||||
err = c->trans_mod->request(c, req);
|
||||
if (err < 0) {
|
||||
/* write won't happen */
|
||||
p9_req_put(req);
|
||||
p9_req_put(c, req);
|
||||
if (err != -ERESTARTSYS && err != -EFAULT)
|
||||
c->status = Disconnected;
|
||||
goto recalc_sigpending;
|
||||
@ -713,7 +711,7 @@ recalc_sigpending:
|
||||
if (!err)
|
||||
return req;
|
||||
reterr:
|
||||
p9_tag_remove(c, req);
|
||||
p9_req_put(c, req);
|
||||
return ERR_PTR(safe_errno(err));
|
||||
}
|
||||
|
||||
@ -728,7 +726,7 @@ reterr:
|
||||
* @in_hdrlen: reader header size, This is the size of response protocol data
|
||||
* @fmt: protocol format string (see protocol.c)
|
||||
*
|
||||
* Returns request structure (which client must free using p9_tag_remove)
|
||||
* Returns request structure (which client must free using p9_req_put)
|
||||
*/
|
||||
static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
|
||||
struct iov_iter *uidata,
|
||||
@ -795,7 +793,7 @@ recalc_sigpending:
|
||||
if (!err)
|
||||
return req;
|
||||
reterr:
|
||||
p9_tag_remove(c, req);
|
||||
p9_req_put(c, req);
|
||||
return ERR_PTR(safe_errno(err));
|
||||
}
|
||||
|
||||
@ -805,16 +803,13 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
|
||||
struct p9_fid *fid;
|
||||
|
||||
p9_debug(P9_DEBUG_FID, "clnt %p\n", clnt);
|
||||
fid = kmalloc(sizeof(*fid), GFP_KERNEL);
|
||||
fid = kzalloc(sizeof(*fid), GFP_KERNEL);
|
||||
if (!fid)
|
||||
return NULL;
|
||||
|
||||
memset(&fid->qid, 0, sizeof(fid->qid));
|
||||
fid->mode = -1;
|
||||
fid->uid = current_fsuid();
|
||||
fid->clnt = clnt;
|
||||
fid->rdir = NULL;
|
||||
fid->fid = 0;
|
||||
refcount_set(&fid->count, 1);
|
||||
|
||||
idr_preload(GFP_KERNEL);
|
||||
@ -823,8 +818,10 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
|
||||
GFP_NOWAIT);
|
||||
spin_unlock_irq(&clnt->lock);
|
||||
idr_preload_end();
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
trace_9p_fid_ref(fid, P9_FID_REF_CREATE);
|
||||
return fid;
|
||||
}
|
||||
|
||||
kfree(fid);
|
||||
return NULL;
|
||||
@ -836,6 +833,7 @@ static void p9_fid_destroy(struct p9_fid *fid)
|
||||
unsigned long flags;
|
||||
|
||||
p9_debug(P9_DEBUG_FID, "fid %d\n", fid->fid);
|
||||
trace_9p_fid_ref(fid, P9_FID_REF_DESTROY);
|
||||
clnt = fid->clnt;
|
||||
spin_lock_irqsave(&clnt->lock, flags);
|
||||
idr_remove(&clnt->fids, fid->fid);
|
||||
@ -844,6 +842,21 @@ static void p9_fid_destroy(struct p9_fid *fid)
|
||||
kfree(fid);
|
||||
}
|
||||
|
||||
/* We also need to export tracepoint symbols for tracepoint_enabled() */
|
||||
EXPORT_TRACEPOINT_SYMBOL(9p_fid_ref);
|
||||
|
||||
void do_trace_9p_fid_get(struct p9_fid *fid)
|
||||
{
|
||||
trace_9p_fid_ref(fid, P9_FID_REF_GET);
|
||||
}
|
||||
EXPORT_SYMBOL(do_trace_9p_fid_get);
|
||||
|
||||
void do_trace_9p_fid_put(struct p9_fid *fid)
|
||||
{
|
||||
trace_9p_fid_ref(fid, P9_FID_REF_PUT);
|
||||
}
|
||||
EXPORT_SYMBOL(do_trace_9p_fid_put);
|
||||
|
||||
static int p9_client_version(struct p9_client *c)
|
||||
{
|
||||
int err = 0;
|
||||
@ -906,7 +919,7 @@ static int p9_client_version(struct p9_client *c)
|
||||
|
||||
error:
|
||||
kfree(version);
|
||||
p9_tag_remove(c, req);
|
||||
p9_req_put(c, req);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -1060,7 +1073,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
|
||||
err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", &qid);
|
||||
if (err) {
|
||||
trace_9p_protocol_dump(clnt, &req->rc);
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -1069,7 +1082,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
|
||||
|
||||
memmove(&fid->qid, &qid, sizeof(struct p9_qid));
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
return fid;
|
||||
|
||||
error:
|
||||
@ -1116,10 +1129,10 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
|
||||
err = p9pdu_readf(&req->rc, clnt->proto_version, "R", &nwqids, &wqids);
|
||||
if (err) {
|
||||
trace_9p_protocol_dump(clnt, &req->rc);
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
goto clunk_fid;
|
||||
}
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
|
||||
p9_debug(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids);
|
||||
|
||||
@ -1144,7 +1157,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
|
||||
|
||||
clunk_fid:
|
||||
kfree(wqids);
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
fid = NULL;
|
||||
|
||||
error:
|
||||
@ -1195,7 +1208,7 @@ int p9_client_open(struct p9_fid *fid, int mode)
|
||||
fid->iounit = iounit;
|
||||
|
||||
free_and_error:
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
@ -1239,7 +1252,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags,
|
||||
ofid->iounit = iounit;
|
||||
|
||||
free_and_error:
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
@ -1283,7 +1296,7 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
|
||||
fid->iounit = iounit;
|
||||
|
||||
free_and_error:
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
@ -1317,7 +1330,7 @@ int p9_client_symlink(struct p9_fid *dfid, const char *name,
|
||||
qid->type, qid->path, qid->version);
|
||||
|
||||
free_and_error:
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
@ -1337,7 +1350,7 @@ int p9_client_link(struct p9_fid *dfid, struct p9_fid *oldfid, const char *newna
|
||||
return PTR_ERR(req);
|
||||
|
||||
p9_debug(P9_DEBUG_9P, "<<< RLINK\n");
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(p9_client_link);
|
||||
@ -1361,7 +1374,7 @@ int p9_client_fsync(struct p9_fid *fid, int datasync)
|
||||
|
||||
p9_debug(P9_DEBUG_9P, "<<< RFSYNC fid %d\n", fid->fid);
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
|
||||
error:
|
||||
return err;
|
||||
@ -1375,15 +1388,6 @@ int p9_client_clunk(struct p9_fid *fid)
|
||||
struct p9_req_t *req;
|
||||
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:
|
||||
p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n",
|
||||
fid->fid, retries);
|
||||
@ -1398,7 +1402,7 @@ again:
|
||||
|
||||
p9_debug(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
/* Fid is not valid even after a failed clunk
|
||||
* If interrupted, retry once then give up and
|
||||
@ -1432,10 +1436,10 @@ int p9_client_remove(struct p9_fid *fid)
|
||||
|
||||
p9_debug(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid);
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
if (err == -ERESTARTSYS)
|
||||
p9_client_clunk(fid);
|
||||
p9_fid_put(fid);
|
||||
else
|
||||
p9_fid_destroy(fid);
|
||||
return err;
|
||||
@ -1459,7 +1463,7 @@ int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags)
|
||||
}
|
||||
p9_debug(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name);
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
@ -1527,7 +1531,7 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
|
||||
"D", &count, &dataptr);
|
||||
if (*err) {
|
||||
trace_9p_protocol_dump(clnt, &req->rc);
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
return 0;
|
||||
}
|
||||
if (rsize < count) {
|
||||
@ -1542,13 +1546,13 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
|
||||
|
||||
if (n != count) {
|
||||
*err = -EFAULT;
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
return n;
|
||||
}
|
||||
} else {
|
||||
iov_iter_advance(to, count);
|
||||
}
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
return count;
|
||||
}
|
||||
EXPORT_SYMBOL(p9_client_read_once);
|
||||
@ -1591,7 +1595,7 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
|
||||
*err = p9pdu_readf(&req->rc, clnt->proto_version, "d", &count);
|
||||
if (*err) {
|
||||
trace_9p_protocol_dump(clnt, &req->rc);
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
break;
|
||||
}
|
||||
if (rsize < count) {
|
||||
@ -1601,7 +1605,7 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
|
||||
|
||||
p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
iov_iter_advance(from, count);
|
||||
total += count;
|
||||
offset += count;
|
||||
@ -1636,7 +1640,7 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
|
||||
err = p9pdu_readf(&req->rc, clnt->proto_version, "wS", &ignored, ret);
|
||||
if (err) {
|
||||
trace_9p_protocol_dump(clnt, &req->rc);
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -1653,7 +1657,7 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
|
||||
from_kgid(&init_user_ns, ret->n_gid),
|
||||
from_kuid(&init_user_ns, ret->n_muid));
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
return ret;
|
||||
|
||||
error:
|
||||
@ -1689,7 +1693,7 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
|
||||
err = p9pdu_readf(&req->rc, clnt->proto_version, "A", ret);
|
||||
if (err) {
|
||||
trace_9p_protocol_dump(clnt, &req->rc);
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -1715,7 +1719,7 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
|
||||
ret->st_btime_sec, ret->st_btime_nsec,
|
||||
ret->st_gen, ret->st_data_version);
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
return ret;
|
||||
|
||||
error:
|
||||
@ -1787,7 +1791,7 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
|
||||
|
||||
p9_debug(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid);
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
@ -1819,7 +1823,7 @@ int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr)
|
||||
goto error;
|
||||
}
|
||||
p9_debug(P9_DEBUG_9P, "<<< RSETATTR fid %d\n", fid->fid);
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
@ -1847,7 +1851,7 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
|
||||
&sb->files, &sb->ffree, &sb->fsid, &sb->namelen);
|
||||
if (err) {
|
||||
trace_9p_protocol_dump(clnt, &req->rc);
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -1856,7 +1860,7 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
|
||||
fid->fid, sb->type, sb->bsize, sb->blocks, sb->bfree,
|
||||
sb->bavail, sb->files, sb->ffree, sb->fsid, sb->namelen);
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
@ -1884,7 +1888,7 @@ int p9_client_rename(struct p9_fid *fid,
|
||||
|
||||
p9_debug(P9_DEBUG_9P, "<<< RRENAME fid %d\n", fid->fid);
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
@ -1914,7 +1918,7 @@ int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
|
||||
p9_debug(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n",
|
||||
newdirfid->fid, new_name);
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
@ -1950,15 +1954,15 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
|
||||
err = p9pdu_readf(&req->rc, clnt->proto_version, "q", attr_size);
|
||||
if (err) {
|
||||
trace_9p_protocol_dump(clnt, &req->rc);
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
goto clunk_fid;
|
||||
}
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
p9_debug(P9_DEBUG_9P, "<<< RXATTRWALK fid %d size %llu\n",
|
||||
attr_fid->fid, *attr_size);
|
||||
return attr_fid;
|
||||
clunk_fid:
|
||||
p9_client_clunk(attr_fid);
|
||||
p9_fid_put(attr_fid);
|
||||
attr_fid = NULL;
|
||||
error:
|
||||
if (attr_fid && attr_fid != file_fid)
|
||||
@ -1987,7 +1991,7 @@ int p9_client_xattrcreate(struct p9_fid *fid, const char *name,
|
||||
goto error;
|
||||
}
|
||||
p9_debug(P9_DEBUG_9P, "<<< RXATTRCREATE fid %d\n", fid->fid);
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
@ -2049,11 +2053,11 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
|
||||
if (non_zc)
|
||||
memmove(data, dataptr, count);
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
return count;
|
||||
|
||||
free_and_error:
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
@ -2085,7 +2089,7 @@ int p9_client_mknod_dotl(struct p9_fid *fid, const char *name, int mode,
|
||||
qid->type, qid->path, qid->version);
|
||||
|
||||
error:
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(p9_client_mknod_dotl);
|
||||
@ -2115,7 +2119,7 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode,
|
||||
qid->path, qid->version);
|
||||
|
||||
error:
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(p9_client_mkdir_dotl);
|
||||
@ -2147,7 +2151,7 @@ int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
|
||||
}
|
||||
p9_debug(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status);
|
||||
error:
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(p9_client_lock_dotl);
|
||||
@ -2184,7 +2188,7 @@ int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
|
||||
glock->type, glock->start, glock->length,
|
||||
glock->proc_id, glock->client_id);
|
||||
error:
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(p9_client_getlock_dotl);
|
||||
@ -2210,7 +2214,7 @@ int p9_client_readlink(struct p9_fid *fid, char **target)
|
||||
}
|
||||
p9_debug(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target);
|
||||
error:
|
||||
p9_tag_remove(clnt, req);
|
||||
p9_req_put(clnt, req);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(p9_client_readlink);
|
||||
|
@ -343,6 +343,7 @@ static void p9_read_work(struct work_struct *work)
|
||||
p9_debug(P9_DEBUG_ERROR,
|
||||
"No recv fcall for tag %d (req %p), disconnecting!\n",
|
||||
m->rc.tag, m->rreq);
|
||||
p9_req_put(m->client, m->rreq);
|
||||
m->rreq = NULL;
|
||||
err = -EIO;
|
||||
goto error;
|
||||
@ -378,7 +379,7 @@ static void p9_read_work(struct work_struct *work)
|
||||
m->rc.sdata = NULL;
|
||||
m->rc.offset = 0;
|
||||
m->rc.capacity = 0;
|
||||
p9_req_put(m->rreq);
|
||||
p9_req_put(m->client, m->rreq);
|
||||
m->rreq = NULL;
|
||||
}
|
||||
|
||||
@ -492,7 +493,7 @@ static void p9_write_work(struct work_struct *work)
|
||||
m->wpos += err;
|
||||
if (m->wpos == m->wsize) {
|
||||
m->wpos = m->wsize = 0;
|
||||
p9_req_put(m->wreq);
|
||||
p9_req_put(m->client, m->wreq);
|
||||
m->wreq = NULL;
|
||||
}
|
||||
|
||||
@ -695,7 +696,7 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
|
||||
if (req->status == REQ_STATUS_UNSENT) {
|
||||
list_del(&req->req_list);
|
||||
req->status = REQ_STATUS_FLSHD;
|
||||
p9_req_put(req);
|
||||
p9_req_put(client, req);
|
||||
ret = 0;
|
||||
}
|
||||
spin_unlock(&client->lock);
|
||||
@ -722,7 +723,7 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
|
||||
list_del(&req->req_list);
|
||||
req->status = REQ_STATUS_FLSHD;
|
||||
spin_unlock(&client->lock);
|
||||
p9_req_put(req);
|
||||
p9_req_put(client, req);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -883,12 +884,12 @@ static void p9_conn_destroy(struct p9_conn *m)
|
||||
p9_mux_poll_stop(m);
|
||||
cancel_work_sync(&m->rq);
|
||||
if (m->rreq) {
|
||||
p9_req_put(m->rreq);
|
||||
p9_req_put(m->client, m->rreq);
|
||||
m->rreq = NULL;
|
||||
}
|
||||
cancel_work_sync(&m->wq);
|
||||
if (m->wreq) {
|
||||
p9_req_put(m->wreq);
|
||||
p9_req_put(m->client, m->wreq);
|
||||
m->wreq = NULL;
|
||||
}
|
||||
|
||||
|
@ -350,7 +350,7 @@ send_done(struct ib_cq *cq, struct ib_wc *wc)
|
||||
c->busa, c->req->tc.size,
|
||||
DMA_TO_DEVICE);
|
||||
up(&rdma->sq_sem);
|
||||
p9_req_put(c->req);
|
||||
p9_req_put(client, c->req);
|
||||
kfree(c);
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
|
||||
/* Reply won't come, so drop req ref */
|
||||
static int p9_virtio_cancelled(struct p9_client *client, struct p9_req_t *req)
|
||||
{
|
||||
p9_req_put(req);
|
||||
p9_req_put(client, req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -557,7 +557,7 @@ err_out:
|
||||
kvfree(out_pages);
|
||||
if (!kicked) {
|
||||
/* reply won't come */
|
||||
p9_req_put(req);
|
||||
p9_req_put(client, req);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ again:
|
||||
ring->intf->out_prod = prod;
|
||||
spin_unlock_irqrestore(&ring->lock, flags);
|
||||
notify_remote_via_irq(ring->irq);
|
||||
p9_req_put(p9_req);
|
||||
p9_req_put(client, p9_req);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user