nfs3xdr.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131
  1. /*
  2. * linux/fs/nfsd/nfs3xdr.c
  3. *
  4. * XDR support for nfsd/protocol version 3.
  5. *
  6. * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
  7. *
  8. * 2003-08-09 Jamie Lokier: Use htonl() for nanoseconds, not htons()!
  9. */
  10. #include <linux/types.h>
  11. #include <linux/time.h>
  12. #include <linux/nfs3.h>
  13. #include <linux/list.h>
  14. #include <linux/spinlock.h>
  15. #include <linux/dcache.h>
  16. #include <linux/namei.h>
  17. #include <linux/mm.h>
  18. #include <linux/vfs.h>
  19. #include <linux/sunrpc/xdr.h>
  20. #include <linux/sunrpc/svc.h>
  21. #include <linux/nfsd/nfsd.h>
  22. #include <linux/nfsd/xdr3.h>
  23. #include "auth.h"
  24. #define NFSDDBG_FACILITY NFSDDBG_XDR
  25. /*
  26. * Mapping of S_IF* types to NFS file types
  27. */
  28. static u32 nfs3_ftypes[] = {
  29. NF3NON, NF3FIFO, NF3CHR, NF3BAD,
  30. NF3DIR, NF3BAD, NF3BLK, NF3BAD,
  31. NF3REG, NF3BAD, NF3LNK, NF3BAD,
  32. NF3SOCK, NF3BAD, NF3LNK, NF3BAD,
  33. };
  34. /*
  35. * XDR functions for basic NFS types
  36. */
  37. static __be32 *
  38. encode_time3(__be32 *p, struct timespec *time)
  39. {
  40. *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec);
  41. return p;
  42. }
  43. static __be32 *
  44. decode_time3(__be32 *p, struct timespec *time)
  45. {
  46. time->tv_sec = ntohl(*p++);
  47. time->tv_nsec = ntohl(*p++);
  48. return p;
  49. }
  50. static __be32 *
  51. decode_fh(__be32 *p, struct svc_fh *fhp)
  52. {
  53. unsigned int size;
  54. fh_init(fhp, NFS3_FHSIZE);
  55. size = ntohl(*p++);
  56. if (size > NFS3_FHSIZE)
  57. return NULL;
  58. memcpy(&fhp->fh_handle.fh_base, p, size);
  59. fhp->fh_handle.fh_size = size;
  60. return p + XDR_QUADLEN(size);
  61. }
  62. /* Helper function for NFSv3 ACL code */
  63. __be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp)
  64. {
  65. return decode_fh(p, fhp);
  66. }
  67. static __be32 *
  68. encode_fh(__be32 *p, struct svc_fh *fhp)
  69. {
  70. unsigned int size = fhp->fh_handle.fh_size;
  71. *p++ = htonl(size);
  72. if (size) p[XDR_QUADLEN(size)-1]=0;
  73. memcpy(p, &fhp->fh_handle.fh_base, size);
  74. return p + XDR_QUADLEN(size);
  75. }
  76. /*
  77. * Decode a file name and make sure that the path contains
  78. * no slashes or null bytes.
  79. */
  80. static __be32 *
  81. decode_filename(__be32 *p, char **namp, unsigned int *lenp)
  82. {
  83. char *name;
  84. unsigned int i;
  85. if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS3_MAXNAMLEN)) != NULL) {
  86. for (i = 0, name = *namp; i < *lenp; i++, name++) {
  87. if (*name == '\0' || *name == '/')
  88. return NULL;
  89. }
  90. }
  91. return p;
  92. }
  93. static __be32 *
  94. decode_sattr3(__be32 *p, struct iattr *iap)
  95. {
  96. u32 tmp;
  97. iap->ia_valid = 0;
  98. if (*p++) {
  99. iap->ia_valid |= ATTR_MODE;
  100. iap->ia_mode = ntohl(*p++);
  101. }
  102. if (*p++) {
  103. iap->ia_valid |= ATTR_UID;
  104. iap->ia_uid = ntohl(*p++);
  105. }
  106. if (*p++) {
  107. iap->ia_valid |= ATTR_GID;
  108. iap->ia_gid = ntohl(*p++);
  109. }
  110. if (*p++) {
  111. u64 newsize;
  112. iap->ia_valid |= ATTR_SIZE;
  113. p = xdr_decode_hyper(p, &newsize);
  114. if (newsize <= NFS_OFFSET_MAX)
  115. iap->ia_size = newsize;
  116. else
  117. iap->ia_size = NFS_OFFSET_MAX;
  118. }
  119. if ((tmp = ntohl(*p++)) == 1) { /* set to server time */
  120. iap->ia_valid |= ATTR_ATIME;
  121. } else if (tmp == 2) { /* set to client time */
  122. iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
  123. iap->ia_atime.tv_sec = ntohl(*p++);
  124. iap->ia_atime.tv_nsec = ntohl(*p++);
  125. }
  126. if ((tmp = ntohl(*p++)) == 1) { /* set to server time */
  127. iap->ia_valid |= ATTR_MTIME;
  128. } else if (tmp == 2) { /* set to client time */
  129. iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
  130. iap->ia_mtime.tv_sec = ntohl(*p++);
  131. iap->ia_mtime.tv_nsec = ntohl(*p++);
  132. }
  133. return p;
  134. }
  135. static __be32 *encode_fsid(__be32 *p, struct svc_fh *fhp)
  136. {
  137. u64 f;
  138. switch(fsid_source(fhp)) {
  139. default:
  140. case FSIDSOURCE_DEV:
  141. p = xdr_encode_hyper(p, (u64)huge_encode_dev
  142. (fhp->fh_dentry->d_inode->i_sb->s_dev));
  143. break;
  144. case FSIDSOURCE_FSID:
  145. p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
  146. break;
  147. case FSIDSOURCE_UUID:
  148. f = ((u64*)fhp->fh_export->ex_uuid)[0];
  149. f ^= ((u64*)fhp->fh_export->ex_uuid)[1];
  150. p = xdr_encode_hyper(p, f);
  151. break;
  152. }
  153. return p;
  154. }
  155. static __be32 *
  156. encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
  157. struct kstat *stat)
  158. {
  159. *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
  160. *p++ = htonl((u32) stat->mode);
  161. *p++ = htonl((u32) stat->nlink);
  162. *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
  163. *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
  164. if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
  165. p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
  166. } else {
  167. p = xdr_encode_hyper(p, (u64) stat->size);
  168. }
  169. p = xdr_encode_hyper(p, ((u64)stat->blocks) << 9);
  170. *p++ = htonl((u32) MAJOR(stat->rdev));
  171. *p++ = htonl((u32) MINOR(stat->rdev));
  172. p = encode_fsid(p, fhp);
  173. p = xdr_encode_hyper(p, stat->ino);
  174. p = encode_time3(p, &stat->atime);
  175. p = encode_time3(p, &stat->mtime);
  176. p = encode_time3(p, &stat->ctime);
  177. return p;
  178. }
  179. static __be32 *
  180. encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
  181. {
  182. /* Attributes to follow */
  183. *p++ = xdr_one;
  184. return encode_fattr3(rqstp, p, fhp, &fhp->fh_post_attr);
  185. }
  186. /*
  187. * Encode post-operation attributes.
  188. * The inode may be NULL if the call failed because of a stale file
  189. * handle. In this case, no attributes are returned.
  190. */
  191. static __be32 *
  192. encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
  193. {
  194. struct dentry *dentry = fhp->fh_dentry;
  195. if (dentry && dentry->d_inode) {
  196. int err;
  197. struct kstat stat;
  198. err = vfs_getattr(fhp->fh_export->ex_path.mnt, dentry, &stat);
  199. if (!err) {
  200. *p++ = xdr_one; /* attributes follow */
  201. lease_get_mtime(dentry->d_inode, &stat.mtime);
  202. return encode_fattr3(rqstp, p, fhp, &stat);
  203. }
  204. }
  205. *p++ = xdr_zero;
  206. return p;
  207. }
  208. /* Helper for NFSv3 ACLs */
  209. __be32 *
  210. nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
  211. {
  212. return encode_post_op_attr(rqstp, p, fhp);
  213. }
  214. /*
  215. * Enocde weak cache consistency data
  216. */
  217. static __be32 *
  218. encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
  219. {
  220. struct dentry *dentry = fhp->fh_dentry;
  221. if (dentry && dentry->d_inode && fhp->fh_post_saved) {
  222. if (fhp->fh_pre_saved) {
  223. *p++ = xdr_one;
  224. p = xdr_encode_hyper(p, (u64) fhp->fh_pre_size);
  225. p = encode_time3(p, &fhp->fh_pre_mtime);
  226. p = encode_time3(p, &fhp->fh_pre_ctime);
  227. } else {
  228. *p++ = xdr_zero;
  229. }
  230. return encode_saved_post_attr(rqstp, p, fhp);
  231. }
  232. /* no pre- or post-attrs */
  233. *p++ = xdr_zero;
  234. return encode_post_op_attr(rqstp, p, fhp);
  235. }
  236. /*
  237. * Fill in the post_op attr for the wcc data
  238. */
  239. void fill_post_wcc(struct svc_fh *fhp)
  240. {
  241. int err;
  242. if (fhp->fh_post_saved)
  243. printk("nfsd: inode locked twice during operation.\n");
  244. err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry,
  245. &fhp->fh_post_attr);
  246. if (err)
  247. fhp->fh_post_saved = 0;
  248. else
  249. fhp->fh_post_saved = 1;
  250. }
  251. /*
  252. * XDR decode functions
  253. */
  254. int
  255. nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args)
  256. {
  257. if (!(p = decode_fh(p, &args->fh)))
  258. return 0;
  259. return xdr_argsize_check(rqstp, p);
  260. }
  261. int
  262. nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p,
  263. struct nfsd3_sattrargs *args)
  264. {
  265. if (!(p = decode_fh(p, &args->fh)))
  266. return 0;
  267. p = decode_sattr3(p, &args->attrs);
  268. if ((args->check_guard = ntohl(*p++)) != 0) {
  269. struct timespec time;
  270. p = decode_time3(p, &time);
  271. args->guardtime = time.tv_sec;
  272. }
  273. return xdr_argsize_check(rqstp, p);
  274. }
  275. int
  276. nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p,
  277. struct nfsd3_diropargs *args)
  278. {
  279. if (!(p = decode_fh(p, &args->fh))
  280. || !(p = decode_filename(p, &args->name, &args->len)))
  281. return 0;
  282. return xdr_argsize_check(rqstp, p);
  283. }
  284. int
  285. nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p,
  286. struct nfsd3_accessargs *args)
  287. {
  288. if (!(p = decode_fh(p, &args->fh)))
  289. return 0;
  290. args->access = ntohl(*p++);
  291. return xdr_argsize_check(rqstp, p);
  292. }
  293. int
  294. nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
  295. struct nfsd3_readargs *args)
  296. {
  297. unsigned int len;
  298. int v,pn;
  299. u32 max_blocksize = svc_max_payload(rqstp);
  300. if (!(p = decode_fh(p, &args->fh)))
  301. return 0;
  302. p = xdr_decode_hyper(p, &args->offset);
  303. len = args->count = ntohl(*p++);
  304. if (len > max_blocksize)
  305. len = max_blocksize;
  306. /* set up the kvec */
  307. v=0;
  308. while (len > 0) {
  309. pn = rqstp->rq_resused++;
  310. rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
  311. rqstp->rq_vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE;
  312. len -= rqstp->rq_vec[v].iov_len;
  313. v++;
  314. }
  315. args->vlen = v;
  316. return xdr_argsize_check(rqstp, p);
  317. }
  318. int
  319. nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
  320. struct nfsd3_writeargs *args)
  321. {
  322. unsigned int len, v, hdr, dlen;
  323. u32 max_blocksize = svc_max_payload(rqstp);
  324. if (!(p = decode_fh(p, &args->fh)))
  325. return 0;
  326. p = xdr_decode_hyper(p, &args->offset);
  327. args->count = ntohl(*p++);
  328. args->stable = ntohl(*p++);
  329. len = args->len = ntohl(*p++);
  330. /*
  331. * The count must equal the amount of data passed.
  332. */
  333. if (args->count != args->len)
  334. return 0;
  335. /*
  336. * Check to make sure that we got the right number of
  337. * bytes.
  338. */
  339. hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
  340. dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len
  341. - hdr;
  342. /*
  343. * Round the length of the data which was specified up to
  344. * the next multiple of XDR units and then compare that
  345. * against the length which was actually received.
  346. * Note that when RPCSEC/GSS (for example) is used, the
  347. * data buffer can be padded so dlen might be larger
  348. * than required. It must never be smaller.
  349. */
  350. if (dlen < XDR_QUADLEN(len)*4)
  351. return 0;
  352. if (args->count > max_blocksize) {
  353. args->count = max_blocksize;
  354. len = args->len = max_blocksize;
  355. }
  356. rqstp->rq_vec[0].iov_base = (void*)p;
  357. rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
  358. v = 0;
  359. while (len > rqstp->rq_vec[v].iov_len) {
  360. len -= rqstp->rq_vec[v].iov_len;
  361. v++;
  362. rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_pages[v]);
  363. rqstp->rq_vec[v].iov_len = PAGE_SIZE;
  364. }
  365. rqstp->rq_vec[v].iov_len = len;
  366. args->vlen = v + 1;
  367. return 1;
  368. }
  369. int
  370. nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p,
  371. struct nfsd3_createargs *args)
  372. {
  373. if (!(p = decode_fh(p, &args->fh))
  374. || !(p = decode_filename(p, &args->name, &args->len)))
  375. return 0;
  376. switch (args->createmode = ntohl(*p++)) {
  377. case NFS3_CREATE_UNCHECKED:
  378. case NFS3_CREATE_GUARDED:
  379. p = decode_sattr3(p, &args->attrs);
  380. break;
  381. case NFS3_CREATE_EXCLUSIVE:
  382. args->verf = p;
  383. p += 2;
  384. break;
  385. default:
  386. return 0;
  387. }
  388. return xdr_argsize_check(rqstp, p);
  389. }
  390. int
  391. nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p,
  392. struct nfsd3_createargs *args)
  393. {
  394. if (!(p = decode_fh(p, &args->fh)) ||
  395. !(p = decode_filename(p, &args->name, &args->len)))
  396. return 0;
  397. p = decode_sattr3(p, &args->attrs);
  398. return xdr_argsize_check(rqstp, p);
  399. }
  400. int
  401. nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
  402. struct nfsd3_symlinkargs *args)
  403. {
  404. unsigned int len, avail;
  405. char *old, *new;
  406. struct kvec *vec;
  407. if (!(p = decode_fh(p, &args->ffh)) ||
  408. !(p = decode_filename(p, &args->fname, &args->flen))
  409. )
  410. return 0;
  411. p = decode_sattr3(p, &args->attrs);
  412. /* now decode the pathname, which might be larger than the first page.
  413. * As we have to check for nul's anyway, we copy it into a new page
  414. * This page appears in the rq_res.pages list, but as pages_len is always
  415. * 0, it won't get in the way
  416. */
  417. len = ntohl(*p++);
  418. if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
  419. return 0;
  420. args->tname = new =
  421. page_address(rqstp->rq_respages[rqstp->rq_resused++]);
  422. args->tlen = len;
  423. /* first copy and check from the first page */
  424. old = (char*)p;
  425. vec = &rqstp->rq_arg.head[0];
  426. avail = vec->iov_len - (old - (char*)vec->iov_base);
  427. while (len && avail && *old) {
  428. *new++ = *old++;
  429. len--;
  430. avail--;
  431. }
  432. /* now copy next page if there is one */
  433. if (len && !avail && rqstp->rq_arg.page_len) {
  434. avail = rqstp->rq_arg.page_len;
  435. if (avail > PAGE_SIZE)
  436. avail = PAGE_SIZE;
  437. old = page_address(rqstp->rq_arg.pages[0]);
  438. }
  439. while (len && avail && *old) {
  440. *new++ = *old++;
  441. len--;
  442. avail--;
  443. }
  444. *new = '\0';
  445. if (len)
  446. return 0;
  447. return 1;
  448. }
  449. int
  450. nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p,
  451. struct nfsd3_mknodargs *args)
  452. {
  453. if (!(p = decode_fh(p, &args->fh))
  454. || !(p = decode_filename(p, &args->name, &args->len)))
  455. return 0;
  456. args->ftype = ntohl(*p++);
  457. if (args->ftype == NF3BLK || args->ftype == NF3CHR
  458. || args->ftype == NF3SOCK || args->ftype == NF3FIFO)
  459. p = decode_sattr3(p, &args->attrs);
  460. if (args->ftype == NF3BLK || args->ftype == NF3CHR) {
  461. args->major = ntohl(*p++);
  462. args->minor = ntohl(*p++);
  463. }
  464. return xdr_argsize_check(rqstp, p);
  465. }
  466. int
  467. nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p,
  468. struct nfsd3_renameargs *args)
  469. {
  470. if (!(p = decode_fh(p, &args->ffh))
  471. || !(p = decode_filename(p, &args->fname, &args->flen))
  472. || !(p = decode_fh(p, &args->tfh))
  473. || !(p = decode_filename(p, &args->tname, &args->tlen)))
  474. return 0;
  475. return xdr_argsize_check(rqstp, p);
  476. }
  477. int
  478. nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p,
  479. struct nfsd3_readlinkargs *args)
  480. {
  481. if (!(p = decode_fh(p, &args->fh)))
  482. return 0;
  483. args->buffer =
  484. page_address(rqstp->rq_respages[rqstp->rq_resused++]);
  485. return xdr_argsize_check(rqstp, p);
  486. }
  487. int
  488. nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p,
  489. struct nfsd3_linkargs *args)
  490. {
  491. if (!(p = decode_fh(p, &args->ffh))
  492. || !(p = decode_fh(p, &args->tfh))
  493. || !(p = decode_filename(p, &args->tname, &args->tlen)))
  494. return 0;
  495. return xdr_argsize_check(rqstp, p);
  496. }
  497. int
  498. nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
  499. struct nfsd3_readdirargs *args)
  500. {
  501. if (!(p = decode_fh(p, &args->fh)))
  502. return 0;
  503. p = xdr_decode_hyper(p, &args->cookie);
  504. args->verf = p; p += 2;
  505. args->dircount = ~0;
  506. args->count = ntohl(*p++);
  507. if (args->count > PAGE_SIZE)
  508. args->count = PAGE_SIZE;
  509. args->buffer =
  510. page_address(rqstp->rq_respages[rqstp->rq_resused++]);
  511. return xdr_argsize_check(rqstp, p);
  512. }
  513. int
  514. nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p,
  515. struct nfsd3_readdirargs *args)
  516. {
  517. int len, pn;
  518. u32 max_blocksize = svc_max_payload(rqstp);
  519. if (!(p = decode_fh(p, &args->fh)))
  520. return 0;
  521. p = xdr_decode_hyper(p, &args->cookie);
  522. args->verf = p; p += 2;
  523. args->dircount = ntohl(*p++);
  524. args->count = ntohl(*p++);
  525. len = (args->count > max_blocksize) ? max_blocksize :
  526. args->count;
  527. args->count = len;
  528. while (len > 0) {
  529. pn = rqstp->rq_resused++;
  530. if (!args->buffer)
  531. args->buffer = page_address(rqstp->rq_respages[pn]);
  532. len -= PAGE_SIZE;
  533. }
  534. return xdr_argsize_check(rqstp, p);
  535. }
  536. int
  537. nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p,
  538. struct nfsd3_commitargs *args)
  539. {
  540. if (!(p = decode_fh(p, &args->fh)))
  541. return 0;
  542. p = xdr_decode_hyper(p, &args->offset);
  543. args->count = ntohl(*p++);
  544. return xdr_argsize_check(rqstp, p);
  545. }
  546. /*
  547. * XDR encode functions
  548. */
  549. /*
  550. * There must be an encoding function for void results so svc_process
  551. * will work properly.
  552. */
  553. int
  554. nfs3svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
  555. {
  556. return xdr_ressize_check(rqstp, p);
  557. }
  558. /* GETATTR */
  559. int
  560. nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p,
  561. struct nfsd3_attrstat *resp)
  562. {
  563. if (resp->status == 0) {
  564. lease_get_mtime(resp->fh.fh_dentry->d_inode,
  565. &resp->stat.mtime);
  566. p = encode_fattr3(rqstp, p, &resp->fh, &resp->stat);
  567. }
  568. return xdr_ressize_check(rqstp, p);
  569. }
  570. /* SETATTR, REMOVE, RMDIR */
  571. int
  572. nfs3svc_encode_wccstat(struct svc_rqst *rqstp, __be32 *p,
  573. struct nfsd3_attrstat *resp)
  574. {
  575. p = encode_wcc_data(rqstp, p, &resp->fh);
  576. return xdr_ressize_check(rqstp, p);
  577. }
  578. /* LOOKUP */
  579. int
  580. nfs3svc_encode_diropres(struct svc_rqst *rqstp, __be32 *p,
  581. struct nfsd3_diropres *resp)
  582. {
  583. if (resp->status == 0) {
  584. p = encode_fh(p, &resp->fh);
  585. p = encode_post_op_attr(rqstp, p, &resp->fh);
  586. }
  587. p = encode_post_op_attr(rqstp, p, &resp->dirfh);
  588. return xdr_ressize_check(rqstp, p);
  589. }
  590. /* ACCESS */
  591. int
  592. nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p,
  593. struct nfsd3_accessres *resp)
  594. {
  595. p = encode_post_op_attr(rqstp, p, &resp->fh);
  596. if (resp->status == 0)
  597. *p++ = htonl(resp->access);
  598. return xdr_ressize_check(rqstp, p);
  599. }
  600. /* READLINK */
  601. int
  602. nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p,
  603. struct nfsd3_readlinkres *resp)
  604. {
  605. p = encode_post_op_attr(rqstp, p, &resp->fh);
  606. if (resp->status == 0) {
  607. *p++ = htonl(resp->len);
  608. xdr_ressize_check(rqstp, p);
  609. rqstp->rq_res.page_len = resp->len;
  610. if (resp->len & 3) {
  611. /* need to pad the tail */
  612. rqstp->rq_res.tail[0].iov_base = p;
  613. *p = 0;
  614. rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
  615. }
  616. return 1;
  617. } else
  618. return xdr_ressize_check(rqstp, p);
  619. }
  620. /* READ */
  621. int
  622. nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p,
  623. struct nfsd3_readres *resp)
  624. {
  625. p = encode_post_op_attr(rqstp, p, &resp->fh);
  626. if (resp->status == 0) {
  627. *p++ = htonl(resp->count);
  628. *p++ = htonl(resp->eof);
  629. *p++ = htonl(resp->count); /* xdr opaque count */
  630. xdr_ressize_check(rqstp, p);
  631. /* now update rqstp->rq_res to reflect data aswell */
  632. rqstp->rq_res.page_len = resp->count;
  633. if (resp->count & 3) {
  634. /* need to pad the tail */
  635. rqstp->rq_res.tail[0].iov_base = p;
  636. *p = 0;
  637. rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3);
  638. }
  639. return 1;
  640. } else
  641. return xdr_ressize_check(rqstp, p);
  642. }
  643. /* WRITE */
  644. int
  645. nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p,
  646. struct nfsd3_writeres *resp)
  647. {
  648. p = encode_wcc_data(rqstp, p, &resp->fh);
  649. if (resp->status == 0) {
  650. *p++ = htonl(resp->count);
  651. *p++ = htonl(resp->committed);
  652. *p++ = htonl(nfssvc_boot.tv_sec);
  653. *p++ = htonl(nfssvc_boot.tv_usec);
  654. }
  655. return xdr_ressize_check(rqstp, p);
  656. }
  657. /* CREATE, MKDIR, SYMLINK, MKNOD */
  658. int
  659. nfs3svc_encode_createres(struct svc_rqst *rqstp, __be32 *p,
  660. struct nfsd3_diropres *resp)
  661. {
  662. if (resp->status == 0) {
  663. *p++ = xdr_one;
  664. p = encode_fh(p, &resp->fh);
  665. p = encode_post_op_attr(rqstp, p, &resp->fh);
  666. }
  667. p = encode_wcc_data(rqstp, p, &resp->dirfh);
  668. return xdr_ressize_check(rqstp, p);
  669. }
  670. /* RENAME */
  671. int
  672. nfs3svc_encode_renameres(struct svc_rqst *rqstp, __be32 *p,
  673. struct nfsd3_renameres *resp)
  674. {
  675. p = encode_wcc_data(rqstp, p, &resp->ffh);
  676. p = encode_wcc_data(rqstp, p, &resp->tfh);
  677. return xdr_ressize_check(rqstp, p);
  678. }
  679. /* LINK */
  680. int
  681. nfs3svc_encode_linkres(struct svc_rqst *rqstp, __be32 *p,
  682. struct nfsd3_linkres *resp)
  683. {
  684. p = encode_post_op_attr(rqstp, p, &resp->fh);
  685. p = encode_wcc_data(rqstp, p, &resp->tfh);
  686. return xdr_ressize_check(rqstp, p);
  687. }
  688. /* READDIR */
  689. int
  690. nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p,
  691. struct nfsd3_readdirres *resp)
  692. {
  693. p = encode_post_op_attr(rqstp, p, &resp->fh);
  694. if (resp->status == 0) {
  695. /* stupid readdir cookie */
  696. memcpy(p, resp->verf, 8); p += 2;
  697. xdr_ressize_check(rqstp, p);
  698. if (rqstp->rq_res.head[0].iov_len + (2<<2) > PAGE_SIZE)
  699. return 1; /*No room for trailer */
  700. rqstp->rq_res.page_len = (resp->count) << 2;
  701. /* add the 'tail' to the end of the 'head' page - page 0. */
  702. rqstp->rq_res.tail[0].iov_base = p;
  703. *p++ = 0; /* no more entries */
  704. *p++ = htonl(resp->common.err == nfserr_eof);
  705. rqstp->rq_res.tail[0].iov_len = 2<<2;
  706. return 1;
  707. } else
  708. return xdr_ressize_check(rqstp, p);
  709. }
  710. static __be32 *
  711. encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name,
  712. int namlen, u64 ino)
  713. {
  714. *p++ = xdr_one; /* mark entry present */
  715. p = xdr_encode_hyper(p, ino); /* file id */
  716. p = xdr_encode_array(p, name, namlen);/* name length & name */
  717. cd->offset = p; /* remember pointer */
  718. p = xdr_encode_hyper(p, NFS_OFFSET_MAX);/* offset of next entry */
  719. return p;
  720. }
  721. static __be32 *
  722. encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p,
  723. struct svc_fh *fhp)
  724. {
  725. p = encode_post_op_attr(cd->rqstp, p, fhp);
  726. *p++ = xdr_one; /* yes, a file handle follows */
  727. p = encode_fh(p, fhp);
  728. fh_put(fhp);
  729. return p;
  730. }
  731. static int
  732. compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
  733. const char *name, int namlen)
  734. {
  735. struct svc_export *exp;
  736. struct dentry *dparent, *dchild;
  737. int rv = 0;
  738. dparent = cd->fh.fh_dentry;
  739. exp = cd->fh.fh_export;
  740. fh_init(fhp, NFS3_FHSIZE);
  741. if (isdotent(name, namlen)) {
  742. if (namlen == 2) {
  743. dchild = dget_parent(dparent);
  744. if (dchild == dparent) {
  745. /* filesystem root - cannot return filehandle for ".." */
  746. dput(dchild);
  747. return 1;
  748. }
  749. } else
  750. dchild = dget(dparent);
  751. } else
  752. dchild = lookup_one_len(name, dparent, namlen);
  753. if (IS_ERR(dchild))
  754. return 1;
  755. if (d_mountpoint(dchild) ||
  756. fh_compose(fhp, exp, dchild, &cd->fh) != 0 ||
  757. !dchild->d_inode)
  758. rv = 1;
  759. dput(dchild);
  760. return rv;
  761. }
  762. /*
  763. * Encode a directory entry. This one works for both normal readdir
  764. * and readdirplus.
  765. * The normal readdir reply requires 2 (fileid) + 1 (stringlen)
  766. * + string + 2 (cookie) + 1 (next) words, i.e. 6 + strlen.
  767. *
  768. * The readdirplus baggage is 1+21 words for post_op_attr, plus the
  769. * file handle.
  770. */
  771. #define NFS3_ENTRY_BAGGAGE (2 + 1 + 2 + 1)
  772. #define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2))
  773. static int
  774. encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
  775. loff_t offset, u64 ino, unsigned int d_type, int plus)
  776. {
  777. struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres,
  778. common);
  779. __be32 *p = cd->buffer;
  780. caddr_t curr_page_addr = NULL;
  781. int pn; /* current page number */
  782. int slen; /* string (name) length */
  783. int elen; /* estimated entry length in words */
  784. int num_entry_words = 0; /* actual number of words */
  785. if (cd->offset) {
  786. u64 offset64 = offset;
  787. if (unlikely(cd->offset1)) {
  788. /* we ended up with offset on a page boundary */
  789. *cd->offset = htonl(offset64 >> 32);
  790. *cd->offset1 = htonl(offset64 & 0xffffffff);
  791. cd->offset1 = NULL;
  792. } else {
  793. xdr_encode_hyper(cd->offset, offset64);
  794. }
  795. }
  796. /*
  797. dprintk("encode_entry(%.*s @%ld%s)\n",
  798. namlen, name, (long) offset, plus? " plus" : "");
  799. */
  800. /* truncate filename if too long */
  801. if (namlen > NFS3_MAXNAMLEN)
  802. namlen = NFS3_MAXNAMLEN;
  803. slen = XDR_QUADLEN(namlen);
  804. elen = slen + NFS3_ENTRY_BAGGAGE
  805. + (plus? NFS3_ENTRYPLUS_BAGGAGE : 0);
  806. if (cd->buflen < elen) {
  807. cd->common.err = nfserr_toosmall;
  808. return -EINVAL;
  809. }
  810. /* determine which page in rq_respages[] we are currently filling */
  811. for (pn=1; pn < cd->rqstp->rq_resused; pn++) {
  812. curr_page_addr = page_address(cd->rqstp->rq_respages[pn]);
  813. if (((caddr_t)cd->buffer >= curr_page_addr) &&
  814. ((caddr_t)cd->buffer < curr_page_addr + PAGE_SIZE))
  815. break;
  816. }
  817. if ((caddr_t)(cd->buffer + elen) < (curr_page_addr + PAGE_SIZE)) {
  818. /* encode entry in current page */
  819. p = encode_entry_baggage(cd, p, name, namlen, ino);
  820. /* throw in readdirplus baggage */
  821. if (plus) {
  822. struct svc_fh fh;
  823. if (compose_entry_fh(cd, &fh, name, namlen) > 0) {
  824. *p++ = 0;
  825. *p++ = 0;
  826. } else
  827. p = encode_entryplus_baggage(cd, p, &fh);
  828. }
  829. num_entry_words = p - cd->buffer;
  830. } else if (cd->rqstp->rq_respages[pn+1] != NULL) {
  831. /* temporarily encode entry into next page, then move back to
  832. * current and next page in rq_respages[] */
  833. __be32 *p1, *tmp;
  834. int len1, len2;
  835. /* grab next page for temporary storage of entry */
  836. p1 = tmp = page_address(cd->rqstp->rq_respages[pn+1]);
  837. p1 = encode_entry_baggage(cd, p1, name, namlen, ino);
  838. /* throw in readdirplus baggage */
  839. if (plus) {
  840. struct svc_fh fh;
  841. if (compose_entry_fh(cd, &fh, name, namlen) > 0) {
  842. /* zero out the filehandle */
  843. *p1++ = 0;
  844. *p1++ = 0;
  845. } else
  846. p1 = encode_entryplus_baggage(cd, p1, &fh);
  847. }
  848. /* determine entry word length and lengths to go in pages */
  849. num_entry_words = p1 - tmp;
  850. len1 = curr_page_addr + PAGE_SIZE - (caddr_t)cd->buffer;
  851. if ((num_entry_words << 2) < len1) {
  852. /* the actual number of words in the entry is less
  853. * than elen and can still fit in the current page
  854. */
  855. memmove(p, tmp, num_entry_words << 2);
  856. p += num_entry_words;
  857. /* update offset */
  858. cd->offset = cd->buffer + (cd->offset - tmp);
  859. } else {
  860. unsigned int offset_r = (cd->offset - tmp) << 2;
  861. /* update pointer to offset location.
  862. * This is a 64bit quantity, so we need to
  863. * deal with 3 cases:
  864. * - entirely in first page
  865. * - entirely in second page
  866. * - 4 bytes in each page
  867. */
  868. if (offset_r + 8 <= len1) {
  869. cd->offset = p + (cd->offset - tmp);
  870. } else if (offset_r >= len1) {
  871. cd->offset -= len1 >> 2;
  872. } else {
  873. /* sitting on the fence */
  874. BUG_ON(offset_r != len1 - 4);
  875. cd->offset = p + (cd->offset - tmp);
  876. cd->offset1 = tmp;
  877. }
  878. len2 = (num_entry_words << 2) - len1;
  879. /* move from temp page to current and next pages */
  880. memmove(p, tmp, len1);
  881. memmove(tmp, (caddr_t)tmp+len1, len2);
  882. p = tmp + (len2 >> 2);
  883. }
  884. }
  885. else {
  886. cd->common.err = nfserr_toosmall;
  887. return -EINVAL;
  888. }
  889. cd->buflen -= num_entry_words;
  890. cd->buffer = p;
  891. cd->common.err = nfs_ok;
  892. return 0;
  893. }
  894. int
  895. nfs3svc_encode_entry(void *cd, const char *name,
  896. int namlen, loff_t offset, u64 ino, unsigned int d_type)
  897. {
  898. return encode_entry(cd, name, namlen, offset, ino, d_type, 0);
  899. }
  900. int
  901. nfs3svc_encode_entry_plus(void *cd, const char *name,
  902. int namlen, loff_t offset, u64 ino,
  903. unsigned int d_type)
  904. {
  905. return encode_entry(cd, name, namlen, offset, ino, d_type, 1);
  906. }
  907. /* FSSTAT */
  908. int
  909. nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, __be32 *p,
  910. struct nfsd3_fsstatres *resp)
  911. {
  912. struct kstatfs *s = &resp->stats;
  913. u64 bs = s->f_bsize;
  914. *p++ = xdr_zero; /* no post_op_attr */
  915. if (resp->status == 0) {
  916. p = xdr_encode_hyper(p, bs * s->f_blocks); /* total bytes */
  917. p = xdr_encode_hyper(p, bs * s->f_bfree); /* free bytes */
  918. p = xdr_encode_hyper(p, bs * s->f_bavail); /* user available bytes */
  919. p = xdr_encode_hyper(p, s->f_files); /* total inodes */
  920. p = xdr_encode_hyper(p, s->f_ffree); /* free inodes */
  921. p = xdr_encode_hyper(p, s->f_ffree); /* user available inodes */
  922. *p++ = htonl(resp->invarsec); /* mean unchanged time */
  923. }
  924. return xdr_ressize_check(rqstp, p);
  925. }
  926. /* FSINFO */
  927. int
  928. nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p,
  929. struct nfsd3_fsinfores *resp)
  930. {
  931. *p++ = xdr_zero; /* no post_op_attr */
  932. if (resp->status == 0) {
  933. *p++ = htonl(resp->f_rtmax);
  934. *p++ = htonl(resp->f_rtpref);
  935. *p++ = htonl(resp->f_rtmult);
  936. *p++ = htonl(resp->f_wtmax);
  937. *p++ = htonl(resp->f_wtpref);
  938. *p++ = htonl(resp->f_wtmult);
  939. *p++ = htonl(resp->f_dtpref);
  940. p = xdr_encode_hyper(p, resp->f_maxfilesize);
  941. *p++ = xdr_one;
  942. *p++ = xdr_zero;
  943. *p++ = htonl(resp->f_properties);
  944. }
  945. return xdr_ressize_check(rqstp, p);
  946. }
  947. /* PATHCONF */
  948. int
  949. nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, __be32 *p,
  950. struct nfsd3_pathconfres *resp)
  951. {
  952. *p++ = xdr_zero; /* no post_op_attr */
  953. if (resp->status == 0) {
  954. *p++ = htonl(resp->p_link_max);
  955. *p++ = htonl(resp->p_name_max);
  956. *p++ = htonl(resp->p_no_trunc);
  957. *p++ = htonl(resp->p_chown_restricted);
  958. *p++ = htonl(resp->p_case_insensitive);
  959. *p++ = htonl(resp->p_case_preserving);
  960. }
  961. return xdr_ressize_check(rqstp, p);
  962. }
  963. /* COMMIT */
  964. int
  965. nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p,
  966. struct nfsd3_commitres *resp)
  967. {
  968. p = encode_wcc_data(rqstp, p, &resp->fh);
  969. /* Write verifier */
  970. if (resp->status == 0) {
  971. *p++ = htonl(nfssvc_boot.tv_sec);
  972. *p++ = htonl(nfssvc_boot.tv_usec);
  973. }
  974. return xdr_ressize_check(rqstp, p);
  975. }
  976. /*
  977. * XDR release functions
  978. */
  979. int
  980. nfs3svc_release_fhandle(struct svc_rqst *rqstp, __be32 *p,
  981. struct nfsd3_attrstat *resp)
  982. {
  983. fh_put(&resp->fh);
  984. return 1;
  985. }
  986. int
  987. nfs3svc_release_fhandle2(struct svc_rqst *rqstp, __be32 *p,
  988. struct nfsd3_fhandle_pair *resp)
  989. {
  990. fh_put(&resp->fh1);
  991. fh_put(&resp->fh2);
  992. return 1;
  993. }