diff options
author | Eric Van Hensbergen <ericvh@gmail.com> | 2009-11-02 09:39:28 -0500 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@gmail.com> | 2009-11-02 09:43:45 -0500 |
commit | 3e2796a90cf349527e50b3bc4d0b2f4019b1ce7a (patch) | |
tree | 80bddc0f5d36a589db5a77b9b60e4c94c75994ed /net/9p | |
parent | 2511cd0b3b9e9b1c3e9360cc565c3745ac3f3f3f (diff) |
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/9p')
-rw-r--r-- | net/9p/client.c | 5 |
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) | |||
582 | 582 | ||
583 | memset(&fid->qid, 0, sizeof(struct p9_qid)); | 583 | memset(&fid->qid, 0, sizeof(struct p9_qid)); |
584 | fid->mode = -1; | 584 | fid->mode = -1; |
585 | fid->rdir_fpos = 0; | ||
586 | fid->uid = current_fsuid(); | 585 | fid->uid = current_fsuid(); |
587 | fid->clnt = clnt; | 586 | fid->clnt = clnt; |
588 | fid->aux = NULL; | 587 | fid->rdir = NULL; |
589 | |||
590 | spin_lock_irqsave(&clnt->lock, flags); | 588 | spin_lock_irqsave(&clnt->lock, flags); |
591 | list_add(&fid->flist, &clnt->fidlist); | 589 | list_add(&fid->flist, &clnt->fidlist); |
592 | spin_unlock_irqrestore(&clnt->lock, flags); | 590 | spin_unlock_irqrestore(&clnt->lock, flags); |
@@ -609,6 +607,7 @@ static void p9_fid_destroy(struct p9_fid *fid) | |||
609 | spin_lock_irqsave(&clnt->lock, flags); | 607 | spin_lock_irqsave(&clnt->lock, flags); |
610 | list_del(&fid->flist); | 608 | list_del(&fid->flist); |
611 | spin_unlock_irqrestore(&clnt->lock, flags); | 609 | spin_unlock_irqrestore(&clnt->lock, flags); |
610 | kfree(fid->rdir); | ||
612 | kfree(fid); | 611 | kfree(fid); |
613 | } | 612 | } |
614 | 613 | ||