Skip to content

Commit 8c7424c

Browse files
author
J. Bruce Fields
committed
nfsd4: don't try to encode conflicting owner if low on space
I ran into this corner case in testing: in theory clients can provide state owners up to 1024 bytes long. In the sessions case there might be a risk of this pushing us over the DRC slot size. The conflicting owner isn't really that important, so let's humor a client that provides a small maxresponsize_cached by allowing ourselves to return without the conflicting owner instead of outright failing the operation. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
1 parent f523601 commit 8c7424c

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

fs/nfsd/nfs4proc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1432,7 +1432,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
14321432
#define op_encode_change_info_maxsz (5)
14331433
#define nfs4_fattr_bitmap_maxsz (4)
14341434

1435-
#define op_encode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
1435+
/* We'll fall back on returning no lockowner if run out of space: */
1436+
#define op_encode_lockowner_maxsz (0)
14361437
#define op_encode_lock_denied_maxsz (8 + op_encode_lockowner_maxsz)
14371438

14381439
#define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))

fs/nfsd/nfs4xdr.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2878,17 +2878,27 @@ nfsd4_encode_lock_denied(struct xdr_stream *xdr, struct nfsd4_lock_denied *ld)
28782878
struct xdr_netobj *conf = &ld->ld_owner;
28792879
__be32 *p;
28802880

2881+
again:
28812882
p = xdr_reserve_space(xdr, 32 + XDR_LEN(conf->len));
2882-
if (!p)
2883+
if (!p) {
2884+
/*
2885+
* Don't fail to return the result just because we can't
2886+
* return the conflicting open:
2887+
*/
2888+
if (conf->len) {
2889+
conf->len = 0;
2890+
conf->data = NULL;
2891+
goto again;
2892+
}
28832893
return nfserr_resource;
2894+
}
28842895
WRITE64(ld->ld_start);
28852896
WRITE64(ld->ld_length);
28862897
WRITE32(ld->ld_type);
28872898
if (conf->len) {
28882899
WRITEMEM(&ld->ld_clientid, 8);
28892900
WRITE32(conf->len);
28902901
WRITEMEM(conf->data, conf->len);
2891-
kfree(conf->data);
28922902
} else { /* non - nfsv4 lock in conflict, no clientid nor owner */
28932903
WRITE64((u64)0); /* clientid */
28942904
WRITE32(0); /* length of owner name */
@@ -2905,7 +2915,7 @@ nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lo
29052915
nfserr = nfsd4_encode_stateid(xdr, &lock->lk_resp_stateid);
29062916
else if (nfserr == nfserr_denied)
29072917
nfserr = nfsd4_encode_lock_denied(xdr, &lock->lk_denied);
2908-
2918+
kfree(lock->lk_denied.ld_owner.data);
29092919
return nfserr;
29102920
}
29112921

0 commit comments

Comments
 (0)