9p for 5.11-rc1
- fix long-standing limitation on open-unlink-fop pattern - add refcount to p9_fid (fixes the above and will allow for more cleanups and simplifications in the future) -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE/IPbcYBuWt0zoYhOq06b7GqY5nAFAl/gWOYACgkQq06b7GqY 5nBcHxAArtfxZ4wGa+OMoWt19UvF0bUeYUYdy75rp6awpXmQyMfMZY9oOrZ9L+St mS3oLd8Mq7MeJQ+iGKPPOX+085aNhRtxjQOiHlv02fi09zVyNqj1vptq+rTRkKZL 8KTs+wYSIX2x1WensDBdohYFiWf87vCWyywpQ/1Vm0585mI8B88N3/H5EpkLbPZn 1bgXkakgd2hS+rKu6vJGV8lCJ8eKOSpQ3WUK0WQhY6ysJEL9dbl00qyNQ4kq2UgI i3CpWC/86297KJOehPmegpVwqTIL5wrCkhQy7sNxDkR9E4Q3VoKTNSrnRDtBI0x/ mRCEnc/2Pf76Zv3LpGXnLFSnDLTQaO842Hla92RZJCcHaDtGDwV9Znq6sZgn+pdV wlEpT383s+7AC/X1EFvLPMr5PHrEM1KW25YEYQI78X2hh8G+utW5p3+vu70b0PyT Z7P9yBW4aU4cZb3XcZZihatZG2P1LxHyjNMmn4YBdUeQuitdiJGc2KwjVyKXi9PX +t6xxI+YAIhu/5I9fRtOoIDQNTjsRRE+4FzRKd2kvxW5Z5sV/bZCf6CHnQ2uKYVP fEMYd0GhjrUABbJPLLdFlBXaV+yigvwKtABDnJ5KSA9NlDSVBGewTRa2I+9DoclL yQS4hELuvQsUNCo4AkICixo9vABt0j1OhXlo+B0WVk8Ilh9Wxpc= =DKlc -----END PGP SIGNATURE----- Merge tag '9p-for-5.11-rc1' of git://github.com/martinetd/linux Pull 9p update from Dominique Martinet: - fix long-standing limitation on open-unlink-fop pattern - add refcount to p9_fid (fixes the above and will allow for more cleanups and simplifications in the future) * tag '9p-for-5.11-rc1' of git://github.com/martinetd/linux: 9p: Remove unnecessary IS_ERR() check 9p: Uninitialized variable in v9fs_writeback_fid() 9p: Fix writeback fid incorrectly being attached to dentry 9p: apply review requests for fid refcounting 9p: add refcount to p9_fid struct fs/9p: search open fids first fs/9p: track open fids fs/9p: fix create-unlink-getattr idiom
This commit is contained in:
commit
70990afa34
65
fs/9p/fid.c
65
fs/9p/fid.c
|
@ -38,6 +38,48 @@ void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
|
||||||
spin_unlock(&dentry->d_lock);
|
spin_unlock(&dentry->d_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v9fs_fid_find_inode - search for an open fid off of the inode list
|
||||||
|
* @inode: return a fid pointing to a specific inode
|
||||||
|
* @uid: return a fid belonging to the specified user
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct p9_fid *v9fs_fid_find_inode(struct inode *inode, kuid_t uid)
|
||||||
|
{
|
||||||
|
struct hlist_head *h;
|
||||||
|
struct p9_fid *fid, *ret = NULL;
|
||||||
|
|
||||||
|
p9_debug(P9_DEBUG_VFS, " inode: %p\n", inode);
|
||||||
|
|
||||||
|
spin_lock(&inode->i_lock);
|
||||||
|
h = (struct hlist_head *)&inode->i_private;
|
||||||
|
hlist_for_each_entry(fid, h, ilist) {
|
||||||
|
if (uid_eq(fid->uid, uid)) {
|
||||||
|
refcount_inc(&fid->count);
|
||||||
|
ret = fid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spin_unlock(&inode->i_lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v9fs_open_fid_add - add an open fid to an inode
|
||||||
|
* @dentry: inode that the fid is being added to
|
||||||
|
* @fid: fid to add
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void v9fs_open_fid_add(struct inode *inode, struct p9_fid *fid)
|
||||||
|
{
|
||||||
|
spin_lock(&inode->i_lock);
|
||||||
|
hlist_add_head(&fid->ilist, (struct hlist_head *)&inode->i_private);
|
||||||
|
spin_unlock(&inode->i_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* v9fs_fid_find - retrieve a fid that belongs to the specified uid
|
* v9fs_fid_find - retrieve a fid that belongs to the specified uid
|
||||||
* @dentry: dentry to look for fid in
|
* @dentry: dentry to look for fid in
|
||||||
|
@ -54,13 +96,18 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
|
||||||
dentry, dentry, from_kuid(&init_user_ns, uid),
|
dentry, dentry, from_kuid(&init_user_ns, uid),
|
||||||
any);
|
any);
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
|
|
||||||
|
if (d_inode(dentry))
|
||||||
|
ret = v9fs_fid_find_inode(d_inode(dentry), uid);
|
||||||
|
|
||||||
/* we'll recheck under lock if there's anything to look in */
|
/* we'll recheck under lock if there's anything to look in */
|
||||||
if (dentry->d_fsdata) {
|
if (!ret && dentry->d_fsdata) {
|
||||||
struct hlist_head *h = (struct hlist_head *)&dentry->d_fsdata;
|
struct hlist_head *h = (struct hlist_head *)&dentry->d_fsdata;
|
||||||
spin_lock(&dentry->d_lock);
|
spin_lock(&dentry->d_lock);
|
||||||
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);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +169,10 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
|
||||||
fid = v9fs_fid_find(ds, uid, any);
|
fid = v9fs_fid_find(ds, uid, any);
|
||||||
if (fid) {
|
if (fid) {
|
||||||
/* Found the parent fid do a lookup with that */
|
/* Found the parent fid do a lookup with that */
|
||||||
fid = p9_client_walk(fid, 1, &dentry->d_name.name, 1);
|
struct p9_fid *ofid = fid;
|
||||||
|
|
||||||
|
fid = p9_client_walk(ofid, 1, &dentry->d_name.name, 1);
|
||||||
|
p9_client_clunk(ofid);
|
||||||
goto fid_out;
|
goto fid_out;
|
||||||
}
|
}
|
||||||
up_read(&v9ses->rename_sem);
|
up_read(&v9ses->rename_sem);
|
||||||
|
@ -147,8 +197,10 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
|
||||||
v9fs_fid_add(dentry->d_sb->s_root, fid);
|
v9fs_fid_add(dentry->d_sb->s_root, fid);
|
||||||
}
|
}
|
||||||
/* If we are root ourself just return that */
|
/* If we are root ourself just return that */
|
||||||
if (dentry->d_sb->s_root == dentry)
|
if (dentry->d_sb->s_root == dentry) {
|
||||||
|
refcount_inc(&fid->count);
|
||||||
return fid;
|
return fid;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Do a multipath walk with attached root.
|
* Do a multipath walk with attached root.
|
||||||
* When walking parent we need to make sure we
|
* When walking parent we need to make sure we
|
||||||
|
@ -195,6 +247,7 @@ fid_out:
|
||||||
fid = ERR_PTR(-ENOENT);
|
fid = ERR_PTR(-ENOENT);
|
||||||
} else {
|
} else {
|
||||||
__add_fid(dentry, fid);
|
__add_fid(dentry, fid);
|
||||||
|
refcount_inc(&fid->count);
|
||||||
spin_unlock(&dentry->d_lock);
|
spin_unlock(&dentry->d_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,11 +298,13 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
|
||||||
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
|
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct p9_fid *fid;
|
struct p9_fid *fid, *ofid;
|
||||||
|
|
||||||
fid = clone_fid(v9fs_fid_lookup_with_uid(dentry, GLOBAL_ROOT_UID, 0));
|
ofid = v9fs_fid_lookup_with_uid(dentry, GLOBAL_ROOT_UID, 0);
|
||||||
|
fid = clone_fid(ofid);
|
||||||
if (IS_ERR(fid))
|
if (IS_ERR(fid))
|
||||||
goto error_out;
|
goto error_out;
|
||||||
|
p9_client_clunk(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
|
||||||
|
|
11
fs/9p/fid.h
11
fs/9p/fid.h
|
@ -15,12 +15,21 @@ static inline struct p9_fid *v9fs_parent_fid(struct dentry *dentry)
|
||||||
}
|
}
|
||||||
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);
|
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry);
|
||||||
|
void v9fs_open_fid_add(struct inode *inode, struct p9_fid *fid);
|
||||||
static inline struct p9_fid *clone_fid(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);
|
return IS_ERR(fid) ? fid : p9_client_walk(fid, 0, NULL, 1);
|
||||||
}
|
}
|
||||||
static inline struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
|
static inline struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
|
||||||
{
|
{
|
||||||
return clone_fid(v9fs_fid_lookup(dentry));
|
struct p9_fid *fid, *nfid;
|
||||||
|
|
||||||
|
fid = v9fs_fid_lookup(dentry);
|
||||||
|
if (!fid || IS_ERR(fid))
|
||||||
|
return fid;
|
||||||
|
|
||||||
|
nfid = clone_fid(fid);
|
||||||
|
p9_client_clunk(fid);
|
||||||
|
return nfid;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -85,6 +85,8 @@ 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);
|
||||||
|
|
||||||
if (retval == -ENOENT)
|
if (retval == -ENOENT)
|
||||||
return 0;
|
return 0;
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
|
|
|
@ -210,8 +210,12 @@ int v9fs_dir_release(struct inode *inode, struct file *filp)
|
||||||
fid = filp->private_data;
|
fid = filp->private_data;
|
||||||
p9_debug(P9_DEBUG_VFS, "inode: %p filp: %p fid: %d\n",
|
p9_debug(P9_DEBUG_VFS, "inode: %p filp: %p fid: %d\n",
|
||||||
inode, filp, fid ? fid->fid : -1);
|
inode, filp, fid ? fid->fid : -1);
|
||||||
if (fid)
|
if (fid) {
|
||||||
|
spin_lock(&inode->i_lock);
|
||||||
|
hlist_del(&fid->ilist);
|
||||||
|
spin_unlock(&inode->i_lock);
|
||||||
p9_client_clunk(fid);
|
p9_client_clunk(fid);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
|
||||||
int err;
|
int err;
|
||||||
struct v9fs_inode *v9inode;
|
struct v9fs_inode *v9inode;
|
||||||
struct v9fs_session_info *v9ses;
|
struct v9fs_session_info *v9ses;
|
||||||
struct p9_fid *fid;
|
struct p9_fid *fid, *writeback_fid;
|
||||||
int omode;
|
int omode;
|
||||||
|
|
||||||
p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file);
|
p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file);
|
||||||
|
@ -85,17 +85,18 @@ int v9fs_file_open(struct inode *inode, struct file *file)
|
||||||
* because we want write after unlink usecase
|
* because we want write after unlink usecase
|
||||||
* to work.
|
* to work.
|
||||||
*/
|
*/
|
||||||
fid = v9fs_writeback_fid(file_dentry(file));
|
writeback_fid = v9fs_writeback_fid(file_dentry(file));
|
||||||
if (IS_ERR(fid)) {
|
if (IS_ERR(fid)) {
|
||||||
err = PTR_ERR(fid);
|
err = PTR_ERR(fid);
|
||||||
mutex_unlock(&v9inode->v_mutex);
|
mutex_unlock(&v9inode->v_mutex);
|
||||||
goto out_error;
|
goto out_error;
|
||||||
}
|
}
|
||||||
v9inode->writeback_fid = (void *) fid;
|
v9inode->writeback_fid = (void *) writeback_fid;
|
||||||
}
|
}
|
||||||
mutex_unlock(&v9inode->v_mutex);
|
mutex_unlock(&v9inode->v_mutex);
|
||||||
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
|
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
|
||||||
v9fs_cache_inode_set_cookie(inode, file);
|
v9fs_cache_inode_set_cookie(inode, file);
|
||||||
|
v9fs_open_fid_add(inode, fid);
|
||||||
return 0;
|
return 0;
|
||||||
out_error:
|
out_error:
|
||||||
p9_client_clunk(file->private_data);
|
p9_client_clunk(file->private_data);
|
||||||
|
|
|
@ -256,6 +256,7 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses,
|
||||||
inode->i_rdev = rdev;
|
inode->i_rdev = rdev;
|
||||||
inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
|
inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
|
||||||
inode->i_mapping->a_ops = &v9fs_addr_operations;
|
inode->i_mapping->a_ops = &v9fs_addr_operations;
|
||||||
|
inode->i_private = NULL;
|
||||||
|
|
||||||
switch (mode & S_IFMT) {
|
switch (mode & S_IFMT) {
|
||||||
case S_IFIFO:
|
case S_IFIFO:
|
||||||
|
@ -550,6 +551,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);
|
||||||
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);
|
||||||
|
@ -570,6 +572,10 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
|
||||||
|
|
||||||
v9fs_invalidate_inode_attr(inode);
|
v9fs_invalidate_inode_attr(inode);
|
||||||
v9fs_invalidate_inode_attr(dir);
|
v9fs_invalidate_inode_attr(dir);
|
||||||
|
|
||||||
|
/* invalidate all fids associated with dentry */
|
||||||
|
/* NOTE: This will not include open fids */
|
||||||
|
dentry->d_op->d_release(dentry);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -590,14 +596,12 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
const unsigned char *name;
|
const unsigned char *name;
|
||||||
struct p9_fid *dfid, *ofid, *fid;
|
struct p9_fid *dfid, *ofid = NULL, *fid = NULL;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
|
||||||
p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry);
|
p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry);
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
ofid = NULL;
|
|
||||||
fid = NULL;
|
|
||||||
name = dentry->d_name.name;
|
name = dentry->d_name.name;
|
||||||
dfid = v9fs_parent_fid(dentry);
|
dfid = v9fs_parent_fid(dentry);
|
||||||
if (IS_ERR(dfid)) {
|
if (IS_ERR(dfid)) {
|
||||||
|
@ -611,12 +615,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);
|
||||||
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);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,6 +634,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);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -638,11 +645,13 @@ 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);
|
||||||
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);
|
||||||
return ofid;
|
return ofid;
|
||||||
error:
|
error:
|
||||||
if (ofid)
|
if (ofid)
|
||||||
|
@ -755,6 +764,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);
|
||||||
if (fid == ERR_PTR(-ENOENT))
|
if (fid == ERR_PTR(-ENOENT))
|
||||||
inode = NULL;
|
inode = NULL;
|
||||||
else if (IS_ERR(fid))
|
else if (IS_ERR(fid))
|
||||||
|
@ -792,6 +802,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||||
struct v9fs_session_info *v9ses;
|
struct v9fs_session_info *v9ses;
|
||||||
struct p9_fid *fid, *inode_fid;
|
struct p9_fid *fid, *inode_fid;
|
||||||
struct dentry *res = NULL;
|
struct dentry *res = NULL;
|
||||||
|
struct inode *inode;
|
||||||
|
|
||||||
if (d_in_lookup(dentry)) {
|
if (d_in_lookup(dentry)) {
|
||||||
res = v9fs_vfs_lookup(dir, dentry, 0);
|
res = v9fs_vfs_lookup(dir, dentry, 0);
|
||||||
|
@ -820,7 +831,8 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||||
}
|
}
|
||||||
|
|
||||||
v9fs_invalidate_inode_attr(dir);
|
v9fs_invalidate_inode_attr(dir);
|
||||||
v9inode = V9FS_I(d_inode(dentry));
|
inode = d_inode(dentry);
|
||||||
|
v9inode = V9FS_I(inode);
|
||||||
mutex_lock(&v9inode->v_mutex);
|
mutex_lock(&v9inode->v_mutex);
|
||||||
if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
|
if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
|
||||||
!v9inode->writeback_fid &&
|
!v9inode->writeback_fid &&
|
||||||
|
@ -848,6 +860,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||||
file->private_data = fid;
|
file->private_data = fid;
|
||||||
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
|
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
|
||||||
v9fs_cache_inode_set_cookie(d_inode(dentry), file);
|
v9fs_cache_inode_set_cookie(d_inode(dentry), file);
|
||||||
|
v9fs_open_fid_add(inode, fid);
|
||||||
|
|
||||||
file->f_mode |= FMODE_CREATED;
|
file->f_mode |= FMODE_CREATED;
|
||||||
out:
|
out:
|
||||||
|
@ -902,7 +915,7 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||||
struct inode *old_inode;
|
struct inode *old_inode;
|
||||||
struct inode *new_inode;
|
struct inode *new_inode;
|
||||||
struct v9fs_session_info *v9ses;
|
struct v9fs_session_info *v9ses;
|
||||||
struct p9_fid *oldfid;
|
struct p9_fid *oldfid, *dfid;
|
||||||
struct p9_fid *olddirfid;
|
struct p9_fid *olddirfid;
|
||||||
struct p9_fid *newdirfid;
|
struct p9_fid *newdirfid;
|
||||||
struct p9_wstat wstat;
|
struct p9_wstat wstat;
|
||||||
|
@ -919,13 +932,20 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||||
if (IS_ERR(oldfid))
|
if (IS_ERR(oldfid))
|
||||||
return PTR_ERR(oldfid);
|
return PTR_ERR(oldfid);
|
||||||
|
|
||||||
olddirfid = clone_fid(v9fs_parent_fid(old_dentry));
|
dfid = v9fs_parent_fid(old_dentry);
|
||||||
|
olddirfid = clone_fid(dfid);
|
||||||
|
if (dfid && !IS_ERR(dfid))
|
||||||
|
p9_client_clunk(dfid);
|
||||||
|
|
||||||
if (IS_ERR(olddirfid)) {
|
if (IS_ERR(olddirfid)) {
|
||||||
retval = PTR_ERR(olddirfid);
|
retval = PTR_ERR(olddirfid);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
newdirfid = clone_fid(v9fs_parent_fid(new_dentry));
|
dfid = v9fs_parent_fid(new_dentry);
|
||||||
|
newdirfid = clone_fid(dfid);
|
||||||
|
p9_client_clunk(dfid);
|
||||||
|
|
||||||
if (IS_ERR(newdirfid)) {
|
if (IS_ERR(newdirfid)) {
|
||||||
retval = PTR_ERR(newdirfid);
|
retval = PTR_ERR(newdirfid);
|
||||||
goto clunk_olddir;
|
goto clunk_olddir;
|
||||||
|
@ -982,6 +1002,7 @@ clunk_olddir:
|
||||||
p9_client_clunk(olddirfid);
|
p9_client_clunk(olddirfid);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
p9_client_clunk(oldfid);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,6 +1035,7 @@ v9fs_vfs_getattr(const struct path *path, struct kstat *stat,
|
||||||
return PTR_ERR(fid);
|
return PTR_ERR(fid);
|
||||||
|
|
||||||
st = p9_client_stat(fid);
|
st = p9_client_stat(fid);
|
||||||
|
p9_client_clunk(fid);
|
||||||
if (IS_ERR(st))
|
if (IS_ERR(st))
|
||||||
return PTR_ERR(st);
|
return PTR_ERR(st);
|
||||||
|
|
||||||
|
@ -1034,7 +1056,7 @@ v9fs_vfs_getattr(const struct path *path, struct kstat *stat,
|
||||||
|
|
||||||
static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
|
static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval, use_dentry = 0;
|
||||||
struct v9fs_session_info *v9ses;
|
struct v9fs_session_info *v9ses;
|
||||||
struct p9_fid *fid = NULL;
|
struct p9_fid *fid = NULL;
|
||||||
struct p9_wstat wstat;
|
struct p9_wstat wstat;
|
||||||
|
@ -1050,8 +1072,10 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
|
||||||
fid = iattr->ia_file->private_data;
|
fid = iattr->ia_file->private_data;
|
||||||
WARN_ON(!fid);
|
WARN_ON(!fid);
|
||||||
}
|
}
|
||||||
if (!fid)
|
if (!fid) {
|
||||||
fid = v9fs_fid_lookup(dentry);
|
fid = v9fs_fid_lookup(dentry);
|
||||||
|
use_dentry = 1;
|
||||||
|
}
|
||||||
if(IS_ERR(fid))
|
if(IS_ERR(fid))
|
||||||
return PTR_ERR(fid);
|
return PTR_ERR(fid);
|
||||||
|
|
||||||
|
@ -1081,6 +1105,10 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
|
||||||
filemap_write_and_wait(d_inode(dentry)->i_mapping);
|
filemap_write_and_wait(d_inode(dentry)->i_mapping);
|
||||||
|
|
||||||
retval = p9_client_wstat(fid, &wstat);
|
retval = p9_client_wstat(fid, &wstat);
|
||||||
|
|
||||||
|
if (use_dentry)
|
||||||
|
p9_client_clunk(fid);
|
||||||
|
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
|
@ -1205,6 +1233,7 @@ static const char *v9fs_vfs_get_link(struct dentry *dentry,
|
||||||
return ERR_PTR(-EBADF);
|
return ERR_PTR(-EBADF);
|
||||||
|
|
||||||
st = p9_client_stat(fid);
|
st = p9_client_stat(fid);
|
||||||
|
p9_client_clunk(fid);
|
||||||
if (IS_ERR(st))
|
if (IS_ERR(st))
|
||||||
return ERR_CAST(st);
|
return ERR_CAST(st);
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
/* 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);
|
||||||
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);
|
||||||
|
@ -342,6 +343,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
||||||
file->private_data = ofid;
|
file->private_data = ofid;
|
||||||
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
|
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
|
||||||
v9fs_cache_inode_set_cookie(inode, file);
|
v9fs_cache_inode_set_cookie(inode, file);
|
||||||
|
v9fs_open_fid_add(inode, ofid);
|
||||||
file->f_mode |= FMODE_CREATED;
|
file->f_mode |= FMODE_CREATED;
|
||||||
out:
|
out:
|
||||||
v9fs_put_acl(dacl, pacl);
|
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);
|
err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
fid = p9_client_walk(dfid, 1, &name, 1);
|
fid = p9_client_walk(dfid, 1, &name, 1);
|
||||||
if (IS_ERR(fid)) {
|
if (IS_ERR(fid)) {
|
||||||
err = PTR_ERR(fid);
|
err = PTR_ERR(fid);
|
||||||
|
@ -451,6 +452,7 @@ error:
|
||||||
if (fid)
|
if (fid)
|
||||||
p9_client_clunk(fid);
|
p9_client_clunk(fid);
|
||||||
v9fs_put_acl(dacl, pacl);
|
v9fs_put_acl(dacl, pacl);
|
||||||
|
p9_client_clunk(dfid);
|
||||||
return err;
|
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);
|
st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
|
||||||
|
p9_client_clunk(fid);
|
||||||
if (IS_ERR(st))
|
if (IS_ERR(st))
|
||||||
return PTR_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 v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval, use_dentry = 0;
|
||||||
struct p9_fid *fid = NULL;
|
struct p9_fid *fid = NULL;
|
||||||
struct p9_iattr_dotl p9attr;
|
struct p9_iattr_dotl p9attr;
|
||||||
struct inode *inode = d_inode(dentry);
|
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;
|
fid = iattr->ia_file->private_data;
|
||||||
WARN_ON(!fid);
|
WARN_ON(!fid);
|
||||||
}
|
}
|
||||||
if (!fid)
|
if (!fid) {
|
||||||
fid = v9fs_fid_lookup(dentry);
|
fid = v9fs_fid_lookup(dentry);
|
||||||
|
use_dentry = 1;
|
||||||
|
}
|
||||||
if (IS_ERR(fid))
|
if (IS_ERR(fid))
|
||||||
return PTR_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);
|
filemap_write_and_wait(inode->i_mapping);
|
||||||
|
|
||||||
retval = p9_client_setattr(fid, &p9attr);
|
retval = p9_client_setattr(fid, &p9attr);
|
||||||
if (retval < 0)
|
if (retval < 0) {
|
||||||
|
if (use_dentry)
|
||||||
|
p9_client_clunk(fid);
|
||||||
return retval;
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
if ((iattr->ia_valid & ATTR_SIZE) &&
|
if ((iattr->ia_valid & ATTR_SIZE) &&
|
||||||
iattr->ia_size != i_size_read(inode))
|
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) {
|
if (iattr->ia_valid & ATTR_MODE) {
|
||||||
/* We also want to update ACL when we update mode bits */
|
/* We also want to update ACL when we update mode bits */
|
||||||
retval = v9fs_acl_chmod(inode, fid);
|
retval = v9fs_acl_chmod(inode, fid);
|
||||||
if (retval < 0)
|
if (retval < 0) {
|
||||||
|
if (use_dentry)
|
||||||
|
p9_client_clunk(fid);
|
||||||
return retval;
|
return retval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (use_dentry)
|
||||||
|
p9_client_clunk(fid);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,6 +755,7 @@ error:
|
||||||
if (fid)
|
if (fid)
|
||||||
p9_client_clunk(fid);
|
p9_client_clunk(fid);
|
||||||
|
|
||||||
|
p9_client_clunk(dfid);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,11 +784,15 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
|
||||||
return PTR_ERR(dfid);
|
return PTR_ERR(dfid);
|
||||||
|
|
||||||
oldfid = v9fs_fid_lookup(old_dentry);
|
oldfid = v9fs_fid_lookup(old_dentry);
|
||||||
if (IS_ERR(oldfid))
|
if (IS_ERR(oldfid)) {
|
||||||
|
p9_client_clunk(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_client_clunk(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;
|
||||||
|
@ -788,6 +807,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);
|
||||||
}
|
}
|
||||||
ihold(d_inode(old_dentry));
|
ihold(d_inode(old_dentry));
|
||||||
d_instantiate(dentry, d_inode(old_dentry));
|
d_instantiate(dentry, d_inode(old_dentry));
|
||||||
|
@ -886,6 +906,8 @@ error:
|
||||||
if (fid)
|
if (fid)
|
||||||
p9_client_clunk(fid);
|
p9_client_clunk(fid);
|
||||||
v9fs_put_acl(dacl, pacl);
|
v9fs_put_acl(dacl, pacl);
|
||||||
|
p9_client_clunk(dfid);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,6 +936,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);
|
||||||
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);
|
||||||
|
|
|
@ -268,6 +268,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);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,14 +71,17 @@ ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name,
|
||||||
void *buffer, size_t buffer_size)
|
void *buffer, size_t buffer_size)
|
||||||
{
|
{
|
||||||
struct p9_fid *fid;
|
struct p9_fid *fid;
|
||||||
|
int ret;
|
||||||
|
|
||||||
p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu\n",
|
p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu\n",
|
||||||
name, buffer_size);
|
name, buffer_size);
|
||||||
fid = v9fs_fid_lookup(dentry);
|
fid = v9fs_fid_lookup(dentry);
|
||||||
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);
|
||||||
|
p9_client_clunk(fid);
|
||||||
|
|
||||||
return v9fs_fid_xattr_get(fid, name, buffer, buffer_size);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -96,8 +99,15 @@ ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name,
|
||||||
int v9fs_xattr_set(struct dentry *dentry, const char *name,
|
int v9fs_xattr_set(struct dentry *dentry, const char *name,
|
||||||
const void *value, size_t value_len, int flags)
|
const void *value, size_t value_len, int flags)
|
||||||
{
|
{
|
||||||
struct p9_fid *fid = v9fs_fid_lookup(dentry);
|
int ret;
|
||||||
return v9fs_fid_xattr_set(fid, name, value, value_len, flags);
|
struct p9_fid *fid;
|
||||||
|
|
||||||
|
fid = v9fs_fid_lookup(dentry);
|
||||||
|
if (IS_ERR(fid))
|
||||||
|
return PTR_ERR(fid);
|
||||||
|
ret = v9fs_fid_xattr_set(fid, name, value, value_len, flags);
|
||||||
|
p9_client_clunk(fid);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
|
int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
|
||||||
|
|
|
@ -140,10 +140,16 @@ struct p9_client {
|
||||||
*
|
*
|
||||||
* TODO: This needs lots of explanation.
|
* TODO: This needs lots of explanation.
|
||||||
*/
|
*/
|
||||||
|
enum fid_source {
|
||||||
|
FID_FROM_OTHER,
|
||||||
|
FID_FROM_INODE,
|
||||||
|
FID_FROM_DENTRY,
|
||||||
|
};
|
||||||
|
|
||||||
struct p9_fid {
|
struct p9_fid {
|
||||||
struct p9_client *clnt;
|
struct p9_client *clnt;
|
||||||
u32 fid;
|
u32 fid;
|
||||||
|
refcount_t count;
|
||||||
int mode;
|
int mode;
|
||||||
struct p9_qid qid;
|
struct p9_qid qid;
|
||||||
u32 iounit;
|
u32 iounit;
|
||||||
|
@ -152,6 +158,7 @@ struct p9_fid {
|
||||||
void *rdir;
|
void *rdir;
|
||||||
|
|
||||||
struct hlist_node dlist; /* list of all fids attached to a dentry */
|
struct hlist_node dlist; /* list of all fids attached to a dentry */
|
||||||
|
struct hlist_node ilist;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -903,6 +903,7 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
|
||||||
fid->clnt = clnt;
|
fid->clnt = clnt;
|
||||||
fid->rdir = NULL;
|
fid->rdir = NULL;
|
||||||
fid->fid = 0;
|
fid->fid = 0;
|
||||||
|
refcount_set(&fid->count, 1);
|
||||||
|
|
||||||
idr_preload(GFP_KERNEL);
|
idr_preload(GFP_KERNEL);
|
||||||
spin_lock_irq(&clnt->lock);
|
spin_lock_irq(&clnt->lock);
|
||||||
|
@ -910,7 +911,6 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
|
||||||
GFP_NOWAIT);
|
GFP_NOWAIT);
|
||||||
spin_unlock_irq(&clnt->lock);
|
spin_unlock_irq(&clnt->lock);
|
||||||
idr_preload_end();
|
idr_preload_end();
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return fid;
|
return fid;
|
||||||
|
|
||||||
|
@ -1189,7 +1189,6 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
|
||||||
|
|
||||||
p9_debug(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %ud wname[0] %s\n",
|
p9_debug(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %ud wname[0] %s\n",
|
||||||
oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL);
|
oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL);
|
||||||
|
|
||||||
req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid,
|
req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid,
|
||||||
nwname, wnames);
|
nwname, wnames);
|
||||||
if (IS_ERR(req)) {
|
if (IS_ERR(req)) {
|
||||||
|
@ -1221,7 +1220,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
|
||||||
if (nwname)
|
if (nwname)
|
||||||
memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid));
|
memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid));
|
||||||
else
|
else
|
||||||
fid->qid = oldfid->qid;
|
memmove(&fid->qid, &oldfid->qid, sizeof(struct p9_qid));
|
||||||
|
|
||||||
kfree(wqids);
|
kfree(wqids);
|
||||||
return fid;
|
return fid;
|
||||||
|
@ -1274,6 +1273,7 @@ int p9_client_open(struct p9_fid *fid, int mode)
|
||||||
p9_is_proto_dotl(clnt) ? "RLOPEN" : "ROPEN", qid.type,
|
p9_is_proto_dotl(clnt) ? "RLOPEN" : "ROPEN", qid.type,
|
||||||
(unsigned long long)qid.path, qid.version, iounit);
|
(unsigned long long)qid.path, qid.version, iounit);
|
||||||
|
|
||||||
|
memmove(&fid->qid, &qid, sizeof(struct p9_qid));
|
||||||
fid->mode = mode;
|
fid->mode = mode;
|
||||||
fid->iounit = iounit;
|
fid->iounit = iounit;
|
||||||
|
|
||||||
|
@ -1319,6 +1319,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32
|
||||||
(unsigned long long)qid->path,
|
(unsigned long long)qid->path,
|
||||||
qid->version, iounit);
|
qid->version, iounit);
|
||||||
|
|
||||||
|
memmove(&ofid->qid, qid, sizeof(struct p9_qid));
|
||||||
ofid->mode = mode;
|
ofid->mode = mode;
|
||||||
ofid->iounit = iounit;
|
ofid->iounit = iounit;
|
||||||
|
|
||||||
|
@ -1364,6 +1365,7 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
|
||||||
(unsigned long long)qid.path,
|
(unsigned long long)qid.path,
|
||||||
qid.version, iounit);
|
qid.version, iounit);
|
||||||
|
|
||||||
|
memmove(&fid->qid, &qid, sizeof(struct p9_qid));
|
||||||
fid->mode = mode;
|
fid->mode = mode;
|
||||||
fid->iounit = iounit;
|
fid->iounit = iounit;
|
||||||
|
|
||||||
|
@ -1460,12 +1462,14 @@ 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) {
|
if (!fid || IS_ERR(fid)) {
|
||||||
pr_warn("%s (%d): Trying to clunk with NULL fid\n",
|
pr_warn("%s (%d): Trying to clunk with invalid fid\n",
|
||||||
__func__, task_pid_nr(current));
|
__func__, task_pid_nr(current));
|
||||||
dump_stack();
|
dump_stack();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (!refcount_dec_and_test(&fid->count))
|
||||||
|
return 0;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n", fid->fid,
|
p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n", fid->fid,
|
||||||
|
|
Loading…
Reference in New Issue