diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 3d681a2c2731..3304984c0fad 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -38,6 +38,33 @@ void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) spin_unlock(&dentry->d_lock); } +/** + * v9fs_fid_find_inode - search for a fid off of the client 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 p9_client *clnt = v9fs_inode2v9ses(inode)->clnt; + struct p9_fid *fid, *fidptr, *ret = NULL; + unsigned long flags; + + p9_debug(P9_DEBUG_VFS, " inode: %p\n", inode); + + spin_lock_irqsave(&clnt->lock, flags); + list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) { + if (uid_eq(fid->uid, uid) && + (inode->i_ino == v9fs_qid2ino(&fid->qid))) { + ret = fid; + break; + } + } + spin_unlock_irqrestore(&clnt->lock, flags); + return ret; +} + /** * v9fs_fid_find - retrieve a fid that belongs to the specified uid * @dentry: dentry to look for fid in @@ -65,6 +92,9 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any) } } spin_unlock(&dentry->d_lock); + } else { + if (dentry->d_inode) + ret = v9fs_fid_find_inode(dentry->d_inode, uid); } return ret; diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index ae0c38ad1fcb..31c2fddabb82 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -570,6 +570,10 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags) v9fs_invalidate_inode_attr(inode); 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; } diff --git a/net/9p/client.c b/net/9p/client.c index 09f1ec589b80..1a3f72bf45fc 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -1219,7 +1219,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname, if (nwname) memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid)); else - fid->qid = oldfid->qid; + memmove(&fid->qid, &oldfid->qid, sizeof(struct p9_qid)); kfree(wqids); return fid; @@ -1272,6 +1272,7 @@ int p9_client_open(struct p9_fid *fid, int mode) p9_is_proto_dotl(clnt) ? "RLOPEN" : "ROPEN", qid.type, (unsigned long long)qid.path, qid.version, iounit); + memmove(&fid->qid, &qid, sizeof(struct p9_qid)); fid->mode = mode; fid->iounit = iounit; @@ -1317,6 +1318,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32 (unsigned long long)qid->path, qid->version, iounit); + memmove(&ofid->qid, qid, sizeof(struct p9_qid)); ofid->mode = mode; ofid->iounit = iounit; @@ -1362,6 +1364,7 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode, (unsigned long long)qid.path, qid.version, iounit); + memmove(&fid->qid, &qid, sizeof(struct p9_qid)); fid->mode = mode; fid->iounit = iounit;