NFSD: Treat rq_reserved when initializing xdr_buf
Subsystems (2)
PATCH 1/2 NFSD: Treat rq_reserved when initializing xdr_buf
After calling svc_reserve() with a small length,
nfsd does't treat it in svcxdr_init_encode().
So, when testing conflock, got message as,
[ 970.127216] RPC request reserved 88 but used 116
Signed-off-by Kinglong Mee <[email protected]>
--- fs/nfsd/nfs4proc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/nfsd/nfs4proc.c +5 -2
@@ -1245,17 +1245,20 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp,struct xdr_stream *xdr = &resp->xdr;struct xdr_buf *buf = &rqstp->rq_res;struct kvec *head = buf->head; +int tlen =0 ; xdr->buf = buf; xdr->iov = head; xdr->p = head->iov_base + head->iov_len; - xdr->end = head->iov_base +PAGE_SIZE - rqstp->rq_auth_slack; + tlen =PAGE_SIZE - rqstp->rq_auth_slack; + xdr->end = head->iov_base +min (tlen, rqstp->rq_reserved);/* Tail and page_len should be zero at this point: */ buf->len = buf->head[0 ].iov_len; xdr->scratch.iov_len =0 ; xdr->page_ptr = buf->pages -1 ; - buf->buflen =PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages) + tlen =PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages) - rqstp->rq_auth_slack; + buf->buflen =min (tlen, rqstp->rq_reserved); }/*
Signature · 1 line
1.9.3
Quoted 6 lines · Kinglong Mee
After calling
svc_reserve()with a small length,
nfsd does't treat it insvcxdr_init_encode().So, when testing conflock, got message as,
[ 970.127216] RPC request reserved 88 but used 116
rq_reserved should always be set no smaller than the maximum possible size of the reply, given everything we know about the request.
So the bug is that rq_reserved was set to small.
The risk of returning a reply larger than rq_reserved is a relatively rare deadlock, so I'd rather just stick to the log warning than convert it to a hard error.
The solution in this case is to fix the incorrect estimate.
--b.
Quoted 36 lines
Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4proc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)fs/nfsd/nfs4proc.c +5
-2@@ -1245,17 +1245,20 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp,struct xdr_stream *xdr = &resp->xdr;struct xdr_buf *buf = &rqstp->rq_res;struct kvec *head = buf->head; +int tlen =0 ; xdr->buf = buf; xdr->iov = head; xdr->p = head->iov_base + head->iov_len; - xdr->end = head->iov_base +PAGE_SIZE - rqstp->rq_auth_slack; + tlen =PAGE_SIZE - rqstp->rq_auth_slack; + xdr->end = head->iov_base +min (tlen, rqstp->rq_reserved);/* Tail and page_len should be zero at this point: */ buf->len = buf->head[0 ].iov_len; xdr->scratch.iov_len =0 ; xdr->page_ptr = buf->pages -1 ; - buf->buflen =PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages) + tlen =PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages) - rqstp->rq_auth_slack; + buf->buflen =min (tlen, rqstp->rq_reserved); }/* Signature · 1 line
1.9.3