0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <linux/file.h>
0037 #include <linux/slab.h>
0038 #include <linux/namei.h>
0039 #include <linux/statfs.h>
0040 #include <linux/utsname.h>
0041 #include <linux/pagemap.h>
0042 #include <linux/sunrpc/svcauth_gss.h>
0043 #include <linux/sunrpc/addr.h>
0044 #include <linux/xattr.h>
0045 #include <uapi/linux/xattr.h>
0046
0047 #include "idmap.h"
0048 #include "acl.h"
0049 #include "xdr4.h"
0050 #include "vfs.h"
0051 #include "state.h"
0052 #include "cache.h"
0053 #include "netns.h"
0054 #include "pnfs.h"
0055 #include "filecache.h"
0056
0057 #include "trace.h"
0058
0059 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
0060 #include <linux/security.h>
0061 #endif
0062
0063
0064 #define NFSDDBG_FACILITY NFSDDBG_XDR
0065
0066 const u32 nfsd_suppattrs[3][3] = {
0067 {NFSD4_SUPPORTED_ATTRS_WORD0,
0068 NFSD4_SUPPORTED_ATTRS_WORD1,
0069 NFSD4_SUPPORTED_ATTRS_WORD2},
0070
0071 {NFSD4_1_SUPPORTED_ATTRS_WORD0,
0072 NFSD4_1_SUPPORTED_ATTRS_WORD1,
0073 NFSD4_1_SUPPORTED_ATTRS_WORD2},
0074
0075 {NFSD4_1_SUPPORTED_ATTRS_WORD0,
0076 NFSD4_1_SUPPORTED_ATTRS_WORD1,
0077 NFSD4_2_SUPPORTED_ATTRS_WORD2},
0078 };
0079
0080
0081
0082
0083
0084
0085 #define NFS4_REFERRAL_FSID_MAJOR 0x8000000ULL
0086 #define NFS4_REFERRAL_FSID_MINOR 0x8000000ULL
0087
0088 static __be32
0089 check_filename(char *str, int len)
0090 {
0091 int i;
0092
0093 if (len == 0)
0094 return nfserr_inval;
0095 if (len > NFS4_MAXNAMLEN)
0096 return nfserr_nametoolong;
0097 if (isdotent(str, len))
0098 return nfserr_badname;
0099 for (i = 0; i < len; i++)
0100 if (str[i] == '/')
0101 return nfserr_badname;
0102 return 0;
0103 }
0104
0105 static int zero_clientid(clientid_t *clid)
0106 {
0107 return (clid->cl_boot == 0) && (clid->cl_id == 0);
0108 }
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118 static void *
0119 svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len)
0120 {
0121 struct svcxdr_tmpbuf *tb;
0122
0123 tb = kmalloc(sizeof(*tb) + len, GFP_KERNEL);
0124 if (!tb)
0125 return NULL;
0126 tb->next = argp->to_free;
0127 argp->to_free = tb;
0128 return tb->buf;
0129 }
0130
0131
0132
0133
0134
0135
0136
0137
0138 static char *
0139 svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
0140 {
0141 char *p = svcxdr_tmpalloc(argp, len + 1);
0142
0143 if (!p)
0144 return NULL;
0145 memcpy(p, buf, len);
0146 p[len] = '\0';
0147 return p;
0148 }
0149
0150 static void *
0151 svcxdr_savemem(struct nfsd4_compoundargs *argp, __be32 *p, u32 len)
0152 {
0153 __be32 *tmp;
0154
0155
0156
0157
0158
0159 if (p != argp->xdr->scratch.iov_base)
0160 return p;
0161
0162 tmp = svcxdr_tmpalloc(argp, len);
0163 if (!tmp)
0164 return NULL;
0165 memcpy(tmp, p, len);
0166 return tmp;
0167 }
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177 static __be32
0178 nfsd4_decode_ignored_string(struct nfsd4_compoundargs *argp, u32 maxlen)
0179 {
0180 u32 len;
0181
0182 if (xdr_stream_decode_u32(argp->xdr, &len) < 0)
0183 return nfserr_bad_xdr;
0184 if (maxlen && len > maxlen)
0185 return nfserr_bad_xdr;
0186 if (!xdr_inline_decode(argp->xdr, len))
0187 return nfserr_bad_xdr;
0188
0189 return nfs_ok;
0190 }
0191
0192 static __be32
0193 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
0194 {
0195 __be32 *p;
0196 u32 len;
0197
0198 if (xdr_stream_decode_u32(argp->xdr, &len) < 0)
0199 return nfserr_bad_xdr;
0200 if (len == 0 || len > NFS4_OPAQUE_LIMIT)
0201 return nfserr_bad_xdr;
0202 p = xdr_inline_decode(argp->xdr, len);
0203 if (!p)
0204 return nfserr_bad_xdr;
0205 o->data = svcxdr_savemem(argp, p, len);
0206 if (!o->data)
0207 return nfserr_jukebox;
0208 o->len = len;
0209
0210 return nfs_ok;
0211 }
0212
0213 static __be32
0214 nfsd4_decode_component4(struct nfsd4_compoundargs *argp, char **namp, u32 *lenp)
0215 {
0216 __be32 *p, status;
0217
0218 if (xdr_stream_decode_u32(argp->xdr, lenp) < 0)
0219 return nfserr_bad_xdr;
0220 p = xdr_inline_decode(argp->xdr, *lenp);
0221 if (!p)
0222 return nfserr_bad_xdr;
0223 status = check_filename((char *)p, *lenp);
0224 if (status)
0225 return status;
0226 *namp = svcxdr_savemem(argp, p, *lenp);
0227 if (!*namp)
0228 return nfserr_jukebox;
0229
0230 return nfs_ok;
0231 }
0232
0233 static __be32
0234 nfsd4_decode_nfstime4(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
0235 {
0236 __be32 *p;
0237
0238 p = xdr_inline_decode(argp->xdr, XDR_UNIT * 3);
0239 if (!p)
0240 return nfserr_bad_xdr;
0241 p = xdr_decode_hyper(p, &tv->tv_sec);
0242 tv->tv_nsec = be32_to_cpup(p++);
0243 if (tv->tv_nsec >= (u32)1000000000)
0244 return nfserr_inval;
0245 return nfs_ok;
0246 }
0247
0248 static __be32
0249 nfsd4_decode_verifier4(struct nfsd4_compoundargs *argp, nfs4_verifier *verf)
0250 {
0251 __be32 *p;
0252
0253 p = xdr_inline_decode(argp->xdr, NFS4_VERIFIER_SIZE);
0254 if (!p)
0255 return nfserr_bad_xdr;
0256 memcpy(verf->data, p, sizeof(verf->data));
0257 return nfs_ok;
0258 }
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277 static __be32
0278 nfsd4_decode_bitmap4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen)
0279 {
0280 ssize_t status;
0281
0282 status = xdr_stream_decode_uint32_array(argp->xdr, bmval, bmlen);
0283 return status == -EBADMSG ? nfserr_bad_xdr : nfs_ok;
0284 }
0285
0286 static __be32
0287 nfsd4_decode_nfsace4(struct nfsd4_compoundargs *argp, struct nfs4_ace *ace)
0288 {
0289 __be32 *p, status;
0290 u32 length;
0291
0292 if (xdr_stream_decode_u32(argp->xdr, &ace->type) < 0)
0293 return nfserr_bad_xdr;
0294 if (xdr_stream_decode_u32(argp->xdr, &ace->flag) < 0)
0295 return nfserr_bad_xdr;
0296 if (xdr_stream_decode_u32(argp->xdr, &ace->access_mask) < 0)
0297 return nfserr_bad_xdr;
0298
0299 if (xdr_stream_decode_u32(argp->xdr, &length) < 0)
0300 return nfserr_bad_xdr;
0301 p = xdr_inline_decode(argp->xdr, length);
0302 if (!p)
0303 return nfserr_bad_xdr;
0304 ace->whotype = nfs4_acl_get_whotype((char *)p, length);
0305 if (ace->whotype != NFS4_ACL_WHO_NAMED)
0306 status = nfs_ok;
0307 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
0308 status = nfsd_map_name_to_gid(argp->rqstp,
0309 (char *)p, length, &ace->who_gid);
0310 else
0311 status = nfsd_map_name_to_uid(argp->rqstp,
0312 (char *)p, length, &ace->who_uid);
0313
0314 return status;
0315 }
0316
0317
0318 static noinline __be32
0319 nfsd4_decode_acl(struct nfsd4_compoundargs *argp, struct nfs4_acl **acl)
0320 {
0321 struct nfs4_ace *ace;
0322 __be32 status;
0323 u32 count;
0324
0325 if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
0326 return nfserr_bad_xdr;
0327
0328 if (count > xdr_stream_remaining(argp->xdr) / 20)
0329
0330
0331
0332
0333
0334 return nfserr_fbig;
0335
0336 *acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(count));
0337 if (*acl == NULL)
0338 return nfserr_jukebox;
0339
0340 (*acl)->naces = count;
0341 for (ace = (*acl)->aces; ace < (*acl)->aces + count; ace++) {
0342 status = nfsd4_decode_nfsace4(argp, ace);
0343 if (status)
0344 return status;
0345 }
0346
0347 return nfs_ok;
0348 }
0349
0350 static noinline __be32
0351 nfsd4_decode_security_label(struct nfsd4_compoundargs *argp,
0352 struct xdr_netobj *label)
0353 {
0354 u32 lfs, pi, length;
0355 __be32 *p;
0356
0357 if (xdr_stream_decode_u32(argp->xdr, &lfs) < 0)
0358 return nfserr_bad_xdr;
0359 if (xdr_stream_decode_u32(argp->xdr, &pi) < 0)
0360 return nfserr_bad_xdr;
0361
0362 if (xdr_stream_decode_u32(argp->xdr, &length) < 0)
0363 return nfserr_bad_xdr;
0364 if (length > NFS4_MAXLABELLEN)
0365 return nfserr_badlabel;
0366 p = xdr_inline_decode(argp->xdr, length);
0367 if (!p)
0368 return nfserr_bad_xdr;
0369 label->len = length;
0370 label->data = svcxdr_dupstr(argp, p, length);
0371 if (!label->data)
0372 return nfserr_jukebox;
0373
0374 return nfs_ok;
0375 }
0376
0377 static __be32
0378 nfsd4_decode_fattr4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen,
0379 struct iattr *iattr, struct nfs4_acl **acl,
0380 struct xdr_netobj *label, int *umask)
0381 {
0382 unsigned int starting_pos;
0383 u32 attrlist4_count;
0384 __be32 *p, status;
0385
0386 iattr->ia_valid = 0;
0387 status = nfsd4_decode_bitmap4(argp, bmval, bmlen);
0388 if (status)
0389 return nfserr_bad_xdr;
0390
0391 if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
0392 || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
0393 || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2) {
0394 if (nfsd_attrs_supported(argp->minorversion, bmval))
0395 return nfserr_inval;
0396 return nfserr_attrnotsupp;
0397 }
0398
0399 if (xdr_stream_decode_u32(argp->xdr, &attrlist4_count) < 0)
0400 return nfserr_bad_xdr;
0401 starting_pos = xdr_stream_pos(argp->xdr);
0402
0403 if (bmval[0] & FATTR4_WORD0_SIZE) {
0404 u64 size;
0405
0406 if (xdr_stream_decode_u64(argp->xdr, &size) < 0)
0407 return nfserr_bad_xdr;
0408 iattr->ia_size = size;
0409 iattr->ia_valid |= ATTR_SIZE;
0410 }
0411 if (bmval[0] & FATTR4_WORD0_ACL) {
0412 status = nfsd4_decode_acl(argp, acl);
0413 if (status)
0414 return status;
0415 } else
0416 *acl = NULL;
0417 if (bmval[1] & FATTR4_WORD1_MODE) {
0418 u32 mode;
0419
0420 if (xdr_stream_decode_u32(argp->xdr, &mode) < 0)
0421 return nfserr_bad_xdr;
0422 iattr->ia_mode = mode;
0423 iattr->ia_mode &= (S_IFMT | S_IALLUGO);
0424 iattr->ia_valid |= ATTR_MODE;
0425 }
0426 if (bmval[1] & FATTR4_WORD1_OWNER) {
0427 u32 length;
0428
0429 if (xdr_stream_decode_u32(argp->xdr, &length) < 0)
0430 return nfserr_bad_xdr;
0431 p = xdr_inline_decode(argp->xdr, length);
0432 if (!p)
0433 return nfserr_bad_xdr;
0434 status = nfsd_map_name_to_uid(argp->rqstp, (char *)p, length,
0435 &iattr->ia_uid);
0436 if (status)
0437 return status;
0438 iattr->ia_valid |= ATTR_UID;
0439 }
0440 if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
0441 u32 length;
0442
0443 if (xdr_stream_decode_u32(argp->xdr, &length) < 0)
0444 return nfserr_bad_xdr;
0445 p = xdr_inline_decode(argp->xdr, length);
0446 if (!p)
0447 return nfserr_bad_xdr;
0448 status = nfsd_map_name_to_gid(argp->rqstp, (char *)p, length,
0449 &iattr->ia_gid);
0450 if (status)
0451 return status;
0452 iattr->ia_valid |= ATTR_GID;
0453 }
0454 if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
0455 u32 set_it;
0456
0457 if (xdr_stream_decode_u32(argp->xdr, &set_it) < 0)
0458 return nfserr_bad_xdr;
0459 switch (set_it) {
0460 case NFS4_SET_TO_CLIENT_TIME:
0461 status = nfsd4_decode_nfstime4(argp, &iattr->ia_atime);
0462 if (status)
0463 return status;
0464 iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
0465 break;
0466 case NFS4_SET_TO_SERVER_TIME:
0467 iattr->ia_valid |= ATTR_ATIME;
0468 break;
0469 default:
0470 return nfserr_bad_xdr;
0471 }
0472 }
0473 if (bmval[1] & FATTR4_WORD1_TIME_CREATE) {
0474 struct timespec64 ts;
0475
0476
0477 bmval[1] &= ~FATTR4_WORD1_TIME_CREATE;
0478 status = nfsd4_decode_nfstime4(argp, &ts);
0479 if (status)
0480 return status;
0481 }
0482 if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
0483 u32 set_it;
0484
0485 if (xdr_stream_decode_u32(argp->xdr, &set_it) < 0)
0486 return nfserr_bad_xdr;
0487 switch (set_it) {
0488 case NFS4_SET_TO_CLIENT_TIME:
0489 status = nfsd4_decode_nfstime4(argp, &iattr->ia_mtime);
0490 if (status)
0491 return status;
0492 iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
0493 break;
0494 case NFS4_SET_TO_SERVER_TIME:
0495 iattr->ia_valid |= ATTR_MTIME;
0496 break;
0497 default:
0498 return nfserr_bad_xdr;
0499 }
0500 }
0501 label->len = 0;
0502 if (IS_ENABLED(CONFIG_NFSD_V4_SECURITY_LABEL) &&
0503 bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
0504 status = nfsd4_decode_security_label(argp, label);
0505 if (status)
0506 return status;
0507 }
0508 if (bmval[2] & FATTR4_WORD2_MODE_UMASK) {
0509 u32 mode, mask;
0510
0511 if (!umask)
0512 return nfserr_bad_xdr;
0513 if (xdr_stream_decode_u32(argp->xdr, &mode) < 0)
0514 return nfserr_bad_xdr;
0515 iattr->ia_mode = mode & (S_IFMT | S_IALLUGO);
0516 if (xdr_stream_decode_u32(argp->xdr, &mask) < 0)
0517 return nfserr_bad_xdr;
0518 *umask = mask & S_IRWXUGO;
0519 iattr->ia_valid |= ATTR_MODE;
0520 }
0521
0522
0523 if (attrlist4_count != xdr_stream_pos(argp->xdr) - starting_pos)
0524 return nfserr_bad_xdr;
0525
0526 return nfs_ok;
0527 }
0528
0529 static __be32
0530 nfsd4_decode_stateid4(struct nfsd4_compoundargs *argp, stateid_t *sid)
0531 {
0532 __be32 *p;
0533
0534 p = xdr_inline_decode(argp->xdr, NFS4_STATEID_SIZE);
0535 if (!p)
0536 return nfserr_bad_xdr;
0537 sid->si_generation = be32_to_cpup(p++);
0538 memcpy(&sid->si_opaque, p, sizeof(sid->si_opaque));
0539 return nfs_ok;
0540 }
0541
0542 static __be32
0543 nfsd4_decode_clientid4(struct nfsd4_compoundargs *argp, clientid_t *clientid)
0544 {
0545 __be32 *p;
0546
0547 p = xdr_inline_decode(argp->xdr, sizeof(__be64));
0548 if (!p)
0549 return nfserr_bad_xdr;
0550 memcpy(clientid, p, sizeof(*clientid));
0551 return nfs_ok;
0552 }
0553
0554 static __be32
0555 nfsd4_decode_state_owner4(struct nfsd4_compoundargs *argp,
0556 clientid_t *clientid, struct xdr_netobj *owner)
0557 {
0558 __be32 status;
0559
0560 status = nfsd4_decode_clientid4(argp, clientid);
0561 if (status)
0562 return status;
0563 return nfsd4_decode_opaque(argp, owner);
0564 }
0565
0566 #ifdef CONFIG_NFSD_PNFS
0567 static __be32
0568 nfsd4_decode_deviceid4(struct nfsd4_compoundargs *argp,
0569 struct nfsd4_deviceid *devid)
0570 {
0571 __be32 *p;
0572
0573 p = xdr_inline_decode(argp->xdr, NFS4_DEVICEID4_SIZE);
0574 if (!p)
0575 return nfserr_bad_xdr;
0576 memcpy(devid, p, sizeof(*devid));
0577 return nfs_ok;
0578 }
0579
0580 static __be32
0581 nfsd4_decode_layoutupdate4(struct nfsd4_compoundargs *argp,
0582 struct nfsd4_layoutcommit *lcp)
0583 {
0584 if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_layout_type) < 0)
0585 return nfserr_bad_xdr;
0586 if (lcp->lc_layout_type < LAYOUT_NFSV4_1_FILES)
0587 return nfserr_bad_xdr;
0588 if (lcp->lc_layout_type >= LAYOUT_TYPE_MAX)
0589 return nfserr_bad_xdr;
0590
0591 if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_up_len) < 0)
0592 return nfserr_bad_xdr;
0593 if (lcp->lc_up_len > 0) {
0594 lcp->lc_up_layout = xdr_inline_decode(argp->xdr, lcp->lc_up_len);
0595 if (!lcp->lc_up_layout)
0596 return nfserr_bad_xdr;
0597 }
0598
0599 return nfs_ok;
0600 }
0601
0602 static __be32
0603 nfsd4_decode_layoutreturn4(struct nfsd4_compoundargs *argp,
0604 struct nfsd4_layoutreturn *lrp)
0605 {
0606 __be32 status;
0607
0608 if (xdr_stream_decode_u32(argp->xdr, &lrp->lr_return_type) < 0)
0609 return nfserr_bad_xdr;
0610 switch (lrp->lr_return_type) {
0611 case RETURN_FILE:
0612 if (xdr_stream_decode_u64(argp->xdr, &lrp->lr_seg.offset) < 0)
0613 return nfserr_bad_xdr;
0614 if (xdr_stream_decode_u64(argp->xdr, &lrp->lr_seg.length) < 0)
0615 return nfserr_bad_xdr;
0616 status = nfsd4_decode_stateid4(argp, &lrp->lr_sid);
0617 if (status)
0618 return status;
0619 if (xdr_stream_decode_u32(argp->xdr, &lrp->lrf_body_len) < 0)
0620 return nfserr_bad_xdr;
0621 if (lrp->lrf_body_len > 0) {
0622 lrp->lrf_body = xdr_inline_decode(argp->xdr, lrp->lrf_body_len);
0623 if (!lrp->lrf_body)
0624 return nfserr_bad_xdr;
0625 }
0626 break;
0627 case RETURN_FSID:
0628 case RETURN_ALL:
0629 lrp->lr_seg.offset = 0;
0630 lrp->lr_seg.length = NFS4_MAX_UINT64;
0631 break;
0632 default:
0633 return nfserr_bad_xdr;
0634 }
0635
0636 return nfs_ok;
0637 }
0638
0639 #endif
0640
0641 static __be32
0642 nfsd4_decode_sessionid4(struct nfsd4_compoundargs *argp,
0643 struct nfs4_sessionid *sessionid)
0644 {
0645 __be32 *p;
0646
0647 p = xdr_inline_decode(argp->xdr, NFS4_MAX_SESSIONID_LEN);
0648 if (!p)
0649 return nfserr_bad_xdr;
0650 memcpy(sessionid->data, p, sizeof(sessionid->data));
0651 return nfs_ok;
0652 }
0653
0654
0655 static __be32
0656 nfsd4_decode_authsys_parms(struct nfsd4_compoundargs *argp,
0657 struct nfsd4_cb_sec *cbs)
0658 {
0659 u32 stamp, gidcount, uid, gid;
0660 __be32 *p, status;
0661
0662 if (xdr_stream_decode_u32(argp->xdr, &stamp) < 0)
0663 return nfserr_bad_xdr;
0664
0665 status = nfsd4_decode_ignored_string(argp, 255);
0666 if (status)
0667 return status;
0668 if (xdr_stream_decode_u32(argp->xdr, &uid) < 0)
0669 return nfserr_bad_xdr;
0670 if (xdr_stream_decode_u32(argp->xdr, &gid) < 0)
0671 return nfserr_bad_xdr;
0672 if (xdr_stream_decode_u32(argp->xdr, &gidcount) < 0)
0673 return nfserr_bad_xdr;
0674 if (gidcount > 16)
0675 return nfserr_bad_xdr;
0676 p = xdr_inline_decode(argp->xdr, gidcount << 2);
0677 if (!p)
0678 return nfserr_bad_xdr;
0679 if (cbs->flavor == (u32)(-1)) {
0680 struct user_namespace *userns = nfsd_user_namespace(argp->rqstp);
0681
0682 kuid_t kuid = make_kuid(userns, uid);
0683 kgid_t kgid = make_kgid(userns, gid);
0684 if (uid_valid(kuid) && gid_valid(kgid)) {
0685 cbs->uid = kuid;
0686 cbs->gid = kgid;
0687 cbs->flavor = RPC_AUTH_UNIX;
0688 } else {
0689 dprintk("RPC_AUTH_UNIX with invalid uid or gid, ignoring!\n");
0690 }
0691 }
0692
0693 return nfs_ok;
0694 }
0695
0696 static __be32
0697 nfsd4_decode_gss_cb_handles4(struct nfsd4_compoundargs *argp,
0698 struct nfsd4_cb_sec *cbs)
0699 {
0700 __be32 status;
0701 u32 service;
0702
0703 dprintk("RPC_AUTH_GSS callback secflavor not supported!\n");
0704
0705 if (xdr_stream_decode_u32(argp->xdr, &service) < 0)
0706 return nfserr_bad_xdr;
0707 if (service < RPC_GSS_SVC_NONE || service > RPC_GSS_SVC_PRIVACY)
0708 return nfserr_bad_xdr;
0709
0710 status = nfsd4_decode_ignored_string(argp, 0);
0711 if (status)
0712 return status;
0713
0714 status = nfsd4_decode_ignored_string(argp, 0);
0715 if (status)
0716 return status;
0717
0718 return nfs_ok;
0719 }
0720
0721
0722 static __be32
0723 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
0724 {
0725 u32 i, secflavor, nr_secflavs;
0726 __be32 status;
0727
0728
0729 if (xdr_stream_decode_u32(argp->xdr, &nr_secflavs) < 0)
0730 return nfserr_bad_xdr;
0731 if (nr_secflavs)
0732 cbs->flavor = (u32)(-1);
0733 else
0734
0735 cbs->flavor = 0;
0736
0737 for (i = 0; i < nr_secflavs; ++i) {
0738 if (xdr_stream_decode_u32(argp->xdr, &secflavor) < 0)
0739 return nfserr_bad_xdr;
0740 switch (secflavor) {
0741 case RPC_AUTH_NULL:
0742
0743 if (cbs->flavor == (u32)(-1))
0744 cbs->flavor = RPC_AUTH_NULL;
0745 break;
0746 case RPC_AUTH_UNIX:
0747 status = nfsd4_decode_authsys_parms(argp, cbs);
0748 if (status)
0749 return status;
0750 break;
0751 case RPC_AUTH_GSS:
0752 status = nfsd4_decode_gss_cb_handles4(argp, cbs);
0753 if (status)
0754 return status;
0755 break;
0756 default:
0757 return nfserr_inval;
0758 }
0759 }
0760
0761 return nfs_ok;
0762 }
0763
0764
0765
0766
0767
0768
0769 static __be32
0770 nfsd4_decode_access(struct nfsd4_compoundargs *argp,
0771 struct nfsd4_access *access)
0772 {
0773 if (xdr_stream_decode_u32(argp->xdr, &access->ac_req_access) < 0)
0774 return nfserr_bad_xdr;
0775 return nfs_ok;
0776 }
0777
0778 static __be32
0779 nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
0780 {
0781 if (xdr_stream_decode_u32(argp->xdr, &close->cl_seqid) < 0)
0782 return nfserr_bad_xdr;
0783 return nfsd4_decode_stateid4(argp, &close->cl_stateid);
0784 }
0785
0786
0787 static __be32
0788 nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit)
0789 {
0790 if (xdr_stream_decode_u64(argp->xdr, &commit->co_offset) < 0)
0791 return nfserr_bad_xdr;
0792 if (xdr_stream_decode_u32(argp->xdr, &commit->co_count) < 0)
0793 return nfserr_bad_xdr;
0794 return nfs_ok;
0795 }
0796
0797 static __be32
0798 nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
0799 {
0800 __be32 *p, status;
0801
0802 if (xdr_stream_decode_u32(argp->xdr, &create->cr_type) < 0)
0803 return nfserr_bad_xdr;
0804 switch (create->cr_type) {
0805 case NF4LNK:
0806 if (xdr_stream_decode_u32(argp->xdr, &create->cr_datalen) < 0)
0807 return nfserr_bad_xdr;
0808 p = xdr_inline_decode(argp->xdr, create->cr_datalen);
0809 if (!p)
0810 return nfserr_bad_xdr;
0811 create->cr_data = svcxdr_dupstr(argp, p, create->cr_datalen);
0812 if (!create->cr_data)
0813 return nfserr_jukebox;
0814 break;
0815 case NF4BLK:
0816 case NF4CHR:
0817 if (xdr_stream_decode_u32(argp->xdr, &create->cr_specdata1) < 0)
0818 return nfserr_bad_xdr;
0819 if (xdr_stream_decode_u32(argp->xdr, &create->cr_specdata2) < 0)
0820 return nfserr_bad_xdr;
0821 break;
0822 case NF4SOCK:
0823 case NF4FIFO:
0824 case NF4DIR:
0825 default:
0826 break;
0827 }
0828 status = nfsd4_decode_component4(argp, &create->cr_name,
0829 &create->cr_namelen);
0830 if (status)
0831 return status;
0832 status = nfsd4_decode_fattr4(argp, create->cr_bmval,
0833 ARRAY_SIZE(create->cr_bmval),
0834 &create->cr_iattr, &create->cr_acl,
0835 &create->cr_label, &create->cr_umask);
0836 if (status)
0837 return status;
0838
0839 return nfs_ok;
0840 }
0841
0842 static inline __be32
0843 nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
0844 {
0845 return nfsd4_decode_stateid4(argp, &dr->dr_stateid);
0846 }
0847
0848 static inline __be32
0849 nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
0850 {
0851 return nfsd4_decode_bitmap4(argp, getattr->ga_bmval,
0852 ARRAY_SIZE(getattr->ga_bmval));
0853 }
0854
0855 static __be32
0856 nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
0857 {
0858 return nfsd4_decode_component4(argp, &link->li_name, &link->li_namelen);
0859 }
0860
0861 static __be32
0862 nfsd4_decode_open_to_lock_owner4(struct nfsd4_compoundargs *argp,
0863 struct nfsd4_lock *lock)
0864 {
0865 __be32 status;
0866
0867 if (xdr_stream_decode_u32(argp->xdr, &lock->lk_new_open_seqid) < 0)
0868 return nfserr_bad_xdr;
0869 status = nfsd4_decode_stateid4(argp, &lock->lk_new_open_stateid);
0870 if (status)
0871 return status;
0872 if (xdr_stream_decode_u32(argp->xdr, &lock->lk_new_lock_seqid) < 0)
0873 return nfserr_bad_xdr;
0874 return nfsd4_decode_state_owner4(argp, &lock->lk_new_clientid,
0875 &lock->lk_new_owner);
0876 }
0877
0878 static __be32
0879 nfsd4_decode_exist_lock_owner4(struct nfsd4_compoundargs *argp,
0880 struct nfsd4_lock *lock)
0881 {
0882 __be32 status;
0883
0884 status = nfsd4_decode_stateid4(argp, &lock->lk_old_lock_stateid);
0885 if (status)
0886 return status;
0887 if (xdr_stream_decode_u32(argp->xdr, &lock->lk_old_lock_seqid) < 0)
0888 return nfserr_bad_xdr;
0889
0890 return nfs_ok;
0891 }
0892
0893 static __be32
0894 nfsd4_decode_locker4(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
0895 {
0896 if (xdr_stream_decode_bool(argp->xdr, &lock->lk_is_new) < 0)
0897 return nfserr_bad_xdr;
0898 if (lock->lk_is_new)
0899 return nfsd4_decode_open_to_lock_owner4(argp, lock);
0900 return nfsd4_decode_exist_lock_owner4(argp, lock);
0901 }
0902
0903 static __be32
0904 nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
0905 {
0906 if (xdr_stream_decode_u32(argp->xdr, &lock->lk_type) < 0)
0907 return nfserr_bad_xdr;
0908 if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT))
0909 return nfserr_bad_xdr;
0910 if (xdr_stream_decode_bool(argp->xdr, &lock->lk_reclaim) < 0)
0911 return nfserr_bad_xdr;
0912 if (xdr_stream_decode_u64(argp->xdr, &lock->lk_offset) < 0)
0913 return nfserr_bad_xdr;
0914 if (xdr_stream_decode_u64(argp->xdr, &lock->lk_length) < 0)
0915 return nfserr_bad_xdr;
0916 return nfsd4_decode_locker4(argp, lock);
0917 }
0918
0919 static __be32
0920 nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
0921 {
0922 if (xdr_stream_decode_u32(argp->xdr, &lockt->lt_type) < 0)
0923 return nfserr_bad_xdr;
0924 if ((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
0925 return nfserr_bad_xdr;
0926 if (xdr_stream_decode_u64(argp->xdr, &lockt->lt_offset) < 0)
0927 return nfserr_bad_xdr;
0928 if (xdr_stream_decode_u64(argp->xdr, &lockt->lt_length) < 0)
0929 return nfserr_bad_xdr;
0930 return nfsd4_decode_state_owner4(argp, &lockt->lt_clientid,
0931 &lockt->lt_owner);
0932 }
0933
0934 static __be32
0935 nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
0936 {
0937 __be32 status;
0938
0939 if (xdr_stream_decode_u32(argp->xdr, &locku->lu_type) < 0)
0940 return nfserr_bad_xdr;
0941 if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
0942 return nfserr_bad_xdr;
0943 if (xdr_stream_decode_u32(argp->xdr, &locku->lu_seqid) < 0)
0944 return nfserr_bad_xdr;
0945 status = nfsd4_decode_stateid4(argp, &locku->lu_stateid);
0946 if (status)
0947 return status;
0948 if (xdr_stream_decode_u64(argp->xdr, &locku->lu_offset) < 0)
0949 return nfserr_bad_xdr;
0950 if (xdr_stream_decode_u64(argp->xdr, &locku->lu_length) < 0)
0951 return nfserr_bad_xdr;
0952
0953 return nfs_ok;
0954 }
0955
0956 static __be32
0957 nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup)
0958 {
0959 return nfsd4_decode_component4(argp, &lookup->lo_name, &lookup->lo_len);
0960 }
0961
0962 static __be32
0963 nfsd4_decode_createhow4(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
0964 {
0965 __be32 status;
0966
0967 if (xdr_stream_decode_u32(argp->xdr, &open->op_createmode) < 0)
0968 return nfserr_bad_xdr;
0969 switch (open->op_createmode) {
0970 case NFS4_CREATE_UNCHECKED:
0971 case NFS4_CREATE_GUARDED:
0972 status = nfsd4_decode_fattr4(argp, open->op_bmval,
0973 ARRAY_SIZE(open->op_bmval),
0974 &open->op_iattr, &open->op_acl,
0975 &open->op_label, &open->op_umask);
0976 if (status)
0977 return status;
0978 break;
0979 case NFS4_CREATE_EXCLUSIVE:
0980 status = nfsd4_decode_verifier4(argp, &open->op_verf);
0981 if (status)
0982 return status;
0983 break;
0984 case NFS4_CREATE_EXCLUSIVE4_1:
0985 if (argp->minorversion < 1)
0986 return nfserr_bad_xdr;
0987 status = nfsd4_decode_verifier4(argp, &open->op_verf);
0988 if (status)
0989 return status;
0990 status = nfsd4_decode_fattr4(argp, open->op_bmval,
0991 ARRAY_SIZE(open->op_bmval),
0992 &open->op_iattr, &open->op_acl,
0993 &open->op_label, &open->op_umask);
0994 if (status)
0995 return status;
0996 break;
0997 default:
0998 return nfserr_bad_xdr;
0999 }
1000
1001 return nfs_ok;
1002 }
1003
1004 static __be32
1005 nfsd4_decode_openflag4(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
1006 {
1007 __be32 status;
1008
1009 if (xdr_stream_decode_u32(argp->xdr, &open->op_create) < 0)
1010 return nfserr_bad_xdr;
1011 switch (open->op_create) {
1012 case NFS4_OPEN_NOCREATE:
1013 break;
1014 case NFS4_OPEN_CREATE:
1015 status = nfsd4_decode_createhow4(argp, open);
1016 if (status)
1017 return status;
1018 break;
1019 default:
1020 return nfserr_bad_xdr;
1021 }
1022
1023 return nfs_ok;
1024 }
1025
1026 static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
1027 {
1028 u32 w;
1029
1030 if (xdr_stream_decode_u32(argp->xdr, &w) < 0)
1031 return nfserr_bad_xdr;
1032 *share_access = w & NFS4_SHARE_ACCESS_MASK;
1033 *deleg_want = w & NFS4_SHARE_WANT_MASK;
1034 if (deleg_when)
1035 *deleg_when = w & NFS4_SHARE_WHEN_MASK;
1036
1037 switch (w & NFS4_SHARE_ACCESS_MASK) {
1038 case NFS4_SHARE_ACCESS_READ:
1039 case NFS4_SHARE_ACCESS_WRITE:
1040 case NFS4_SHARE_ACCESS_BOTH:
1041 break;
1042 default:
1043 return nfserr_bad_xdr;
1044 }
1045 w &= ~NFS4_SHARE_ACCESS_MASK;
1046 if (!w)
1047 return nfs_ok;
1048 if (!argp->minorversion)
1049 return nfserr_bad_xdr;
1050 switch (w & NFS4_SHARE_WANT_MASK) {
1051 case NFS4_SHARE_WANT_NO_PREFERENCE:
1052 case NFS4_SHARE_WANT_READ_DELEG:
1053 case NFS4_SHARE_WANT_WRITE_DELEG:
1054 case NFS4_SHARE_WANT_ANY_DELEG:
1055 case NFS4_SHARE_WANT_NO_DELEG:
1056 case NFS4_SHARE_WANT_CANCEL:
1057 break;
1058 default:
1059 return nfserr_bad_xdr;
1060 }
1061 w &= ~NFS4_SHARE_WANT_MASK;
1062 if (!w)
1063 return nfs_ok;
1064
1065 if (!deleg_when)
1066 return nfserr_inval;
1067 switch (w) {
1068 case NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL:
1069 case NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED:
1070 case (NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL |
1071 NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED):
1072 return nfs_ok;
1073 }
1074 return nfserr_bad_xdr;
1075 }
1076
1077 static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
1078 {
1079 if (xdr_stream_decode_u32(argp->xdr, x) < 0)
1080 return nfserr_bad_xdr;
1081
1082 if (*x & ~NFS4_SHARE_DENY_BOTH)
1083 return nfserr_bad_xdr;
1084
1085 return nfs_ok;
1086 }
1087
1088 static __be32
1089 nfsd4_decode_open_claim4(struct nfsd4_compoundargs *argp,
1090 struct nfsd4_open *open)
1091 {
1092 __be32 status;
1093
1094 if (xdr_stream_decode_u32(argp->xdr, &open->op_claim_type) < 0)
1095 return nfserr_bad_xdr;
1096 switch (open->op_claim_type) {
1097 case NFS4_OPEN_CLAIM_NULL:
1098 case NFS4_OPEN_CLAIM_DELEGATE_PREV:
1099 status = nfsd4_decode_component4(argp, &open->op_fname,
1100 &open->op_fnamelen);
1101 if (status)
1102 return status;
1103 break;
1104 case NFS4_OPEN_CLAIM_PREVIOUS:
1105 if (xdr_stream_decode_u32(argp->xdr, &open->op_delegate_type) < 0)
1106 return nfserr_bad_xdr;
1107 break;
1108 case NFS4_OPEN_CLAIM_DELEGATE_CUR:
1109 status = nfsd4_decode_stateid4(argp, &open->op_delegate_stateid);
1110 if (status)
1111 return status;
1112 status = nfsd4_decode_component4(argp, &open->op_fname,
1113 &open->op_fnamelen);
1114 if (status)
1115 return status;
1116 break;
1117 case NFS4_OPEN_CLAIM_FH:
1118 case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
1119 if (argp->minorversion < 1)
1120 return nfserr_bad_xdr;
1121
1122 break;
1123 case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
1124 if (argp->minorversion < 1)
1125 return nfserr_bad_xdr;
1126 status = nfsd4_decode_stateid4(argp, &open->op_delegate_stateid);
1127 if (status)
1128 return status;
1129 break;
1130 default:
1131 return nfserr_bad_xdr;
1132 }
1133
1134 return nfs_ok;
1135 }
1136
1137 static __be32
1138 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
1139 {
1140 __be32 status;
1141 u32 dummy;
1142
1143 memset(open->op_bmval, 0, sizeof(open->op_bmval));
1144 open->op_iattr.ia_valid = 0;
1145 open->op_openowner = NULL;
1146
1147 open->op_xdr_error = 0;
1148 if (xdr_stream_decode_u32(argp->xdr, &open->op_seqid) < 0)
1149 return nfserr_bad_xdr;
1150
1151 status = nfsd4_decode_share_access(argp, &open->op_share_access,
1152 &open->op_deleg_want, &dummy);
1153 if (status)
1154 return status;
1155 status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
1156 if (status)
1157 return status;
1158 status = nfsd4_decode_state_owner4(argp, &open->op_clientid,
1159 &open->op_owner);
1160 if (status)
1161 return status;
1162 status = nfsd4_decode_openflag4(argp, open);
1163 if (status)
1164 return status;
1165 return nfsd4_decode_open_claim4(argp, open);
1166 }
1167
1168 static __be32
1169 nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
1170 {
1171 __be32 status;
1172
1173 if (argp->minorversion >= 1)
1174 return nfserr_notsupp;
1175
1176 status = nfsd4_decode_stateid4(argp, &open_conf->oc_req_stateid);
1177 if (status)
1178 return status;
1179 if (xdr_stream_decode_u32(argp->xdr, &open_conf->oc_seqid) < 0)
1180 return nfserr_bad_xdr;
1181
1182 return nfs_ok;
1183 }
1184
1185 static __be32
1186 nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
1187 {
1188 __be32 status;
1189
1190 status = nfsd4_decode_stateid4(argp, &open_down->od_stateid);
1191 if (status)
1192 return status;
1193 if (xdr_stream_decode_u32(argp->xdr, &open_down->od_seqid) < 0)
1194 return nfserr_bad_xdr;
1195
1196 status = nfsd4_decode_share_access(argp, &open_down->od_share_access,
1197 &open_down->od_deleg_want, NULL);
1198 if (status)
1199 return status;
1200 return nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
1201 }
1202
1203 static __be32
1204 nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
1205 {
1206 __be32 *p;
1207
1208 if (xdr_stream_decode_u32(argp->xdr, &putfh->pf_fhlen) < 0)
1209 return nfserr_bad_xdr;
1210 if (putfh->pf_fhlen > NFS4_FHSIZE)
1211 return nfserr_bad_xdr;
1212 p = xdr_inline_decode(argp->xdr, putfh->pf_fhlen);
1213 if (!p)
1214 return nfserr_bad_xdr;
1215 putfh->pf_fhval = svcxdr_savemem(argp, p, putfh->pf_fhlen);
1216 if (!putfh->pf_fhval)
1217 return nfserr_jukebox;
1218
1219 return nfs_ok;
1220 }
1221
1222 static __be32
1223 nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p)
1224 {
1225 if (argp->minorversion == 0)
1226 return nfs_ok;
1227 return nfserr_notsupp;
1228 }
1229
1230 static __be32
1231 nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
1232 {
1233 __be32 status;
1234
1235 status = nfsd4_decode_stateid4(argp, &read->rd_stateid);
1236 if (status)
1237 return status;
1238 if (xdr_stream_decode_u64(argp->xdr, &read->rd_offset) < 0)
1239 return nfserr_bad_xdr;
1240 if (xdr_stream_decode_u32(argp->xdr, &read->rd_length) < 0)
1241 return nfserr_bad_xdr;
1242
1243 return nfs_ok;
1244 }
1245
1246 static __be32
1247 nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir)
1248 {
1249 __be32 status;
1250
1251 if (xdr_stream_decode_u64(argp->xdr, &readdir->rd_cookie) < 0)
1252 return nfserr_bad_xdr;
1253 status = nfsd4_decode_verifier4(argp, &readdir->rd_verf);
1254 if (status)
1255 return status;
1256 if (xdr_stream_decode_u32(argp->xdr, &readdir->rd_dircount) < 0)
1257 return nfserr_bad_xdr;
1258 if (xdr_stream_decode_u32(argp->xdr, &readdir->rd_maxcount) < 0)
1259 return nfserr_bad_xdr;
1260 if (xdr_stream_decode_uint32_array(argp->xdr, readdir->rd_bmval,
1261 ARRAY_SIZE(readdir->rd_bmval)) < 0)
1262 return nfserr_bad_xdr;
1263
1264 return nfs_ok;
1265 }
1266
1267 static __be32
1268 nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove)
1269 {
1270 return nfsd4_decode_component4(argp, &remove->rm_name, &remove->rm_namelen);
1271 }
1272
1273 static __be32
1274 nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename)
1275 {
1276 __be32 status;
1277
1278 status = nfsd4_decode_component4(argp, &rename->rn_sname, &rename->rn_snamelen);
1279 if (status)
1280 return status;
1281 return nfsd4_decode_component4(argp, &rename->rn_tname, &rename->rn_tnamelen);
1282 }
1283
1284 static __be32
1285 nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
1286 {
1287 return nfsd4_decode_clientid4(argp, clientid);
1288 }
1289
1290 static __be32
1291 nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
1292 struct nfsd4_secinfo *secinfo)
1293 {
1294 return nfsd4_decode_component4(argp, &secinfo->si_name, &secinfo->si_namelen);
1295 }
1296
1297 static __be32
1298 nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
1299 {
1300 __be32 status;
1301
1302 status = nfsd4_decode_stateid4(argp, &setattr->sa_stateid);
1303 if (status)
1304 return status;
1305 return nfsd4_decode_fattr4(argp, setattr->sa_bmval,
1306 ARRAY_SIZE(setattr->sa_bmval),
1307 &setattr->sa_iattr, &setattr->sa_acl,
1308 &setattr->sa_label, NULL);
1309 }
1310
1311 static __be32
1312 nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid)
1313 {
1314 __be32 *p, status;
1315
1316 if (argp->minorversion >= 1)
1317 return nfserr_notsupp;
1318
1319 status = nfsd4_decode_verifier4(argp, &setclientid->se_verf);
1320 if (status)
1321 return status;
1322 status = nfsd4_decode_opaque(argp, &setclientid->se_name);
1323 if (status)
1324 return status;
1325 if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_prog) < 0)
1326 return nfserr_bad_xdr;
1327 if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_netid_len) < 0)
1328 return nfserr_bad_xdr;
1329 p = xdr_inline_decode(argp->xdr, setclientid->se_callback_netid_len);
1330 if (!p)
1331 return nfserr_bad_xdr;
1332 setclientid->se_callback_netid_val = svcxdr_savemem(argp, p,
1333 setclientid->se_callback_netid_len);
1334 if (!setclientid->se_callback_netid_val)
1335 return nfserr_jukebox;
1336
1337 if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_addr_len) < 0)
1338 return nfserr_bad_xdr;
1339 p = xdr_inline_decode(argp->xdr, setclientid->se_callback_addr_len);
1340 if (!p)
1341 return nfserr_bad_xdr;
1342 setclientid->se_callback_addr_val = svcxdr_savemem(argp, p,
1343 setclientid->se_callback_addr_len);
1344 if (!setclientid->se_callback_addr_val)
1345 return nfserr_jukebox;
1346 if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_ident) < 0)
1347 return nfserr_bad_xdr;
1348
1349 return nfs_ok;
1350 }
1351
1352 static __be32
1353 nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c)
1354 {
1355 __be32 status;
1356
1357 if (argp->minorversion >= 1)
1358 return nfserr_notsupp;
1359
1360 status = nfsd4_decode_clientid4(argp, &scd_c->sc_clientid);
1361 if (status)
1362 return status;
1363 return nfsd4_decode_verifier4(argp, &scd_c->sc_confirm);
1364 }
1365
1366
1367 static __be32
1368 nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
1369 {
1370 __be32 *p, status;
1371
1372 status = nfsd4_decode_bitmap4(argp, verify->ve_bmval,
1373 ARRAY_SIZE(verify->ve_bmval));
1374 if (status)
1375 return status;
1376
1377
1378
1379
1380 if (xdr_stream_decode_u32(argp->xdr, &verify->ve_attrlen) < 0)
1381 return nfserr_bad_xdr;
1382 p = xdr_inline_decode(argp->xdr, verify->ve_attrlen);
1383 if (!p)
1384 return nfserr_bad_xdr;
1385 verify->ve_attrval = svcxdr_savemem(argp, p, verify->ve_attrlen);
1386 if (!verify->ve_attrval)
1387 return nfserr_jukebox;
1388
1389 return nfs_ok;
1390 }
1391
1392 static __be32
1393 nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
1394 {
1395 __be32 status;
1396
1397 status = nfsd4_decode_stateid4(argp, &write->wr_stateid);
1398 if (status)
1399 return status;
1400 if (xdr_stream_decode_u64(argp->xdr, &write->wr_offset) < 0)
1401 return nfserr_bad_xdr;
1402 if (xdr_stream_decode_u32(argp->xdr, &write->wr_stable_how) < 0)
1403 return nfserr_bad_xdr;
1404 if (write->wr_stable_how > NFS_FILE_SYNC)
1405 return nfserr_bad_xdr;
1406 if (xdr_stream_decode_u32(argp->xdr, &write->wr_buflen) < 0)
1407 return nfserr_bad_xdr;
1408 if (!xdr_stream_subsegment(argp->xdr, &write->wr_payload, write->wr_buflen))
1409 return nfserr_bad_xdr;
1410
1411 return nfs_ok;
1412 }
1413
1414 static __be32
1415 nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner)
1416 {
1417 __be32 status;
1418
1419 if (argp->minorversion >= 1)
1420 return nfserr_notsupp;
1421
1422 status = nfsd4_decode_state_owner4(argp, &rlockowner->rl_clientid,
1423 &rlockowner->rl_owner);
1424 if (status)
1425 return status;
1426
1427 if (argp->minorversion && !zero_clientid(&rlockowner->rl_clientid))
1428 return nfserr_inval;
1429
1430 return nfs_ok;
1431 }
1432
1433 static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc)
1434 {
1435 if (xdr_stream_decode_u32(argp->xdr, &bc->bc_cb_program) < 0)
1436 return nfserr_bad_xdr;
1437 return nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec);
1438 }
1439
1440 static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
1441 {
1442 u32 use_conn_in_rdma_mode;
1443 __be32 status;
1444
1445 status = nfsd4_decode_sessionid4(argp, &bcts->sessionid);
1446 if (status)
1447 return status;
1448 if (xdr_stream_decode_u32(argp->xdr, &bcts->dir) < 0)
1449 return nfserr_bad_xdr;
1450 if (xdr_stream_decode_u32(argp->xdr, &use_conn_in_rdma_mode) < 0)
1451 return nfserr_bad_xdr;
1452
1453 return nfs_ok;
1454 }
1455
1456 static __be32
1457 nfsd4_decode_state_protect_ops(struct nfsd4_compoundargs *argp,
1458 struct nfsd4_exchange_id *exid)
1459 {
1460 __be32 status;
1461
1462 status = nfsd4_decode_bitmap4(argp, exid->spo_must_enforce,
1463 ARRAY_SIZE(exid->spo_must_enforce));
1464 if (status)
1465 return nfserr_bad_xdr;
1466 status = nfsd4_decode_bitmap4(argp, exid->spo_must_allow,
1467 ARRAY_SIZE(exid->spo_must_allow));
1468 if (status)
1469 return nfserr_bad_xdr;
1470
1471 return nfs_ok;
1472 }
1473
1474
1475
1476
1477
1478 static noinline __be32
1479 nfsd4_decode_ssv_sp_parms(struct nfsd4_compoundargs *argp,
1480 struct nfsd4_exchange_id *exid)
1481 {
1482 u32 count, window, num_gss_handles;
1483 __be32 status;
1484
1485
1486 status = nfsd4_decode_state_protect_ops(argp, exid);
1487 if (status)
1488 return status;
1489
1490
1491 if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
1492 return nfserr_bad_xdr;
1493 while (count--) {
1494 status = nfsd4_decode_ignored_string(argp, 0);
1495 if (status)
1496 return status;
1497 }
1498
1499
1500 if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
1501 return nfserr_bad_xdr;
1502 while (count--) {
1503 status = nfsd4_decode_ignored_string(argp, 0);
1504 if (status)
1505 return status;
1506 }
1507
1508 if (xdr_stream_decode_u32(argp->xdr, &window) < 0)
1509 return nfserr_bad_xdr;
1510 if (xdr_stream_decode_u32(argp->xdr, &num_gss_handles) < 0)
1511 return nfserr_bad_xdr;
1512
1513 return nfs_ok;
1514 }
1515
1516 static __be32
1517 nfsd4_decode_state_protect4_a(struct nfsd4_compoundargs *argp,
1518 struct nfsd4_exchange_id *exid)
1519 {
1520 __be32 status;
1521
1522 if (xdr_stream_decode_u32(argp->xdr, &exid->spa_how) < 0)
1523 return nfserr_bad_xdr;
1524 switch (exid->spa_how) {
1525 case SP4_NONE:
1526 break;
1527 case SP4_MACH_CRED:
1528 status = nfsd4_decode_state_protect_ops(argp, exid);
1529 if (status)
1530 return status;
1531 break;
1532 case SP4_SSV:
1533 status = nfsd4_decode_ssv_sp_parms(argp, exid);
1534 if (status)
1535 return status;
1536 break;
1537 default:
1538 return nfserr_bad_xdr;
1539 }
1540
1541 return nfs_ok;
1542 }
1543
1544 static __be32
1545 nfsd4_decode_nfs_impl_id4(struct nfsd4_compoundargs *argp,
1546 struct nfsd4_exchange_id *exid)
1547 {
1548 __be32 status;
1549 u32 count;
1550
1551 if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
1552 return nfserr_bad_xdr;
1553 switch (count) {
1554 case 0:
1555 break;
1556 case 1:
1557
1558
1559
1560 status = nfsd4_decode_opaque(argp, &exid->nii_domain);
1561 if (status)
1562 return status;
1563
1564
1565
1566 status = nfsd4_decode_opaque(argp, &exid->nii_name);
1567 if (status)
1568 return status;
1569 status = nfsd4_decode_nfstime4(argp, &exid->nii_time);
1570 if (status)
1571 return status;
1572 break;
1573 default:
1574 return nfserr_bad_xdr;
1575 }
1576
1577 return nfs_ok;
1578 }
1579
1580 static __be32
1581 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1582 struct nfsd4_exchange_id *exid)
1583 {
1584 __be32 status;
1585
1586 status = nfsd4_decode_verifier4(argp, &exid->verifier);
1587 if (status)
1588 return status;
1589 status = nfsd4_decode_opaque(argp, &exid->clname);
1590 if (status)
1591 return status;
1592 if (xdr_stream_decode_u32(argp->xdr, &exid->flags) < 0)
1593 return nfserr_bad_xdr;
1594 status = nfsd4_decode_state_protect4_a(argp, exid);
1595 if (status)
1596 return status;
1597 return nfsd4_decode_nfs_impl_id4(argp, exid);
1598 }
1599
1600 static __be32
1601 nfsd4_decode_channel_attrs4(struct nfsd4_compoundargs *argp,
1602 struct nfsd4_channel_attrs *ca)
1603 {
1604 __be32 *p;
1605
1606 p = xdr_inline_decode(argp->xdr, XDR_UNIT * 7);
1607 if (!p)
1608 return nfserr_bad_xdr;
1609
1610
1611 p++;
1612 ca->maxreq_sz = be32_to_cpup(p++);
1613 ca->maxresp_sz = be32_to_cpup(p++);
1614 ca->maxresp_cached = be32_to_cpup(p++);
1615 ca->maxops = be32_to_cpup(p++);
1616 ca->maxreqs = be32_to_cpup(p++);
1617 ca->nr_rdma_attrs = be32_to_cpup(p);
1618 switch (ca->nr_rdma_attrs) {
1619 case 0:
1620 break;
1621 case 1:
1622 if (xdr_stream_decode_u32(argp->xdr, &ca->rdma_attrs) < 0)
1623 return nfserr_bad_xdr;
1624 break;
1625 default:
1626 return nfserr_bad_xdr;
1627 }
1628
1629 return nfs_ok;
1630 }
1631
1632 static __be32
1633 nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1634 struct nfsd4_create_session *sess)
1635 {
1636 __be32 status;
1637
1638 status = nfsd4_decode_clientid4(argp, &sess->clientid);
1639 if (status)
1640 return status;
1641 if (xdr_stream_decode_u32(argp->xdr, &sess->seqid) < 0)
1642 return nfserr_bad_xdr;
1643 if (xdr_stream_decode_u32(argp->xdr, &sess->flags) < 0)
1644 return nfserr_bad_xdr;
1645 status = nfsd4_decode_channel_attrs4(argp, &sess->fore_channel);
1646 if (status)
1647 return status;
1648 status = nfsd4_decode_channel_attrs4(argp, &sess->back_channel);
1649 if (status)
1650 return status;
1651 if (xdr_stream_decode_u32(argp->xdr, &sess->callback_prog) < 0)
1652 return nfserr_bad_xdr;
1653 status = nfsd4_decode_cb_sec(argp, &sess->cb_sec);
1654 if (status)
1655 return status;
1656
1657 return nfs_ok;
1658 }
1659
1660 static __be32
1661 nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp,
1662 struct nfsd4_destroy_session *destroy_session)
1663 {
1664 return nfsd4_decode_sessionid4(argp, &destroy_session->sessionid);
1665 }
1666
1667 static __be32
1668 nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
1669 struct nfsd4_free_stateid *free_stateid)
1670 {
1671 return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
1672 }
1673
1674 #ifdef CONFIG_NFSD_PNFS
1675 static __be32
1676 nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
1677 struct nfsd4_getdeviceinfo *gdev)
1678 {
1679 __be32 status;
1680
1681 status = nfsd4_decode_deviceid4(argp, &gdev->gd_devid);
1682 if (status)
1683 return status;
1684 if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_layout_type) < 0)
1685 return nfserr_bad_xdr;
1686 if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_maxcount) < 0)
1687 return nfserr_bad_xdr;
1688 if (xdr_stream_decode_uint32_array(argp->xdr,
1689 &gdev->gd_notify_types, 1) < 0)
1690 return nfserr_bad_xdr;
1691
1692 return nfs_ok;
1693 }
1694
1695 static __be32
1696 nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
1697 struct nfsd4_layoutcommit *lcp)
1698 {
1699 __be32 *p, status;
1700
1701 if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_seg.offset) < 0)
1702 return nfserr_bad_xdr;
1703 if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_seg.length) < 0)
1704 return nfserr_bad_xdr;
1705 if (xdr_stream_decode_bool(argp->xdr, &lcp->lc_reclaim) < 0)
1706 return nfserr_bad_xdr;
1707 status = nfsd4_decode_stateid4(argp, &lcp->lc_sid);
1708 if (status)
1709 return status;
1710 if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_newoffset) < 0)
1711 return nfserr_bad_xdr;
1712 if (lcp->lc_newoffset) {
1713 if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_last_wr) < 0)
1714 return nfserr_bad_xdr;
1715 } else
1716 lcp->lc_last_wr = 0;
1717 p = xdr_inline_decode(argp->xdr, XDR_UNIT);
1718 if (!p)
1719 return nfserr_bad_xdr;
1720 if (xdr_item_is_present(p)) {
1721 status = nfsd4_decode_nfstime4(argp, &lcp->lc_mtime);
1722 if (status)
1723 return status;
1724 } else {
1725 lcp->lc_mtime.tv_nsec = UTIME_NOW;
1726 }
1727 return nfsd4_decode_layoutupdate4(argp, lcp);
1728 }
1729
1730 static __be32
1731 nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
1732 struct nfsd4_layoutget *lgp)
1733 {
1734 __be32 status;
1735
1736 if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_signal) < 0)
1737 return nfserr_bad_xdr;
1738 if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_layout_type) < 0)
1739 return nfserr_bad_xdr;
1740 if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_seg.iomode) < 0)
1741 return nfserr_bad_xdr;
1742 if (xdr_stream_decode_u64(argp->xdr, &lgp->lg_seg.offset) < 0)
1743 return nfserr_bad_xdr;
1744 if (xdr_stream_decode_u64(argp->xdr, &lgp->lg_seg.length) < 0)
1745 return nfserr_bad_xdr;
1746 if (xdr_stream_decode_u64(argp->xdr, &lgp->lg_minlength) < 0)
1747 return nfserr_bad_xdr;
1748 status = nfsd4_decode_stateid4(argp, &lgp->lg_sid);
1749 if (status)
1750 return status;
1751 if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_maxcount) < 0)
1752 return nfserr_bad_xdr;
1753
1754 return nfs_ok;
1755 }
1756
1757 static __be32
1758 nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
1759 struct nfsd4_layoutreturn *lrp)
1760 {
1761 if (xdr_stream_decode_bool(argp->xdr, &lrp->lr_reclaim) < 0)
1762 return nfserr_bad_xdr;
1763 if (xdr_stream_decode_u32(argp->xdr, &lrp->lr_layout_type) < 0)
1764 return nfserr_bad_xdr;
1765 if (xdr_stream_decode_u32(argp->xdr, &lrp->lr_seg.iomode) < 0)
1766 return nfserr_bad_xdr;
1767 return nfsd4_decode_layoutreturn4(argp, lrp);
1768 }
1769 #endif
1770
1771 static __be32 nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
1772 struct nfsd4_secinfo_no_name *sin)
1773 {
1774 if (xdr_stream_decode_u32(argp->xdr, &sin->sin_style) < 0)
1775 return nfserr_bad_xdr;
1776 return nfs_ok;
1777 }
1778
1779 static __be32
1780 nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
1781 struct nfsd4_sequence *seq)
1782 {
1783 __be32 *p, status;
1784
1785 status = nfsd4_decode_sessionid4(argp, &seq->sessionid);
1786 if (status)
1787 return status;
1788 p = xdr_inline_decode(argp->xdr, XDR_UNIT * 4);
1789 if (!p)
1790 return nfserr_bad_xdr;
1791 seq->seqid = be32_to_cpup(p++);
1792 seq->slotid = be32_to_cpup(p++);
1793 seq->maxslots = be32_to_cpup(p++);
1794 seq->cachethis = be32_to_cpup(p);
1795
1796 return nfs_ok;
1797 }
1798
1799 static __be32
1800 nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
1801 {
1802 struct nfsd4_test_stateid_id *stateid;
1803 __be32 status;
1804 u32 i;
1805
1806 if (xdr_stream_decode_u32(argp->xdr, &test_stateid->ts_num_ids) < 0)
1807 return nfserr_bad_xdr;
1808
1809 INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
1810 for (i = 0; i < test_stateid->ts_num_ids; i++) {
1811 stateid = svcxdr_tmpalloc(argp, sizeof(*stateid));
1812 if (!stateid)
1813 return nfserr_jukebox;
1814 INIT_LIST_HEAD(&stateid->ts_id_list);
1815 list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
1816 status = nfsd4_decode_stateid4(argp, &stateid->ts_id_stateid);
1817 if (status)
1818 return status;
1819 }
1820
1821 return nfs_ok;
1822 }
1823
1824 static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp,
1825 struct nfsd4_destroy_clientid *dc)
1826 {
1827 return nfsd4_decode_clientid4(argp, &dc->clientid);
1828 }
1829
1830 static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp,
1831 struct nfsd4_reclaim_complete *rc)
1832 {
1833 if (xdr_stream_decode_bool(argp->xdr, &rc->rca_one_fs) < 0)
1834 return nfserr_bad_xdr;
1835 return nfs_ok;
1836 }
1837
1838 static __be32
1839 nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
1840 struct nfsd4_fallocate *fallocate)
1841 {
1842 __be32 status;
1843
1844 status = nfsd4_decode_stateid4(argp, &fallocate->falloc_stateid);
1845 if (status)
1846 return status;
1847 if (xdr_stream_decode_u64(argp->xdr, &fallocate->falloc_offset) < 0)
1848 return nfserr_bad_xdr;
1849 if (xdr_stream_decode_u64(argp->xdr, &fallocate->falloc_length) < 0)
1850 return nfserr_bad_xdr;
1851
1852 return nfs_ok;
1853 }
1854
1855 static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp,
1856 struct nl4_server *ns)
1857 {
1858 struct nfs42_netaddr *naddr;
1859 __be32 *p;
1860
1861 if (xdr_stream_decode_u32(argp->xdr, &ns->nl4_type) < 0)
1862 return nfserr_bad_xdr;
1863
1864
1865 switch (ns->nl4_type) {
1866 case NL4_NETADDR:
1867 naddr = &ns->u.nl4_addr;
1868
1869 if (xdr_stream_decode_u32(argp->xdr, &naddr->netid_len) < 0)
1870 return nfserr_bad_xdr;
1871 if (naddr->netid_len > RPCBIND_MAXNETIDLEN)
1872 return nfserr_bad_xdr;
1873
1874 p = xdr_inline_decode(argp->xdr, naddr->netid_len);
1875 if (!p)
1876 return nfserr_bad_xdr;
1877 memcpy(naddr->netid, p, naddr->netid_len);
1878
1879 if (xdr_stream_decode_u32(argp->xdr, &naddr->addr_len) < 0)
1880 return nfserr_bad_xdr;
1881 if (naddr->addr_len > RPCBIND_MAXUADDRLEN)
1882 return nfserr_bad_xdr;
1883
1884 p = xdr_inline_decode(argp->xdr, naddr->addr_len);
1885 if (!p)
1886 return nfserr_bad_xdr;
1887 memcpy(naddr->addr, p, naddr->addr_len);
1888 break;
1889 default:
1890 return nfserr_bad_xdr;
1891 }
1892
1893 return nfs_ok;
1894 }
1895
1896 static __be32
1897 nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
1898 {
1899 u32 consecutive, i, count, sync;
1900 struct nl4_server *ns_dummy;
1901 __be32 status;
1902
1903 status = nfsd4_decode_stateid4(argp, ©->cp_src_stateid);
1904 if (status)
1905 return status;
1906 status = nfsd4_decode_stateid4(argp, ©->cp_dst_stateid);
1907 if (status)
1908 return status;
1909 if (xdr_stream_decode_u64(argp->xdr, ©->cp_src_pos) < 0)
1910 return nfserr_bad_xdr;
1911 if (xdr_stream_decode_u64(argp->xdr, ©->cp_dst_pos) < 0)
1912 return nfserr_bad_xdr;
1913 if (xdr_stream_decode_u64(argp->xdr, ©->cp_count) < 0)
1914 return nfserr_bad_xdr;
1915
1916 if (xdr_stream_decode_u32(argp->xdr, &consecutive) < 0)
1917 return nfserr_bad_xdr;
1918 if (xdr_stream_decode_bool(argp->xdr, &sync) < 0)
1919 return nfserr_bad_xdr;
1920 nfsd4_copy_set_sync(copy, sync);
1921
1922 if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
1923 return nfserr_bad_xdr;
1924 copy->cp_src = svcxdr_tmpalloc(argp, sizeof(*copy->cp_src));
1925 if (copy->cp_src == NULL)
1926 return nfserr_jukebox;
1927 if (count == 0) {
1928 __set_bit(NFSD4_COPY_F_INTRA, ©->cp_flags);
1929 return nfs_ok;
1930 }
1931
1932
1933 status = nfsd4_decode_nl4_server(argp, copy->cp_src);
1934 if (status)
1935 return status;
1936
1937 ns_dummy = kmalloc(sizeof(struct nl4_server), GFP_KERNEL);
1938 if (ns_dummy == NULL)
1939 return nfserr_jukebox;
1940 for (i = 0; i < count - 1; i++) {
1941 status = nfsd4_decode_nl4_server(argp, ns_dummy);
1942 if (status) {
1943 kfree(ns_dummy);
1944 return status;
1945 }
1946 }
1947 kfree(ns_dummy);
1948
1949 return nfs_ok;
1950 }
1951
1952 static __be32
1953 nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp,
1954 struct nfsd4_copy_notify *cn)
1955 {
1956 __be32 status;
1957
1958 cn->cpn_src = svcxdr_tmpalloc(argp, sizeof(*cn->cpn_src));
1959 if (cn->cpn_src == NULL)
1960 return nfserr_jukebox;
1961 cn->cpn_dst = svcxdr_tmpalloc(argp, sizeof(*cn->cpn_dst));
1962 if (cn->cpn_dst == NULL)
1963 return nfserr_jukebox;
1964
1965 status = nfsd4_decode_stateid4(argp, &cn->cpn_src_stateid);
1966 if (status)
1967 return status;
1968 return nfsd4_decode_nl4_server(argp, cn->cpn_dst);
1969 }
1970
1971 static __be32
1972 nfsd4_decode_offload_status(struct nfsd4_compoundargs *argp,
1973 struct nfsd4_offload_status *os)
1974 {
1975 return nfsd4_decode_stateid4(argp, &os->stateid);
1976 }
1977
1978 static __be32
1979 nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
1980 {
1981 __be32 status;
1982
1983 status = nfsd4_decode_stateid4(argp, &seek->seek_stateid);
1984 if (status)
1985 return status;
1986 if (xdr_stream_decode_u64(argp->xdr, &seek->seek_offset) < 0)
1987 return nfserr_bad_xdr;
1988 if (xdr_stream_decode_u32(argp->xdr, &seek->seek_whence) < 0)
1989 return nfserr_bad_xdr;
1990
1991 return nfs_ok;
1992 }
1993
1994 static __be32
1995 nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone)
1996 {
1997 __be32 status;
1998
1999 status = nfsd4_decode_stateid4(argp, &clone->cl_src_stateid);
2000 if (status)
2001 return status;
2002 status = nfsd4_decode_stateid4(argp, &clone->cl_dst_stateid);
2003 if (status)
2004 return status;
2005 if (xdr_stream_decode_u64(argp->xdr, &clone->cl_src_pos) < 0)
2006 return nfserr_bad_xdr;
2007 if (xdr_stream_decode_u64(argp->xdr, &clone->cl_dst_pos) < 0)
2008 return nfserr_bad_xdr;
2009 if (xdr_stream_decode_u64(argp->xdr, &clone->cl_count) < 0)
2010 return nfserr_bad_xdr;
2011
2012 return nfs_ok;
2013 }
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027 static __be32
2028 nfsd4_vbuf_from_vector(struct nfsd4_compoundargs *argp, struct xdr_buf *xdr,
2029 char **bufp, u32 buflen)
2030 {
2031 struct page **pages = xdr->pages;
2032 struct kvec *head = xdr->head;
2033 char *tmp, *dp;
2034 u32 len;
2035
2036 if (buflen <= head->iov_len) {
2037
2038
2039
2040
2041 *bufp = head->iov_base;
2042 return 0;
2043 }
2044
2045 tmp = svcxdr_tmpalloc(argp, buflen);
2046 if (tmp == NULL)
2047 return nfserr_jukebox;
2048
2049 dp = tmp;
2050 memcpy(dp, head->iov_base, head->iov_len);
2051 buflen -= head->iov_len;
2052 dp += head->iov_len;
2053
2054 while (buflen > 0) {
2055 len = min_t(u32, buflen, PAGE_SIZE);
2056 memcpy(dp, page_address(*pages), len);
2057
2058 buflen -= len;
2059 dp += len;
2060 pages++;
2061 }
2062
2063 *bufp = tmp;
2064 return 0;
2065 }
2066
2067
2068
2069
2070
2071
2072 static __be32
2073 nfsd4_decode_xattr_name(struct nfsd4_compoundargs *argp, char **namep)
2074 {
2075 char *name, *sp, *dp;
2076 u32 namelen, cnt;
2077 __be32 *p;
2078
2079 if (xdr_stream_decode_u32(argp->xdr, &namelen) < 0)
2080 return nfserr_bad_xdr;
2081 if (namelen > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN))
2082 return nfserr_nametoolong;
2083 if (namelen == 0)
2084 return nfserr_bad_xdr;
2085 p = xdr_inline_decode(argp->xdr, namelen);
2086 if (!p)
2087 return nfserr_bad_xdr;
2088 name = svcxdr_tmpalloc(argp, namelen + XATTR_USER_PREFIX_LEN + 1);
2089 if (!name)
2090 return nfserr_jukebox;
2091 memcpy(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
2092
2093
2094
2095
2096
2097 sp = (char *)p;
2098 dp = name + XATTR_USER_PREFIX_LEN;
2099 cnt = namelen;
2100
2101 while (cnt-- > 0) {
2102 if (*sp == '\0')
2103 return nfserr_bad_xdr;
2104 *dp++ = *sp++;
2105 }
2106 *dp = '\0';
2107
2108 *namep = name;
2109
2110 return nfs_ok;
2111 }
2112
2113
2114
2115
2116
2117
2118
2119 static __be32
2120 nfsd4_decode_getxattr(struct nfsd4_compoundargs *argp,
2121 struct nfsd4_getxattr *getxattr)
2122 {
2123 __be32 status;
2124 u32 maxcount;
2125
2126 status = nfsd4_decode_xattr_name(argp, &getxattr->getxa_name);
2127 if (status)
2128 return status;
2129
2130 maxcount = svc_max_payload(argp->rqstp);
2131 maxcount = min_t(u32, XATTR_SIZE_MAX, maxcount);
2132
2133 getxattr->getxa_len = maxcount;
2134
2135 return status;
2136 }
2137
2138 static __be32
2139 nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp,
2140 struct nfsd4_setxattr *setxattr)
2141 {
2142 u32 flags, maxcount, size;
2143 __be32 status;
2144
2145 if (xdr_stream_decode_u32(argp->xdr, &flags) < 0)
2146 return nfserr_bad_xdr;
2147
2148 if (flags > SETXATTR4_REPLACE)
2149 return nfserr_inval;
2150 setxattr->setxa_flags = flags;
2151
2152 status = nfsd4_decode_xattr_name(argp, &setxattr->setxa_name);
2153 if (status)
2154 return status;
2155
2156 maxcount = svc_max_payload(argp->rqstp);
2157 maxcount = min_t(u32, XATTR_SIZE_MAX, maxcount);
2158
2159 if (xdr_stream_decode_u32(argp->xdr, &size) < 0)
2160 return nfserr_bad_xdr;
2161 if (size > maxcount)
2162 return nfserr_xattr2big;
2163
2164 setxattr->setxa_len = size;
2165 if (size > 0) {
2166 struct xdr_buf payload;
2167
2168 if (!xdr_stream_subsegment(argp->xdr, &payload, size))
2169 return nfserr_bad_xdr;
2170 status = nfsd4_vbuf_from_vector(argp, &payload,
2171 &setxattr->setxa_buf, size);
2172 }
2173
2174 return nfs_ok;
2175 }
2176
2177 static __be32
2178 nfsd4_decode_listxattrs(struct nfsd4_compoundargs *argp,
2179 struct nfsd4_listxattrs *listxattrs)
2180 {
2181 u32 maxcount;
2182
2183 if (xdr_stream_decode_u64(argp->xdr, &listxattrs->lsxa_cookie) < 0)
2184 return nfserr_bad_xdr;
2185
2186
2187
2188
2189
2190 if (listxattrs->lsxa_cookie >=
2191 (XATTR_LIST_MAX / (XATTR_USER_PREFIX_LEN + 2)))
2192 return nfserr_badcookie;
2193
2194 if (xdr_stream_decode_u32(argp->xdr, &maxcount) < 0)
2195 return nfserr_bad_xdr;
2196 if (maxcount < 8)
2197
2198 return nfserr_inval;
2199
2200 maxcount = min(maxcount, svc_max_payload(argp->rqstp));
2201 listxattrs->lsxa_maxcount = maxcount;
2202
2203 return nfs_ok;
2204 }
2205
2206 static __be32
2207 nfsd4_decode_removexattr(struct nfsd4_compoundargs *argp,
2208 struct nfsd4_removexattr *removexattr)
2209 {
2210 return nfsd4_decode_xattr_name(argp, &removexattr->rmxa_name);
2211 }
2212
2213 static __be32
2214 nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
2215 {
2216 return nfs_ok;
2217 }
2218
2219 static __be32
2220 nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p)
2221 {
2222 return nfserr_notsupp;
2223 }
2224
2225 typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *);
2226
2227 static const nfsd4_dec nfsd4_dec_ops[] = {
2228 [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access,
2229 [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close,
2230 [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit,
2231 [OP_CREATE] = (nfsd4_dec)nfsd4_decode_create,
2232 [OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp,
2233 [OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn,
2234 [OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr,
2235 [OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop,
2236 [OP_LINK] = (nfsd4_dec)nfsd4_decode_link,
2237 [OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock,
2238 [OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt,
2239 [OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku,
2240 [OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup,
2241 [OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop,
2242 [OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify,
2243 [OP_OPEN] = (nfsd4_dec)nfsd4_decode_open,
2244 [OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp,
2245 [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm,
2246 [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade,
2247 [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh,
2248 [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_putpubfh,
2249 [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop,
2250 [OP_READ] = (nfsd4_dec)nfsd4_decode_read,
2251 [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir,
2252 [OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop,
2253 [OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove,
2254 [OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename,
2255 [OP_RENEW] = (nfsd4_dec)nfsd4_decode_renew,
2256 [OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop,
2257 [OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop,
2258 [OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo,
2259 [OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr,
2260 [OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_setclientid,
2261 [OP_SETCLIENTID_CONFIRM] = (nfsd4_dec)nfsd4_decode_setclientid_confirm,
2262 [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify,
2263 [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write,
2264 [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner,
2265
2266
2267 [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl,
2268 [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session,
2269 [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id,
2270 [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session,
2271 [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session,
2272 [OP_FREE_STATEID] = (nfsd4_dec)nfsd4_decode_free_stateid,
2273 [OP_GET_DIR_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp,
2274 #ifdef CONFIG_NFSD_PNFS
2275 [OP_GETDEVICEINFO] = (nfsd4_dec)nfsd4_decode_getdeviceinfo,
2276 [OP_GETDEVICELIST] = (nfsd4_dec)nfsd4_decode_notsupp,
2277 [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_layoutcommit,
2278 [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_layoutget,
2279 [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_layoutreturn,
2280 #else
2281 [OP_GETDEVICEINFO] = (nfsd4_dec)nfsd4_decode_notsupp,
2282 [OP_GETDEVICELIST] = (nfsd4_dec)nfsd4_decode_notsupp,
2283 [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp,
2284 [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp,
2285 [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp,
2286 #endif
2287 [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_secinfo_no_name,
2288 [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence,
2289 [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp,
2290 [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_test_stateid,
2291 [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp,
2292 [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_destroy_clientid,
2293 [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete,
2294
2295
2296 [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate,
2297 [OP_COPY] = (nfsd4_dec)nfsd4_decode_copy,
2298 [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_copy_notify,
2299 [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate,
2300 [OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp,
2301 [OP_LAYOUTERROR] = (nfsd4_dec)nfsd4_decode_notsupp,
2302 [OP_LAYOUTSTATS] = (nfsd4_dec)nfsd4_decode_notsupp,
2303 [OP_OFFLOAD_CANCEL] = (nfsd4_dec)nfsd4_decode_offload_status,
2304 [OP_OFFLOAD_STATUS] = (nfsd4_dec)nfsd4_decode_offload_status,
2305 [OP_READ_PLUS] = (nfsd4_dec)nfsd4_decode_read,
2306 [OP_SEEK] = (nfsd4_dec)nfsd4_decode_seek,
2307 [OP_WRITE_SAME] = (nfsd4_dec)nfsd4_decode_notsupp,
2308 [OP_CLONE] = (nfsd4_dec)nfsd4_decode_clone,
2309
2310 [OP_GETXATTR] = (nfsd4_dec)nfsd4_decode_getxattr,
2311 [OP_SETXATTR] = (nfsd4_dec)nfsd4_decode_setxattr,
2312 [OP_LISTXATTRS] = (nfsd4_dec)nfsd4_decode_listxattrs,
2313 [OP_REMOVEXATTR] = (nfsd4_dec)nfsd4_decode_removexattr,
2314 };
2315
2316 static inline bool
2317 nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op)
2318 {
2319 if (op->opnum < FIRST_NFS4_OP)
2320 return false;
2321 else if (argp->minorversion == 0 && op->opnum > LAST_NFS40_OP)
2322 return false;
2323 else if (argp->minorversion == 1 && op->opnum > LAST_NFS41_OP)
2324 return false;
2325 else if (argp->minorversion == 2 && op->opnum > LAST_NFS42_OP)
2326 return false;
2327 return true;
2328 }
2329
2330 static bool
2331 nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
2332 {
2333 struct nfsd4_op *op;
2334 bool cachethis = false;
2335 int auth_slack= argp->rqstp->rq_auth_slack;
2336 int max_reply = auth_slack + 8;
2337 int readcount = 0;
2338 int readbytes = 0;
2339 __be32 *p;
2340 int i;
2341
2342 if (xdr_stream_decode_u32(argp->xdr, &argp->taglen) < 0)
2343 return false;
2344 max_reply += XDR_UNIT;
2345 argp->tag = NULL;
2346 if (unlikely(argp->taglen)) {
2347 if (argp->taglen > NFSD4_MAX_TAGLEN)
2348 return false;
2349 p = xdr_inline_decode(argp->xdr, argp->taglen);
2350 if (!p)
2351 return false;
2352 argp->tag = svcxdr_savemem(argp, p, argp->taglen);
2353 if (!argp->tag)
2354 return false;
2355 max_reply += xdr_align_size(argp->taglen);
2356 }
2357
2358 if (xdr_stream_decode_u32(argp->xdr, &argp->minorversion) < 0)
2359 return false;
2360 if (xdr_stream_decode_u32(argp->xdr, &argp->opcnt) < 0)
2361 return false;
2362
2363
2364
2365
2366
2367
2368 if (argp->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
2369 return true;
2370
2371 if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
2372 argp->ops = kzalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
2373 if (!argp->ops) {
2374 argp->ops = argp->iops;
2375 dprintk("nfsd: couldn't allocate room for COMPOUND\n");
2376 return false;
2377 }
2378 }
2379
2380 if (argp->minorversion > NFSD_SUPPORTED_MINOR_VERSION)
2381 argp->opcnt = 0;
2382
2383 for (i = 0; i < argp->opcnt; i++) {
2384 op = &argp->ops[i];
2385 op->replay = NULL;
2386
2387 if (xdr_stream_decode_u32(argp->xdr, &op->opnum) < 0)
2388 return false;
2389 if (nfsd4_opnum_in_range(argp, op)) {
2390 op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
2391 if (op->status != nfs_ok)
2392 trace_nfsd_compound_decode_err(argp->rqstp,
2393 argp->opcnt, i,
2394 op->opnum,
2395 op->status);
2396 } else {
2397 op->opnum = OP_ILLEGAL;
2398 op->status = nfserr_op_illegal;
2399 }
2400 op->opdesc = OPDESC(op);
2401
2402
2403
2404
2405 cachethis |= nfsd4_cache_this_op(op);
2406
2407 if (op->opnum == OP_READ || op->opnum == OP_READ_PLUS) {
2408 readcount++;
2409 readbytes += nfsd4_max_reply(argp->rqstp, op);
2410 } else
2411 max_reply += nfsd4_max_reply(argp->rqstp, op);
2412
2413
2414
2415
2416
2417
2418 if (op->opnum == OP_LOCK || op->opnum == OP_LOCKT)
2419 max_reply += NFS4_OPAQUE_LIMIT;
2420
2421 if (op->status) {
2422 argp->opcnt = i+1;
2423 break;
2424 }
2425 }
2426
2427 if (argp->minorversion)
2428 cachethis = false;
2429 svc_reserve(argp->rqstp, max_reply + readbytes);
2430 argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE;
2431
2432 if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack)
2433 __clear_bit(RQ_SPLICE_OK, &argp->rqstp->rq_flags);
2434
2435 return true;
2436 }
2437
2438 static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode,
2439 struct svc_export *exp)
2440 {
2441 if (exp->ex_flags & NFSEXP_V4ROOT) {
2442 *p++ = cpu_to_be32(convert_to_wallclock(exp->cd->flush_time));
2443 *p++ = 0;
2444 } else
2445 p = xdr_encode_hyper(p, nfsd4_change_attribute(stat, inode));
2446 return p;
2447 }
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460 static __be32 *encode_time_delta(__be32 *p, struct inode *inode)
2461 {
2462 struct timespec64 ts;
2463 u32 ns;
2464
2465 ns = max_t(u32, NSEC_PER_SEC/HZ, inode->i_sb->s_time_gran);
2466 ts = ns_to_timespec64(ns);
2467
2468 p = xdr_encode_hyper(p, ts.tv_sec);
2469 *p++ = cpu_to_be32(ts.tv_nsec);
2470
2471 return p;
2472 }
2473
2474 static __be32 *encode_cinfo(__be32 *p, struct nfsd4_change_info *c)
2475 {
2476 *p++ = cpu_to_be32(c->atomic);
2477 p = xdr_encode_hyper(p, c->before_change);
2478 p = xdr_encode_hyper(p, c->after_change);
2479 return p;
2480 }
2481
2482
2483
2484
2485 static __be32 nfsd4_encode_components_esc(struct xdr_stream *xdr, char sep,
2486 char *components, char esc_enter,
2487 char esc_exit)
2488 {
2489 __be32 *p;
2490 __be32 pathlen;
2491 int pathlen_offset;
2492 int strlen, count=0;
2493 char *str, *end, *next;
2494
2495 dprintk("nfsd4_encode_components(%s)\n", components);
2496
2497 pathlen_offset = xdr->buf->len;
2498 p = xdr_reserve_space(xdr, 4);
2499 if (!p)
2500 return nfserr_resource;
2501 p++;
2502
2503 end = str = components;
2504 while (*end) {
2505 bool found_esc = false;
2506
2507
2508 if (*str == esc_enter) {
2509 for (; *end && (*end != esc_exit); end++)
2510 ;
2511 next = end + 1;
2512 if (*end && (!*next || *next == sep)) {
2513 str++;
2514 found_esc = true;
2515 }
2516 }
2517
2518 if (!found_esc)
2519 for (; *end && (*end != sep); end++)
2520 ;
2521
2522 strlen = end - str;
2523 if (strlen) {
2524 p = xdr_reserve_space(xdr, strlen + 4);
2525 if (!p)
2526 return nfserr_resource;
2527 p = xdr_encode_opaque(p, str, strlen);
2528 count++;
2529 }
2530 else
2531 end++;
2532 if (found_esc)
2533 end = next;
2534
2535 str = end;
2536 }
2537 pathlen = htonl(count);
2538 write_bytes_to_xdr_buf(xdr->buf, pathlen_offset, &pathlen, 4);
2539 return 0;
2540 }
2541
2542
2543
2544
2545 static __be32 nfsd4_encode_components(struct xdr_stream *xdr, char sep,
2546 char *components)
2547 {
2548 return nfsd4_encode_components_esc(xdr, sep, components, 0, 0);
2549 }
2550
2551
2552
2553
2554 static __be32 nfsd4_encode_fs_location4(struct xdr_stream *xdr,
2555 struct nfsd4_fs_location *location)
2556 {
2557 __be32 status;
2558
2559 status = nfsd4_encode_components_esc(xdr, ':', location->hosts,
2560 '[', ']');
2561 if (status)
2562 return status;
2563 status = nfsd4_encode_components(xdr, '/', location->path);
2564 if (status)
2565 return status;
2566 return 0;
2567 }
2568
2569
2570
2571
2572 static __be32 nfsd4_encode_path(struct xdr_stream *xdr,
2573 const struct path *root,
2574 const struct path *path)
2575 {
2576 struct path cur = *path;
2577 __be32 *p;
2578 struct dentry **components = NULL;
2579 unsigned int ncomponents = 0;
2580 __be32 err = nfserr_jukebox;
2581
2582 dprintk("nfsd4_encode_components(");
2583
2584 path_get(&cur);
2585
2586
2587
2588 for (;;) {
2589 if (path_equal(&cur, root))
2590 break;
2591 if (cur.dentry == cur.mnt->mnt_root) {
2592 if (follow_up(&cur))
2593 continue;
2594 goto out_free;
2595 }
2596 if ((ncomponents & 15) == 0) {
2597 struct dentry **new;
2598 new = krealloc(components,
2599 sizeof(*new) * (ncomponents + 16),
2600 GFP_KERNEL);
2601 if (!new)
2602 goto out_free;
2603 components = new;
2604 }
2605 components[ncomponents++] = cur.dentry;
2606 cur.dentry = dget_parent(cur.dentry);
2607 }
2608 err = nfserr_resource;
2609 p = xdr_reserve_space(xdr, 4);
2610 if (!p)
2611 goto out_free;
2612 *p++ = cpu_to_be32(ncomponents);
2613
2614 while (ncomponents) {
2615 struct dentry *dentry = components[ncomponents - 1];
2616 unsigned int len;
2617
2618 spin_lock(&dentry->d_lock);
2619 len = dentry->d_name.len;
2620 p = xdr_reserve_space(xdr, len + 4);
2621 if (!p) {
2622 spin_unlock(&dentry->d_lock);
2623 goto out_free;
2624 }
2625 p = xdr_encode_opaque(p, dentry->d_name.name, len);
2626 dprintk("/%pd", dentry);
2627 spin_unlock(&dentry->d_lock);
2628 dput(dentry);
2629 ncomponents--;
2630 }
2631
2632 err = 0;
2633 out_free:
2634 dprintk(")\n");
2635 while (ncomponents)
2636 dput(components[--ncomponents]);
2637 kfree(components);
2638 path_put(&cur);
2639 return err;
2640 }
2641
2642 static __be32 nfsd4_encode_fsloc_fsroot(struct xdr_stream *xdr,
2643 struct svc_rqst *rqstp, const struct path *path)
2644 {
2645 struct svc_export *exp_ps;
2646 __be32 res;
2647
2648 exp_ps = rqst_find_fsidzero_export(rqstp);
2649 if (IS_ERR(exp_ps))
2650 return nfserrno(PTR_ERR(exp_ps));
2651 res = nfsd4_encode_path(xdr, &exp_ps->ex_path, path);
2652 exp_put(exp_ps);
2653 return res;
2654 }
2655
2656
2657
2658
2659 static __be32 nfsd4_encode_fs_locations(struct xdr_stream *xdr,
2660 struct svc_rqst *rqstp, struct svc_export *exp)
2661 {
2662 __be32 status;
2663 int i;
2664 __be32 *p;
2665 struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
2666
2667 status = nfsd4_encode_fsloc_fsroot(xdr, rqstp, &exp->ex_path);
2668 if (status)
2669 return status;
2670 p = xdr_reserve_space(xdr, 4);
2671 if (!p)
2672 return nfserr_resource;
2673 *p++ = cpu_to_be32(fslocs->locations_count);
2674 for (i=0; i<fslocs->locations_count; i++) {
2675 status = nfsd4_encode_fs_location4(xdr, &fslocs->locations[i]);
2676 if (status)
2677 return status;
2678 }
2679 return 0;
2680 }
2681
2682 static u32 nfs4_file_type(umode_t mode)
2683 {
2684 switch (mode & S_IFMT) {
2685 case S_IFIFO: return NF4FIFO;
2686 case S_IFCHR: return NF4CHR;
2687 case S_IFDIR: return NF4DIR;
2688 case S_IFBLK: return NF4BLK;
2689 case S_IFLNK: return NF4LNK;
2690 case S_IFREG: return NF4REG;
2691 case S_IFSOCK: return NF4SOCK;
2692 default: return NF4BAD;
2693 }
2694 }
2695
2696 static inline __be32
2697 nfsd4_encode_aclname(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2698 struct nfs4_ace *ace)
2699 {
2700 if (ace->whotype != NFS4_ACL_WHO_NAMED)
2701 return nfs4_acl_write_who(xdr, ace->whotype);
2702 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
2703 return nfsd4_encode_group(xdr, rqstp, ace->who_gid);
2704 else
2705 return nfsd4_encode_user(xdr, rqstp, ace->who_uid);
2706 }
2707
2708 static inline __be32
2709 nfsd4_encode_layout_types(struct xdr_stream *xdr, u32 layout_types)
2710 {
2711 __be32 *p;
2712 unsigned long i = hweight_long(layout_types);
2713
2714 p = xdr_reserve_space(xdr, 4 + 4 * i);
2715 if (!p)
2716 return nfserr_resource;
2717
2718 *p++ = cpu_to_be32(i);
2719
2720 for (i = LAYOUT_NFSV4_1_FILES; i < LAYOUT_TYPE_MAX; ++i)
2721 if (layout_types & (1 << i))
2722 *p++ = cpu_to_be32(i);
2723
2724 return 0;
2725 }
2726
2727 #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
2728 FATTR4_WORD0_RDATTR_ERROR)
2729 #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
2730 #define WORD2_ABSENT_FS_ATTRS 0
2731
2732 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2733 static inline __be32
2734 nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2735 void *context, int len)
2736 {
2737 __be32 *p;
2738
2739 p = xdr_reserve_space(xdr, len + 4 + 4 + 4);
2740 if (!p)
2741 return nfserr_resource;
2742
2743
2744
2745
2746
2747 *p++ = cpu_to_be32(0);
2748 *p++ = cpu_to_be32(0);
2749 p = xdr_encode_opaque(p, context, len);
2750 return 0;
2751 }
2752 #else
2753 static inline __be32
2754 nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2755 void *context, int len)
2756 { return 0; }
2757 #endif
2758
2759 static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *bmval2, u32 *rdattr_err)
2760 {
2761
2762 if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
2763 *bmval1 & ~WORD1_ABSENT_FS_ATTRS) {
2764 if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR ||
2765 *bmval0 & FATTR4_WORD0_FS_LOCATIONS)
2766 *rdattr_err = NFSERR_MOVED;
2767 else
2768 return nfserr_moved;
2769 }
2770 *bmval0 &= WORD0_ABSENT_FS_ATTRS;
2771 *bmval1 &= WORD1_ABSENT_FS_ATTRS;
2772 *bmval2 &= WORD2_ABSENT_FS_ATTRS;
2773 return 0;
2774 }
2775
2776
2777 static int get_parent_attributes(struct svc_export *exp, struct kstat *stat)
2778 {
2779 struct path path = exp->ex_path;
2780 int err;
2781
2782 path_get(&path);
2783 while (follow_up(&path)) {
2784 if (path.dentry != path.mnt->mnt_root)
2785 break;
2786 }
2787 err = vfs_getattr(&path, stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
2788 path_put(&path);
2789 return err;
2790 }
2791
2792 static __be32
2793 nfsd4_encode_bitmap(struct xdr_stream *xdr, u32 bmval0, u32 bmval1, u32 bmval2)
2794 {
2795 __be32 *p;
2796
2797 if (bmval2) {
2798 p = xdr_reserve_space(xdr, 16);
2799 if (!p)
2800 goto out_resource;
2801 *p++ = cpu_to_be32(3);
2802 *p++ = cpu_to_be32(bmval0);
2803 *p++ = cpu_to_be32(bmval1);
2804 *p++ = cpu_to_be32(bmval2);
2805 } else if (bmval1) {
2806 p = xdr_reserve_space(xdr, 12);
2807 if (!p)
2808 goto out_resource;
2809 *p++ = cpu_to_be32(2);
2810 *p++ = cpu_to_be32(bmval0);
2811 *p++ = cpu_to_be32(bmval1);
2812 } else {
2813 p = xdr_reserve_space(xdr, 8);
2814 if (!p)
2815 goto out_resource;
2816 *p++ = cpu_to_be32(1);
2817 *p++ = cpu_to_be32(bmval0);
2818 }
2819
2820 return 0;
2821 out_resource:
2822 return nfserr_resource;
2823 }
2824
2825
2826
2827
2828
2829 static __be32
2830 nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
2831 struct svc_export *exp,
2832 struct dentry *dentry, u32 *bmval,
2833 struct svc_rqst *rqstp, int ignore_crossmnt)
2834 {
2835 u32 bmval0 = bmval[0];
2836 u32 bmval1 = bmval[1];
2837 u32 bmval2 = bmval[2];
2838 struct kstat stat;
2839 struct svc_fh *tempfh = NULL;
2840 struct kstatfs statfs;
2841 __be32 *p, *attrlen_p;
2842 int starting_len = xdr->buf->len;
2843 int attrlen_offset;
2844 u32 dummy;
2845 u64 dummy64;
2846 u32 rdattr_err = 0;
2847 __be32 status;
2848 int err;
2849 struct nfs4_acl *acl = NULL;
2850 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2851 void *context = NULL;
2852 int contextlen;
2853 #endif
2854 bool contextsupport = false;
2855 struct nfsd4_compoundres *resp = rqstp->rq_resp;
2856 u32 minorversion = resp->cstate.minorversion;
2857 struct path path = {
2858 .mnt = exp->ex_path.mnt,
2859 .dentry = dentry,
2860 };
2861 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2862
2863 BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
2864 BUG_ON(!nfsd_attrs_supported(minorversion, bmval));
2865
2866 if (exp->ex_fslocs.migrated) {
2867 status = fattr_handle_absent_fs(&bmval0, &bmval1, &bmval2, &rdattr_err);
2868 if (status)
2869 goto out;
2870 }
2871
2872 err = vfs_getattr(&path, &stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
2873 if (err)
2874 goto out_nfserr;
2875 if (!(stat.result_mask & STATX_BTIME))
2876
2877 bmval1 &= ~FATTR4_WORD1_TIME_CREATE;
2878 if ((bmval0 & (FATTR4_WORD0_FILES_AVAIL | FATTR4_WORD0_FILES_FREE |
2879 FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_MAXNAME)) ||
2880 (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
2881 FATTR4_WORD1_SPACE_TOTAL))) {
2882 err = vfs_statfs(&path, &statfs);
2883 if (err)
2884 goto out_nfserr;
2885 }
2886 if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) {
2887 tempfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
2888 status = nfserr_jukebox;
2889 if (!tempfh)
2890 goto out;
2891 fh_init(tempfh, NFS4_FHSIZE);
2892 status = fh_compose(tempfh, exp, dentry, NULL);
2893 if (status)
2894 goto out;
2895 fhp = tempfh;
2896 }
2897 if (bmval0 & FATTR4_WORD0_ACL) {
2898 err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
2899 if (err == -EOPNOTSUPP)
2900 bmval0 &= ~FATTR4_WORD0_ACL;
2901 else if (err == -EINVAL) {
2902 status = nfserr_attrnotsupp;
2903 goto out;
2904 } else if (err != 0)
2905 goto out_nfserr;
2906 }
2907
2908 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2909 if ((bmval2 & FATTR4_WORD2_SECURITY_LABEL) ||
2910 bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
2911 if (exp->ex_flags & NFSEXP_SECURITY_LABEL)
2912 err = security_inode_getsecctx(d_inode(dentry),
2913 &context, &contextlen);
2914 else
2915 err = -EOPNOTSUPP;
2916 contextsupport = (err == 0);
2917 if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
2918 if (err == -EOPNOTSUPP)
2919 bmval2 &= ~FATTR4_WORD2_SECURITY_LABEL;
2920 else if (err)
2921 goto out_nfserr;
2922 }
2923 }
2924 #endif
2925
2926 status = nfsd4_encode_bitmap(xdr, bmval0, bmval1, bmval2);
2927 if (status)
2928 goto out;
2929
2930 attrlen_offset = xdr->buf->len;
2931 attrlen_p = xdr_reserve_space(xdr, XDR_UNIT);
2932 if (!attrlen_p)
2933 goto out_resource;
2934
2935 if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
2936 u32 supp[3];
2937
2938 memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp));
2939
2940 if (!IS_POSIXACL(dentry->d_inode))
2941 supp[0] &= ~FATTR4_WORD0_ACL;
2942 if (!contextsupport)
2943 supp[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
2944 if (!supp[2]) {
2945 p = xdr_reserve_space(xdr, 12);
2946 if (!p)
2947 goto out_resource;
2948 *p++ = cpu_to_be32(2);
2949 *p++ = cpu_to_be32(supp[0]);
2950 *p++ = cpu_to_be32(supp[1]);
2951 } else {
2952 p = xdr_reserve_space(xdr, 16);
2953 if (!p)
2954 goto out_resource;
2955 *p++ = cpu_to_be32(3);
2956 *p++ = cpu_to_be32(supp[0]);
2957 *p++ = cpu_to_be32(supp[1]);
2958 *p++ = cpu_to_be32(supp[2]);
2959 }
2960 }
2961 if (bmval0 & FATTR4_WORD0_TYPE) {
2962 p = xdr_reserve_space(xdr, 4);
2963 if (!p)
2964 goto out_resource;
2965 dummy = nfs4_file_type(stat.mode);
2966 if (dummy == NF4BAD) {
2967 status = nfserr_serverfault;
2968 goto out;
2969 }
2970 *p++ = cpu_to_be32(dummy);
2971 }
2972 if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
2973 p = xdr_reserve_space(xdr, 4);
2974 if (!p)
2975 goto out_resource;
2976 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
2977 *p++ = cpu_to_be32(NFS4_FH_PERSISTENT);
2978 else
2979 *p++ = cpu_to_be32(NFS4_FH_PERSISTENT|
2980 NFS4_FH_VOL_RENAME);
2981 }
2982 if (bmval0 & FATTR4_WORD0_CHANGE) {
2983 p = xdr_reserve_space(xdr, 8);
2984 if (!p)
2985 goto out_resource;
2986 p = encode_change(p, &stat, d_inode(dentry), exp);
2987 }
2988 if (bmval0 & FATTR4_WORD0_SIZE) {
2989 p = xdr_reserve_space(xdr, 8);
2990 if (!p)
2991 goto out_resource;
2992 p = xdr_encode_hyper(p, stat.size);
2993 }
2994 if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) {
2995 p = xdr_reserve_space(xdr, 4);
2996 if (!p)
2997 goto out_resource;
2998 *p++ = cpu_to_be32(1);
2999 }
3000 if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) {
3001 p = xdr_reserve_space(xdr, 4);
3002 if (!p)
3003 goto out_resource;
3004 *p++ = cpu_to_be32(1);
3005 }
3006 if (bmval0 & FATTR4_WORD0_NAMED_ATTR) {
3007 p = xdr_reserve_space(xdr, 4);
3008 if (!p)
3009 goto out_resource;
3010 *p++ = cpu_to_be32(0);
3011 }
3012 if (bmval0 & FATTR4_WORD0_FSID) {
3013 p = xdr_reserve_space(xdr, 16);
3014 if (!p)
3015 goto out_resource;
3016 if (exp->ex_fslocs.migrated) {
3017 p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MAJOR);
3018 p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MINOR);
3019 } else switch(fsid_source(fhp)) {
3020 case FSIDSOURCE_FSID:
3021 p = xdr_encode_hyper(p, (u64)exp->ex_fsid);
3022 p = xdr_encode_hyper(p, (u64)0);
3023 break;
3024 case FSIDSOURCE_DEV:
3025 *p++ = cpu_to_be32(0);
3026 *p++ = cpu_to_be32(MAJOR(stat.dev));
3027 *p++ = cpu_to_be32(0);
3028 *p++ = cpu_to_be32(MINOR(stat.dev));
3029 break;
3030 case FSIDSOURCE_UUID:
3031 p = xdr_encode_opaque_fixed(p, exp->ex_uuid,
3032 EX_UUID_LEN);
3033 break;
3034 }
3035 }
3036 if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
3037 p = xdr_reserve_space(xdr, 4);
3038 if (!p)
3039 goto out_resource;
3040 *p++ = cpu_to_be32(0);
3041 }
3042 if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
3043 p = xdr_reserve_space(xdr, 4);
3044 if (!p)
3045 goto out_resource;
3046 *p++ = cpu_to_be32(nn->nfsd4_lease);
3047 }
3048 if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
3049 p = xdr_reserve_space(xdr, 4);
3050 if (!p)
3051 goto out_resource;
3052 *p++ = cpu_to_be32(rdattr_err);
3053 }
3054 if (bmval0 & FATTR4_WORD0_ACL) {
3055 struct nfs4_ace *ace;
3056
3057 if (acl == NULL) {
3058 p = xdr_reserve_space(xdr, 4);
3059 if (!p)
3060 goto out_resource;
3061
3062 *p++ = cpu_to_be32(0);
3063 goto out_acl;
3064 }
3065 p = xdr_reserve_space(xdr, 4);
3066 if (!p)
3067 goto out_resource;
3068 *p++ = cpu_to_be32(acl->naces);
3069
3070 for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
3071 p = xdr_reserve_space(xdr, 4*3);
3072 if (!p)
3073 goto out_resource;
3074 *p++ = cpu_to_be32(ace->type);
3075 *p++ = cpu_to_be32(ace->flag);
3076 *p++ = cpu_to_be32(ace->access_mask &
3077 NFS4_ACE_MASK_ALL);
3078 status = nfsd4_encode_aclname(xdr, rqstp, ace);
3079 if (status)
3080 goto out;
3081 }
3082 }
3083 out_acl:
3084 if (bmval0 & FATTR4_WORD0_ACLSUPPORT) {
3085 p = xdr_reserve_space(xdr, 4);
3086 if (!p)
3087 goto out_resource;
3088 *p++ = cpu_to_be32(IS_POSIXACL(dentry->d_inode) ?
3089 ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0);
3090 }
3091 if (bmval0 & FATTR4_WORD0_CANSETTIME) {
3092 p = xdr_reserve_space(xdr, 4);
3093 if (!p)
3094 goto out_resource;
3095 *p++ = cpu_to_be32(1);
3096 }
3097 if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
3098 p = xdr_reserve_space(xdr, 4);
3099 if (!p)
3100 goto out_resource;
3101 *p++ = cpu_to_be32(0);
3102 }
3103 if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
3104 p = xdr_reserve_space(xdr, 4);
3105 if (!p)
3106 goto out_resource;
3107 *p++ = cpu_to_be32(1);
3108 }
3109 if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) {
3110 p = xdr_reserve_space(xdr, 4);
3111 if (!p)
3112 goto out_resource;
3113 *p++ = cpu_to_be32(1);
3114 }
3115 if (bmval0 & FATTR4_WORD0_FILEHANDLE) {
3116 p = xdr_reserve_space(xdr, fhp->fh_handle.fh_size + 4);
3117 if (!p)
3118 goto out_resource;
3119 p = xdr_encode_opaque(p, &fhp->fh_handle.fh_raw,
3120 fhp->fh_handle.fh_size);
3121 }
3122 if (bmval0 & FATTR4_WORD0_FILEID) {
3123 p = xdr_reserve_space(xdr, 8);
3124 if (!p)
3125 goto out_resource;
3126 p = xdr_encode_hyper(p, stat.ino);
3127 }
3128 if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {
3129 p = xdr_reserve_space(xdr, 8);
3130 if (!p)
3131 goto out_resource;
3132 p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
3133 }
3134 if (bmval0 & FATTR4_WORD0_FILES_FREE) {
3135 p = xdr_reserve_space(xdr, 8);
3136 if (!p)
3137 goto out_resource;
3138 p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
3139 }
3140 if (bmval0 & FATTR4_WORD0_FILES_TOTAL) {
3141 p = xdr_reserve_space(xdr, 8);
3142 if (!p)
3143 goto out_resource;
3144 p = xdr_encode_hyper(p, (u64) statfs.f_files);
3145 }
3146 if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
3147 status = nfsd4_encode_fs_locations(xdr, rqstp, exp);
3148 if (status)
3149 goto out;
3150 }
3151 if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
3152 p = xdr_reserve_space(xdr, 4);
3153 if (!p)
3154 goto out_resource;
3155 *p++ = cpu_to_be32(1);
3156 }
3157 if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
3158 p = xdr_reserve_space(xdr, 8);
3159 if (!p)
3160 goto out_resource;
3161 p = xdr_encode_hyper(p, exp->ex_path.mnt->mnt_sb->s_maxbytes);
3162 }
3163 if (bmval0 & FATTR4_WORD0_MAXLINK) {
3164 p = xdr_reserve_space(xdr, 4);
3165 if (!p)
3166 goto out_resource;
3167 *p++ = cpu_to_be32(255);
3168 }
3169 if (bmval0 & FATTR4_WORD0_MAXNAME) {
3170 p = xdr_reserve_space(xdr, 4);
3171 if (!p)
3172 goto out_resource;
3173 *p++ = cpu_to_be32(statfs.f_namelen);
3174 }
3175 if (bmval0 & FATTR4_WORD0_MAXREAD) {
3176 p = xdr_reserve_space(xdr, 8);
3177 if (!p)
3178 goto out_resource;
3179 p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
3180 }
3181 if (bmval0 & FATTR4_WORD0_MAXWRITE) {
3182 p = xdr_reserve_space(xdr, 8);
3183 if (!p)
3184 goto out_resource;
3185 p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
3186 }
3187 if (bmval1 & FATTR4_WORD1_MODE) {
3188 p = xdr_reserve_space(xdr, 4);
3189 if (!p)
3190 goto out_resource;
3191 *p++ = cpu_to_be32(stat.mode & S_IALLUGO);
3192 }
3193 if (bmval1 & FATTR4_WORD1_NO_TRUNC) {
3194 p = xdr_reserve_space(xdr, 4);
3195 if (!p)
3196 goto out_resource;
3197 *p++ = cpu_to_be32(1);
3198 }
3199 if (bmval1 & FATTR4_WORD1_NUMLINKS) {
3200 p = xdr_reserve_space(xdr, 4);
3201 if (!p)
3202 goto out_resource;
3203 *p++ = cpu_to_be32(stat.nlink);
3204 }
3205 if (bmval1 & FATTR4_WORD1_OWNER) {
3206 status = nfsd4_encode_user(xdr, rqstp, stat.uid);
3207 if (status)
3208 goto out;
3209 }
3210 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
3211 status = nfsd4_encode_group(xdr, rqstp, stat.gid);
3212 if (status)
3213 goto out;
3214 }
3215 if (bmval1 & FATTR4_WORD1_RAWDEV) {
3216 p = xdr_reserve_space(xdr, 8);
3217 if (!p)
3218 goto out_resource;
3219 *p++ = cpu_to_be32((u32) MAJOR(stat.rdev));
3220 *p++ = cpu_to_be32((u32) MINOR(stat.rdev));
3221 }
3222 if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
3223 p = xdr_reserve_space(xdr, 8);
3224 if (!p)
3225 goto out_resource;
3226 dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize;
3227 p = xdr_encode_hyper(p, dummy64);
3228 }
3229 if (bmval1 & FATTR4_WORD1_SPACE_FREE) {
3230 p = xdr_reserve_space(xdr, 8);
3231 if (!p)
3232 goto out_resource;
3233 dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize;
3234 p = xdr_encode_hyper(p, dummy64);
3235 }
3236 if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) {
3237 p = xdr_reserve_space(xdr, 8);
3238 if (!p)
3239 goto out_resource;
3240 dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize;
3241 p = xdr_encode_hyper(p, dummy64);
3242 }
3243 if (bmval1 & FATTR4_WORD1_SPACE_USED) {
3244 p = xdr_reserve_space(xdr, 8);
3245 if (!p)
3246 goto out_resource;
3247 dummy64 = (u64)stat.blocks << 9;
3248 p = xdr_encode_hyper(p, dummy64);
3249 }
3250 if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
3251 p = xdr_reserve_space(xdr, 12);
3252 if (!p)
3253 goto out_resource;
3254 p = xdr_encode_hyper(p, (s64)stat.atime.tv_sec);
3255 *p++ = cpu_to_be32(stat.atime.tv_nsec);
3256 }
3257 if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
3258 p = xdr_reserve_space(xdr, 12);
3259 if (!p)
3260 goto out_resource;
3261 p = encode_time_delta(p, d_inode(dentry));
3262 }
3263 if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
3264 p = xdr_reserve_space(xdr, 12);
3265 if (!p)
3266 goto out_resource;
3267 p = xdr_encode_hyper(p, (s64)stat.ctime.tv_sec);
3268 *p++ = cpu_to_be32(stat.ctime.tv_nsec);
3269 }
3270 if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
3271 p = xdr_reserve_space(xdr, 12);
3272 if (!p)
3273 goto out_resource;
3274 p = xdr_encode_hyper(p, (s64)stat.mtime.tv_sec);
3275 *p++ = cpu_to_be32(stat.mtime.tv_nsec);
3276 }
3277 if (bmval1 & FATTR4_WORD1_TIME_CREATE) {
3278 p = xdr_reserve_space(xdr, 12);
3279 if (!p)
3280 goto out_resource;
3281 p = xdr_encode_hyper(p, (s64)stat.btime.tv_sec);
3282 *p++ = cpu_to_be32(stat.btime.tv_nsec);
3283 }
3284 if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
3285 struct kstat parent_stat;
3286 u64 ino = stat.ino;
3287
3288 p = xdr_reserve_space(xdr, 8);
3289 if (!p)
3290 goto out_resource;
3291
3292
3293
3294
3295 if (ignore_crossmnt == 0 &&
3296 dentry == exp->ex_path.mnt->mnt_root) {
3297 err = get_parent_attributes(exp, &parent_stat);
3298 if (err)
3299 goto out_nfserr;
3300 ino = parent_stat.ino;
3301 }
3302 p = xdr_encode_hyper(p, ino);
3303 }
3304 #ifdef CONFIG_NFSD_PNFS
3305 if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) {
3306 status = nfsd4_encode_layout_types(xdr, exp->ex_layout_types);
3307 if (status)
3308 goto out;
3309 }
3310
3311 if (bmval2 & FATTR4_WORD2_LAYOUT_TYPES) {
3312 status = nfsd4_encode_layout_types(xdr, exp->ex_layout_types);
3313 if (status)
3314 goto out;
3315 }
3316
3317 if (bmval2 & FATTR4_WORD2_LAYOUT_BLKSIZE) {
3318 p = xdr_reserve_space(xdr, 4);
3319 if (!p)
3320 goto out_resource;
3321 *p++ = cpu_to_be32(stat.blksize);
3322 }
3323 #endif
3324 if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
3325 u32 supp[3];
3326
3327 memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp));
3328 supp[0] &= NFSD_SUPPATTR_EXCLCREAT_WORD0;
3329 supp[1] &= NFSD_SUPPATTR_EXCLCREAT_WORD1;
3330 supp[2] &= NFSD_SUPPATTR_EXCLCREAT_WORD2;
3331
3332 status = nfsd4_encode_bitmap(xdr, supp[0], supp[1], supp[2]);
3333 if (status)
3334 goto out;
3335 }
3336
3337 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
3338 if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
3339 status = nfsd4_encode_security_label(xdr, rqstp, context,
3340 contextlen);
3341 if (status)
3342 goto out;
3343 }
3344 #endif
3345
3346 if (bmval2 & FATTR4_WORD2_XATTR_SUPPORT) {
3347 p = xdr_reserve_space(xdr, 4);
3348 if (!p)
3349 goto out_resource;
3350 err = xattr_supported_namespace(d_inode(dentry),
3351 XATTR_USER_PREFIX);
3352 *p++ = cpu_to_be32(err == 0);
3353 }
3354
3355 *attrlen_p = cpu_to_be32(xdr->buf->len - attrlen_offset - XDR_UNIT);
3356 status = nfs_ok;
3357
3358 out:
3359 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
3360 if (context)
3361 security_release_secctx(context, contextlen);
3362 #endif
3363 kfree(acl);
3364 if (tempfh) {
3365 fh_put(tempfh);
3366 kfree(tempfh);
3367 }
3368 if (status)
3369 xdr_truncate_encode(xdr, starting_len);
3370 return status;
3371 out_nfserr:
3372 status = nfserrno(err);
3373 goto out;
3374 out_resource:
3375 status = nfserr_resource;
3376 goto out;
3377 }
3378
3379 static void svcxdr_init_encode_from_buffer(struct xdr_stream *xdr,
3380 struct xdr_buf *buf, __be32 *p, int bytes)
3381 {
3382 xdr->scratch.iov_len = 0;
3383 memset(buf, 0, sizeof(struct xdr_buf));
3384 buf->head[0].iov_base = p;
3385 buf->head[0].iov_len = 0;
3386 buf->len = 0;
3387 xdr->buf = buf;
3388 xdr->iov = buf->head;
3389 xdr->p = p;
3390 xdr->end = (void *)p + bytes;
3391 buf->buflen = bytes;
3392 }
3393
3394 __be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words,
3395 struct svc_fh *fhp, struct svc_export *exp,
3396 struct dentry *dentry, u32 *bmval,
3397 struct svc_rqst *rqstp, int ignore_crossmnt)
3398 {
3399 struct xdr_buf dummy;
3400 struct xdr_stream xdr;
3401 __be32 ret;
3402
3403 svcxdr_init_encode_from_buffer(&xdr, &dummy, *p, words << 2);
3404 ret = nfsd4_encode_fattr(&xdr, fhp, exp, dentry, bmval, rqstp,
3405 ignore_crossmnt);
3406 *p = xdr.p;
3407 return ret;
3408 }
3409
3410 static inline int attributes_need_mount(u32 *bmval)
3411 {
3412 if (bmval[0] & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_LEASE_TIME))
3413 return 1;
3414 if (bmval[1] & ~FATTR4_WORD1_MOUNTED_ON_FILEID)
3415 return 1;
3416 return 0;
3417 }
3418
3419 static __be32
3420 nfsd4_encode_dirent_fattr(struct xdr_stream *xdr, struct nfsd4_readdir *cd,
3421 const char *name, int namlen)
3422 {
3423 struct svc_export *exp = cd->rd_fhp->fh_export;
3424 struct dentry *dentry;
3425 __be32 nfserr;
3426 int ignore_crossmnt = 0;
3427
3428 dentry = lookup_positive_unlocked(name, cd->rd_fhp->fh_dentry, namlen);
3429 if (IS_ERR(dentry))
3430 return nfserrno(PTR_ERR(dentry));
3431
3432 exp_get(exp);
3433
3434
3435
3436
3437
3438
3439
3440 if (nfsd_mountpoint(dentry, exp)) {
3441 int err;
3442
3443 if (!(exp->ex_flags & NFSEXP_V4ROOT)
3444 && !attributes_need_mount(cd->rd_bmval)) {
3445 ignore_crossmnt = 1;
3446 goto out_encode;
3447 }
3448
3449
3450
3451
3452
3453 err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);
3454 if (err) {
3455 nfserr = nfserrno(err);
3456 goto out_put;
3457 }
3458 nfserr = check_nfsd_access(exp, cd->rd_rqstp);
3459 if (nfserr)
3460 goto out_put;
3461
3462 }
3463 out_encode:
3464 nfserr = nfsd4_encode_fattr(xdr, NULL, exp, dentry, cd->rd_bmval,
3465 cd->rd_rqstp, ignore_crossmnt);
3466 out_put:
3467 dput(dentry);
3468 exp_put(exp);
3469 return nfserr;
3470 }
3471
3472 static __be32 *
3473 nfsd4_encode_rdattr_error(struct xdr_stream *xdr, __be32 nfserr)
3474 {
3475 __be32 *p;
3476
3477 p = xdr_reserve_space(xdr, 20);
3478 if (!p)
3479 return NULL;
3480 *p++ = htonl(2);
3481 *p++ = htonl(FATTR4_WORD0_RDATTR_ERROR);
3482 *p++ = htonl(0);
3483
3484 *p++ = htonl(4);
3485 *p++ = nfserr;
3486 return p;
3487 }
3488
3489 static int
3490 nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
3491 loff_t offset, u64 ino, unsigned int d_type)
3492 {
3493 struct readdir_cd *ccd = ccdv;
3494 struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
3495 struct xdr_stream *xdr = cd->xdr;
3496 int start_offset = xdr->buf->len;
3497 int cookie_offset;
3498 u32 name_and_cookie;
3499 int entry_bytes;
3500 __be32 nfserr = nfserr_toosmall;
3501 __be64 wire_offset;
3502 __be32 *p;
3503
3504
3505 if (name && isdotent(name, namlen)) {
3506 cd->common.err = nfs_ok;
3507 return 0;
3508 }
3509
3510 if (cd->cookie_offset) {
3511 wire_offset = cpu_to_be64(offset);
3512 write_bytes_to_xdr_buf(xdr->buf, cd->cookie_offset,
3513 &wire_offset, 8);
3514 }
3515
3516 p = xdr_reserve_space(xdr, 4);
3517 if (!p)
3518 goto fail;
3519 *p++ = xdr_one;
3520 cookie_offset = xdr->buf->len;
3521 p = xdr_reserve_space(xdr, 3*4 + namlen);
3522 if (!p)
3523 goto fail;
3524 p = xdr_encode_hyper(p, OFFSET_MAX);
3525 p = xdr_encode_array(p, name, namlen);
3526
3527 nfserr = nfsd4_encode_dirent_fattr(xdr, cd, name, namlen);
3528 switch (nfserr) {
3529 case nfs_ok:
3530 break;
3531 case nfserr_resource:
3532 nfserr = nfserr_toosmall;
3533 goto fail;
3534 case nfserr_noent:
3535 xdr_truncate_encode(xdr, start_offset);
3536 goto skip_entry;
3537 default:
3538
3539
3540
3541
3542
3543
3544
3545 if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))
3546 goto fail;
3547 p = nfsd4_encode_rdattr_error(xdr, nfserr);
3548 if (p == NULL) {
3549 nfserr = nfserr_toosmall;
3550 goto fail;
3551 }
3552 }
3553 nfserr = nfserr_toosmall;
3554 entry_bytes = xdr->buf->len - start_offset;
3555 if (entry_bytes > cd->rd_maxcount)
3556 goto fail;
3557 cd->rd_maxcount -= entry_bytes;
3558
3559
3560
3561
3562
3563 if (cd->rd_dircount) {
3564 name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8;
3565 if (name_and_cookie > cd->rd_dircount && cd->cookie_offset)
3566 goto fail;
3567 cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie);
3568 if (!cd->rd_dircount)
3569 cd->rd_maxcount = 0;
3570 }
3571
3572 cd->cookie_offset = cookie_offset;
3573 skip_entry:
3574 cd->common.err = nfs_ok;
3575 return 0;
3576 fail:
3577 xdr_truncate_encode(xdr, start_offset);
3578 cd->common.err = nfserr;
3579 return -EINVAL;
3580 }
3581
3582 static __be32
3583 nfsd4_encode_stateid(struct xdr_stream *xdr, stateid_t *sid)
3584 {
3585 __be32 *p;
3586
3587 p = xdr_reserve_space(xdr, sizeof(stateid_t));
3588 if (!p)
3589 return nfserr_resource;
3590 *p++ = cpu_to_be32(sid->si_generation);
3591 p = xdr_encode_opaque_fixed(p, &sid->si_opaque,
3592 sizeof(stateid_opaque_t));
3593 return 0;
3594 }
3595
3596 static __be32
3597 nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
3598 {
3599 struct xdr_stream *xdr = resp->xdr;
3600 __be32 *p;
3601
3602 p = xdr_reserve_space(xdr, 8);
3603 if (!p)
3604 return nfserr_resource;
3605 *p++ = cpu_to_be32(access->ac_supported);
3606 *p++ = cpu_to_be32(access->ac_resp_access);
3607 return 0;
3608 }
3609
3610 static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
3611 {
3612 struct xdr_stream *xdr = resp->xdr;
3613 __be32 *p;
3614
3615 p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8);
3616 if (!p)
3617 return nfserr_resource;
3618 p = xdr_encode_opaque_fixed(p, bcts->sessionid.data,
3619 NFS4_MAX_SESSIONID_LEN);
3620 *p++ = cpu_to_be32(bcts->dir);
3621
3622 *p++ = cpu_to_be32(0);
3623 return 0;
3624 }
3625
3626 static __be32
3627 nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
3628 {
3629 struct xdr_stream *xdr = resp->xdr;
3630
3631 return nfsd4_encode_stateid(xdr, &close->cl_stateid);
3632 }
3633
3634
3635 static __be32
3636 nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
3637 {
3638 struct xdr_stream *xdr = resp->xdr;
3639 __be32 *p;
3640
3641 p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
3642 if (!p)
3643 return nfserr_resource;
3644 p = xdr_encode_opaque_fixed(p, commit->co_verf.data,
3645 NFS4_VERIFIER_SIZE);
3646 return 0;
3647 }
3648
3649 static __be32
3650 nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
3651 {
3652 struct xdr_stream *xdr = resp->xdr;
3653 __be32 *p;
3654
3655 p = xdr_reserve_space(xdr, 20);
3656 if (!p)
3657 return nfserr_resource;
3658 encode_cinfo(p, &create->cr_cinfo);
3659 return nfsd4_encode_bitmap(xdr, create->cr_bmval[0],
3660 create->cr_bmval[1], create->cr_bmval[2]);
3661 }
3662
3663 static __be32
3664 nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr)
3665 {
3666 struct svc_fh *fhp = getattr->ga_fhp;
3667 struct xdr_stream *xdr = resp->xdr;
3668
3669 return nfsd4_encode_fattr(xdr, fhp, fhp->fh_export, fhp->fh_dentry,
3670 getattr->ga_bmval, resp->rqstp, 0);
3671 }
3672
3673 static __be32
3674 nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
3675 {
3676 struct xdr_stream *xdr = resp->xdr;
3677 struct svc_fh *fhp = *fhpp;
3678 unsigned int len;
3679 __be32 *p;
3680
3681 len = fhp->fh_handle.fh_size;
3682 p = xdr_reserve_space(xdr, len + 4);
3683 if (!p)
3684 return nfserr_resource;
3685 p = xdr_encode_opaque(p, &fhp->fh_handle.fh_raw, len);
3686 return 0;
3687 }
3688
3689
3690
3691
3692
3693 static __be32
3694 nfsd4_encode_lock_denied(struct xdr_stream *xdr, struct nfsd4_lock_denied *ld)
3695 {
3696 struct xdr_netobj *conf = &ld->ld_owner;
3697 __be32 *p;
3698
3699 again:
3700 p = xdr_reserve_space(xdr, 32 + XDR_LEN(conf->len));
3701 if (!p) {
3702
3703
3704
3705
3706 if (conf->len) {
3707 kfree(conf->data);
3708 conf->len = 0;
3709 conf->data = NULL;
3710 goto again;
3711 }
3712 return nfserr_resource;
3713 }
3714 p = xdr_encode_hyper(p, ld->ld_start);
3715 p = xdr_encode_hyper(p, ld->ld_length);
3716 *p++ = cpu_to_be32(ld->ld_type);
3717 if (conf->len) {
3718 p = xdr_encode_opaque_fixed(p, &ld->ld_clientid, 8);
3719 p = xdr_encode_opaque(p, conf->data, conf->len);
3720 kfree(conf->data);
3721 } else {
3722 p = xdr_encode_hyper(p, (u64)0);
3723 *p++ = cpu_to_be32(0);
3724 }
3725 return nfserr_denied;
3726 }
3727
3728 static __be32
3729 nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
3730 {
3731 struct xdr_stream *xdr = resp->xdr;
3732
3733 if (!nfserr)
3734 nfserr = nfsd4_encode_stateid(xdr, &lock->lk_resp_stateid);
3735 else if (nfserr == nfserr_denied)
3736 nfserr = nfsd4_encode_lock_denied(xdr, &lock->lk_denied);
3737
3738 return nfserr;
3739 }
3740
3741 static __be32
3742 nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
3743 {
3744 struct xdr_stream *xdr = resp->xdr;
3745
3746 if (nfserr == nfserr_denied)
3747 nfsd4_encode_lock_denied(xdr, &lockt->lt_denied);
3748 return nfserr;
3749 }
3750
3751 static __be32
3752 nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
3753 {
3754 struct xdr_stream *xdr = resp->xdr;
3755
3756 return nfsd4_encode_stateid(xdr, &locku->lu_stateid);
3757 }
3758
3759
3760 static __be32
3761 nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
3762 {
3763 struct xdr_stream *xdr = resp->xdr;
3764 __be32 *p;
3765
3766 p = xdr_reserve_space(xdr, 20);
3767 if (!p)
3768 return nfserr_resource;
3769 p = encode_cinfo(p, &link->li_cinfo);
3770 return 0;
3771 }
3772
3773
3774 static __be32
3775 nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
3776 {
3777 struct xdr_stream *xdr = resp->xdr;
3778 __be32 *p;
3779
3780 nfserr = nfsd4_encode_stateid(xdr, &open->op_stateid);
3781 if (nfserr)
3782 return nfserr;
3783 p = xdr_reserve_space(xdr, 24);
3784 if (!p)
3785 return nfserr_resource;
3786 p = encode_cinfo(p, &open->op_cinfo);
3787 *p++ = cpu_to_be32(open->op_rflags);
3788
3789 nfserr = nfsd4_encode_bitmap(xdr, open->op_bmval[0], open->op_bmval[1],
3790 open->op_bmval[2]);
3791 if (nfserr)
3792 return nfserr;
3793
3794 p = xdr_reserve_space(xdr, 4);
3795 if (!p)
3796 return nfserr_resource;
3797
3798 *p++ = cpu_to_be32(open->op_delegate_type);
3799 switch (open->op_delegate_type) {
3800 case NFS4_OPEN_DELEGATE_NONE:
3801 break;
3802 case NFS4_OPEN_DELEGATE_READ:
3803 nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
3804 if (nfserr)
3805 return nfserr;
3806 p = xdr_reserve_space(xdr, 20);
3807 if (!p)
3808 return nfserr_resource;
3809 *p++ = cpu_to_be32(open->op_recall);
3810
3811
3812
3813
3814 *p++ = cpu_to_be32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
3815 *p++ = cpu_to_be32(0);
3816 *p++ = cpu_to_be32(0);
3817 *p++ = cpu_to_be32(0);
3818 break;
3819 case NFS4_OPEN_DELEGATE_WRITE:
3820 nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
3821 if (nfserr)
3822 return nfserr;
3823 p = xdr_reserve_space(xdr, 32);
3824 if (!p)
3825 return nfserr_resource;
3826 *p++ = cpu_to_be32(0);
3827
3828
3829
3830
3831 *p++ = cpu_to_be32(NFS4_LIMIT_SIZE);
3832 *p++ = cpu_to_be32(~(u32)0);
3833 *p++ = cpu_to_be32(~(u32)0);
3834
3835
3836
3837
3838 *p++ = cpu_to_be32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
3839 *p++ = cpu_to_be32(0);
3840 *p++ = cpu_to_be32(0);
3841 *p++ = cpu_to_be32(0);
3842 break;
3843 case NFS4_OPEN_DELEGATE_NONE_EXT:
3844 switch (open->op_why_no_deleg) {
3845 case WND4_CONTENTION:
3846 case WND4_RESOURCE:
3847 p = xdr_reserve_space(xdr, 8);
3848 if (!p)
3849 return nfserr_resource;
3850 *p++ = cpu_to_be32(open->op_why_no_deleg);
3851
3852 *p++ = cpu_to_be32(0);
3853 break;
3854 default:
3855 p = xdr_reserve_space(xdr, 4);
3856 if (!p)
3857 return nfserr_resource;
3858 *p++ = cpu_to_be32(open->op_why_no_deleg);
3859 }
3860 break;
3861 default:
3862 BUG();
3863 }
3864
3865 return 0;
3866 }
3867
3868 static __be32
3869 nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
3870 {
3871 struct xdr_stream *xdr = resp->xdr;
3872
3873 return nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid);
3874 }
3875
3876 static __be32
3877 nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
3878 {
3879 struct xdr_stream *xdr = resp->xdr;
3880
3881 return nfsd4_encode_stateid(xdr, &od->od_stateid);
3882 }
3883
3884 static __be32 nfsd4_encode_splice_read(
3885 struct nfsd4_compoundres *resp,
3886 struct nfsd4_read *read,
3887 struct file *file, unsigned long maxcount)
3888 {
3889 struct xdr_stream *xdr = resp->xdr;
3890 struct xdr_buf *buf = xdr->buf;
3891 int status, space_left;
3892 __be32 nfserr;
3893
3894
3895 if (xdr->end - xdr->p < 1)
3896 return nfserr_resource;
3897
3898 nfserr = nfsd_splice_read(read->rd_rqstp, read->rd_fhp,
3899 file, read->rd_offset, &maxcount,
3900 &read->rd_eof);
3901 read->rd_length = maxcount;
3902 if (nfserr)
3903 goto out_err;
3904 status = svc_encode_result_payload(read->rd_rqstp,
3905 buf->head[0].iov_len, maxcount);
3906 if (status) {
3907 nfserr = nfserrno(status);
3908 goto out_err;
3909 }
3910
3911 buf->page_len = maxcount;
3912 buf->len += maxcount;
3913 xdr->page_ptr += (buf->page_base + maxcount + PAGE_SIZE - 1)
3914 / PAGE_SIZE;
3915
3916
3917 buf->tail[0].iov_base = xdr->p;
3918 buf->tail[0].iov_len = 0;
3919 xdr->iov = buf->tail;
3920 if (maxcount&3) {
3921 int pad = 4 - (maxcount&3);
3922
3923 *(xdr->p++) = 0;
3924
3925 buf->tail[0].iov_base += maxcount&3;
3926 buf->tail[0].iov_len = pad;
3927 buf->len += pad;
3928 }
3929
3930 space_left = min_t(int, (void *)xdr->end - (void *)xdr->p,
3931 buf->buflen - buf->len);
3932 buf->buflen = buf->len + space_left;
3933 xdr->end = (__be32 *)((void *)xdr->end + space_left);
3934
3935 return 0;
3936
3937 out_err:
3938
3939
3940
3941
3942
3943 buf->page_len = 0;
3944 return nfserr;
3945 }
3946
3947 static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp,
3948 struct nfsd4_read *read,
3949 struct file *file, unsigned long maxcount)
3950 {
3951 struct xdr_stream *xdr = resp->xdr;
3952 unsigned int starting_len = xdr->buf->len;
3953 __be32 zero = xdr_zero;
3954 __be32 nfserr;
3955
3956 read->rd_vlen = xdr_reserve_space_vec(xdr, resp->rqstp->rq_vec, maxcount);
3957 if (read->rd_vlen < 0)
3958 return nfserr_resource;
3959
3960 nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset,
3961 resp->rqstp->rq_vec, read->rd_vlen, &maxcount,
3962 &read->rd_eof);
3963 read->rd_length = maxcount;
3964 if (nfserr)
3965 return nfserr;
3966 if (svc_encode_result_payload(resp->rqstp, starting_len, maxcount))
3967 return nfserr_io;
3968 xdr_truncate_encode(xdr, starting_len + xdr_align_size(maxcount));
3969
3970 write_bytes_to_xdr_buf(xdr->buf, starting_len + maxcount, &zero,
3971 xdr_pad_size(maxcount));
3972 return nfs_ok;
3973 }
3974
3975 static __be32
3976 nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
3977 struct nfsd4_read *read)
3978 {
3979 bool splice_ok = test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags);
3980 unsigned long maxcount;
3981 struct xdr_stream *xdr = resp->xdr;
3982 struct file *file;
3983 int starting_len = xdr->buf->len;
3984 __be32 *p;
3985
3986 if (nfserr)
3987 return nfserr;
3988 file = read->rd_nf->nf_file;
3989
3990 p = xdr_reserve_space(xdr, 8);
3991 if (!p) {
3992 WARN_ON_ONCE(splice_ok);
3993 return nfserr_resource;
3994 }
3995 if (resp->xdr->buf->page_len && splice_ok) {
3996 WARN_ON_ONCE(1);
3997 return nfserr_resource;
3998 }
3999 xdr_commit_encode(xdr);
4000
4001 maxcount = min_t(unsigned long, read->rd_length,
4002 (xdr->buf->buflen - xdr->buf->len));
4003
4004 if (file->f_op->splice_read && splice_ok)
4005 nfserr = nfsd4_encode_splice_read(resp, read, file, maxcount);
4006 else
4007 nfserr = nfsd4_encode_readv(resp, read, file, maxcount);
4008 if (nfserr) {
4009 xdr_truncate_encode(xdr, starting_len);
4010 return nfserr;
4011 }
4012
4013 p = xdr_encode_bool(p, read->rd_eof);
4014 *p = cpu_to_be32(read->rd_length);
4015 return nfs_ok;
4016 }
4017
4018 static __be32
4019 nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink)
4020 {
4021 __be32 *p, *maxcount_p, zero = xdr_zero;
4022 struct xdr_stream *xdr = resp->xdr;
4023 int length_offset = xdr->buf->len;
4024 int maxcount, status;
4025
4026 maxcount_p = xdr_reserve_space(xdr, XDR_UNIT);
4027 if (!maxcount_p)
4028 return nfserr_resource;
4029 maxcount = PAGE_SIZE;
4030
4031 p = xdr_reserve_space(xdr, maxcount);
4032 if (!p)
4033 return nfserr_resource;
4034
4035
4036
4037
4038
4039
4040 nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp,
4041 (char *)p, &maxcount);
4042 if (nfserr == nfserr_isdir)
4043 nfserr = nfserr_inval;
4044 if (nfserr)
4045 goto out_err;
4046 status = svc_encode_result_payload(readlink->rl_rqstp, length_offset,
4047 maxcount);
4048 if (status) {
4049 nfserr = nfserrno(status);
4050 goto out_err;
4051 }
4052 *maxcount_p = cpu_to_be32(maxcount);
4053 xdr_truncate_encode(xdr, length_offset + 4 + xdr_align_size(maxcount));
4054 write_bytes_to_xdr_buf(xdr->buf, length_offset + 4 + maxcount, &zero,
4055 xdr_pad_size(maxcount));
4056 return nfs_ok;
4057
4058 out_err:
4059 xdr_truncate_encode(xdr, length_offset);
4060 return nfserr;
4061 }
4062
4063 static __be32
4064 nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir)
4065 {
4066 int maxcount;
4067 int bytes_left;
4068 loff_t offset;
4069 __be64 wire_offset;
4070 struct xdr_stream *xdr = resp->xdr;
4071 int starting_len = xdr->buf->len;
4072 __be32 *p;
4073
4074 p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
4075 if (!p)
4076 return nfserr_resource;
4077
4078
4079 *p++ = cpu_to_be32(0);
4080 *p++ = cpu_to_be32(0);
4081 xdr->buf->head[0].iov_len = (char *)xdr->p -
4082 (char *)xdr->buf->head[0].iov_base;
4083
4084
4085
4086
4087
4088 bytes_left = xdr->buf->buflen - xdr->buf->len
4089 - COMPOUND_ERR_SLACK_SPACE - 8;
4090 if (bytes_left < 0) {
4091 nfserr = nfserr_resource;
4092 goto err_no_verf;
4093 }
4094 maxcount = svc_max_payload(resp->rqstp);
4095 maxcount = min_t(u32, readdir->rd_maxcount, maxcount);
4096
4097
4098
4099
4100
4101 if (maxcount < 16) {
4102 nfserr = nfserr_toosmall;
4103 goto err_no_verf;
4104 }
4105 maxcount = min_t(int, maxcount-16, bytes_left);
4106
4107
4108 if (!readdir->rd_dircount)
4109 readdir->rd_dircount = svc_max_payload(resp->rqstp);
4110
4111 readdir->xdr = xdr;
4112 readdir->rd_maxcount = maxcount;
4113 readdir->common.err = 0;
4114 readdir->cookie_offset = 0;
4115
4116 offset = readdir->rd_cookie;
4117 nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp,
4118 &offset,
4119 &readdir->common, nfsd4_encode_dirent);
4120 if (nfserr == nfs_ok &&
4121 readdir->common.err == nfserr_toosmall &&
4122 xdr->buf->len == starting_len + 8) {
4123
4124 if (maxcount - 16 < bytes_left)
4125
4126 nfserr = nfserr_toosmall;
4127 else
4128
4129 nfserr = nfserr_resource;
4130 }
4131 if (nfserr)
4132 goto err_no_verf;
4133
4134 if (readdir->cookie_offset) {
4135 wire_offset = cpu_to_be64(offset);
4136 write_bytes_to_xdr_buf(xdr->buf, readdir->cookie_offset,
4137 &wire_offset, 8);
4138 }
4139
4140 p = xdr_reserve_space(xdr, 8);
4141 if (!p) {
4142 WARN_ON_ONCE(1);
4143 goto err_no_verf;
4144 }
4145 *p++ = 0;
4146 *p++ = htonl(readdir->common.err == nfserr_eof);
4147
4148 return 0;
4149 err_no_verf:
4150 xdr_truncate_encode(xdr, starting_len);
4151 return nfserr;
4152 }
4153
4154 static __be32
4155 nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
4156 {
4157 struct xdr_stream *xdr = resp->xdr;
4158 __be32 *p;
4159
4160 p = xdr_reserve_space(xdr, 20);
4161 if (!p)
4162 return nfserr_resource;
4163 p = encode_cinfo(p, &remove->rm_cinfo);
4164 return 0;
4165 }
4166
4167 static __be32
4168 nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
4169 {
4170 struct xdr_stream *xdr = resp->xdr;
4171 __be32 *p;
4172
4173 p = xdr_reserve_space(xdr, 40);
4174 if (!p)
4175 return nfserr_resource;
4176 p = encode_cinfo(p, &rename->rn_sinfo);
4177 p = encode_cinfo(p, &rename->rn_tinfo);
4178 return 0;
4179 }
4180
4181 static __be32
4182 nfsd4_do_encode_secinfo(struct xdr_stream *xdr, struct svc_export *exp)
4183 {
4184 u32 i, nflavs, supported;
4185 struct exp_flavor_info *flavs;
4186 struct exp_flavor_info def_flavs[2];
4187 __be32 *p, *flavorsp;
4188 static bool report = true;
4189
4190 if (exp->ex_nflavors) {
4191 flavs = exp->ex_flavors;
4192 nflavs = exp->ex_nflavors;
4193 } else {
4194 flavs = def_flavs;
4195 if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) {
4196 nflavs = 2;
4197 flavs[0].pseudoflavor = RPC_AUTH_UNIX;
4198 flavs[1].pseudoflavor = RPC_AUTH_NULL;
4199 } else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) {
4200 nflavs = 1;
4201 flavs[0].pseudoflavor
4202 = svcauth_gss_flavor(exp->ex_client);
4203 } else {
4204 nflavs = 1;
4205 flavs[0].pseudoflavor
4206 = exp->ex_client->flavour->flavour;
4207 }
4208 }
4209
4210 supported = 0;
4211 p = xdr_reserve_space(xdr, 4);
4212 if (!p)
4213 return nfserr_resource;
4214 flavorsp = p++;
4215
4216 for (i = 0; i < nflavs; i++) {
4217 rpc_authflavor_t pf = flavs[i].pseudoflavor;
4218 struct rpcsec_gss_info info;
4219
4220 if (rpcauth_get_gssinfo(pf, &info) == 0) {
4221 supported++;
4222 p = xdr_reserve_space(xdr, 4 + 4 +
4223 XDR_LEN(info.oid.len) + 4 + 4);
4224 if (!p)
4225 return nfserr_resource;
4226 *p++ = cpu_to_be32(RPC_AUTH_GSS);
4227 p = xdr_encode_opaque(p, info.oid.data, info.oid.len);
4228 *p++ = cpu_to_be32(info.qop);
4229 *p++ = cpu_to_be32(info.service);
4230 } else if (pf < RPC_AUTH_MAXFLAVOR) {
4231 supported++;
4232 p = xdr_reserve_space(xdr, 4);
4233 if (!p)
4234 return nfserr_resource;
4235 *p++ = cpu_to_be32(pf);
4236 } else {
4237 if (report)
4238 pr_warn("NFS: SECINFO: security flavor %u "
4239 "is not supported\n", pf);
4240 }
4241 }
4242
4243 if (nflavs != supported)
4244 report = false;
4245 *flavorsp = htonl(supported);
4246 return 0;
4247 }
4248
4249 static __be32
4250 nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
4251 struct nfsd4_secinfo *secinfo)
4252 {
4253 struct xdr_stream *xdr = resp->xdr;
4254
4255 return nfsd4_do_encode_secinfo(xdr, secinfo->si_exp);
4256 }
4257
4258 static __be32
4259 nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
4260 struct nfsd4_secinfo_no_name *secinfo)
4261 {
4262 struct xdr_stream *xdr = resp->xdr;
4263
4264 return nfsd4_do_encode_secinfo(xdr, secinfo->sin_exp);
4265 }
4266
4267
4268
4269
4270
4271 static __be32
4272 nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
4273 {
4274 struct xdr_stream *xdr = resp->xdr;
4275 __be32 *p;
4276
4277 p = xdr_reserve_space(xdr, 16);
4278 if (!p)
4279 return nfserr_resource;
4280 if (nfserr) {
4281 *p++ = cpu_to_be32(3);
4282 *p++ = cpu_to_be32(0);
4283 *p++ = cpu_to_be32(0);
4284 *p++ = cpu_to_be32(0);
4285 }
4286 else {
4287 *p++ = cpu_to_be32(3);
4288 *p++ = cpu_to_be32(setattr->sa_bmval[0]);
4289 *p++ = cpu_to_be32(setattr->sa_bmval[1]);
4290 *p++ = cpu_to_be32(setattr->sa_bmval[2]);
4291 }
4292 return nfserr;
4293 }
4294
4295 static __be32
4296 nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
4297 {
4298 struct xdr_stream *xdr = resp->xdr;
4299 __be32 *p;
4300
4301 if (!nfserr) {
4302 p = xdr_reserve_space(xdr, 8 + NFS4_VERIFIER_SIZE);
4303 if (!p)
4304 return nfserr_resource;
4305 p = xdr_encode_opaque_fixed(p, &scd->se_clientid, 8);
4306 p = xdr_encode_opaque_fixed(p, &scd->se_confirm,
4307 NFS4_VERIFIER_SIZE);
4308 }
4309 else if (nfserr == nfserr_clid_inuse) {
4310 p = xdr_reserve_space(xdr, 8);
4311 if (!p)
4312 return nfserr_resource;
4313 *p++ = cpu_to_be32(0);
4314 *p++ = cpu_to_be32(0);
4315 }
4316 return nfserr;
4317 }
4318
4319 static __be32
4320 nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
4321 {
4322 struct xdr_stream *xdr = resp->xdr;
4323 __be32 *p;
4324
4325 p = xdr_reserve_space(xdr, 16);
4326 if (!p)
4327 return nfserr_resource;
4328 *p++ = cpu_to_be32(write->wr_bytes_written);
4329 *p++ = cpu_to_be32(write->wr_how_written);
4330 p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
4331 NFS4_VERIFIER_SIZE);
4332 return 0;
4333 }
4334
4335 static __be32
4336 nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
4337 struct nfsd4_exchange_id *exid)
4338 {
4339 struct xdr_stream *xdr = resp->xdr;
4340 __be32 *p;
4341 char *major_id;
4342 char *server_scope;
4343 int major_id_sz;
4344 int server_scope_sz;
4345 uint64_t minor_id = 0;
4346 struct nfsd_net *nn = net_generic(SVC_NET(resp->rqstp), nfsd_net_id);
4347
4348 major_id = nn->nfsd_name;
4349 major_id_sz = strlen(nn->nfsd_name);
4350 server_scope = nn->nfsd_name;
4351 server_scope_sz = strlen(nn->nfsd_name);
4352
4353 p = xdr_reserve_space(xdr,
4354 8 +
4355 4 +
4356 4 +
4357 4 );
4358 if (!p)
4359 return nfserr_resource;
4360
4361 p = xdr_encode_opaque_fixed(p, &exid->clientid, 8);
4362 *p++ = cpu_to_be32(exid->seqid);
4363 *p++ = cpu_to_be32(exid->flags);
4364
4365 *p++ = cpu_to_be32(exid->spa_how);
4366
4367 switch (exid->spa_how) {
4368 case SP4_NONE:
4369 break;
4370 case SP4_MACH_CRED:
4371
4372 nfserr = nfsd4_encode_bitmap(xdr,
4373 exid->spo_must_enforce[0],
4374 exid->spo_must_enforce[1],
4375 exid->spo_must_enforce[2]);
4376 if (nfserr)
4377 return nfserr;
4378
4379 nfserr = nfsd4_encode_bitmap(xdr,
4380 exid->spo_must_allow[0],
4381 exid->spo_must_allow[1],
4382 exid->spo_must_allow[2]);
4383 if (nfserr)
4384 return nfserr;
4385 break;
4386 default:
4387 WARN_ON_ONCE(1);
4388 }
4389
4390 p = xdr_reserve_space(xdr,
4391 8 +
4392 4 +
4393 (XDR_QUADLEN(major_id_sz) * 4) +
4394 4 +
4395 (XDR_QUADLEN(server_scope_sz) * 4) +
4396 4 );
4397 if (!p)
4398 return nfserr_resource;
4399
4400
4401 p = xdr_encode_hyper(p, minor_id);
4402
4403 p = xdr_encode_opaque(p, major_id, major_id_sz);
4404
4405
4406 p = xdr_encode_opaque(p, server_scope, server_scope_sz);
4407
4408
4409 *p++ = cpu_to_be32(0);
4410 return 0;
4411 }
4412
4413 static __be32
4414 nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
4415 struct nfsd4_create_session *sess)
4416 {
4417 struct xdr_stream *xdr = resp->xdr;
4418 __be32 *p;
4419
4420 p = xdr_reserve_space(xdr, 24);
4421 if (!p)
4422 return nfserr_resource;
4423 p = xdr_encode_opaque_fixed(p, sess->sessionid.data,
4424 NFS4_MAX_SESSIONID_LEN);
4425 *p++ = cpu_to_be32(sess->seqid);
4426 *p++ = cpu_to_be32(sess->flags);
4427
4428 p = xdr_reserve_space(xdr, 28);
4429 if (!p)
4430 return nfserr_resource;
4431 *p++ = cpu_to_be32(0);
4432 *p++ = cpu_to_be32(sess->fore_channel.maxreq_sz);
4433 *p++ = cpu_to_be32(sess->fore_channel.maxresp_sz);
4434 *p++ = cpu_to_be32(sess->fore_channel.maxresp_cached);
4435 *p++ = cpu_to_be32(sess->fore_channel.maxops);
4436 *p++ = cpu_to_be32(sess->fore_channel.maxreqs);
4437 *p++ = cpu_to_be32(sess->fore_channel.nr_rdma_attrs);
4438
4439 if (sess->fore_channel.nr_rdma_attrs) {
4440 p = xdr_reserve_space(xdr, 4);
4441 if (!p)
4442 return nfserr_resource;
4443 *p++ = cpu_to_be32(sess->fore_channel.rdma_attrs);
4444 }
4445
4446 p = xdr_reserve_space(xdr, 28);
4447 if (!p)
4448 return nfserr_resource;
4449 *p++ = cpu_to_be32(0);
4450 *p++ = cpu_to_be32(sess->back_channel.maxreq_sz);
4451 *p++ = cpu_to_be32(sess->back_channel.maxresp_sz);
4452 *p++ = cpu_to_be32(sess->back_channel.maxresp_cached);
4453 *p++ = cpu_to_be32(sess->back_channel.maxops);
4454 *p++ = cpu_to_be32(sess->back_channel.maxreqs);
4455 *p++ = cpu_to_be32(sess->back_channel.nr_rdma_attrs);
4456
4457 if (sess->back_channel.nr_rdma_attrs) {
4458 p = xdr_reserve_space(xdr, 4);
4459 if (!p)
4460 return nfserr_resource;
4461 *p++ = cpu_to_be32(sess->back_channel.rdma_attrs);
4462 }
4463 return 0;
4464 }
4465
4466 static __be32
4467 nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
4468 struct nfsd4_sequence *seq)
4469 {
4470 struct xdr_stream *xdr = resp->xdr;
4471 __be32 *p;
4472
4473 p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 20);
4474 if (!p)
4475 return nfserr_resource;
4476 p = xdr_encode_opaque_fixed(p, seq->sessionid.data,
4477 NFS4_MAX_SESSIONID_LEN);
4478 *p++ = cpu_to_be32(seq->seqid);
4479 *p++ = cpu_to_be32(seq->slotid);
4480
4481 *p++ = cpu_to_be32(seq->maxslots - 1);
4482 *p++ = cpu_to_be32(seq->maxslots - 1);
4483 *p++ = cpu_to_be32(seq->status_flags);
4484
4485 resp->cstate.data_offset = xdr->buf->len;
4486 return 0;
4487 }
4488
4489 static __be32
4490 nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
4491 struct nfsd4_test_stateid *test_stateid)
4492 {
4493 struct xdr_stream *xdr = resp->xdr;
4494 struct nfsd4_test_stateid_id *stateid, *next;
4495 __be32 *p;
4496
4497 p = xdr_reserve_space(xdr, 4 + (4 * test_stateid->ts_num_ids));
4498 if (!p)
4499 return nfserr_resource;
4500 *p++ = htonl(test_stateid->ts_num_ids);
4501
4502 list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
4503 *p++ = stateid->ts_id_status;
4504 }
4505
4506 return 0;
4507 }
4508
4509 #ifdef CONFIG_NFSD_PNFS
4510 static __be32
4511 nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
4512 struct nfsd4_getdeviceinfo *gdev)
4513 {
4514 struct xdr_stream *xdr = resp->xdr;
4515 const struct nfsd4_layout_ops *ops;
4516 u32 starting_len = xdr->buf->len, needed_len;
4517 __be32 *p;
4518
4519 p = xdr_reserve_space(xdr, 4);
4520 if (!p)
4521 return nfserr_resource;
4522
4523 *p++ = cpu_to_be32(gdev->gd_layout_type);
4524
4525
4526 if (gdev->gd_maxcount != 0) {
4527 ops = nfsd4_layout_ops[gdev->gd_layout_type];
4528 nfserr = ops->encode_getdeviceinfo(xdr, gdev);
4529 if (nfserr) {
4530
4531
4532
4533
4534
4535 if (xdr->buf->len + 4 > gdev->gd_maxcount)
4536 goto toosmall;
4537 return nfserr;
4538 }
4539 }
4540
4541 if (gdev->gd_notify_types) {
4542 p = xdr_reserve_space(xdr, 4 + 4);
4543 if (!p)
4544 return nfserr_resource;
4545 *p++ = cpu_to_be32(1);
4546 *p++ = cpu_to_be32(gdev->gd_notify_types);
4547 } else {
4548 p = xdr_reserve_space(xdr, 4);
4549 if (!p)
4550 return nfserr_resource;
4551 *p++ = 0;
4552 }
4553
4554 return 0;
4555 toosmall:
4556 dprintk("%s: maxcount too small\n", __func__);
4557 needed_len = xdr->buf->len + 4 ;
4558 xdr_truncate_encode(xdr, starting_len);
4559 p = xdr_reserve_space(xdr, 4);
4560 if (!p)
4561 return nfserr_resource;
4562 *p++ = cpu_to_be32(needed_len);
4563 return nfserr_toosmall;
4564 }
4565
4566 static __be32
4567 nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr,
4568 struct nfsd4_layoutget *lgp)
4569 {
4570 struct xdr_stream *xdr = resp->xdr;
4571 const struct nfsd4_layout_ops *ops;
4572 __be32 *p;
4573
4574 p = xdr_reserve_space(xdr, 36 + sizeof(stateid_opaque_t));
4575 if (!p)
4576 return nfserr_resource;
4577
4578 *p++ = cpu_to_be32(1);
4579 *p++ = cpu_to_be32(lgp->lg_sid.si_generation);
4580 p = xdr_encode_opaque_fixed(p, &lgp->lg_sid.si_opaque,
4581 sizeof(stateid_opaque_t));
4582
4583 *p++ = cpu_to_be32(1);
4584 p = xdr_encode_hyper(p, lgp->lg_seg.offset);
4585 p = xdr_encode_hyper(p, lgp->lg_seg.length);
4586 *p++ = cpu_to_be32(lgp->lg_seg.iomode);
4587 *p++ = cpu_to_be32(lgp->lg_layout_type);
4588
4589 ops = nfsd4_layout_ops[lgp->lg_layout_type];
4590 return ops->encode_layoutget(xdr, lgp);
4591 }
4592
4593 static __be32
4594 nfsd4_encode_layoutcommit(struct nfsd4_compoundres *resp, __be32 nfserr,
4595 struct nfsd4_layoutcommit *lcp)
4596 {
4597 struct xdr_stream *xdr = resp->xdr;
4598 __be32 *p;
4599
4600 p = xdr_reserve_space(xdr, 4);
4601 if (!p)
4602 return nfserr_resource;
4603 *p++ = cpu_to_be32(lcp->lc_size_chg);
4604 if (lcp->lc_size_chg) {
4605 p = xdr_reserve_space(xdr, 8);
4606 if (!p)
4607 return nfserr_resource;
4608 p = xdr_encode_hyper(p, lcp->lc_newsize);
4609 }
4610
4611 return 0;
4612 }
4613
4614 static __be32
4615 nfsd4_encode_layoutreturn(struct nfsd4_compoundres *resp, __be32 nfserr,
4616 struct nfsd4_layoutreturn *lrp)
4617 {
4618 struct xdr_stream *xdr = resp->xdr;
4619 __be32 *p;
4620
4621 p = xdr_reserve_space(xdr, 4);
4622 if (!p)
4623 return nfserr_resource;
4624 *p++ = cpu_to_be32(lrp->lrs_present);
4625 if (lrp->lrs_present)
4626 return nfsd4_encode_stateid(xdr, &lrp->lr_sid);
4627 return 0;
4628 }
4629 #endif
4630
4631 static __be32
4632 nfsd42_encode_write_res(struct nfsd4_compoundres *resp,
4633 struct nfsd42_write_res *write, bool sync)
4634 {
4635 __be32 *p;
4636 p = xdr_reserve_space(resp->xdr, 4);
4637 if (!p)
4638 return nfserr_resource;
4639
4640 if (sync)
4641 *p++ = cpu_to_be32(0);
4642 else {
4643 __be32 nfserr;
4644 *p++ = cpu_to_be32(1);
4645 nfserr = nfsd4_encode_stateid(resp->xdr, &write->cb_stateid);
4646 if (nfserr)
4647 return nfserr;
4648 }
4649 p = xdr_reserve_space(resp->xdr, 8 + 4 + NFS4_VERIFIER_SIZE);
4650 if (!p)
4651 return nfserr_resource;
4652
4653 p = xdr_encode_hyper(p, write->wr_bytes_written);
4654 *p++ = cpu_to_be32(write->wr_stable_how);
4655 p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
4656 NFS4_VERIFIER_SIZE);
4657 return nfs_ok;
4658 }
4659
4660 static __be32
4661 nfsd42_encode_nl4_server(struct nfsd4_compoundres *resp, struct nl4_server *ns)
4662 {
4663 struct xdr_stream *xdr = resp->xdr;
4664 struct nfs42_netaddr *addr;
4665 __be32 *p;
4666
4667 p = xdr_reserve_space(xdr, 4);
4668 *p++ = cpu_to_be32(ns->nl4_type);
4669
4670 switch (ns->nl4_type) {
4671 case NL4_NETADDR:
4672 addr = &ns->u.nl4_addr;
4673
4674
4675
4676
4677 p = xdr_reserve_space(xdr,
4678 4 +
4679 (XDR_QUADLEN(addr->netid_len) * 4) +
4680 4 +
4681 (XDR_QUADLEN(addr->addr_len) * 4));
4682 if (!p)
4683 return nfserr_resource;
4684
4685 *p++ = cpu_to_be32(addr->netid_len);
4686 p = xdr_encode_opaque_fixed(p, addr->netid,
4687 addr->netid_len);
4688 *p++ = cpu_to_be32(addr->addr_len);
4689 p = xdr_encode_opaque_fixed(p, addr->addr,
4690 addr->addr_len);
4691 break;
4692 default:
4693 WARN_ON_ONCE(ns->nl4_type != NL4_NETADDR);
4694 return nfserr_inval;
4695 }
4696
4697 return 0;
4698 }
4699
4700 static __be32
4701 nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
4702 struct nfsd4_copy *copy)
4703 {
4704 __be32 *p;
4705
4706 nfserr = nfsd42_encode_write_res(resp, ©->cp_res,
4707 nfsd4_copy_is_sync(copy));
4708 if (nfserr)
4709 return nfserr;
4710
4711 p = xdr_reserve_space(resp->xdr, 4 + 4);
4712 *p++ = xdr_one;
4713 *p = nfsd4_copy_is_sync(copy) ? xdr_one : xdr_zero;
4714 return 0;
4715 }
4716
4717 static __be32
4718 nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr,
4719 struct nfsd4_offload_status *os)
4720 {
4721 struct xdr_stream *xdr = resp->xdr;
4722 __be32 *p;
4723
4724 p = xdr_reserve_space(xdr, 8 + 4);
4725 if (!p)
4726 return nfserr_resource;
4727 p = xdr_encode_hyper(p, os->count);
4728 *p++ = cpu_to_be32(0);
4729 return nfserr;
4730 }
4731
4732 static __be32
4733 nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp,
4734 struct nfsd4_read *read,
4735 unsigned long *maxcount, u32 *eof,
4736 loff_t *pos)
4737 {
4738 struct xdr_stream *xdr = resp->xdr;
4739 struct file *file = read->rd_nf->nf_file;
4740 int starting_len = xdr->buf->len;
4741 loff_t hole_pos;
4742 __be32 nfserr;
4743 __be32 *p, tmp;
4744 __be64 tmp64;
4745
4746 hole_pos = pos ? *pos : vfs_llseek(file, read->rd_offset, SEEK_HOLE);
4747 if (hole_pos > read->rd_offset)
4748 *maxcount = min_t(unsigned long, *maxcount, hole_pos - read->rd_offset);
4749 *maxcount = min_t(unsigned long, *maxcount, (xdr->buf->buflen - xdr->buf->len));
4750
4751
4752 p = xdr_reserve_space(xdr, 4 + 8 + 4);
4753 if (!p)
4754 return nfserr_resource;
4755
4756 read->rd_vlen = xdr_reserve_space_vec(xdr, resp->rqstp->rq_vec, *maxcount);
4757 if (read->rd_vlen < 0)
4758 return nfserr_resource;
4759
4760 nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset,
4761 resp->rqstp->rq_vec, read->rd_vlen, maxcount, eof);
4762 if (nfserr)
4763 return nfserr;
4764 xdr_truncate_encode(xdr, starting_len + 16 + xdr_align_size(*maxcount));
4765
4766 tmp = htonl(NFS4_CONTENT_DATA);
4767 write_bytes_to_xdr_buf(xdr->buf, starting_len, &tmp, 4);
4768 tmp64 = cpu_to_be64(read->rd_offset);
4769 write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp64, 8);
4770 tmp = htonl(*maxcount);
4771 write_bytes_to_xdr_buf(xdr->buf, starting_len + 12, &tmp, 4);
4772
4773 tmp = xdr_zero;
4774 write_bytes_to_xdr_buf(xdr->buf, starting_len + 16 + *maxcount, &tmp,
4775 xdr_pad_size(*maxcount));
4776 return nfs_ok;
4777 }
4778
4779 static __be32
4780 nfsd4_encode_read_plus_hole(struct nfsd4_compoundres *resp,
4781 struct nfsd4_read *read,
4782 unsigned long *maxcount, u32 *eof)
4783 {
4784 struct file *file = read->rd_nf->nf_file;
4785 loff_t data_pos = vfs_llseek(file, read->rd_offset, SEEK_DATA);
4786 loff_t f_size = i_size_read(file_inode(file));
4787 unsigned long count;
4788 __be32 *p;
4789
4790 if (data_pos == -ENXIO)
4791 data_pos = f_size;
4792 else if (data_pos <= read->rd_offset || (data_pos < f_size && data_pos % PAGE_SIZE))
4793 return nfsd4_encode_read_plus_data(resp, read, maxcount, eof, &f_size);
4794 count = data_pos - read->rd_offset;
4795
4796
4797 p = xdr_reserve_space(resp->xdr, 4 + 8 + 8);
4798 if (!p)
4799 return nfserr_resource;
4800
4801 *p++ = htonl(NFS4_CONTENT_HOLE);
4802 p = xdr_encode_hyper(p, read->rd_offset);
4803 p = xdr_encode_hyper(p, count);
4804
4805 *eof = (read->rd_offset + count) >= f_size;
4806 *maxcount = min_t(unsigned long, count, *maxcount);
4807 return nfs_ok;
4808 }
4809
4810 static __be32
4811 nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr,
4812 struct nfsd4_read *read)
4813 {
4814 unsigned long maxcount, count;
4815 struct xdr_stream *xdr = resp->xdr;
4816 struct file *file;
4817 int starting_len = xdr->buf->len;
4818 int last_segment = xdr->buf->len;
4819 int segments = 0;
4820 __be32 *p, tmp;
4821 bool is_data;
4822 loff_t pos;
4823 u32 eof;
4824
4825 if (nfserr)
4826 return nfserr;
4827 file = read->rd_nf->nf_file;
4828
4829
4830 p = xdr_reserve_space(xdr, 4 + 4);
4831 if (!p)
4832 return nfserr_resource;
4833 xdr_commit_encode(xdr);
4834
4835 maxcount = min_t(unsigned long, read->rd_length,
4836 (xdr->buf->buflen - xdr->buf->len));
4837 count = maxcount;
4838
4839 eof = read->rd_offset >= i_size_read(file_inode(file));
4840 if (eof)
4841 goto out;
4842
4843 pos = vfs_llseek(file, read->rd_offset, SEEK_HOLE);
4844 is_data = pos > read->rd_offset;
4845
4846 while (count > 0 && !eof) {
4847 maxcount = count;
4848 if (is_data)
4849 nfserr = nfsd4_encode_read_plus_data(resp, read, &maxcount, &eof,
4850 segments == 0 ? &pos : NULL);
4851 else
4852 nfserr = nfsd4_encode_read_plus_hole(resp, read, &maxcount, &eof);
4853 if (nfserr)
4854 goto out;
4855 count -= maxcount;
4856 read->rd_offset += maxcount;
4857 is_data = !is_data;
4858 last_segment = xdr->buf->len;
4859 segments++;
4860 }
4861
4862 out:
4863 if (nfserr && segments == 0)
4864 xdr_truncate_encode(xdr, starting_len);
4865 else {
4866 if (nfserr) {
4867 xdr_truncate_encode(xdr, last_segment);
4868 nfserr = nfs_ok;
4869 eof = 0;
4870 }
4871 tmp = htonl(eof);
4872 write_bytes_to_xdr_buf(xdr->buf, starting_len, &tmp, 4);
4873 tmp = htonl(segments);
4874 write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp, 4);
4875 }
4876
4877 return nfserr;
4878 }
4879
4880 static __be32
4881 nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr,
4882 struct nfsd4_copy_notify *cn)
4883 {
4884 struct xdr_stream *xdr = resp->xdr;
4885 __be32 *p;
4886
4887 if (nfserr)
4888 return nfserr;
4889
4890
4891 p = xdr_reserve_space(xdr, 12);
4892 if (!p)
4893 return nfserr_resource;
4894
4895
4896 p = xdr_encode_hyper(p, cn->cpn_sec);
4897 *p++ = cpu_to_be32(cn->cpn_nsec);
4898
4899
4900 nfserr = nfsd4_encode_stateid(xdr, &cn->cpn_cnr_stateid);
4901 if (nfserr)
4902 return nfserr;
4903
4904
4905 p = xdr_reserve_space(xdr, 4);
4906 if (!p)
4907 return nfserr_resource;
4908
4909 *p++ = cpu_to_be32(1);
4910
4911 nfserr = nfsd42_encode_nl4_server(resp, cn->cpn_src);
4912 return nfserr;
4913 }
4914
4915 static __be32
4916 nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
4917 struct nfsd4_seek *seek)
4918 {
4919 __be32 *p;
4920
4921 p = xdr_reserve_space(resp->xdr, 4 + 8);
4922 *p++ = cpu_to_be32(seek->seek_eof);
4923 p = xdr_encode_hyper(p, seek->seek_pos);
4924
4925 return 0;
4926 }
4927
4928 static __be32
4929 nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
4930 {
4931 return nfserr;
4932 }
4933
4934
4935
4936
4937 static __be32
4938 nfsd4_vbuf_to_stream(struct xdr_stream *xdr, char *buf, u32 buflen)
4939 {
4940 u32 cplen;
4941 __be32 *p;
4942
4943 cplen = min_t(unsigned long, buflen,
4944 ((void *)xdr->end - (void *)xdr->p));
4945 p = xdr_reserve_space(xdr, cplen);
4946 if (!p)
4947 return nfserr_resource;
4948
4949 memcpy(p, buf, cplen);
4950 buf += cplen;
4951 buflen -= cplen;
4952
4953 while (buflen) {
4954 cplen = min_t(u32, buflen, PAGE_SIZE);
4955 p = xdr_reserve_space(xdr, cplen);
4956 if (!p)
4957 return nfserr_resource;
4958
4959 memcpy(p, buf, cplen);
4960
4961 if (cplen < PAGE_SIZE) {
4962
4963
4964
4965
4966
4967 xdr_encode_opaque_fixed(p, NULL, cplen);
4968 break;
4969 }
4970
4971 buflen -= PAGE_SIZE;
4972 buf += PAGE_SIZE;
4973 }
4974
4975 return 0;
4976 }
4977
4978 static __be32
4979 nfsd4_encode_getxattr(struct nfsd4_compoundres *resp, __be32 nfserr,
4980 struct nfsd4_getxattr *getxattr)
4981 {
4982 struct xdr_stream *xdr = resp->xdr;
4983 __be32 *p, err;
4984
4985 p = xdr_reserve_space(xdr, 4);
4986 if (!p)
4987 return nfserr_resource;
4988
4989 *p = cpu_to_be32(getxattr->getxa_len);
4990
4991 if (getxattr->getxa_len == 0)
4992 return 0;
4993
4994 err = nfsd4_vbuf_to_stream(xdr, getxattr->getxa_buf,
4995 getxattr->getxa_len);
4996
4997 kvfree(getxattr->getxa_buf);
4998
4999 return err;
5000 }
5001
5002 static __be32
5003 nfsd4_encode_setxattr(struct nfsd4_compoundres *resp, __be32 nfserr,
5004 struct nfsd4_setxattr *setxattr)
5005 {
5006 struct xdr_stream *xdr = resp->xdr;
5007 __be32 *p;
5008
5009 p = xdr_reserve_space(xdr, 20);
5010 if (!p)
5011 return nfserr_resource;
5012
5013 encode_cinfo(p, &setxattr->setxa_cinfo);
5014
5015 return 0;
5016 }
5017
5018
5019
5020
5021 static __be32
5022 nfsd4_listxattr_validate_cookie(struct nfsd4_listxattrs *listxattrs,
5023 u32 *offsetp)
5024 {
5025 u64 cookie = listxattrs->lsxa_cookie;
5026
5027
5028
5029
5030
5031
5032 if (cookie > (listxattrs->lsxa_len) / (XATTR_USER_PREFIX_LEN + 2))
5033 return nfserr_badcookie;
5034
5035 if (cookie > (listxattrs->lsxa_maxcount /
5036 (XDR_QUADLEN(XATTR_USER_PREFIX_LEN + 2) + 4)))
5037 return nfserr_badcookie;
5038
5039 *offsetp = (u32)cookie;
5040 return 0;
5041 }
5042
5043 static __be32
5044 nfsd4_encode_listxattrs(struct nfsd4_compoundres *resp, __be32 nfserr,
5045 struct nfsd4_listxattrs *listxattrs)
5046 {
5047 struct xdr_stream *xdr = resp->xdr;
5048 u32 cookie_offset, count_offset, eof;
5049 u32 left, xdrleft, slen, count;
5050 u32 xdrlen, offset;
5051 u64 cookie;
5052 char *sp;
5053 __be32 status, tmp;
5054 __be32 *p;
5055 u32 nuser;
5056
5057 eof = 1;
5058
5059 status = nfsd4_listxattr_validate_cookie(listxattrs, &offset);
5060 if (status)
5061 goto out;
5062
5063
5064
5065
5066
5067 cookie_offset = xdr->buf->len;
5068 count_offset = cookie_offset + 8;
5069 p = xdr_reserve_space(xdr, 12);
5070 if (!p) {
5071 status = nfserr_resource;
5072 goto out;
5073 }
5074
5075 count = 0;
5076 left = listxattrs->lsxa_len;
5077 sp = listxattrs->lsxa_buf;
5078 nuser = 0;
5079
5080 xdrleft = listxattrs->lsxa_maxcount;
5081
5082 while (left > 0 && xdrleft > 0) {
5083 slen = strlen(sp);
5084
5085
5086
5087
5088 if (strncmp(sp, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
5089 goto contloop;
5090
5091 slen -= XATTR_USER_PREFIX_LEN;
5092 xdrlen = 4 + ((slen + 3) & ~3);
5093 if (xdrlen > xdrleft) {
5094 if (count == 0) {
5095
5096
5097
5098 status = nfserr_toosmall;
5099 goto out;
5100 }
5101 eof = 0;
5102 goto wreof;
5103 }
5104
5105 left -= XATTR_USER_PREFIX_LEN;
5106 sp += XATTR_USER_PREFIX_LEN;
5107 if (nuser++ < offset)
5108 goto contloop;
5109
5110
5111 p = xdr_reserve_space(xdr, xdrlen);
5112 if (!p) {
5113 status = nfserr_resource;
5114 goto out;
5115 }
5116
5117 xdr_encode_opaque(p, sp, slen);
5118
5119 xdrleft -= xdrlen;
5120 count++;
5121 contloop:
5122 sp += slen + 1;
5123 left -= slen + 1;
5124 }
5125
5126
5127
5128
5129
5130 if (nuser > 0 && count == 0) {
5131 status = nfserr_badcookie;
5132 goto out;
5133 }
5134
5135 wreof:
5136 p = xdr_reserve_space(xdr, 4);
5137 if (!p) {
5138 status = nfserr_resource;
5139 goto out;
5140 }
5141 *p = cpu_to_be32(eof);
5142
5143 cookie = offset + count;
5144
5145 write_bytes_to_xdr_buf(xdr->buf, cookie_offset, &cookie, 8);
5146 tmp = cpu_to_be32(count);
5147 write_bytes_to_xdr_buf(xdr->buf, count_offset, &tmp, 4);
5148 out:
5149 if (listxattrs->lsxa_len)
5150 kvfree(listxattrs->lsxa_buf);
5151 return status;
5152 }
5153
5154 static __be32
5155 nfsd4_encode_removexattr(struct nfsd4_compoundres *resp, __be32 nfserr,
5156 struct nfsd4_removexattr *removexattr)
5157 {
5158 struct xdr_stream *xdr = resp->xdr;
5159 __be32 *p;
5160
5161 p = xdr_reserve_space(xdr, 20);
5162 if (!p)
5163 return nfserr_resource;
5164
5165 p = encode_cinfo(p, &removexattr->rmxa_cinfo);
5166 return 0;
5167 }
5168
5169 typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
5170
5171
5172
5173
5174
5175
5176 static const nfsd4_enc nfsd4_enc_ops[] = {
5177 [OP_ACCESS] = (nfsd4_enc)nfsd4_encode_access,
5178 [OP_CLOSE] = (nfsd4_enc)nfsd4_encode_close,
5179 [OP_COMMIT] = (nfsd4_enc)nfsd4_encode_commit,
5180 [OP_CREATE] = (nfsd4_enc)nfsd4_encode_create,
5181 [OP_DELEGPURGE] = (nfsd4_enc)nfsd4_encode_noop,
5182 [OP_DELEGRETURN] = (nfsd4_enc)nfsd4_encode_noop,
5183 [OP_GETATTR] = (nfsd4_enc)nfsd4_encode_getattr,
5184 [OP_GETFH] = (nfsd4_enc)nfsd4_encode_getfh,
5185 [OP_LINK] = (nfsd4_enc)nfsd4_encode_link,
5186 [OP_LOCK] = (nfsd4_enc)nfsd4_encode_lock,
5187 [OP_LOCKT] = (nfsd4_enc)nfsd4_encode_lockt,
5188 [OP_LOCKU] = (nfsd4_enc)nfsd4_encode_locku,
5189 [OP_LOOKUP] = (nfsd4_enc)nfsd4_encode_noop,
5190 [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop,
5191 [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop,
5192 [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open,
5193 [OP_OPENATTR] = (nfsd4_enc)nfsd4_encode_noop,
5194 [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm,
5195 [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade,
5196 [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop,
5197 [OP_PUTPUBFH] = (nfsd4_enc)nfsd4_encode_noop,
5198 [OP_PUTROOTFH] = (nfsd4_enc)nfsd4_encode_noop,
5199 [OP_READ] = (nfsd4_enc)nfsd4_encode_read,
5200 [OP_READDIR] = (nfsd4_enc)nfsd4_encode_readdir,
5201 [OP_READLINK] = (nfsd4_enc)nfsd4_encode_readlink,
5202 [OP_REMOVE] = (nfsd4_enc)nfsd4_encode_remove,
5203 [OP_RENAME] = (nfsd4_enc)nfsd4_encode_rename,
5204 [OP_RENEW] = (nfsd4_enc)nfsd4_encode_noop,
5205 [OP_RESTOREFH] = (nfsd4_enc)nfsd4_encode_noop,
5206 [OP_SAVEFH] = (nfsd4_enc)nfsd4_encode_noop,
5207 [OP_SECINFO] = (nfsd4_enc)nfsd4_encode_secinfo,
5208 [OP_SETATTR] = (nfsd4_enc)nfsd4_encode_setattr,
5209 [OP_SETCLIENTID] = (nfsd4_enc)nfsd4_encode_setclientid,
5210 [OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop,
5211 [OP_VERIFY] = (nfsd4_enc)nfsd4_encode_noop,
5212 [OP_WRITE] = (nfsd4_enc)nfsd4_encode_write,
5213 [OP_RELEASE_LOCKOWNER] = (nfsd4_enc)nfsd4_encode_noop,
5214
5215
5216 [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop,
5217 [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session,
5218 [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id,
5219 [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session,
5220 [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_noop,
5221 [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_noop,
5222 [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop,
5223 #ifdef CONFIG_NFSD_PNFS
5224 [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_getdeviceinfo,
5225 [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop,
5226 [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_layoutcommit,
5227 [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_layoutget,
5228 [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_layoutreturn,
5229 #else
5230 [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_noop,
5231 [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop,
5232 [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop,
5233 [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop,
5234 [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop,
5235 #endif
5236 [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo_no_name,
5237 [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence,
5238 [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop,
5239 [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_test_stateid,
5240 [OP_WANT_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop,
5241 [OP_DESTROY_CLIENTID] = (nfsd4_enc)nfsd4_encode_noop,
5242 [OP_RECLAIM_COMPLETE] = (nfsd4_enc)nfsd4_encode_noop,
5243
5244
5245 [OP_ALLOCATE] = (nfsd4_enc)nfsd4_encode_noop,
5246 [OP_COPY] = (nfsd4_enc)nfsd4_encode_copy,
5247 [OP_COPY_NOTIFY] = (nfsd4_enc)nfsd4_encode_copy_notify,
5248 [OP_DEALLOCATE] = (nfsd4_enc)nfsd4_encode_noop,
5249 [OP_IO_ADVISE] = (nfsd4_enc)nfsd4_encode_noop,
5250 [OP_LAYOUTERROR] = (nfsd4_enc)nfsd4_encode_noop,
5251 [OP_LAYOUTSTATS] = (nfsd4_enc)nfsd4_encode_noop,
5252 [OP_OFFLOAD_CANCEL] = (nfsd4_enc)nfsd4_encode_noop,
5253 [OP_OFFLOAD_STATUS] = (nfsd4_enc)nfsd4_encode_offload_status,
5254 [OP_READ_PLUS] = (nfsd4_enc)nfsd4_encode_read_plus,
5255 [OP_SEEK] = (nfsd4_enc)nfsd4_encode_seek,
5256 [OP_WRITE_SAME] = (nfsd4_enc)nfsd4_encode_noop,
5257 [OP_CLONE] = (nfsd4_enc)nfsd4_encode_noop,
5258
5259
5260 [OP_GETXATTR] = (nfsd4_enc)nfsd4_encode_getxattr,
5261 [OP_SETXATTR] = (nfsd4_enc)nfsd4_encode_setxattr,
5262 [OP_LISTXATTRS] = (nfsd4_enc)nfsd4_encode_listxattrs,
5263 [OP_REMOVEXATTR] = (nfsd4_enc)nfsd4_encode_removexattr,
5264 };
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279 __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 respsize)
5280 {
5281 struct xdr_buf *buf = &resp->rqstp->rq_res;
5282 struct nfsd4_slot *slot = resp->cstate.slot;
5283
5284 if (buf->len + respsize <= buf->buflen)
5285 return nfs_ok;
5286 if (!nfsd4_has_session(&resp->cstate))
5287 return nfserr_resource;
5288 if (slot->sl_flags & NFSD4_SLOT_CACHETHIS) {
5289 WARN_ON_ONCE(1);
5290 return nfserr_rep_too_big_to_cache;
5291 }
5292 return nfserr_rep_too_big;
5293 }
5294
5295 void
5296 nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
5297 {
5298 struct xdr_stream *xdr = resp->xdr;
5299 struct nfs4_stateowner *so = resp->cstate.replay_owner;
5300 struct svc_rqst *rqstp = resp->rqstp;
5301 const struct nfsd4_operation *opdesc = op->opdesc;
5302 int post_err_offset;
5303 nfsd4_enc encoder;
5304 __be32 *p;
5305
5306 p = xdr_reserve_space(xdr, 8);
5307 if (!p) {
5308 WARN_ON_ONCE(1);
5309 return;
5310 }
5311 *p++ = cpu_to_be32(op->opnum);
5312 post_err_offset = xdr->buf->len;
5313
5314 if (op->opnum == OP_ILLEGAL)
5315 goto status;
5316 if (op->status && opdesc &&
5317 !(opdesc->op_flags & OP_NONTRIVIAL_ERROR_ENCODE))
5318 goto status;
5319 BUG_ON(op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
5320 !nfsd4_enc_ops[op->opnum]);
5321 encoder = nfsd4_enc_ops[op->opnum];
5322 op->status = encoder(resp, op->status, &op->u);
5323 if (op->status)
5324 trace_nfsd_compound_encode_err(rqstp, op->opnum, op->status);
5325 if (opdesc && opdesc->op_release)
5326 opdesc->op_release(&op->u);
5327 xdr_commit_encode(xdr);
5328
5329
5330 if (!op->status) {
5331 int space_needed = 0;
5332 if (!nfsd4_last_compound_op(rqstp))
5333 space_needed = COMPOUND_ERR_SLACK_SPACE;
5334 op->status = nfsd4_check_resp_size(resp, space_needed);
5335 }
5336 if (op->status == nfserr_resource && nfsd4_has_session(&resp->cstate)) {
5337 struct nfsd4_slot *slot = resp->cstate.slot;
5338
5339 if (slot->sl_flags & NFSD4_SLOT_CACHETHIS)
5340 op->status = nfserr_rep_too_big_to_cache;
5341 else
5342 op->status = nfserr_rep_too_big;
5343 }
5344 if (op->status == nfserr_resource ||
5345 op->status == nfserr_rep_too_big ||
5346 op->status == nfserr_rep_too_big_to_cache) {
5347
5348
5349
5350
5351
5352
5353
5354 warn_on_nonidempotent_op(op);
5355 xdr_truncate_encode(xdr, post_err_offset);
5356 }
5357 if (so) {
5358 int len = xdr->buf->len - post_err_offset;
5359
5360 so->so_replay.rp_status = op->status;
5361 so->so_replay.rp_buflen = len;
5362 read_bytes_from_xdr_buf(xdr->buf, post_err_offset,
5363 so->so_replay.rp_buf, len);
5364 }
5365 status:
5366 *p = op->status;
5367 }
5368
5369
5370
5371
5372
5373
5374
5375 void
5376 nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op)
5377 {
5378 __be32 *p;
5379 struct nfs4_replay *rp = op->replay;
5380
5381 p = xdr_reserve_space(xdr, 8 + rp->rp_buflen);
5382 if (!p) {
5383 WARN_ON_ONCE(1);
5384 return;
5385 }
5386 *p++ = cpu_to_be32(op->opnum);
5387 *p++ = rp->rp_status;
5388
5389 p = xdr_encode_opaque_fixed(p, rp->rp_buf, rp->rp_buflen);
5390 }
5391
5392 void nfsd4_release_compoundargs(struct svc_rqst *rqstp)
5393 {
5394 struct nfsd4_compoundargs *args = rqstp->rq_argp;
5395
5396 if (args->ops != args->iops) {
5397 kfree(args->ops);
5398 args->ops = args->iops;
5399 }
5400 while (args->to_free) {
5401 struct svcxdr_tmpbuf *tb = args->to_free;
5402 args->to_free = tb->next;
5403 kfree(tb);
5404 }
5405 }
5406
5407 bool
5408 nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
5409 {
5410 struct nfsd4_compoundargs *args = rqstp->rq_argp;
5411
5412
5413 args->to_free = NULL;
5414
5415 args->xdr = xdr;
5416 args->ops = args->iops;
5417 args->rqstp = rqstp;
5418
5419 return nfsd4_decode_compound(args);
5420 }
5421
5422 bool
5423 nfs4svc_encode_compoundres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
5424 {
5425 struct nfsd4_compoundres *resp = rqstp->rq_resp;
5426 struct xdr_buf *buf = xdr->buf;
5427 __be32 *p;
5428
5429 WARN_ON_ONCE(buf->len != buf->head[0].iov_len + buf->page_len +
5430 buf->tail[0].iov_len);
5431
5432
5433
5434
5435
5436 p = resp->statusp;
5437
5438 *p++ = resp->cstate.status;
5439
5440 rqstp->rq_next_page = xdr->page_ptr + 1;
5441
5442 *p++ = htonl(resp->taglen);
5443 memcpy(p, resp->tag, resp->taglen);
5444 p += XDR_QUADLEN(resp->taglen);
5445 *p++ = htonl(resp->opcnt);
5446
5447 nfsd4_sequence_done(resp);
5448 return true;
5449 }