hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/nfsd/nfs3xdr.c
....@@ -27,18 +27,19 @@
2727 NF3SOCK, NF3BAD, NF3LNK, NF3BAD,
2828 };
2929
30
+
3031 /*
3132 * XDR functions for basic NFS types
3233 */
3334 static __be32 *
34
-encode_time3(__be32 *p, struct timespec *time)
35
+encode_time3(__be32 *p, struct timespec64 *time)
3536 {
3637 *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec);
3738 return p;
3839 }
3940
4041 static __be32 *
41
-decode_time3(__be32 *p, struct timespec *time)
42
+decode_time3(__be32 *p, struct timespec64 *time)
4243 {
4344 time->tv_sec = ntohl(*p++);
4445 time->tv_nsec = ntohl(*p++);
....@@ -96,7 +97,7 @@
9697 }
9798
9899 static __be32 *
99
-decode_sattr3(__be32 *p, struct iattr *iap)
100
+decode_sattr3(__be32 *p, struct iattr *iap, struct user_namespace *userns)
100101 {
101102 u32 tmp;
102103
....@@ -107,12 +108,12 @@
107108 iap->ia_mode = ntohl(*p++);
108109 }
109110 if (*p++) {
110
- iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++));
111
+ iap->ia_uid = make_kuid(userns, ntohl(*p++));
111112 if (uid_valid(iap->ia_uid))
112113 iap->ia_valid |= ATTR_UID;
113114 }
114115 if (*p++) {
115
- iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++));
116
+ iap->ia_gid = make_kgid(userns, ntohl(*p++));
116117 if (gid_valid(iap->ia_gid))
117118 iap->ia_valid |= ATTR_GID;
118119 }
....@@ -165,12 +166,12 @@
165166 encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
166167 struct kstat *stat)
167168 {
168
- struct timespec ts;
169
+ struct user_namespace *userns = nfsd_user_namespace(rqstp);
169170 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
170171 *p++ = htonl((u32) (stat->mode & S_IALLUGO));
171172 *p++ = htonl((u32) stat->nlink);
172
- *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
173
- *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
173
+ *p++ = htonl((u32) from_kuid_munged(userns, stat->uid));
174
+ *p++ = htonl((u32) from_kgid_munged(userns, stat->gid));
174175 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
175176 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
176177 } else {
....@@ -181,12 +182,9 @@
181182 *p++ = htonl((u32) MINOR(stat->rdev));
182183 p = encode_fsid(p, fhp);
183184 p = xdr_encode_hyper(p, stat->ino);
184
- ts = timespec64_to_timespec(stat->atime);
185
- p = encode_time3(p, &ts);
186
- ts = timespec64_to_timespec(stat->mtime);
187
- p = encode_time3(p, &ts);
188
- ts = timespec64_to_timespec(stat->ctime);
189
- p = encode_time3(p, &ts);
185
+ p = encode_time3(p, &stat->atime);
186
+ p = encode_time3(p, &stat->mtime);
187
+ p = encode_time3(p, &stat->ctime);
190188
191189 return p;
192190 }
....@@ -275,8 +273,8 @@
275273 stat.size = inode->i_size;
276274 }
277275
278
- fhp->fh_pre_mtime = timespec64_to_timespec(stat.mtime);
279
- fhp->fh_pre_ctime = timespec64_to_timespec(stat.ctime);
276
+ fhp->fh_pre_mtime = stat.mtime;
277
+ fhp->fh_pre_ctime = stat.ctime;
280278 fhp->fh_pre_size = stat.size;
281279 fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
282280 fhp->fh_pre_saved = true;
....@@ -307,6 +305,12 @@
307305 * XDR decode functions
308306 */
309307 int
308
+nfs3svc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p)
309
+{
310
+ return 1;
311
+}
312
+
313
+int
310314 nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p)
311315 {
312316 struct nfsd_fhandle *args = rqstp->rq_argp;
....@@ -325,10 +329,10 @@
325329 p = decode_fh(p, &args->fh);
326330 if (!p)
327331 return 0;
328
- p = decode_sattr3(p, &args->attrs);
332
+ p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
329333
330334 if ((args->check_guard = ntohl(*p++)) != 0) {
331
- struct timespec time;
335
+ struct timespec64 time;
332336 p = decode_time3(p, &time);
333337 args->guardtime = time.tv_sec;
334338 }
....@@ -455,7 +459,7 @@
455459 switch (args->createmode = ntohl(*p++)) {
456460 case NFS3_CREATE_UNCHECKED:
457461 case NFS3_CREATE_GUARDED:
458
- p = decode_sattr3(p, &args->attrs);
462
+ p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
459463 break;
460464 case NFS3_CREATE_EXCLUSIVE:
461465 args->verf = p;
....@@ -476,7 +480,7 @@
476480 if (!(p = decode_fh(p, &args->fh)) ||
477481 !(p = decode_filename(p, &args->name, &args->len)))
478482 return 0;
479
- p = decode_sattr3(p, &args->attrs);
483
+ p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
480484
481485 return xdr_argsize_check(rqstp, p);
482486 }
....@@ -491,7 +495,7 @@
491495 if (!(p = decode_fh(p, &args->ffh)) ||
492496 !(p = decode_filename(p, &args->fname, &args->flen)))
493497 return 0;
494
- p = decode_sattr3(p, &args->attrs);
498
+ p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
495499
496500 args->tlen = ntohl(*p++);
497501
....@@ -519,7 +523,7 @@
519523
520524 if (args->ftype == NF3BLK || args->ftype == NF3CHR
521525 || args->ftype == NF3SOCK || args->ftype == NF3FIFO)
522
- p = decode_sattr3(p, &args->attrs);
526
+ p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
523527
524528 if (args->ftype == NF3BLK || args->ftype == NF3CHR) {
525529 args->major = ntohl(*p++);
....@@ -573,6 +577,9 @@
573577 nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
574578 {
575579 struct nfsd3_readdirargs *args = rqstp->rq_argp;
580
+ int len;
581
+ u32 max_blocksize = svc_max_payload(rqstp);
582
+
576583 p = decode_fh(p, &args->fh);
577584 if (!p)
578585 return 0;
....@@ -580,8 +587,14 @@
580587 args->verf = p; p += 2;
581588 args->dircount = ~0;
582589 args->count = ntohl(*p++);
583
- args->count = min_t(u32, args->count, PAGE_SIZE);
584
- args->buffer = page_address(*(rqstp->rq_next_page++));
590
+ len = args->count = min_t(u32, args->count, max_blocksize);
591
+
592
+ while (len > 0) {
593
+ struct page *p = *(rqstp->rq_next_page++);
594
+ if (!args->buffer)
595
+ args->buffer = page_address(p);
596
+ len -= PAGE_SIZE;
597
+ }
585598
586599 return xdr_argsize_check(rqstp, p);
587600 }
....@@ -628,10 +641,7 @@
628641 /*
629642 * XDR encode functions
630643 */
631
-/*
632
- * There must be an encoding function for void results so svc_process
633
- * will work properly.
634
- */
644
+
635645 int
636646 nfs3svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p)
637647 {
....@@ -644,6 +654,7 @@
644654 {
645655 struct nfsd3_attrstat *resp = rqstp->rq_resp;
646656
657
+ *p++ = resp->status;
647658 if (resp->status == 0) {
648659 lease_get_mtime(d_inode(resp->fh.fh_dentry),
649660 &resp->stat.mtime);
....@@ -658,6 +669,7 @@
658669 {
659670 struct nfsd3_attrstat *resp = rqstp->rq_resp;
660671
672
+ *p++ = resp->status;
661673 p = encode_wcc_data(rqstp, p, &resp->fh);
662674 return xdr_ressize_check(rqstp, p);
663675 }
....@@ -668,6 +680,7 @@
668680 {
669681 struct nfsd3_diropres *resp = rqstp->rq_resp;
670682
683
+ *p++ = resp->status;
671684 if (resp->status == 0) {
672685 p = encode_fh(p, &resp->fh);
673686 p = encode_post_op_attr(rqstp, p, &resp->fh);
....@@ -682,6 +695,7 @@
682695 {
683696 struct nfsd3_accessres *resp = rqstp->rq_resp;
684697
698
+ *p++ = resp->status;
685699 p = encode_post_op_attr(rqstp, p, &resp->fh);
686700 if (resp->status == 0)
687701 *p++ = htonl(resp->access);
....@@ -694,6 +708,7 @@
694708 {
695709 struct nfsd3_readlinkres *resp = rqstp->rq_resp;
696710
711
+ *p++ = resp->status;
697712 p = encode_post_op_attr(rqstp, p, &resp->fh);
698713 if (resp->status == 0) {
699714 *p++ = htonl(resp->len);
....@@ -716,6 +731,7 @@
716731 {
717732 struct nfsd3_readres *resp = rqstp->rq_resp;
718733
734
+ *p++ = resp->status;
719735 p = encode_post_op_attr(rqstp, p, &resp->fh);
720736 if (resp->status == 0) {
721737 *p++ = htonl(resp->count);
....@@ -740,15 +756,14 @@
740756 nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p)
741757 {
742758 struct nfsd3_writeres *resp = rqstp->rq_resp;
743
- struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
744759
760
+ *p++ = resp->status;
745761 p = encode_wcc_data(rqstp, p, &resp->fh);
746762 if (resp->status == 0) {
747763 *p++ = htonl(resp->count);
748764 *p++ = htonl(resp->committed);
749
- /* unique identifier, y2038 overflow can be ignored */
750
- *p++ = htonl((u32)nn->nfssvc_boot.tv_sec);
751
- *p++ = htonl(nn->nfssvc_boot.tv_nsec);
765
+ *p++ = resp->verf[0];
766
+ *p++ = resp->verf[1];
752767 }
753768 return xdr_ressize_check(rqstp, p);
754769 }
....@@ -759,6 +774,7 @@
759774 {
760775 struct nfsd3_diropres *resp = rqstp->rq_resp;
761776
777
+ *p++ = resp->status;
762778 if (resp->status == 0) {
763779 *p++ = xdr_one;
764780 p = encode_fh(p, &resp->fh);
....@@ -774,6 +790,7 @@
774790 {
775791 struct nfsd3_renameres *resp = rqstp->rq_resp;
776792
793
+ *p++ = resp->status;
777794 p = encode_wcc_data(rqstp, p, &resp->ffh);
778795 p = encode_wcc_data(rqstp, p, &resp->tfh);
779796 return xdr_ressize_check(rqstp, p);
....@@ -785,6 +802,7 @@
785802 {
786803 struct nfsd3_linkres *resp = rqstp->rq_resp;
787804
805
+ *p++ = resp->status;
788806 p = encode_post_op_attr(rqstp, p, &resp->fh);
789807 p = encode_wcc_data(rqstp, p, &resp->tfh);
790808 return xdr_ressize_check(rqstp, p);
....@@ -796,6 +814,7 @@
796814 {
797815 struct nfsd3_readdirres *resp = rqstp->rq_resp;
798816
817
+ *p++ = resp->status;
799818 p = encode_post_op_attr(rqstp, p, &resp->fh);
800819
801820 if (resp->status == 0) {
....@@ -855,12 +874,10 @@
855874 } else
856875 dchild = dget(dparent);
857876 } else
858
- dchild = lookup_one_len_unlocked(name, dparent, namlen);
877
+ dchild = lookup_positive_unlocked(name, dparent, namlen);
859878 if (IS_ERR(dchild))
860879 return rv;
861880 if (d_mountpoint(dchild))
862
- goto out;
863
- if (d_really_is_negative(dchild))
864881 goto out;
865882 if (dchild->d_inode->i_ino != ino)
866883 goto out;
....@@ -1055,6 +1072,7 @@
10551072 struct kstatfs *s = &resp->stats;
10561073 u64 bs = s->f_bsize;
10571074
1075
+ *p++ = resp->status;
10581076 *p++ = xdr_zero; /* no post_op_attr */
10591077
10601078 if (resp->status == 0) {
....@@ -1075,6 +1093,7 @@
10751093 {
10761094 struct nfsd3_fsinfores *resp = rqstp->rq_resp;
10771095
1096
+ *p++ = resp->status;
10781097 *p++ = xdr_zero; /* no post_op_attr */
10791098
10801099 if (resp->status == 0) {
....@@ -1100,6 +1119,7 @@
11001119 {
11011120 struct nfsd3_pathconfres *resp = rqstp->rq_resp;
11021121
1122
+ *p++ = resp->status;
11031123 *p++ = xdr_zero; /* no post_op_attr */
11041124
11051125 if (resp->status == 0) {
....@@ -1119,14 +1139,13 @@
11191139 nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p)
11201140 {
11211141 struct nfsd3_commitres *resp = rqstp->rq_resp;
1122
- struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
11231142
1143
+ *p++ = resp->status;
11241144 p = encode_wcc_data(rqstp, p, &resp->fh);
11251145 /* Write verifier */
11261146 if (resp->status == 0) {
1127
- /* unique identifier, y2038 overflow can be ignored */
1128
- *p++ = htonl((u32)nn->nfssvc_boot.tv_sec);
1129
- *p++ = htonl(nn->nfssvc_boot.tv_nsec);
1147
+ *p++ = resp->verf[0];
1148
+ *p++ = resp->verf[1];
11301149 }
11311150 return xdr_ressize_check(rqstp, p);
11321151 }