13 #define NFSDDBG_FACILITY NFSDDBG_XDR
19 static u32 nfs3_ftypes[] = {
55 return p + XDR_QUADLEN(size);
61 return decode_fh(p, fhp);
67 unsigned int size = fhp->
fh_handle.fh_size;
69 if (size) p[XDR_QUADLEN(size)-1]=0;
71 return p + XDR_QUADLEN(size);
79 decode_filename(
__be32 *p,
char **namp,
unsigned int *lenp)
85 for (i = 0, name = *namp; i < *lenp; i++, name++) {
86 if (*name ==
'\0' || *name ==
'/')
117 p = xdr_decode_hyper(p, &newsize);
123 if ((tmp =
ntohl(*p++)) == 1) {
125 }
else if (tmp == 2) {
130 if ((tmp =
ntohl(*p++)) == 1) {
132 }
else if (tmp == 2) {
146 p = xdr_encode_hyper(p, (
u64)huge_encode_dev
155 p = xdr_encode_hyper(p, f);
173 p = xdr_encode_hyper(p, (
u64) stat->
size);
175 p = xdr_encode_hyper(p, ((
u64)stat->
blocks) << 9);
178 p = encode_fsid(p, fhp);
179 p = xdr_encode_hyper(p, stat->
ino);
180 p = encode_time3(p, &stat->
atime);
181 p = encode_time3(p, &stat->
mtime);
182 p = encode_time3(p, &stat->
ctime);
192 return encode_fattr3(rqstp, p, fhp, &fhp->fh_post_attr);
204 if (dentry && dentry->
d_inode) {
212 return encode_fattr3(rqstp, p, fhp, &stat);
223 return encode_post_op_attr(rqstp, p, fhp);
234 if (dentry && dentry->
d_inode && fhp->fh_post_saved) {
235 if (fhp->fh_pre_saved) {
237 p = xdr_encode_hyper(p, (
u64) fhp->fh_pre_size);
238 p = encode_time3(p, &fhp->fh_pre_mtime);
239 p = encode_time3(p, &fhp->fh_pre_ctime);
243 return encode_saved_post_attr(rqstp, p, fhp);
247 return encode_post_op_attr(rqstp, p, fhp);
257 if (fhp->fh_post_saved)
258 printk(
"nfsd: inode locked twice during operation.\n");
262 fhp->fh_post_change = fhp->
fh_dentry->d_inode->i_version;
264 fhp->fh_post_saved = 0;
266 fhp->fh_post_attr.ctime = fhp->
fh_dentry->d_inode->i_ctime;
268 fhp->fh_post_saved = 1;
277 if (!(p = decode_fh(p, &args->
fh)))
279 return xdr_argsize_check(rqstp, p);
286 if (!(p = decode_fh(p, &args->
fh)))
288 p = decode_sattr3(p, &args->
attrs);
292 p = decode_time3(p, &time);
296 return xdr_argsize_check(rqstp, p);
303 if (!(p = decode_fh(p, &args->
fh))
304 || !(p = decode_filename(p, &args->
name, &args->
len)))
307 return xdr_argsize_check(rqstp, p);
314 if (!(p = decode_fh(p, &args->
fh)))
318 return xdr_argsize_check(rqstp, p);
329 if (!(p = decode_fh(p, &args->
fh)))
331 p = xdr_decode_hyper(p, &args->
offset);
335 if (len > max_blocksize)
344 len -= rqstp->
rq_vec[
v].iov_len;
348 return xdr_argsize_check(rqstp, p);
358 if (!(p = decode_fh(p, &args->
fh)))
360 p = xdr_decode_hyper(p, &args->
offset);
375 hdr = (
void*)p - rqstp->
rq_arg.head[0].iov_base;
376 dlen = rqstp->
rq_arg.head[0].iov_len + rqstp->
rq_arg.page_len
386 if (dlen < XDR_QUADLEN(len)*4)
389 if (args->
count > max_blocksize) {
390 args->
count = max_blocksize;
391 len = args->
len = max_blocksize;
393 rqstp->
rq_vec[0].iov_base = (
void*)p;
396 while (len > rqstp->
rq_vec[v].iov_len) {
397 len -= rqstp->
rq_vec[
v].iov_len;
402 rqstp->
rq_vec[
v].iov_len = len;
411 if (!(p = decode_fh(p, &args->
fh))
412 || !(p = decode_filename(p, &args->
name, &args->
len)))
418 p = decode_sattr3(p, &args->
attrs);
428 return xdr_argsize_check(rqstp, p);
434 if (!(p = decode_fh(p, &args->
fh)) ||
435 !(p = decode_filename(p, &args->
name, &args->
len)))
437 p = decode_sattr3(p, &args->
attrs);
439 return xdr_argsize_check(rqstp, p);
450 if (!(p = decode_fh(p, &args->
ffh)) ||
451 !(p = decode_filename(p, &args->
fname, &args->
flen))
454 p = decode_sattr3(p, &args->
attrs);
469 vec = &rqstp->
rq_arg.head[0];
471 while (len && avail && *old) {
477 if (len && !avail && rqstp->
rq_arg.page_len) {
478 avail = rqstp->
rq_arg.page_len;
483 while (len && avail && *old) {
499 if (!(p = decode_fh(p, &args->
fh))
500 || !(p = decode_filename(p, &args->
name, &args->
len)))
507 p = decode_sattr3(p, &args->
attrs);
514 return xdr_argsize_check(rqstp, p);
521 if (!(p = decode_fh(p, &args->
ffh))
522 || !(p = decode_filename(p, &args->
fname, &args->
flen))
523 || !(p = decode_fh(p, &args->
tfh))
524 || !(p = decode_filename(p, &args->
tname, &args->
tlen)))
527 return xdr_argsize_check(rqstp, p);
534 if (!(p = decode_fh(p, &args->
fh)))
539 return xdr_argsize_check(rqstp, p);
546 if (!(p = decode_fh(p, &args->
ffh))
547 || !(p = decode_fh(p, &args->
tfh))
548 || !(p = decode_filename(p, &args->
tname, &args->
tlen)))
551 return xdr_argsize_check(rqstp, p);
558 if (!(p = decode_fh(p, &args->
fh)))
560 p = xdr_decode_hyper(p, &args->
cookie);
561 args->
verf =
p; p += 2;
571 return xdr_argsize_check(rqstp, p);
581 if (!(p = decode_fh(p, &args->
fh)))
583 p = xdr_decode_hyper(p, &args->
cookie);
584 args->
verf =
p; p += 2;
588 len = (args->
count > max_blocksize) ? max_blocksize :
599 return xdr_argsize_check(rqstp, p);
606 if (!(p = decode_fh(p, &args->
fh)))
608 p = xdr_decode_hyper(p, &args->
offset);
611 return xdr_argsize_check(rqstp, p);
624 return xdr_ressize_check(rqstp, p);
635 p = encode_fattr3(rqstp, p, &resp->
fh, &resp->
stat);
637 return xdr_ressize_check(rqstp, p);
645 p = encode_wcc_data(rqstp, p, &resp->
fh);
646 return xdr_ressize_check(rqstp, p);
655 p = encode_fh(p, &resp->
fh);
656 p = encode_post_op_attr(rqstp, p, &resp->
fh);
658 p = encode_post_op_attr(rqstp, p, &resp->
dirfh);
659 return xdr_ressize_check(rqstp, p);
667 p = encode_post_op_attr(rqstp, p, &resp->
fh);
670 return xdr_ressize_check(rqstp, p);
678 p = encode_post_op_attr(rqstp, p, &resp->
fh);
681 xdr_ressize_check(rqstp, p);
685 rqstp->
rq_res.tail[0].iov_base =
p;
687 rqstp->
rq_res.tail[0].iov_len = 4 - (resp->
len&3);
691 return xdr_ressize_check(rqstp, p);
699 p = encode_post_op_attr(rqstp, p, &resp->
fh);
704 xdr_ressize_check(rqstp, p);
707 if (resp->
count & 3) {
709 rqstp->
rq_res.tail[0].iov_base =
p;
711 rqstp->
rq_res.tail[0].iov_len = 4 - (resp->
count & 3);
715 return xdr_ressize_check(rqstp, p);
723 p = encode_wcc_data(rqstp, p, &resp->
fh);
730 return xdr_ressize_check(rqstp, p);
740 p = encode_fh(p, &resp->
fh);
741 p = encode_post_op_attr(rqstp, p, &resp->
fh);
743 p = encode_wcc_data(rqstp, p, &resp->
dirfh);
744 return xdr_ressize_check(rqstp, p);
752 p = encode_wcc_data(rqstp, p, &resp->
ffh);
753 p = encode_wcc_data(rqstp, p, &resp->
tfh);
754 return xdr_ressize_check(rqstp, p);
762 p = encode_post_op_attr(rqstp, p, &resp->
fh);
763 p = encode_wcc_data(rqstp, p, &resp->
tfh);
764 return xdr_ressize_check(rqstp, p);
772 p = encode_post_op_attr(rqstp, p, &resp->
fh);
777 xdr_ressize_check(rqstp, p);
783 rqstp->
rq_res.tail[0].iov_base =
p;
786 rqstp->
rq_res.tail[0].iov_len = 2<<2;
789 return xdr_ressize_check(rqstp, p);
797 p = xdr_encode_hyper(p, ino);
798 p = xdr_encode_array(p, name, namlen);
808 const char *name,
int namlen)
811 struct dentry *dparent, *dchild;
814 dparent = cd->
fh.fh_dentry;
815 exp = cd->
fh.fh_export;
821 if (dchild == dparent)
824 dchild = dget(dparent);
829 if (d_mountpoint(dchild))
845 err = compose_entry_fh(cd, &fh, name, namlen);
851 p = encode_post_op_attr(cd->
rqstp, p, &fh);
853 p = encode_fh(p, &fh);
869 #define NFS3_ENTRY_BAGGAGE (2 + 1 + 2 + 1)
870 #define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2))
872 encode_entry(
struct readdir_cd *ccd,
const char *name,
int namlen,
882 int num_entry_words = 0;
893 xdr_encode_hyper(cd->
offset, offset64);
906 slen = XDR_QUADLEN(namlen);
916 for (pn=1; pn < cd->
rqstp->rq_resused; pn++) {
927 p = encode_entry_baggage(cd, p, name, namlen, ino);
930 p = encode_entryplus_baggage(cd, p, name, namlen);
931 num_entry_words = p - cd->
buffer;
932 }
else if (cd->
rqstp->rq_respages[pn+1] !=
NULL) {
941 p1 = encode_entry_baggage(cd, p1, name, namlen, ino);
944 p1 = encode_entryplus_baggage(cd, p1, name, namlen);
947 num_entry_words = p1 -
tmp;
949 if ((num_entry_words << 2) < len1) {
953 memmove(p, tmp, num_entry_words << 2);
954 p += num_entry_words;
959 unsigned int offset_r = (cd->
offset -
tmp) << 2;
968 if (offset_r + 8 <= len1) {
970 }
else if (offset_r >= len1) {
974 BUG_ON(offset_r != len1 - 4);
979 len2 = (num_entry_words << 2) - len1;
985 p = tmp + (len2 >> 2);
993 cd->
buflen -= num_entry_words;
1002 int namlen, loff_t
offset,
u64 ino,
unsigned int d_type)
1004 return encode_entry(cd, name, namlen, offset, ino, d_type, 0);
1010 unsigned int d_type)
1012 return encode_entry(cd, name, namlen, offset, ino, d_type, 1);
1026 p = xdr_encode_hyper(p, bs * s->
f_blocks);
1027 p = xdr_encode_hyper(p, bs * s->
f_bfree);
1028 p = xdr_encode_hyper(p, bs * s->
f_bavail);
1029 p = xdr_encode_hyper(p, s->
f_files);
1030 p = xdr_encode_hyper(p, s->
f_ffree);
1031 p = xdr_encode_hyper(p, s->
f_ffree);
1034 return xdr_ressize_check(rqstp, p);
1058 return xdr_ressize_check(rqstp, p);
1077 return xdr_ressize_check(rqstp, p);
1085 p = encode_wcc_data(rqstp, p, &resp->
fh);
1091 return xdr_ressize_check(rqstp, p);