aboutsummaryrefslogtreecommitdiff
path: root/fs/9p/fid.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/9p/fid.c')
-rw-r--r--fs/9p/fid.c88
1 files changed, 37 insertions, 51 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index 0ee594569dc..d51ec9fafcc 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -41,29 +41,16 @@
*
*/
-int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
+static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid)
{
- struct v9fs_dentry *dent;
-
- P9_DPRINTK(P9_DEBUG_VFS, "fid %d dentry %s\n",
- fid->fid, dentry->d_name.name);
-
- dent = dentry->d_fsdata;
- if (!dent) {
- dent = kmalloc(sizeof(struct v9fs_dentry), GFP_KERNEL);
- if (!dent)
- return -ENOMEM;
-
- spin_lock_init(&dent->lock);
- INIT_LIST_HEAD(&dent->fidlist);
- dentry->d_fsdata = dent;
- }
-
- spin_lock(&dent->lock);
- list_add(&fid->dlist, &dent->fidlist);
- spin_unlock(&dent->lock);
+ hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata);
+}
- return 0;
+void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
+{
+ spin_lock(&dentry->d_lock);
+ __add_fid(dentry, fid);
+ spin_unlock(&dentry->d_lock);
}
/**
@@ -74,24 +61,25 @@ int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
*
*/
-static struct p9_fid *v9fs_fid_find(struct dentry *dentry, u32 uid, int any)
+static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
{
- struct v9fs_dentry *dent;
struct p9_fid *fid, *ret;
- P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n",
- dentry->d_name.name, dentry, uid, any);
- dent = (struct v9fs_dentry *) dentry->d_fsdata;
+ p9_debug(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n",
+ dentry->d_name.name, dentry, from_kuid(&init_user_ns, uid),
+ any);
ret = NULL;
- if (dent) {
- spin_lock(&dent->lock);
- list_for_each_entry(fid, &dent->fidlist, dlist) {
- if (any || fid->uid == uid) {
+ /* we'll recheck under lock if there's anything to look in */
+ if (dentry->d_fsdata) {
+ struct hlist_head *h = (struct hlist_head *)&dentry->d_fsdata;
+ spin_lock(&dentry->d_lock);
+ hlist_for_each_entry(fid, h, dlist) {
+ if (any || uid_eq(fid->uid, uid)) {
ret = fid;
break;
}
}
- spin_unlock(&dent->lock);
+ spin_unlock(&dentry->d_lock);
}
return ret;
@@ -126,7 +114,7 @@ err_out:
}
static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
- uid_t uid, int any)
+ kuid_t uid, int any)
{
struct dentry *ds;
char **wnames, *uname;
@@ -214,8 +202,17 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
}
kfree(wnames);
fid_out:
- if (!IS_ERR(fid))
- v9fs_fid_add(dentry, fid);
+ if (!IS_ERR(fid)) {
+ spin_lock(&dentry->d_lock);
+ if (d_unhashed(dentry)) {
+ spin_unlock(&dentry->d_lock);
+ p9_client_clunk(fid);
+ fid = ERR_PTR(-ENOENT);
+ } else {
+ __add_fid(dentry, fid);
+ spin_unlock(&dentry->d_lock);
+ }
+ }
err_out:
up_read(&v9ses->rename_sem);
return fid;
@@ -233,7 +230,7 @@ err_out:
struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
{
- uid_t uid;
+ kuid_t uid;
int any, access;
struct v9fs_session_info *v9ses;
@@ -253,7 +250,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
break;
default:
- uid = ~0;
+ uid = INVALID_UID;
any = 0;
break;
}
@@ -272,7 +269,7 @@ struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
return ret;
}
-static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, uid_t uid)
+static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, kuid_t uid)
{
struct p9_fid *fid, *ret;
@@ -286,12 +283,10 @@ static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, uid_t uid)
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
{
- int err, flags;
+ int err;
struct p9_fid *fid;
- struct v9fs_session_info *v9ses;
- v9ses = v9fs_dentry2v9ses(dentry);
- fid = v9fs_fid_clone_with_uid(dentry, 0);
+ fid = v9fs_fid_clone_with_uid(dentry, GLOBAL_ROOT_UID);
if (IS_ERR(fid))
goto error_out;
/*
@@ -299,17 +294,8 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
* dirty pages. We always request for the open fid in read-write
* mode so that a partial page write which result in page
* read can work.
- *
- * we don't have a tsyncfs operation for older version
- * of protocol. So make sure the write back fid is
- * opened in O_SYNC mode.
*/
- if (!v9fs_proto_dotl(v9ses))
- flags = O_RDWR | O_SYNC;
- else
- flags = O_RDWR;
-
- err = p9_client_open(fid, flags);
+ err = p9_client_open(fid, O_RDWR);
if (err < 0) {
p9_client_clunk(fid);
fid = ERR_PTR(err);