Merge tag 'nfsd-6.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux

Pull nfsd fixes from Chuck Lever:
"A set of NFSD fixes that arrived just a bit late for the 6.19 merge
window.

Regression fixes:
- Mark variable __maybe_unused to avoid W=1 build break

Stable fixes:
- NFSv4 file creation neglects setting ACL
- Clear TIME_DELEG in the suppattr_exclcreat bitmap
- Clear SECLABEL in the suppattr_exclcreat bitmap
- Fix memory leak in nfsd_create_serv error paths
- Bound check rq_pages index in inline path
- Return 0 on success from svc_rdma_copy_inline_range
- Use rc_pageoff for memcpy byte offset
- Avoid NULL deref on zero length gss_token in gss_read_proxy_verf"

* tag 'nfsd-6.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux:
NFSD: NFSv4 file creation neglects setting ACL
NFSD: Clear TIME_DELEG in the suppattr_exclcreat bitmap
NFSD: Clear SECLABEL in the suppattr_exclcreat bitmap
nfsd: fix memory leak in nfsd_create_serv error paths
nfsd: Mark variable __maybe_unused to avoid W=1 build break
svcrdma: bound check rq_pages index in inline path
svcrdma: return 0 on success from svc_rdma_copy_inline_range
svcrdma: use rc_pageoff for memcpy byte offset
SUNRPC: svcauth_gss: avoid NULL deref on zero length gss_token in gss_read_proxy_verf

+26 -7
+1 -1
fs/nfsd/export.c
··· 1024 { 1025 struct svc_export *exp; 1026 struct path path; 1027 - struct inode *inode; 1028 struct svc_fh fh; 1029 int err; 1030 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
··· 1024 { 1025 struct svc_export *exp; 1026 struct path path; 1027 + struct inode *inode __maybe_unused; 1028 struct svc_fh fh; 1029 int err; 1030 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+5
fs/nfsd/nfs4xdr.c
··· 3375 u32 supp[3]; 3376 3377 memcpy(supp, nfsd_suppattrs[resp->cstate.minorversion], sizeof(supp)); 3378 supp[0] &= NFSD_SUPPATTR_EXCLCREAT_WORD0; 3379 supp[1] &= NFSD_SUPPATTR_EXCLCREAT_WORD1; 3380 supp[2] &= NFSD_SUPPATTR_EXCLCREAT_WORD2;
··· 3375 u32 supp[3]; 3376 3377 memcpy(supp, nfsd_suppattrs[resp->cstate.minorversion], sizeof(supp)); 3378 + if (!IS_POSIXACL(d_inode(args->dentry))) 3379 + supp[0] &= ~FATTR4_WORD0_ACL; 3380 + if (!args->contextsupport) 3381 + supp[2] &= ~FATTR4_WORD2_SECURITY_LABEL; 3382 + 3383 supp[0] &= NFSD_SUPPATTR_EXCLCREAT_WORD0; 3384 supp[1] &= NFSD_SUPPATTR_EXCLCREAT_WORD1; 3385 supp[2] &= NFSD_SUPPATTR_EXCLCREAT_WORD2;
+7 -1
fs/nfsd/nfsd.h
··· 547 #define NFSD_SUPPATTR_EXCLCREAT_WORD1 \ 548 (NFSD_WRITEABLE_ATTRS_WORD1 & \ 549 ~(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)) 550 #define NFSD_SUPPATTR_EXCLCREAT_WORD2 \ 551 - NFSD_WRITEABLE_ATTRS_WORD2 552 553 extern int nfsd4_is_junction(struct dentry *dentry); 554 extern int register_cld_notifier(void);
··· 547 #define NFSD_SUPPATTR_EXCLCREAT_WORD1 \ 548 (NFSD_WRITEABLE_ATTRS_WORD1 & \ 549 ~(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)) 550 + /* 551 + * The FATTR4_WORD2_TIME_DELEG attributes are not to be allowed for 552 + * OPEN(create) with EXCLUSIVE4_1. It doesn't make sense to set a 553 + * delegated timestamp on a new file. 554 + */ 555 #define NFSD_SUPPATTR_EXCLCREAT_WORD2 \ 556 + (NFSD_WRITEABLE_ATTRS_WORD2 & \ 557 + ~(FATTR4_WORD2_TIME_DELEG_ACCESS | FATTR4_WORD2_TIME_DELEG_MODIFY)) 558 559 extern int nfsd4_is_junction(struct dentry *dentry); 560 extern int register_cld_notifier(void);
+4 -1
fs/nfsd/nfssvc.c
··· 615 serv = svc_create_pooled(nfsd_programs, ARRAY_SIZE(nfsd_programs), 616 &nn->nfsd_svcstats, 617 nfsd_max_blksize, nfsd); 618 - if (serv == NULL) 619 return -ENOMEM; 620 621 error = svc_bind(serv, net); 622 if (error < 0) { 623 svc_destroy(&serv); 624 return error; 625 } 626 spin_lock(&nfsd_notifier_lock);
··· 615 serv = svc_create_pooled(nfsd_programs, ARRAY_SIZE(nfsd_programs), 616 &nn->nfsd_svcstats, 617 nfsd_max_blksize, nfsd); 618 + if (serv == NULL) { 619 + percpu_ref_exit(&nn->nfsd_net_ref); 620 return -ENOMEM; 621 + } 622 623 error = svc_bind(serv, net); 624 if (error < 0) { 625 svc_destroy(&serv); 626 + percpu_ref_exit(&nn->nfsd_net_ref); 627 return error; 628 } 629 spin_lock(&nfsd_notifier_lock);
+2 -1
fs/nfsd/vfs.h
··· 67 struct iattr *iap = attrs->na_iattr; 68 69 return (iap->ia_valid || (attrs->na_seclabel && 70 - attrs->na_seclabel->len)); 71 } 72 73 __be32 nfserrno (int errno);
··· 67 struct iattr *iap = attrs->na_iattr; 68 69 return (iap->ia_valid || (attrs->na_seclabel && 70 + attrs->na_seclabel->len) || 71 + attrs->na_pacl || attrs->na_dpacl); 72 } 73 74 __be32 nfserrno (int errno);
+2 -1
net/sunrpc/auth_gss/svcauth_gss.c
··· 1083 } 1084 1085 length = min_t(unsigned int, inlen, (char *)xdr->end - (char *)xdr->p); 1086 - memcpy(page_address(in_token->pages[0]), xdr->p, length); 1087 inlen -= length; 1088 1089 to_offs = length;
··· 1083 } 1084 1085 length = min_t(unsigned int, inlen, (char *)xdr->end - (char *)xdr->p); 1086 + if (length) 1087 + memcpy(page_address(in_token->pages[0]), xdr->p, length); 1088 inlen -= length; 1089 1090 to_offs = length;
+5 -2
net/sunrpc/xprtrdma/svc_rdma_rw.c
··· 841 for (page_no = 0; page_no < numpages; page_no++) { 842 unsigned int page_len; 843 844 page_len = min_t(unsigned int, remaining, 845 PAGE_SIZE - head->rc_pageoff); 846 ··· 851 head->rc_page_count++; 852 853 dst = page_address(rqstp->rq_pages[head->rc_curpage]); 854 - memcpy(dst + head->rc_curpage, src + offset, page_len); 855 856 head->rc_readbytes += page_len; 857 head->rc_pageoff += page_len; ··· 863 offset += page_len; 864 } 865 866 - return -EINVAL; 867 } 868 869 /**
··· 841 for (page_no = 0; page_no < numpages; page_no++) { 842 unsigned int page_len; 843 844 + if (head->rc_curpage >= rqstp->rq_maxpages) 845 + return -EINVAL; 846 + 847 page_len = min_t(unsigned int, remaining, 848 PAGE_SIZE - head->rc_pageoff); 849 ··· 848 head->rc_page_count++; 849 850 dst = page_address(rqstp->rq_pages[head->rc_curpage]); 851 + memcpy((unsigned char *)dst + head->rc_pageoff, src + offset, page_len); 852 853 head->rc_readbytes += page_len; 854 head->rc_pageoff += page_len; ··· 860 offset += page_len; 861 } 862 863 + return 0; 864 } 865 866 /**