0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/namei.h>
0011 #include <linux/sunrpc/svc_xprt.h>
0012 #include "xdr3.h"
0013 #include "auth.h"
0014 #include "netns.h"
0015 #include "vfs.h"
0016
0017
0018
0019
0020 static const struct svc_fh nfs3svc_null_fh = {
0021 .fh_no_wcc = true,
0022 };
0023
0024
0025
0026
0027
0028 static const struct timespec64 nfs3svc_time_delta = {
0029 .tv_sec = 1,
0030 .tv_nsec = 0,
0031 };
0032
0033
0034
0035
0036 static const u32 nfs3_ftypes[] = {
0037 NF3NON, NF3FIFO, NF3CHR, NF3BAD,
0038 NF3DIR, NF3BAD, NF3BLK, NF3BAD,
0039 NF3REG, NF3BAD, NF3LNK, NF3BAD,
0040 NF3SOCK, NF3BAD, NF3LNK, NF3BAD,
0041 };
0042
0043
0044
0045
0046
0047
0048 static __be32 *
0049 encode_nfstime3(__be32 *p, const struct timespec64 *time)
0050 {
0051 *p++ = cpu_to_be32((u32)time->tv_sec);
0052 *p++ = cpu_to_be32(time->tv_nsec);
0053
0054 return p;
0055 }
0056
0057 static bool
0058 svcxdr_decode_nfstime3(struct xdr_stream *xdr, struct timespec64 *timep)
0059 {
0060 __be32 *p;
0061
0062 p = xdr_inline_decode(xdr, XDR_UNIT * 2);
0063 if (!p)
0064 return false;
0065 timep->tv_sec = be32_to_cpup(p++);
0066 timep->tv_nsec = be32_to_cpup(p);
0067
0068 return true;
0069 }
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 bool
0081 svcxdr_decode_nfs_fh3(struct xdr_stream *xdr, struct svc_fh *fhp)
0082 {
0083 __be32 *p;
0084 u32 size;
0085
0086 if (xdr_stream_decode_u32(xdr, &size) < 0)
0087 return false;
0088 if (size == 0 || size > NFS3_FHSIZE)
0089 return false;
0090 p = xdr_inline_decode(xdr, size);
0091 if (!p)
0092 return false;
0093 fh_init(fhp, NFS3_FHSIZE);
0094 fhp->fh_handle.fh_size = size;
0095 memcpy(&fhp->fh_handle.fh_raw, p, size);
0096
0097 return true;
0098 }
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 bool
0110 svcxdr_encode_nfsstat3(struct xdr_stream *xdr, __be32 status)
0111 {
0112 __be32 *p;
0113
0114 p = xdr_reserve_space(xdr, sizeof(status));
0115 if (!p)
0116 return false;
0117 *p = status;
0118
0119 return true;
0120 }
0121
0122 static bool
0123 svcxdr_encode_nfs_fh3(struct xdr_stream *xdr, const struct svc_fh *fhp)
0124 {
0125 u32 size = fhp->fh_handle.fh_size;
0126 __be32 *p;
0127
0128 p = xdr_reserve_space(xdr, XDR_UNIT + size);
0129 if (!p)
0130 return false;
0131 *p++ = cpu_to_be32(size);
0132 if (size)
0133 p[XDR_QUADLEN(size) - 1] = 0;
0134 memcpy(p, &fhp->fh_handle.fh_raw, size);
0135
0136 return true;
0137 }
0138
0139 static bool
0140 svcxdr_encode_post_op_fh3(struct xdr_stream *xdr, const struct svc_fh *fhp)
0141 {
0142 if (xdr_stream_encode_item_present(xdr) < 0)
0143 return false;
0144 if (!svcxdr_encode_nfs_fh3(xdr, fhp))
0145 return false;
0146
0147 return true;
0148 }
0149
0150 static bool
0151 svcxdr_encode_cookieverf3(struct xdr_stream *xdr, const __be32 *verf)
0152 {
0153 __be32 *p;
0154
0155 p = xdr_reserve_space(xdr, NFS3_COOKIEVERFSIZE);
0156 if (!p)
0157 return false;
0158 memcpy(p, verf, NFS3_COOKIEVERFSIZE);
0159
0160 return true;
0161 }
0162
0163 static bool
0164 svcxdr_encode_writeverf3(struct xdr_stream *xdr, const __be32 *verf)
0165 {
0166 __be32 *p;
0167
0168 p = xdr_reserve_space(xdr, NFS3_WRITEVERFSIZE);
0169 if (!p)
0170 return false;
0171 memcpy(p, verf, NFS3_WRITEVERFSIZE);
0172
0173 return true;
0174 }
0175
0176 static bool
0177 svcxdr_decode_filename3(struct xdr_stream *xdr, char **name, unsigned int *len)
0178 {
0179 u32 size, i;
0180 __be32 *p;
0181 char *c;
0182
0183 if (xdr_stream_decode_u32(xdr, &size) < 0)
0184 return false;
0185 if (size == 0 || size > NFS3_MAXNAMLEN)
0186 return false;
0187 p = xdr_inline_decode(xdr, size);
0188 if (!p)
0189 return false;
0190
0191 *len = size;
0192 *name = (char *)p;
0193 for (i = 0, c = *name; i < size; i++, c++) {
0194 if (*c == '\0' || *c == '/')
0195 return false;
0196 }
0197
0198 return true;
0199 }
0200
0201 static bool
0202 svcxdr_decode_diropargs3(struct xdr_stream *xdr, struct svc_fh *fhp,
0203 char **name, unsigned int *len)
0204 {
0205 return svcxdr_decode_nfs_fh3(xdr, fhp) &&
0206 svcxdr_decode_filename3(xdr, name, len);
0207 }
0208
0209 static bool
0210 svcxdr_decode_sattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
0211 struct iattr *iap)
0212 {
0213 u32 set_it;
0214
0215 iap->ia_valid = 0;
0216
0217 if (xdr_stream_decode_bool(xdr, &set_it) < 0)
0218 return false;
0219 if (set_it) {
0220 u32 mode;
0221
0222 if (xdr_stream_decode_u32(xdr, &mode) < 0)
0223 return false;
0224 iap->ia_valid |= ATTR_MODE;
0225 iap->ia_mode = mode;
0226 }
0227 if (xdr_stream_decode_bool(xdr, &set_it) < 0)
0228 return false;
0229 if (set_it) {
0230 u32 uid;
0231
0232 if (xdr_stream_decode_u32(xdr, &uid) < 0)
0233 return false;
0234 iap->ia_uid = make_kuid(nfsd_user_namespace(rqstp), uid);
0235 if (uid_valid(iap->ia_uid))
0236 iap->ia_valid |= ATTR_UID;
0237 }
0238 if (xdr_stream_decode_bool(xdr, &set_it) < 0)
0239 return false;
0240 if (set_it) {
0241 u32 gid;
0242
0243 if (xdr_stream_decode_u32(xdr, &gid) < 0)
0244 return false;
0245 iap->ia_gid = make_kgid(nfsd_user_namespace(rqstp), gid);
0246 if (gid_valid(iap->ia_gid))
0247 iap->ia_valid |= ATTR_GID;
0248 }
0249 if (xdr_stream_decode_bool(xdr, &set_it) < 0)
0250 return false;
0251 if (set_it) {
0252 u64 newsize;
0253
0254 if (xdr_stream_decode_u64(xdr, &newsize) < 0)
0255 return false;
0256 iap->ia_valid |= ATTR_SIZE;
0257 iap->ia_size = newsize;
0258 }
0259 if (xdr_stream_decode_u32(xdr, &set_it) < 0)
0260 return false;
0261 switch (set_it) {
0262 case DONT_CHANGE:
0263 break;
0264 case SET_TO_SERVER_TIME:
0265 iap->ia_valid |= ATTR_ATIME;
0266 break;
0267 case SET_TO_CLIENT_TIME:
0268 if (!svcxdr_decode_nfstime3(xdr, &iap->ia_atime))
0269 return false;
0270 iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
0271 break;
0272 default:
0273 return false;
0274 }
0275 if (xdr_stream_decode_u32(xdr, &set_it) < 0)
0276 return false;
0277 switch (set_it) {
0278 case DONT_CHANGE:
0279 break;
0280 case SET_TO_SERVER_TIME:
0281 iap->ia_valid |= ATTR_MTIME;
0282 break;
0283 case SET_TO_CLIENT_TIME:
0284 if (!svcxdr_decode_nfstime3(xdr, &iap->ia_mtime))
0285 return false;
0286 iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
0287 break;
0288 default:
0289 return false;
0290 }
0291
0292 return true;
0293 }
0294
0295 static bool
0296 svcxdr_decode_sattrguard3(struct xdr_stream *xdr, struct nfsd3_sattrargs *args)
0297 {
0298 __be32 *p;
0299 u32 check;
0300
0301 if (xdr_stream_decode_bool(xdr, &check) < 0)
0302 return false;
0303 if (check) {
0304 p = xdr_inline_decode(xdr, XDR_UNIT * 2);
0305 if (!p)
0306 return false;
0307 args->check_guard = 1;
0308 args->guardtime = be32_to_cpup(p);
0309 } else
0310 args->check_guard = 0;
0311
0312 return true;
0313 }
0314
0315 static bool
0316 svcxdr_decode_specdata3(struct xdr_stream *xdr, struct nfsd3_mknodargs *args)
0317 {
0318 __be32 *p;
0319
0320 p = xdr_inline_decode(xdr, XDR_UNIT * 2);
0321 if (!p)
0322 return false;
0323 args->major = be32_to_cpup(p++);
0324 args->minor = be32_to_cpup(p);
0325
0326 return true;
0327 }
0328
0329 static bool
0330 svcxdr_decode_devicedata3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
0331 struct nfsd3_mknodargs *args)
0332 {
0333 return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs) &&
0334 svcxdr_decode_specdata3(xdr, args);
0335 }
0336
0337 static bool
0338 svcxdr_encode_fattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
0339 const struct svc_fh *fhp, const struct kstat *stat)
0340 {
0341 struct user_namespace *userns = nfsd_user_namespace(rqstp);
0342 __be32 *p;
0343 u64 fsid;
0344
0345 p = xdr_reserve_space(xdr, XDR_UNIT * 21);
0346 if (!p)
0347 return false;
0348
0349 *p++ = cpu_to_be32(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
0350 *p++ = cpu_to_be32((u32)(stat->mode & S_IALLUGO));
0351 *p++ = cpu_to_be32((u32)stat->nlink);
0352 *p++ = cpu_to_be32((u32)from_kuid_munged(userns, stat->uid));
0353 *p++ = cpu_to_be32((u32)from_kgid_munged(userns, stat->gid));
0354 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN)
0355 p = xdr_encode_hyper(p, (u64)NFS3_MAXPATHLEN);
0356 else
0357 p = xdr_encode_hyper(p, (u64)stat->size);
0358
0359
0360 p = xdr_encode_hyper(p, ((u64)stat->blocks) << 9);
0361
0362
0363 *p++ = cpu_to_be32((u32)MAJOR(stat->rdev));
0364 *p++ = cpu_to_be32((u32)MINOR(stat->rdev));
0365
0366 switch(fsid_source(fhp)) {
0367 case FSIDSOURCE_FSID:
0368 fsid = (u64)fhp->fh_export->ex_fsid;
0369 break;
0370 case FSIDSOURCE_UUID:
0371 fsid = ((u64 *)fhp->fh_export->ex_uuid)[0];
0372 fsid ^= ((u64 *)fhp->fh_export->ex_uuid)[1];
0373 break;
0374 default:
0375 fsid = (u64)huge_encode_dev(fhp->fh_dentry->d_sb->s_dev);
0376 }
0377 p = xdr_encode_hyper(p, fsid);
0378
0379
0380 p = xdr_encode_hyper(p, stat->ino);
0381
0382 p = encode_nfstime3(p, &stat->atime);
0383 p = encode_nfstime3(p, &stat->mtime);
0384 encode_nfstime3(p, &stat->ctime);
0385
0386 return true;
0387 }
0388
0389 static bool
0390 svcxdr_encode_wcc_attr(struct xdr_stream *xdr, const struct svc_fh *fhp)
0391 {
0392 __be32 *p;
0393
0394 p = xdr_reserve_space(xdr, XDR_UNIT * 6);
0395 if (!p)
0396 return false;
0397 p = xdr_encode_hyper(p, (u64)fhp->fh_pre_size);
0398 p = encode_nfstime3(p, &fhp->fh_pre_mtime);
0399 encode_nfstime3(p, &fhp->fh_pre_ctime);
0400
0401 return true;
0402 }
0403
0404 static bool
0405 svcxdr_encode_pre_op_attr(struct xdr_stream *xdr, const struct svc_fh *fhp)
0406 {
0407 if (!fhp->fh_pre_saved) {
0408 if (xdr_stream_encode_item_absent(xdr) < 0)
0409 return false;
0410 return true;
0411 }
0412
0413 if (xdr_stream_encode_item_present(xdr) < 0)
0414 return false;
0415 return svcxdr_encode_wcc_attr(xdr, fhp);
0416 }
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428 bool
0429 svcxdr_encode_post_op_attr(struct svc_rqst *rqstp, struct xdr_stream *xdr,
0430 const struct svc_fh *fhp)
0431 {
0432 struct dentry *dentry = fhp->fh_dentry;
0433 struct kstat stat;
0434
0435
0436
0437
0438
0439
0440 if (fhp->fh_no_wcc || !dentry || !d_really_is_positive(dentry))
0441 goto no_post_op_attrs;
0442 if (fh_getattr(fhp, &stat) != nfs_ok)
0443 goto no_post_op_attrs;
0444
0445 if (xdr_stream_encode_item_present(xdr) < 0)
0446 return false;
0447 lease_get_mtime(d_inode(dentry), &stat.mtime);
0448 if (!svcxdr_encode_fattr3(rqstp, xdr, fhp, &stat))
0449 return false;
0450
0451 return true;
0452
0453 no_post_op_attrs:
0454 return xdr_stream_encode_item_absent(xdr) > 0;
0455 }
0456
0457
0458
0459
0460 static bool
0461 svcxdr_encode_wcc_data(struct svc_rqst *rqstp, struct xdr_stream *xdr,
0462 const struct svc_fh *fhp)
0463 {
0464 struct dentry *dentry = fhp->fh_dentry;
0465
0466 if (!dentry || !d_really_is_positive(dentry) || !fhp->fh_post_saved)
0467 goto neither;
0468
0469
0470 if (!svcxdr_encode_pre_op_attr(xdr, fhp))
0471 return false;
0472
0473
0474 if (xdr_stream_encode_item_present(xdr) < 0)
0475 return false;
0476 if (!svcxdr_encode_fattr3(rqstp, xdr, fhp, &fhp->fh_post_attr))
0477 return false;
0478
0479 return true;
0480
0481 neither:
0482 if (xdr_stream_encode_item_absent(xdr) < 0)
0483 return false;
0484 if (!svcxdr_encode_post_op_attr(rqstp, xdr, fhp))
0485 return false;
0486
0487 return true;
0488 }
0489
0490
0491
0492
0493
0494 bool
0495 nfs3svc_decode_fhandleargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0496 {
0497 struct nfsd_fhandle *args = rqstp->rq_argp;
0498
0499 return svcxdr_decode_nfs_fh3(xdr, &args->fh);
0500 }
0501
0502 bool
0503 nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0504 {
0505 struct nfsd3_sattrargs *args = rqstp->rq_argp;
0506
0507 return svcxdr_decode_nfs_fh3(xdr, &args->fh) &&
0508 svcxdr_decode_sattr3(rqstp, xdr, &args->attrs) &&
0509 svcxdr_decode_sattrguard3(xdr, args);
0510 }
0511
0512 bool
0513 nfs3svc_decode_diropargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0514 {
0515 struct nfsd3_diropargs *args = rqstp->rq_argp;
0516
0517 return svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len);
0518 }
0519
0520 bool
0521 nfs3svc_decode_accessargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0522 {
0523 struct nfsd3_accessargs *args = rqstp->rq_argp;
0524
0525 if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
0526 return false;
0527 if (xdr_stream_decode_u32(xdr, &args->access) < 0)
0528 return false;
0529
0530 return true;
0531 }
0532
0533 bool
0534 nfs3svc_decode_readargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0535 {
0536 struct nfsd3_readargs *args = rqstp->rq_argp;
0537
0538 if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
0539 return false;
0540 if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
0541 return false;
0542 if (xdr_stream_decode_u32(xdr, &args->count) < 0)
0543 return false;
0544
0545 return true;
0546 }
0547
0548 bool
0549 nfs3svc_decode_writeargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0550 {
0551 struct nfsd3_writeargs *args = rqstp->rq_argp;
0552 u32 max_blocksize = svc_max_payload(rqstp);
0553
0554 if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
0555 return false;
0556 if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
0557 return false;
0558 if (xdr_stream_decode_u32(xdr, &args->count) < 0)
0559 return false;
0560 if (xdr_stream_decode_u32(xdr, &args->stable) < 0)
0561 return false;
0562
0563
0564 if (xdr_stream_decode_u32(xdr, &args->len) < 0)
0565 return false;
0566
0567
0568 if (args->count != args->len)
0569 return false;
0570 if (args->count > max_blocksize) {
0571 args->count = max_blocksize;
0572 args->len = max_blocksize;
0573 }
0574 if (!xdr_stream_subsegment(xdr, &args->payload, args->count))
0575 return false;
0576
0577 return true;
0578 }
0579
0580 bool
0581 nfs3svc_decode_createargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0582 {
0583 struct nfsd3_createargs *args = rqstp->rq_argp;
0584
0585 if (!svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len))
0586 return false;
0587 if (xdr_stream_decode_u32(xdr, &args->createmode) < 0)
0588 return false;
0589 switch (args->createmode) {
0590 case NFS3_CREATE_UNCHECKED:
0591 case NFS3_CREATE_GUARDED:
0592 return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs);
0593 case NFS3_CREATE_EXCLUSIVE:
0594 args->verf = xdr_inline_decode(xdr, NFS3_CREATEVERFSIZE);
0595 if (!args->verf)
0596 return false;
0597 break;
0598 default:
0599 return false;
0600 }
0601 return true;
0602 }
0603
0604 bool
0605 nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0606 {
0607 struct nfsd3_createargs *args = rqstp->rq_argp;
0608
0609 return svcxdr_decode_diropargs3(xdr, &args->fh,
0610 &args->name, &args->len) &&
0611 svcxdr_decode_sattr3(rqstp, xdr, &args->attrs);
0612 }
0613
0614 bool
0615 nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0616 {
0617 struct nfsd3_symlinkargs *args = rqstp->rq_argp;
0618 struct kvec *head = rqstp->rq_arg.head;
0619 struct kvec *tail = rqstp->rq_arg.tail;
0620 size_t remaining;
0621
0622 if (!svcxdr_decode_diropargs3(xdr, &args->ffh, &args->fname, &args->flen))
0623 return false;
0624 if (!svcxdr_decode_sattr3(rqstp, xdr, &args->attrs))
0625 return false;
0626 if (xdr_stream_decode_u32(xdr, &args->tlen) < 0)
0627 return false;
0628
0629
0630 remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len;
0631 remaining -= xdr_stream_pos(xdr);
0632 if (remaining < xdr_align_size(args->tlen))
0633 return false;
0634
0635 args->first.iov_base = xdr->p;
0636 args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
0637
0638 return true;
0639 }
0640
0641 bool
0642 nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0643 {
0644 struct nfsd3_mknodargs *args = rqstp->rq_argp;
0645
0646 if (!svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len))
0647 return false;
0648 if (xdr_stream_decode_u32(xdr, &args->ftype) < 0)
0649 return false;
0650 switch (args->ftype) {
0651 case NF3CHR:
0652 case NF3BLK:
0653 return svcxdr_decode_devicedata3(rqstp, xdr, args);
0654 case NF3SOCK:
0655 case NF3FIFO:
0656 return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs);
0657 case NF3REG:
0658 case NF3DIR:
0659 case NF3LNK:
0660
0661 break;
0662 default:
0663 return false;
0664 }
0665
0666 return true;
0667 }
0668
0669 bool
0670 nfs3svc_decode_renameargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0671 {
0672 struct nfsd3_renameargs *args = rqstp->rq_argp;
0673
0674 return svcxdr_decode_diropargs3(xdr, &args->ffh,
0675 &args->fname, &args->flen) &&
0676 svcxdr_decode_diropargs3(xdr, &args->tfh,
0677 &args->tname, &args->tlen);
0678 }
0679
0680 bool
0681 nfs3svc_decode_linkargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0682 {
0683 struct nfsd3_linkargs *args = rqstp->rq_argp;
0684
0685 return svcxdr_decode_nfs_fh3(xdr, &args->ffh) &&
0686 svcxdr_decode_diropargs3(xdr, &args->tfh,
0687 &args->tname, &args->tlen);
0688 }
0689
0690 bool
0691 nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0692 {
0693 struct nfsd3_readdirargs *args = rqstp->rq_argp;
0694
0695 if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
0696 return false;
0697 if (xdr_stream_decode_u64(xdr, &args->cookie) < 0)
0698 return false;
0699 args->verf = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
0700 if (!args->verf)
0701 return false;
0702 if (xdr_stream_decode_u32(xdr, &args->count) < 0)
0703 return false;
0704
0705 return true;
0706 }
0707
0708 bool
0709 nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0710 {
0711 struct nfsd3_readdirargs *args = rqstp->rq_argp;
0712 u32 dircount;
0713
0714 if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
0715 return false;
0716 if (xdr_stream_decode_u64(xdr, &args->cookie) < 0)
0717 return false;
0718 args->verf = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
0719 if (!args->verf)
0720 return false;
0721
0722 if (xdr_stream_decode_u32(xdr, &dircount) < 0)
0723 return false;
0724 if (xdr_stream_decode_u32(xdr, &args->count) < 0)
0725 return false;
0726
0727 return true;
0728 }
0729
0730 bool
0731 nfs3svc_decode_commitargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0732 {
0733 struct nfsd3_commitargs *args = rqstp->rq_argp;
0734
0735 if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
0736 return false;
0737 if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
0738 return false;
0739 if (xdr_stream_decode_u32(xdr, &args->count) < 0)
0740 return false;
0741
0742 return true;
0743 }
0744
0745
0746
0747
0748
0749
0750 bool
0751 nfs3svc_encode_getattrres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0752 {
0753 struct nfsd3_attrstat *resp = rqstp->rq_resp;
0754
0755 if (!svcxdr_encode_nfsstat3(xdr, resp->status))
0756 return false;
0757 switch (resp->status) {
0758 case nfs_ok:
0759 lease_get_mtime(d_inode(resp->fh.fh_dentry), &resp->stat.mtime);
0760 if (!svcxdr_encode_fattr3(rqstp, xdr, &resp->fh, &resp->stat))
0761 return false;
0762 break;
0763 }
0764
0765 return true;
0766 }
0767
0768
0769 bool
0770 nfs3svc_encode_wccstat(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0771 {
0772 struct nfsd3_attrstat *resp = rqstp->rq_resp;
0773
0774 return svcxdr_encode_nfsstat3(xdr, resp->status) &&
0775 svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh);
0776 }
0777
0778
0779 bool
0780 nfs3svc_encode_lookupres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0781 {
0782 struct nfsd3_diropres *resp = rqstp->rq_resp;
0783
0784 if (!svcxdr_encode_nfsstat3(xdr, resp->status))
0785 return false;
0786 switch (resp->status) {
0787 case nfs_ok:
0788 if (!svcxdr_encode_nfs_fh3(xdr, &resp->fh))
0789 return false;
0790 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
0791 return false;
0792 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->dirfh))
0793 return false;
0794 break;
0795 default:
0796 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->dirfh))
0797 return false;
0798 }
0799
0800 return true;
0801 }
0802
0803
0804 bool
0805 nfs3svc_encode_accessres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0806 {
0807 struct nfsd3_accessres *resp = rqstp->rq_resp;
0808
0809 if (!svcxdr_encode_nfsstat3(xdr, resp->status))
0810 return false;
0811 switch (resp->status) {
0812 case nfs_ok:
0813 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
0814 return false;
0815 if (xdr_stream_encode_u32(xdr, resp->access) < 0)
0816 return false;
0817 break;
0818 default:
0819 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
0820 return false;
0821 }
0822
0823 return true;
0824 }
0825
0826
0827 bool
0828 nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0829 {
0830 struct nfsd3_readlinkres *resp = rqstp->rq_resp;
0831 struct kvec *head = rqstp->rq_res.head;
0832
0833 if (!svcxdr_encode_nfsstat3(xdr, resp->status))
0834 return false;
0835 switch (resp->status) {
0836 case nfs_ok:
0837 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
0838 return false;
0839 if (xdr_stream_encode_u32(xdr, resp->len) < 0)
0840 return false;
0841 xdr_write_pages(xdr, resp->pages, 0, resp->len);
0842 if (svc_encode_result_payload(rqstp, head->iov_len, resp->len) < 0)
0843 return false;
0844 break;
0845 default:
0846 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
0847 return false;
0848 }
0849
0850 return true;
0851 }
0852
0853
0854 bool
0855 nfs3svc_encode_readres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0856 {
0857 struct nfsd3_readres *resp = rqstp->rq_resp;
0858 struct kvec *head = rqstp->rq_res.head;
0859
0860 if (!svcxdr_encode_nfsstat3(xdr, resp->status))
0861 return false;
0862 switch (resp->status) {
0863 case nfs_ok:
0864 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
0865 return false;
0866 if (xdr_stream_encode_u32(xdr, resp->count) < 0)
0867 return false;
0868 if (xdr_stream_encode_bool(xdr, resp->eof) < 0)
0869 return false;
0870 if (xdr_stream_encode_u32(xdr, resp->count) < 0)
0871 return false;
0872 xdr_write_pages(xdr, resp->pages, rqstp->rq_res.page_base,
0873 resp->count);
0874 if (svc_encode_result_payload(rqstp, head->iov_len, resp->count) < 0)
0875 return false;
0876 break;
0877 default:
0878 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
0879 return false;
0880 }
0881
0882 return true;
0883 }
0884
0885
0886 bool
0887 nfs3svc_encode_writeres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0888 {
0889 struct nfsd3_writeres *resp = rqstp->rq_resp;
0890
0891 if (!svcxdr_encode_nfsstat3(xdr, resp->status))
0892 return false;
0893 switch (resp->status) {
0894 case nfs_ok:
0895 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh))
0896 return false;
0897 if (xdr_stream_encode_u32(xdr, resp->count) < 0)
0898 return false;
0899 if (xdr_stream_encode_u32(xdr, resp->committed) < 0)
0900 return false;
0901 if (!svcxdr_encode_writeverf3(xdr, resp->verf))
0902 return false;
0903 break;
0904 default:
0905 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh))
0906 return false;
0907 }
0908
0909 return true;
0910 }
0911
0912
0913 bool
0914 nfs3svc_encode_createres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0915 {
0916 struct nfsd3_diropres *resp = rqstp->rq_resp;
0917
0918 if (!svcxdr_encode_nfsstat3(xdr, resp->status))
0919 return false;
0920 switch (resp->status) {
0921 case nfs_ok:
0922 if (!svcxdr_encode_post_op_fh3(xdr, &resp->fh))
0923 return false;
0924 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
0925 return false;
0926 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->dirfh))
0927 return false;
0928 break;
0929 default:
0930 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->dirfh))
0931 return false;
0932 }
0933
0934 return true;
0935 }
0936
0937
0938 bool
0939 nfs3svc_encode_renameres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0940 {
0941 struct nfsd3_renameres *resp = rqstp->rq_resp;
0942
0943 return svcxdr_encode_nfsstat3(xdr, resp->status) &&
0944 svcxdr_encode_wcc_data(rqstp, xdr, &resp->ffh) &&
0945 svcxdr_encode_wcc_data(rqstp, xdr, &resp->tfh);
0946 }
0947
0948
0949 bool
0950 nfs3svc_encode_linkres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0951 {
0952 struct nfsd3_linkres *resp = rqstp->rq_resp;
0953
0954 return svcxdr_encode_nfsstat3(xdr, resp->status) &&
0955 svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh) &&
0956 svcxdr_encode_wcc_data(rqstp, xdr, &resp->tfh);
0957 }
0958
0959
0960 bool
0961 nfs3svc_encode_readdirres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0962 {
0963 struct nfsd3_readdirres *resp = rqstp->rq_resp;
0964 struct xdr_buf *dirlist = &resp->dirlist;
0965
0966 if (!svcxdr_encode_nfsstat3(xdr, resp->status))
0967 return false;
0968 switch (resp->status) {
0969 case nfs_ok:
0970 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
0971 return false;
0972 if (!svcxdr_encode_cookieverf3(xdr, resp->verf))
0973 return false;
0974 xdr_write_pages(xdr, dirlist->pages, 0, dirlist->len);
0975
0976 if (xdr_stream_encode_item_absent(xdr) < 0)
0977 return false;
0978 if (xdr_stream_encode_bool(xdr, resp->common.err == nfserr_eof) < 0)
0979 return false;
0980 break;
0981 default:
0982 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
0983 return false;
0984 }
0985
0986 return true;
0987 }
0988
0989 static __be32
0990 compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
0991 const char *name, int namlen, u64 ino)
0992 {
0993 struct svc_export *exp;
0994 struct dentry *dparent, *dchild;
0995 __be32 rv = nfserr_noent;
0996
0997 dparent = cd->fh.fh_dentry;
0998 exp = cd->fh.fh_export;
0999
1000 if (isdotent(name, namlen)) {
1001 if (namlen == 2) {
1002 dchild = dget_parent(dparent);
1003
1004
1005
1006
1007 if (dchild == dparent)
1008 goto out;
1009 if (dparent == exp->ex_path.dentry)
1010 goto out;
1011 } else
1012 dchild = dget(dparent);
1013 } else
1014 dchild = lookup_positive_unlocked(name, dparent, namlen);
1015 if (IS_ERR(dchild))
1016 return rv;
1017 if (d_mountpoint(dchild))
1018 goto out;
1019 if (dchild->d_inode->i_ino != ino)
1020 goto out;
1021 rv = fh_compose(fhp, exp, dchild, &cd->fh);
1022 out:
1023 dput(dchild);
1024 return rv;
1025 }
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035 void nfs3svc_encode_cookie3(struct nfsd3_readdirres *resp, u64 offset)
1036 {
1037 __be64 cookie = cpu_to_be64(offset);
1038
1039 if (!resp->cookie_offset)
1040 return;
1041 write_bytes_to_xdr_buf(&resp->dirlist, resp->cookie_offset, &cookie,
1042 sizeof(cookie));
1043 resp->cookie_offset = 0;
1044 }
1045
1046 static bool
1047 svcxdr_encode_entry3_common(struct nfsd3_readdirres *resp, const char *name,
1048 int namlen, loff_t offset, u64 ino)
1049 {
1050 struct xdr_buf *dirlist = &resp->dirlist;
1051 struct xdr_stream *xdr = &resp->xdr;
1052
1053 if (xdr_stream_encode_item_present(xdr) < 0)
1054 return false;
1055
1056 if (xdr_stream_encode_u64(xdr, ino) < 0)
1057 return false;
1058
1059 if (xdr_stream_encode_opaque(xdr, name, min(namlen, NFS3_MAXNAMLEN)) < 0)
1060 return false;
1061
1062 resp->cookie_offset = dirlist->len;
1063 if (xdr_stream_encode_u64(xdr, OFFSET_MAX) < 0)
1064 return false;
1065
1066 return true;
1067 }
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087 int nfs3svc_encode_entry3(void *data, const char *name, int namlen,
1088 loff_t offset, u64 ino, unsigned int d_type)
1089 {
1090 struct readdir_cd *ccd = data;
1091 struct nfsd3_readdirres *resp = container_of(ccd,
1092 struct nfsd3_readdirres,
1093 common);
1094 unsigned int starting_length = resp->dirlist.len;
1095
1096
1097 nfs3svc_encode_cookie3(resp, offset);
1098
1099 if (!svcxdr_encode_entry3_common(resp, name, namlen, offset, ino))
1100 goto out_toosmall;
1101
1102 xdr_commit_encode(&resp->xdr);
1103 resp->common.err = nfs_ok;
1104 return 0;
1105
1106 out_toosmall:
1107 resp->cookie_offset = 0;
1108 resp->common.err = nfserr_toosmall;
1109 resp->dirlist.len = starting_length;
1110 return -EINVAL;
1111 }
1112
1113 static bool
1114 svcxdr_encode_entry3_plus(struct nfsd3_readdirres *resp, const char *name,
1115 int namlen, u64 ino)
1116 {
1117 struct xdr_stream *xdr = &resp->xdr;
1118 struct svc_fh *fhp = &resp->scratch;
1119 bool result;
1120
1121 result = false;
1122 fh_init(fhp, NFS3_FHSIZE);
1123 if (compose_entry_fh(resp, fhp, name, namlen, ino) != nfs_ok)
1124 goto out_noattrs;
1125
1126 if (!svcxdr_encode_post_op_attr(resp->rqstp, xdr, fhp))
1127 goto out;
1128 if (!svcxdr_encode_post_op_fh3(xdr, fhp))
1129 goto out;
1130 result = true;
1131
1132 out:
1133 fh_put(fhp);
1134 return result;
1135
1136 out_noattrs:
1137 if (xdr_stream_encode_item_absent(xdr) < 0)
1138 return false;
1139 if (xdr_stream_encode_item_absent(xdr) < 0)
1140 return false;
1141 return true;
1142 }
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162 int nfs3svc_encode_entryplus3(void *data, const char *name, int namlen,
1163 loff_t offset, u64 ino, unsigned int d_type)
1164 {
1165 struct readdir_cd *ccd = data;
1166 struct nfsd3_readdirres *resp = container_of(ccd,
1167 struct nfsd3_readdirres,
1168 common);
1169 unsigned int starting_length = resp->dirlist.len;
1170
1171
1172 nfs3svc_encode_cookie3(resp, offset);
1173
1174 if (!svcxdr_encode_entry3_common(resp, name, namlen, offset, ino))
1175 goto out_toosmall;
1176 if (!svcxdr_encode_entry3_plus(resp, name, namlen, ino))
1177 goto out_toosmall;
1178
1179 xdr_commit_encode(&resp->xdr);
1180 resp->common.err = nfs_ok;
1181 return 0;
1182
1183 out_toosmall:
1184 resp->cookie_offset = 0;
1185 resp->common.err = nfserr_toosmall;
1186 resp->dirlist.len = starting_length;
1187 return -EINVAL;
1188 }
1189
1190 static bool
1191 svcxdr_encode_fsstat3resok(struct xdr_stream *xdr,
1192 const struct nfsd3_fsstatres *resp)
1193 {
1194 const struct kstatfs *s = &resp->stats;
1195 u64 bs = s->f_bsize;
1196 __be32 *p;
1197
1198 p = xdr_reserve_space(xdr, XDR_UNIT * 13);
1199 if (!p)
1200 return false;
1201 p = xdr_encode_hyper(p, bs * s->f_blocks);
1202 p = xdr_encode_hyper(p, bs * s->f_bfree);
1203 p = xdr_encode_hyper(p, bs * s->f_bavail);
1204 p = xdr_encode_hyper(p, s->f_files);
1205 p = xdr_encode_hyper(p, s->f_ffree);
1206 p = xdr_encode_hyper(p, s->f_ffree);
1207 *p = cpu_to_be32(resp->invarsec);
1208
1209 return true;
1210 }
1211
1212
1213 bool
1214 nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
1215 {
1216 struct nfsd3_fsstatres *resp = rqstp->rq_resp;
1217
1218 if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1219 return false;
1220 switch (resp->status) {
1221 case nfs_ok:
1222 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1223 return false;
1224 if (!svcxdr_encode_fsstat3resok(xdr, resp))
1225 return false;
1226 break;
1227 default:
1228 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1229 return false;
1230 }
1231
1232 return true;
1233 }
1234
1235 static bool
1236 svcxdr_encode_fsinfo3resok(struct xdr_stream *xdr,
1237 const struct nfsd3_fsinfores *resp)
1238 {
1239 __be32 *p;
1240
1241 p = xdr_reserve_space(xdr, XDR_UNIT * 12);
1242 if (!p)
1243 return false;
1244 *p++ = cpu_to_be32(resp->f_rtmax);
1245 *p++ = cpu_to_be32(resp->f_rtpref);
1246 *p++ = cpu_to_be32(resp->f_rtmult);
1247 *p++ = cpu_to_be32(resp->f_wtmax);
1248 *p++ = cpu_to_be32(resp->f_wtpref);
1249 *p++ = cpu_to_be32(resp->f_wtmult);
1250 *p++ = cpu_to_be32(resp->f_dtpref);
1251 p = xdr_encode_hyper(p, resp->f_maxfilesize);
1252 p = encode_nfstime3(p, &nfs3svc_time_delta);
1253 *p = cpu_to_be32(resp->f_properties);
1254
1255 return true;
1256 }
1257
1258
1259 bool
1260 nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, struct xdr_stream *xdr)
1261 {
1262 struct nfsd3_fsinfores *resp = rqstp->rq_resp;
1263
1264 if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1265 return false;
1266 switch (resp->status) {
1267 case nfs_ok:
1268 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1269 return false;
1270 if (!svcxdr_encode_fsinfo3resok(xdr, resp))
1271 return false;
1272 break;
1273 default:
1274 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1275 return false;
1276 }
1277
1278 return true;
1279 }
1280
1281 static bool
1282 svcxdr_encode_pathconf3resok(struct xdr_stream *xdr,
1283 const struct nfsd3_pathconfres *resp)
1284 {
1285 __be32 *p;
1286
1287 p = xdr_reserve_space(xdr, XDR_UNIT * 6);
1288 if (!p)
1289 return false;
1290 *p++ = cpu_to_be32(resp->p_link_max);
1291 *p++ = cpu_to_be32(resp->p_name_max);
1292 p = xdr_encode_bool(p, resp->p_no_trunc);
1293 p = xdr_encode_bool(p, resp->p_chown_restricted);
1294 p = xdr_encode_bool(p, resp->p_case_insensitive);
1295 xdr_encode_bool(p, resp->p_case_preserving);
1296
1297 return true;
1298 }
1299
1300
1301 bool
1302 nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
1303 {
1304 struct nfsd3_pathconfres *resp = rqstp->rq_resp;
1305
1306 if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1307 return false;
1308 switch (resp->status) {
1309 case nfs_ok:
1310 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1311 return false;
1312 if (!svcxdr_encode_pathconf3resok(xdr, resp))
1313 return false;
1314 break;
1315 default:
1316 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1317 return false;
1318 }
1319
1320 return true;
1321 }
1322
1323
1324 bool
1325 nfs3svc_encode_commitres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
1326 {
1327 struct nfsd3_commitres *resp = rqstp->rq_resp;
1328
1329 if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1330 return false;
1331 switch (resp->status) {
1332 case nfs_ok:
1333 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh))
1334 return false;
1335 if (!svcxdr_encode_writeverf3(xdr, resp->verf))
1336 return false;
1337 break;
1338 default:
1339 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh))
1340 return false;
1341 }
1342
1343 return true;
1344 }
1345
1346
1347
1348
1349 void
1350 nfs3svc_release_fhandle(struct svc_rqst *rqstp)
1351 {
1352 struct nfsd3_attrstat *resp = rqstp->rq_resp;
1353
1354 fh_put(&resp->fh);
1355 }
1356
1357 void
1358 nfs3svc_release_fhandle2(struct svc_rqst *rqstp)
1359 {
1360 struct nfsd3_fhandle_pair *resp = rqstp->rq_resp;
1361
1362 fh_put(&resp->fh1);
1363 fh_put(&resp->fh2);
1364 }