summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric Van Hensbergen <ericvh@gmail.com>2009-11-02 08:39:28 -0600
committerEric Van Hensbergen <ericvh@gmail.com>2009-11-02 08:43:45 -0600
commit3e2796a90cf349527e50b3bc4d0b2f4019b1ce7a (patch)
tree80bddc0f5d36a589db5a77b9b60e4c94c75994ed /net
parent2511cd0b3b9e9b1c3e9360cc565c3745ac3f3f3f (diff)
downloadlinux-3e2796a90cf349527e50b3bc4d0b2f4019b1ce7a.tar.gz
linux-3e2796a90cf349527e50b3bc4d0b2f4019b1ce7a.tar.bz2
linux-3e2796a90cf349527e50b3bc4d0b2f4019b1ce7a.zip
9p: fix readdir corner cases
The patch below also addresses a couple of other corner cases in readdir seen with a large (e.g. 64k) msize. I'm not sure what people think of my co-opting of fid->aux here. I'd be happy to rework if there's a better way. When the size of the user supplied buffer passed to readdir is smaller than the data returned in one go by the 9P read request, v9fs_dir_readdir() currently discards extra data so that, on the next call, a 9P read request will be issued with offset < previous offset + bytes returned, which voilates the constraint described in paragraph 3 of read(5) description. This patch preseves the leftover data in fid->aux for use in the next call. Signed-off-by: Jim Garlick <garlick@llnl.gov> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'net')
-rw-r--r--net/9p/client.c5
1 files changed, 2 insertions, 3 deletions
diff --git a/net/9p/client.c b/net/9p/client.c
index 5bf5f227dbe0..8af95b2dddd6 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -582,11 +582,9 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
memset(&fid->qid, 0, sizeof(struct p9_qid));
fid->mode = -1;
- fid->rdir_fpos = 0;
fid->uid = current_fsuid();
fid->clnt = clnt;
- fid->aux = NULL;
-
+ fid->rdir = NULL;
spin_lock_irqsave(&clnt->lock, flags);
list_add(&fid->flist, &clnt->fidlist);
spin_unlock_irqrestore(&clnt->lock, flags);
@@ -609,6 +607,7 @@ static void p9_fid_destroy(struct p9_fid *fid)
spin_lock_irqsave(&clnt->lock, flags);
list_del(&fid->flist);
spin_unlock_irqrestore(&clnt->lock, flags);
+ kfree(fid->rdir);
kfree(fid);
}