diff options
author | Bryan Schumaker <bjschuma@netapp.com> | 2010-10-20 15:44:31 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-10-23 15:27:34 -0400 |
commit | afa8ccc978c24d8ab22e3b3b8cbd1054c84c070b (patch) | |
tree | 77a05498dd1decb19f296f0e9f60da0916a40bbd /fs/nfs/nfs4xdr.c | |
parent | babddc72a9468884ce1a23db3c3d54b0afa299f0 (diff) |
NFS: remove page size checking code
Remove the page size checking code for a readdir decode. This is now done
by decode_dirent with xdr_streams.
Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 68 |
1 files changed, 1 insertions, 67 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index a4919e999354..8346e977d837 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -4200,12 +4200,9 @@ out_overflow: | |||
4200 | static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir) | 4200 | static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir) |
4201 | { | 4201 | { |
4202 | struct xdr_buf *rcvbuf = &req->rq_rcv_buf; | 4202 | struct xdr_buf *rcvbuf = &req->rq_rcv_buf; |
4203 | struct page *page = *rcvbuf->pages; | ||
4204 | struct kvec *iov = rcvbuf->head; | 4203 | struct kvec *iov = rcvbuf->head; |
4205 | size_t hdrlen; | 4204 | size_t hdrlen; |
4206 | u32 recvd, pglen = rcvbuf->page_len; | 4205 | u32 recvd, pglen = rcvbuf->page_len; |
4207 | __be32 *end, *entry, *p, *kaddr; | ||
4208 | unsigned int nr = 0; | ||
4209 | int status; | 4206 | int status; |
4210 | 4207 | ||
4211 | status = decode_op_hdr(xdr, OP_READDIR); | 4208 | status = decode_op_hdr(xdr, OP_READDIR); |
@@ -4225,71 +4222,8 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n | |||
4225 | pglen = recvd; | 4222 | pglen = recvd; |
4226 | xdr_read_pages(xdr, pglen); | 4223 | xdr_read_pages(xdr, pglen); |
4227 | 4224 | ||
4228 | BUG_ON(pglen + readdir->pgbase > PAGE_CACHE_SIZE); | 4225 | |
4229 | kaddr = p = kmap_atomic(page, KM_USER0); | ||
4230 | end = p + ((pglen + readdir->pgbase) >> 2); | ||
4231 | entry = p; | ||
4232 | |||
4233 | /* Make sure the packet actually has a value_follows and EOF entry */ | ||
4234 | if ((entry + 1) > end) | ||
4235 | goto short_pkt; | ||
4236 | |||
4237 | for (; *p++; nr++) { | ||
4238 | u32 len, attrlen, xlen; | ||
4239 | if (end - p < 3) | ||
4240 | goto short_pkt; | ||
4241 | dprintk("cookie = %Lu, ", *((unsigned long long *)p)); | ||
4242 | p += 2; /* cookie */ | ||
4243 | len = ntohl(*p++); /* filename length */ | ||
4244 | if (len > NFS4_MAXNAMLEN) { | ||
4245 | dprintk("NFS: giant filename in readdir (len 0x%x)\n", | ||
4246 | len); | ||
4247 | goto err_unmap; | ||
4248 | } | ||
4249 | xlen = XDR_QUADLEN(len); | ||
4250 | if (end - p < xlen + 1) | ||
4251 | goto short_pkt; | ||
4252 | dprintk("filename = %*s\n", len, (char *)p); | ||
4253 | p += xlen; | ||
4254 | len = ntohl(*p++); /* bitmap length */ | ||
4255 | if (end - p < len + 1) | ||
4256 | goto short_pkt; | ||
4257 | p += len; | ||
4258 | attrlen = XDR_QUADLEN(ntohl(*p++)); | ||
4259 | if (end - p < attrlen + 2) | ||
4260 | goto short_pkt; | ||
4261 | p += attrlen; /* attributes */ | ||
4262 | entry = p; | ||
4263 | } | ||
4264 | /* | ||
4265 | * Apparently some server sends responses that are a valid size, but | ||
4266 | * contain no entries, and have value_follows==0 and EOF==0. For | ||
4267 | * those, just set the EOF marker. | ||
4268 | */ | ||
4269 | if (!nr && entry[1] == 0) { | ||
4270 | dprintk("NFS: readdir reply truncated!\n"); | ||
4271 | entry[1] = 1; | ||
4272 | } | ||
4273 | out: | ||
4274 | kunmap_atomic(kaddr, KM_USER0); | ||
4275 | return 0; | 4226 | return 0; |
4276 | short_pkt: | ||
4277 | /* | ||
4278 | * When we get a short packet there are 2 possibilities. We can | ||
4279 | * return an error, or fix up the response to look like a valid | ||
4280 | * response and return what we have so far. If there are no | ||
4281 | * entries and the packet was short, then return -EIO. If there | ||
4282 | * are valid entries in the response, return them and pretend that | ||
4283 | * the call was successful, but incomplete. The caller can retry the | ||
4284 | * readdir starting at the last cookie. | ||
4285 | */ | ||
4286 | dprintk("%s: short packet at entry %d\n", __func__, nr); | ||
4287 | entry[0] = entry[1] = 0; | ||
4288 | if (nr) | ||
4289 | goto out; | ||
4290 | err_unmap: | ||
4291 | kunmap_atomic(kaddr, KM_USER0); | ||
4292 | return -errno_NFSERR_IO; | ||
4293 | } | 4227 | } |
4294 | 4228 | ||
4295 | static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) | 4229 | static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) |