43 #include <linux/slab.h>
46 #include <linux/utsname.h>
57 #define NFSDDBG_FACILITY NFSDDBG_XDR
64 #define NFS4_REFERRAL_FSID_MAJOR 0x8000000ULL
65 #define NFS4_REFERRAL_FSID_MINOR 0x8000000ULL
76 for (i = 0; i < len; i++)
90 dprintk("NFSD: xdr error (%s:%d)\n", \
91 __FILE__, __LINE__); \
92 status = nfserr_bad_xdr; \
95 #define READ32(x) (x) = ntohl(*p++)
96 #define READ64(x) do { \
97 (x) = (u64)ntohl(*p++) << 32; \
100 #define READTIME(x) do { \
105 #define READMEM(x,nbytes) do { \
107 p += XDR_QUADLEN(nbytes); \
109 #define SAVEMEM(x,nbytes) do { \
110 if (!(x = (p==argp->tmp || p == argp->tmpp) ? \
111 savemem(argp, p, nbytes) : \
113 dprintk("NFSD: xdr error (%s:%d)\n", \
114 __FILE__, __LINE__); \
117 p += XDR_QUADLEN(nbytes); \
119 #define COPYMEM(x,nbytes) do { \
120 memcpy((x), p, nbytes); \
121 p += XDR_QUADLEN(nbytes); \
125 #define READ_BUF(nbytes) do { \
126 if (nbytes <= (u32)((char *)argp->end - (char *)argp->p)) { \
128 argp->p += XDR_QUADLEN(nbytes); \
129 } else if (!(p = read_buf(argp, nbytes))) { \
130 dprintk("NFSD: xdr error (%s:%d)\n", \
131 __FILE__, __LINE__); \
141 unsigned int avail = (
char *)argp->
end - (
char *)argp->
p;
143 if (avail + argp->
pagelen < nbytes)
148 if (nbytes <=
sizeof(argp->
tmp))
185 void (*
release)(
const void *),
void *
p)
201 if (p == argp->
tmp) {
209 if (defer_free(argp,
kfree, p)) {
246 int expected_len,
len = 0;
253 if ((
status = nfsd4_decode_bitmap(argp, bmval)))
280 defer_free(argp,
kfree, *acl);
282 (*acl)->naces = nace;
283 for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
290 len += XDR_QUADLEN(dummy32) << 2;
298 buf, dummy32, &ace->
who);
301 buf, dummy32, &ace->
who);
319 len += (XDR_QUADLEN(dummy32) << 2);
330 len += (XDR_QUADLEN(dummy32) << 2);
388 if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
389 || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
390 || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2)
392 else if (len != expected_len)
444 return nfsd4_decode_stateid(argp, &close->
cl_stateid);
472 READ32(create->cr_linklen);
474 SAVEMEM(create->cr_linkname, create->cr_linklen);
479 READ32(create->cr_specdata1);
480 READ32(create->cr_specdata2);
507 return nfsd4_decode_stateid(argp, &dr->
dr_stateid);
513 return nfsd4_decode_bitmap(argp, getattr->
ga_bmval);
550 READ32(lock->lk_new_open_seqid);
551 status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid);
555 READ32(lock->lk_new_lock_seqid);
557 READ32(lock->lk_new_owner.len);
559 READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len);
561 status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid);
565 READ32(lock->lk_old_lock_seqid);
637 switch (w & NFS4_SHARE_ACCESS_MASK) {
645 w &= ~NFS4_SHARE_ACCESS_MASK;
650 switch (w & NFS4_SHARE_WANT_MASK) {
661 w &= ~NFS4_SHARE_WANT_MASK;
716 open->op_iattr.ia_valid = 0;
747 &open->op_iattr, &open->
op_acl);
761 &open->op_iattr, &open->
op_acl);
907 READ32(remove->rm_namelen);
909 SAVEMEM(remove->rm_name, remove->rm_namelen);
980 status = nfsd4_decode_stateid(argp, &setattr->
sa_stateid);
995 status = nfsd4_decode_opaque(argp, &setclientid->
se_name);
1033 .rqstp = argp->
rqstp,
1036 struct iattr ve_iattr;
1041 if ((status = nfsd4_decode_bitmap(argp, verify->
ve_bmval)))
1048 status = nfsd4_decode_fattr(ve_bmval, &ve_iattr, &ve_acl);
1070 status = nfsd4_decode_stateid(argp, &write->
wr_stateid);
1084 avail = (
char*)argp->
end - (
char*)argp->
p;
1086 dprintk(
"NFSD: xdr error (%s:%d)\n",
1087 __FILE__, __LINE__);
1090 argp->
rqstp->rq_vec[0].iov_base =
p;
1094 while (len > argp->
rqstp->rq_vec[v].iov_len) {
1095 len -= argp->
rqstp->rq_vec[
v].iov_len;
1108 argp->
p = (
__be32*) (argp->
rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2));
1109 argp->
rqstp->rq_vec[
v].iov_len = len;
1141 status = nfsd4_decode_opaque(argp, &exid->
clname);
1186 p += XDR_QUADLEN(dummy);
1196 p += XDR_QUADLEN(dummy);
1220 p += XDR_QUADLEN(dummy);
1226 p += XDR_QUADLEN(dummy);
1264 dprintk(
"Too many fore channel attr bitmaps!\n");
1281 dprintk(
"Too many back channel attr bitmaps!\n");
1290 for (i = 0; i < nr_secflavs; ++
i) {
1318 dprintk(
"RPC_AUTH_GSS callback secflavor "
1319 "not supported!\n");
1326 p += XDR_QUADLEN(dummy);
1333 dprintk(
"Illegal callback secflavor\n");
1392 for (i = 0; i < test_stateid->
ts_num_ids; i++) {
1399 defer_free(argp,
kfree, stateid);
1403 status = nfsd4_decode_stateid(argp, &stateid->
ts_id_stateid);
1412 dprintk(
"NFSD: xdr error (%s:%d)\n", __FILE__, __LINE__);
1558 [0] = { nfsd4_dec_ops,
ARRAY_SIZE(nfsd4_dec_ops) },
1559 [1] = { nfsd41_dec_ops,
ARRAY_SIZE(nfsd41_dec_ops) },
1568 bool cachethis =
false;
1586 if (argp->
opcnt > 100)
1593 dprintk(
"nfsd: couldn't allocate room for COMPOUND\n");
1602 for (i = 0; i < argp->
opcnt; i++) {
1613 if (argp->
p == argp->
end) {
1664 #define WRITE32(n) *p++ = htonl(n)
1665 #define WRITE64(n) do { \
1666 *p++ = htonl((u32)((n) >> 32)); \
1667 *p++ = htonl((u32)(n)); \
1669 #define WRITEMEM(ptr,nbytes) do { if (nbytes > 0) { \
1670 *(p + XDR_QUADLEN(nbytes) -1) = 0; \
1671 memcpy(p, ptr, nbytes); \
1672 p += XDR_QUADLEN(nbytes); \
1682 write32(p, (n >> 32));
1691 write32(p, stat->
ctime.tv_sec);
1692 write32(p, stat->
ctime.tv_nsec);
1710 #define RESERVE_SPACE(nbytes) do { \
1712 BUG_ON(p + XDR_QUADLEN(nbytes) > resp->end); \
1714 #define ADJUST_ARGS() resp->p = p
1719 #define ENCODE_SEQID_OP_HEAD \
1735 if (seqid_mutating_err(
ntohl(nfserr)) && stateowner) {
1737 stateowner->
so_replay.rp_status = nfserr;
1739 (
char *)resp->
p - (
char *)save;
1749 static __be32 nfsd4_encode_components_esc(
char sep,
char *components,
1751 char esc_enter,
char esc_exit)
1758 dprintk(
"nfsd4_encode_components(%s)\n", components);
1759 if ((*buflen -= 4) < 0)
1762 end = str = components;
1764 bool found_esc =
false;
1767 if (*str == esc_enter) {
1768 for (; *end && (*end != esc_exit); end++)
1771 if (*end && (!*next || *next == sep)) {
1778 for (; *end && (*end != sep); end++)
1783 if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0)
1802 static __be32 nfsd4_encode_components(
char sep,
char *components,
1803 __be32 **pp,
int *buflen)
1805 return nfsd4_encode_components_esc(sep, components, pp, buflen, 0, 0);
1812 __be32 **pp,
int *buflen)
1817 status = nfsd4_encode_components_esc(
':', location->
hosts, &p, buflen,
1821 status = nfsd4_encode_components(
'/', location->
path, &p, buflen);
1831 static __be32 nfsd4_encode_path(
const struct path *root,
1840 unsigned int ncomponents = 0;
1843 dprintk(
"nfsd4_encode_components(");
1857 if ((ncomponents & 15) == 0) {
1860 sizeof(*
new) * (ncomponents + 16),
1866 components[ncomponents++] = cur.
dentry;
1875 while (ncomponents) {
1877 unsigned int len = dentry->
d_name.len;
1879 *buflen -= 4 + (XDR_QUADLEN(len) << 2);
1894 dput(components[--ncomponents]);
1901 const struct path *path,
__be32 **pp,
int *buflen)
1909 res = nfsd4_encode_path(&exp_ps->
ex_path, path, pp, buflen);
1919 __be32 **pp,
int *buflen)
1926 status = nfsd4_encode_fsloc_fsroot(rqstp, &exp->
ex_path, &p, buflen);
1929 if ((*buflen -= 4) < 0)
1933 status = nfsd4_encode_fs_location4(&fslocs->
locations[i],
1973 *buflen -= (XDR_QUADLEN(status) << 2) + 4;
1991 nfsd4_encode_aclname(
struct svc_rqst *rqstp,
int whotype,
uid_t id,
int group,
1994 return nfsd4_encode_name(rqstp, whotype,
id, group, p, buflen);
1997 #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
1998 FATTR4_WORD0_RDATTR_ERROR)
1999 #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
2001 static __be32 fattr_handle_absent_fs(
u32 *bmval0,
u32 *bmval1,
u32 *rdattr_err)
2027 struct svc_rqst *rqstp,
int ignore_crossmnt)
2029 u32 bmval0 = bmval[0];
2030 u32 bmval1 = bmval[1];
2031 u32 bmval2 = bmval[2];
2035 int buflen = *countp << 2;
2046 u32 minorversion = resp->
cstate.minorversion;
2047 struct path path = {
2052 BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
2053 BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion));
2054 BUG_ON(bmval1 & ~nfsd_suppattrs1(minorversion));
2055 BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion));
2059 status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err);
2084 err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
2085 aclsupport = (err == 0);
2086 if (bmval0 & FATTR4_WORD0_ACL) {
2088 bmval0 &= ~FATTR4_WORD0_ACL;
2089 else if (err == -
EINVAL) {
2092 }
else if (err != 0)
2098 if ((buflen -= 16) < 0)
2104 }
else if (bmval1) {
2105 if ((buflen -= 12) < 0)
2111 if ((buflen -= 8) < 0)
2119 u32 word0 = nfsd_suppattrs0(minorversion);
2120 u32 word1 = nfsd_suppattrs1(minorversion);
2121 u32 word2 = nfsd_suppattrs2(minorversion);
2124 word0 &= ~FATTR4_WORD0_ACL;
2126 if ((buflen -= 12) < 0)
2132 if ((buflen -= 16) < 0)
2141 if ((buflen -= 4) < 0)
2143 dummy = nfs4_file_type(stat.
mode);
2145 goto out_serverfault;
2149 if ((buflen -= 4) < 0)
2157 if ((buflen -= 8) < 0)
2159 write_change(&p, &stat, dentry->
d_inode);
2161 if (bmval0 & FATTR4_WORD0_SIZE) {
2162 if ((buflen -= 8) < 0)
2167 if ((buflen -= 4) < 0)
2172 if ((buflen -= 4) < 0)
2177 if ((buflen -= 4) < 0)
2182 if ((buflen -= 16) < 0)
2204 if ((buflen -= 4) < 0)
2209 if ((buflen -= 4) < 0)
2214 if ((buflen -= 4) < 0)
2218 if (bmval0 & FATTR4_WORD0_ACL) {
2222 if ((buflen -= 4) < 0)
2228 if ((buflen -= 4) < 0)
2232 for (ace = acl->
aces; ace < acl->aces + acl->
naces; ace++) {
2233 if ((buflen -= 4*3) < 0)
2238 status = nfsd4_encode_aclname(rqstp, ace->
whotype,
2249 if ((buflen -= 4) < 0)
2255 if ((buflen -= 4) < 0)
2260 if ((buflen -= 4) < 0)
2265 if ((buflen -= 4) < 0)
2270 if ((buflen -= 4) < 0)
2275 buflen -= (XDR_QUADLEN(fhp->
fh_handle.fh_size) << 2) + 4;
2282 if ((buflen -= 8) < 0)
2287 if ((buflen -= 8) < 0)
2292 if ((buflen -= 8) < 0)
2297 if ((buflen -= 8) < 0)
2302 status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen);
2309 if ((buflen -= 4) < 0)
2314 if ((buflen -= 8) < 0)
2319 if ((buflen -= 4) < 0)
2324 if ((buflen -= 4) < 0)
2329 if ((buflen -= 8) < 0)
2334 if ((buflen -= 8) < 0)
2338 if (bmval1 & FATTR4_WORD1_MODE) {
2339 if ((buflen -= 4) < 0)
2344 if ((buflen -= 4) < 0)
2349 if ((buflen -= 4) < 0)
2353 if (bmval1 & FATTR4_WORD1_OWNER) {
2354 status = nfsd4_encode_user(rqstp, stat.
uid, &p, &buflen);
2360 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
2361 status = nfsd4_encode_group(rqstp, stat.
gid, &p, &buflen);
2368 if ((buflen -= 8) < 0)
2374 if ((buflen -= 8) < 0)
2380 if ((buflen -= 8) < 0)
2386 if ((buflen -= 8) < 0)
2392 if ((buflen -= 8) < 0)
2398 if ((buflen -= 12) < 0)
2405 if ((buflen -= 12) < 0)
2412 if ((buflen -= 12) < 0)
2419 if ((buflen -= 12) < 0)
2426 if ((buflen -= 8) < 0)
2432 if (ignore_crossmnt == 0 &&
2433 dentry == exp->
ex_path.mnt->mnt_root) {
2434 struct path path = exp->
ex_path;
2449 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0);
2450 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD1);
2451 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD2);
2454 *attrlenp =
htonl((
char *)p - (
char *)attrlenp - 4);
2475 static inline int attributes_need_mount(
u32 *bmval)
2486 const char *
name,
int namlen,
__be32 *p,
int *buflen)
2489 struct dentry *dentry;
2491 int ignore_crossmnt = 0;
2518 && !attributes_need_mount(cd->
rd_bmval)) {
2519 ignore_crossmnt = 1;
2547 nfsd4_encode_rdattr_error(
__be32 *p,
int buflen,
__be32 nfserr)
2559 *attrlenp =
htonl((
char *)p - (
char *)attrlenp - 4);
2564 nfsd4_encode_dirent(
void *ccdv,
const char *name,
int namlen,
2575 if (name &&
isdotent(name, namlen)) {
2581 xdr_encode_hyper(cd->
offset, (
u64) offset);
2583 buflen = cd->
buflen - 4 - XDR_QUADLEN(namlen);
2590 p = xdr_encode_array(p, name, namlen);
2592 nfserr = nfsd4_encode_dirent_fattr(cd, name, namlen, p, &buflen);
2612 p = nfsd4_encode_rdattr_error(p, buflen, nfserr);
2675 nfsd4_encode_stateid(resp, &close->
cl_stateid);
2677 encode_seqid_op_tail(resp, save, nfserr);
2702 write_cinfo(&p, &create->
cr_cinfo);
2720 buflen = resp->
end - resp->
p - (COMPOUND_ERR_SLACK_SPACE >> 2);
2732 struct svc_fh *fhp = *fhpp;
2753 struct xdr_netobj *conf = &ld->
ld_owner;
2778 nfsd4_encode_stateid(resp, &lock->lk_resp_stateid);
2780 nfsd4_encode_lock_denied(resp, &lock->lk_denied);
2782 encode_seqid_op_tail(resp, save, nfserr);
2790 nfsd4_encode_lock_denied(resp, &lockt->
lt_denied);
2800 nfsd4_encode_stateid(resp, &locku->
lu_stateid);
2802 encode_seqid_op_tail(resp, save, nfserr);
2830 nfsd4_encode_stateid(resp, &open->
op_stateid);
2897 encode_seqid_op_tail(resp, save, nfserr);
2909 encode_seqid_op_tail(resp, save, nfserr);
2921 encode_seqid_op_tail(resp, save, nfserr);
2931 unsigned long maxcount;
2937 if (resp->
xbuf->page_len)
2949 pn = resp->
rqstp->rq_resused++;
2950 resp->
rqstp->rq_vec[
v].iov_base =
2952 resp->
rqstp->rq_vec[
v].iov_len =
2966 read->
rd_fhp->fh_dentry->d_inode->i_size);
2971 resp->
xbuf->head[0].iov_len = (
char*)p
2972 - (
char*)resp->
xbuf->head[0].iov_base;
2973 resp->
xbuf->page_len = maxcount;
2976 resp->
xbuf->tail[0].iov_base =
p;
2977 resp->
xbuf->tail[0].iov_len = 0;
2981 resp->
xbuf->tail[0].iov_base += maxcount&3;
2982 resp->
xbuf->tail[0].iov_len = 4 - (maxcount&3);
2997 if (resp->
xbuf->page_len)
3019 resp->
xbuf->head[0].iov_len = (
char*)p
3020 - (
char*)resp->
xbuf->head[0].iov_base;
3021 resp->
xbuf->page_len = maxcount;
3024 resp->
xbuf->tail[0].iov_base =
p;
3025 resp->
xbuf->tail[0].iov_len = 0;
3029 resp->
xbuf->tail[0].iov_base += maxcount&3;
3030 resp->
xbuf->tail[0].iov_len = 4 - (maxcount&3);
3046 if (resp->
xbuf->page_len)
3056 resp->
xbuf->head[0].iov_len = ((
char*)resp->
p) - (
char*)resp->
xbuf->head[0].iov_base;
3068 maxcount = (maxcount >> 2) - 4;
3076 readdir->
buflen = maxcount;
3083 &readdir->
common, nfsd4_encode_dirent);
3092 xdr_encode_hyper(readdir->
offset, offset);
3098 resp->
rqstp->rq_respages[resp->
rqstp->rq_resused-1]);
3101 resp->
xbuf->tail[0].iov_base = tailbase;
3102 resp->
xbuf->tail[0].iov_len = 0;
3103 resp->
p = resp->
xbuf->tail[0].iov_base;
3120 write_cinfo(&p, &remove->rm_cinfo);
3133 write_cinfo(&p, &rename->
rn_sinfo);
3134 write_cinfo(&p, &rename->
rn_tinfo);
3157 if (exp->
ex_client->flavour->flavour == RPC_AUTH_UNIX) {
3161 }
else if (exp->
ex_client->flavour->flavour == RPC_AUTH_GSS) {
3175 for (i = 0; i < nflavs; i++) {
3185 WRITEMEM(gm->gm_oid.data, gm->gm_oid.len);
3210 return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->
si_exp);
3217 return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->
sin_exp);
3287 int server_scope_sz;
3293 major_id = utsname()->nodename;
3294 major_id_sz =
strlen(major_id);
3295 server_scope = utsname()->nodename;
3296 server_scope_sz =
strlen(server_scope);
3305 (XDR_QUADLEN(major_id_sz) * 4) +
3307 (XDR_QUADLEN(server_scope_sz) * 4) +
3326 WRITEMEM(server_scope, server_scope_sz);
3534 struct xdr_buf *
xb = &resp->
rqstp->rq_res;
3539 if (!nfsd4_has_session(&resp->
cstate))
3542 session = resp->
cstate.session;
3543 if (session ==
NULL)
3546 if (xb->page_len == 0) {
3547 length = (
char *)resp->
p - (
char *)xb->head[0].iov_base +
pad;
3549 if (xb->tail[0].iov_base && xb->tail[0].iov_len > 0)
3550 tlen = (
char *)resp->
p - (
char *)xb->tail[0].iov_base;
3552 length = xb->head[0].iov_len + xb->page_len + tlen +
pad;
3554 dprintk(
"%s length %u, xb->page_len %u tlen %u pad %u\n", __func__,
3555 length, xb->page_len, tlen, pad);
3581 !nfsd4_enc_ops[op->
opnum]);
3623 return xdr_ressize_check(rqstp, p);
3631 if (args->
ops != args->
iops) {
3640 tb->release(tb->buf);
3650 args->
end = rqstp->
rq_arg.head[0].iov_base + rqstp->
rq_arg.head[0].iov_len;
3656 args->
rqstp = rqstp;
3658 return !nfsd4_decode_compound(args);
3672 p += XDR_QUADLEN(resp->
taglen);
3675 if (rqstp->
rq_res.page_len)
3676 iov = &rqstp->
rq_res.tail[0];
3678 iov = &rqstp->
rq_res.head[0];
3681 if (nfsd4_has_session(cs)) {