nfs2xdr.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  1. /*
  2. * linux/fs/nfs/nfs2xdr.c
  3. *
  4. * XDR functions to encode/decode NFS RPC arguments and results.
  5. *
  6. * Copyright (C) 1992, 1993, 1994 Rick Sladkey
  7. * Copyright (C) 1996 Olaf Kirch
  8. * 04 Aug 1998 Ion Badulescu <ionut@cs.columbia.edu>
  9. * FIFO's need special handling in NFSv2
  10. */
  11. #include <linux/param.h>
  12. #include <linux/time.h>
  13. #include <linux/mm.h>
  14. #include <linux/errno.h>
  15. #include <linux/string.h>
  16. #include <linux/in.h>
  17. #include <linux/pagemap.h>
  18. #include <linux/proc_fs.h>
  19. #include <linux/sunrpc/clnt.h>
  20. #include <linux/nfs.h>
  21. #include <linux/nfs2.h>
  22. #include <linux/nfs_fs.h>
  23. #include "internal.h"
  24. #define NFSDBG_FACILITY NFSDBG_XDR
  25. /* Mapping from NFS error code to "errno" error code. */
  26. #define errno_NFSERR_IO EIO
  27. /*
  28. * Declare the space requirements for NFS arguments and replies as
  29. * number of 32bit-words
  30. */
  31. #define NFS_fhandle_sz (8)
  32. #define NFS_sattr_sz (8)
  33. #define NFS_filename_sz (1+(NFS2_MAXNAMLEN>>2))
  34. #define NFS_path_sz (1+(NFS2_MAXPATHLEN>>2))
  35. #define NFS_fattr_sz (17)
  36. #define NFS_info_sz (5)
  37. #define NFS_entry_sz (NFS_filename_sz+3)
  38. #define NFS_diropargs_sz (NFS_fhandle_sz+NFS_filename_sz)
  39. #define NFS_removeargs_sz (NFS_fhandle_sz+NFS_filename_sz)
  40. #define NFS_sattrargs_sz (NFS_fhandle_sz+NFS_sattr_sz)
  41. #define NFS_readlinkargs_sz (NFS_fhandle_sz)
  42. #define NFS_readargs_sz (NFS_fhandle_sz+3)
  43. #define NFS_writeargs_sz (NFS_fhandle_sz+4)
  44. #define NFS_createargs_sz (NFS_diropargs_sz+NFS_sattr_sz)
  45. #define NFS_renameargs_sz (NFS_diropargs_sz+NFS_diropargs_sz)
  46. #define NFS_linkargs_sz (NFS_fhandle_sz+NFS_diropargs_sz)
  47. #define NFS_symlinkargs_sz (NFS_diropargs_sz+1+NFS_sattr_sz)
  48. #define NFS_readdirargs_sz (NFS_fhandle_sz+2)
  49. #define NFS_attrstat_sz (1+NFS_fattr_sz)
  50. #define NFS_diropres_sz (1+NFS_fhandle_sz+NFS_fattr_sz)
  51. #define NFS_readlinkres_sz (2)
  52. #define NFS_readres_sz (1+NFS_fattr_sz+1)
  53. #define NFS_writeres_sz (NFS_attrstat_sz)
  54. #define NFS_stat_sz (1)
  55. #define NFS_readdirres_sz (1)
  56. #define NFS_statfsres_sz (1+NFS_info_sz)
  57. /*
  58. * While encoding arguments, set up the reply buffer in advance to
  59. * receive reply data directly into the page cache.
  60. */
  61. static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
  62. unsigned int base, unsigned int len,
  63. unsigned int bufsize)
  64. {
  65. struct rpc_auth *auth = req->rq_cred->cr_auth;
  66. unsigned int replen;
  67. replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
  68. xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
  69. }
  70. /*
  71. * Common NFS XDR functions as inlines
  72. */
  73. static inline __be32 *
  74. xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle)
  75. {
  76. /* NFSv2 handles have a fixed length */
  77. fhandle->size = NFS2_FHSIZE;
  78. memcpy(fhandle->data, p, NFS2_FHSIZE);
  79. return p + XDR_QUADLEN(NFS2_FHSIZE);
  80. }
  81. static inline __be32*
  82. xdr_encode_time(__be32 *p, const struct timespec *timep)
  83. {
  84. *p++ = htonl(timep->tv_sec);
  85. /* Convert nanoseconds into microseconds */
  86. *p++ = htonl(timep->tv_nsec ? timep->tv_nsec / 1000 : 0);
  87. return p;
  88. }
  89. static inline __be32*
  90. xdr_encode_current_server_time(__be32 *p, const struct timespec *timep)
  91. {
  92. /*
  93. * Passing the invalid value useconds=1000000 is a
  94. * Sun convention for "set to current server time".
  95. * It's needed to make permissions checks for the
  96. * "touch" program across v2 mounts to Solaris and
  97. * Irix boxes work correctly. See description of
  98. * sattr in section 6.1 of "NFS Illustrated" by
  99. * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5
  100. */
  101. *p++ = htonl(timep->tv_sec);
  102. *p++ = htonl(1000000);
  103. return p;
  104. }
  105. static inline __be32*
  106. xdr_decode_time(__be32 *p, struct timespec *timep)
  107. {
  108. timep->tv_sec = ntohl(*p++);
  109. /* Convert microseconds into nanoseconds */
  110. timep->tv_nsec = ntohl(*p++) * 1000;
  111. return p;
  112. }
  113. static __be32 *
  114. xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
  115. {
  116. u32 rdev, type;
  117. type = ntohl(*p++);
  118. fattr->mode = ntohl(*p++);
  119. fattr->nlink = ntohl(*p++);
  120. fattr->uid = ntohl(*p++);
  121. fattr->gid = ntohl(*p++);
  122. fattr->size = ntohl(*p++);
  123. fattr->du.nfs2.blocksize = ntohl(*p++);
  124. rdev = ntohl(*p++);
  125. fattr->du.nfs2.blocks = ntohl(*p++);
  126. fattr->fsid.major = ntohl(*p++);
  127. fattr->fsid.minor = 0;
  128. fattr->fileid = ntohl(*p++);
  129. p = xdr_decode_time(p, &fattr->atime);
  130. p = xdr_decode_time(p, &fattr->mtime);
  131. p = xdr_decode_time(p, &fattr->ctime);
  132. fattr->valid |= NFS_ATTR_FATTR_V2;
  133. fattr->rdev = new_decode_dev(rdev);
  134. if (type == NFCHR && rdev == NFS2_FIFO_DEV) {
  135. fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
  136. fattr->rdev = 0;
  137. }
  138. return p;
  139. }
  140. /*
  141. * Encode/decode NFSv2 basic data types
  142. *
  143. * Basic NFSv2 data types are defined in section 2.3 of RFC 1094:
  144. * "NFS: Network File System Protocol Specification".
  145. *
  146. * Not all basic data types have their own encoding and decoding
  147. * functions. For run-time efficiency, some data types are encoded
  148. * or decoded inline.
  149. */
  150. /*
  151. * 2.3.3. fhandle
  152. *
  153. * typedef opaque fhandle[FHSIZE];
  154. */
  155. static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
  156. {
  157. __be32 *p;
  158. BUG_ON(fh->size != NFS2_FHSIZE);
  159. p = xdr_reserve_space(xdr, NFS2_FHSIZE);
  160. memcpy(p, fh->data, NFS2_FHSIZE);
  161. }
  162. /*
  163. * 2.3.6. sattr
  164. *
  165. * struct sattr {
  166. * unsigned int mode;
  167. * unsigned int uid;
  168. * unsigned int gid;
  169. * unsigned int size;
  170. * timeval atime;
  171. * timeval mtime;
  172. * };
  173. */
  174. #define NFS2_SATTR_NOT_SET (0xffffffff)
  175. static __be32 *xdr_time_not_set(__be32 *p)
  176. {
  177. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  178. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  179. return p;
  180. }
  181. static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
  182. {
  183. __be32 *p;
  184. p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
  185. if (attr->ia_valid & ATTR_MODE)
  186. *p++ = cpu_to_be32(attr->ia_mode);
  187. else
  188. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  189. if (attr->ia_valid & ATTR_UID)
  190. *p++ = cpu_to_be32(attr->ia_uid);
  191. else
  192. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  193. if (attr->ia_valid & ATTR_GID)
  194. *p++ = cpu_to_be32(attr->ia_gid);
  195. else
  196. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  197. if (attr->ia_valid & ATTR_SIZE)
  198. *p++ = cpu_to_be32((u32)attr->ia_size);
  199. else
  200. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  201. if (attr->ia_valid & ATTR_ATIME_SET)
  202. p = xdr_encode_time(p, &attr->ia_atime);
  203. else if (attr->ia_valid & ATTR_ATIME)
  204. p = xdr_encode_current_server_time(p, &attr->ia_atime);
  205. else
  206. p = xdr_time_not_set(p);
  207. if (attr->ia_valid & ATTR_MTIME_SET)
  208. xdr_encode_time(p, &attr->ia_mtime);
  209. else if (attr->ia_valid & ATTR_MTIME)
  210. xdr_encode_current_server_time(p, &attr->ia_mtime);
  211. else
  212. xdr_time_not_set(p);
  213. }
  214. /*
  215. * 2.3.7. filename
  216. *
  217. * typedef string filename<MAXNAMLEN>;
  218. */
  219. static void encode_filename(struct xdr_stream *xdr,
  220. const char *name, u32 length)
  221. {
  222. __be32 *p;
  223. BUG_ON(length > NFS2_MAXNAMLEN);
  224. p = xdr_reserve_space(xdr, 4 + length);
  225. xdr_encode_opaque(p, name, length);
  226. }
  227. /*
  228. * 2.3.8. path
  229. *
  230. * typedef string path<MAXPATHLEN>;
  231. */
  232. static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
  233. {
  234. __be32 *p;
  235. BUG_ON(length > NFS2_MAXPATHLEN);
  236. p = xdr_reserve_space(xdr, 4);
  237. *p = cpu_to_be32(length);
  238. xdr_write_pages(xdr, pages, 0, length);
  239. }
  240. /*
  241. * 2.3.10. diropargs
  242. *
  243. * struct diropargs {
  244. * fhandle dir;
  245. * filename name;
  246. * };
  247. */
  248. static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
  249. const char *name, u32 length)
  250. {
  251. encode_fhandle(xdr, fh);
  252. encode_filename(xdr, name, length);
  253. }
  254. /*
  255. * NFSv2 XDR encode functions
  256. *
  257. * NFSv2 argument types are defined in section 2.2 of RFC 1094:
  258. * "NFS: Network File System Protocol Specification".
  259. */
  260. static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p,
  261. const struct nfs_fh *fh)
  262. {
  263. struct xdr_stream xdr;
  264. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  265. encode_fhandle(&xdr, fh);
  266. return 0;
  267. }
  268. /*
  269. * 2.2.3. sattrargs
  270. *
  271. * struct sattrargs {
  272. * fhandle file;
  273. * sattr attributes;
  274. * };
  275. */
  276. static int nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, __be32 *p,
  277. const struct nfs_sattrargs *args)
  278. {
  279. struct xdr_stream xdr;
  280. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  281. encode_fhandle(&xdr, args->fh);
  282. encode_sattr(&xdr, args->sattr);
  283. return 0;
  284. }
  285. static int nfs2_xdr_enc_diropargs(struct rpc_rqst *req, __be32 *p,
  286. const struct nfs_diropargs *args)
  287. {
  288. struct xdr_stream xdr;
  289. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  290. encode_diropargs(&xdr, args->fh, args->name, args->len);
  291. return 0;
  292. }
  293. static int nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, __be32 *p,
  294. const struct nfs_readlinkargs *args)
  295. {
  296. struct xdr_stream xdr;
  297. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  298. encode_fhandle(&xdr, args->fh);
  299. prepare_reply_buffer(req, args->pages, args->pgbase,
  300. args->pglen, NFS_readlinkres_sz);
  301. return 0;
  302. }
  303. /*
  304. * 2.2.7. readargs
  305. *
  306. * struct readargs {
  307. * fhandle file;
  308. * unsigned offset;
  309. * unsigned count;
  310. * unsigned totalcount;
  311. * };
  312. */
  313. static void encode_readargs(struct xdr_stream *xdr,
  314. const struct nfs_readargs *args)
  315. {
  316. u32 offset = args->offset;
  317. u32 count = args->count;
  318. __be32 *p;
  319. encode_fhandle(xdr, args->fh);
  320. p = xdr_reserve_space(xdr, 4 + 4 + 4);
  321. *p++ = cpu_to_be32(offset);
  322. *p++ = cpu_to_be32(count);
  323. *p = cpu_to_be32(count);
  324. }
  325. static int nfs2_xdr_enc_readargs(struct rpc_rqst *req, __be32 *p,
  326. const struct nfs_readargs *args)
  327. {
  328. struct xdr_stream xdr;
  329. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  330. encode_readargs(&xdr, args);
  331. prepare_reply_buffer(req, args->pages, args->pgbase,
  332. args->count, NFS_readres_sz);
  333. req->rq_rcv_buf.flags |= XDRBUF_READ;
  334. return 0;
  335. }
  336. /*
  337. * Decode READ reply
  338. */
  339. static int
  340. nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
  341. {
  342. struct kvec *iov = req->rq_rcv_buf.head;
  343. size_t hdrlen;
  344. u32 count, recvd;
  345. int status;
  346. if ((status = ntohl(*p++)))
  347. return nfs_stat_to_errno(status);
  348. p = xdr_decode_fattr(p, res->fattr);
  349. count = ntohl(*p++);
  350. res->eof = 0;
  351. hdrlen = (u8 *) p - (u8 *) iov->iov_base;
  352. if (iov->iov_len < hdrlen) {
  353. dprintk("NFS: READ reply header overflowed:"
  354. "length %Zu > %Zu\n", hdrlen, iov->iov_len);
  355. return -errno_NFSERR_IO;
  356. } else if (iov->iov_len != hdrlen) {
  357. dprintk("NFS: READ header is short. iovec will be shifted.\n");
  358. xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
  359. }
  360. recvd = req->rq_rcv_buf.len - hdrlen;
  361. if (count > recvd) {
  362. dprintk("NFS: server cheating in read reply: "
  363. "count %u > recvd %u\n", count, recvd);
  364. count = recvd;
  365. }
  366. dprintk("RPC: readres OK count %u\n", count);
  367. if (count < res->count)
  368. res->count = count;
  369. return count;
  370. }
  371. /*
  372. * 2.2.9. writeargs
  373. *
  374. * struct writeargs {
  375. * fhandle file;
  376. * unsigned beginoffset;
  377. * unsigned offset;
  378. * unsigned totalcount;
  379. * nfsdata data;
  380. * };
  381. */
  382. static void encode_writeargs(struct xdr_stream *xdr,
  383. const struct nfs_writeargs *args)
  384. {
  385. u32 offset = args->offset;
  386. u32 count = args->count;
  387. __be32 *p;
  388. encode_fhandle(xdr, args->fh);
  389. p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
  390. *p++ = cpu_to_be32(offset);
  391. *p++ = cpu_to_be32(offset);
  392. *p++ = cpu_to_be32(count);
  393. /* nfsdata */
  394. *p = cpu_to_be32(count);
  395. xdr_write_pages(xdr, args->pages, args->pgbase, count);
  396. }
  397. static int nfs2_xdr_enc_writeargs(struct rpc_rqst *req, __be32 *p,
  398. const struct nfs_writeargs *args)
  399. {
  400. struct xdr_stream xdr;
  401. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  402. encode_writeargs(&xdr, args);
  403. xdr.buf->flags |= XDRBUF_WRITE;
  404. return 0;
  405. }
  406. /*
  407. * 2.2.10. createargs
  408. *
  409. * struct createargs {
  410. * diropargs where;
  411. * sattr attributes;
  412. * };
  413. */
  414. static int nfs2_xdr_enc_createargs(struct rpc_rqst *req, __be32 *p,
  415. const struct nfs_createargs *args)
  416. {
  417. struct xdr_stream xdr;
  418. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  419. encode_diropargs(&xdr, args->fh, args->name, args->len);
  420. encode_sattr(&xdr, args->sattr);
  421. return 0;
  422. }
  423. static int nfs2_xdr_enc_removeargs(struct rpc_rqst *req, __be32 *p,
  424. const struct nfs_removeargs *args)
  425. {
  426. struct xdr_stream xdr;
  427. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  428. encode_diropargs(&xdr, args->fh, args->name.name, args->name.len);
  429. return 0;
  430. }
  431. /*
  432. * 2.2.12. renameargs
  433. *
  434. * struct renameargs {
  435. * diropargs from;
  436. * diropargs to;
  437. * };
  438. */
  439. static int nfs2_xdr_enc_renameargs(struct rpc_rqst *req, __be32 *p,
  440. const struct nfs_renameargs *args)
  441. {
  442. const struct qstr *old = args->old_name;
  443. const struct qstr *new = args->new_name;
  444. struct xdr_stream xdr;
  445. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  446. encode_diropargs(&xdr, args->old_dir, old->name, old->len);
  447. encode_diropargs(&xdr, args->new_dir, new->name, new->len);
  448. return 0;
  449. }
  450. /*
  451. * 2.2.13. linkargs
  452. *
  453. * struct linkargs {
  454. * fhandle from;
  455. * diropargs to;
  456. * };
  457. */
  458. static int nfs2_xdr_enc_linkargs(struct rpc_rqst *req, __be32 *p,
  459. const struct nfs_linkargs *args)
  460. {
  461. struct xdr_stream xdr;
  462. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  463. encode_fhandle(&xdr, args->fromfh);
  464. encode_diropargs(&xdr, args->tofh, args->toname, args->tolen);
  465. return 0;
  466. }
  467. /*
  468. * 2.2.14. symlinkargs
  469. *
  470. * struct symlinkargs {
  471. * diropargs from;
  472. * path to;
  473. * sattr attributes;
  474. * };
  475. */
  476. static int nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, __be32 *p,
  477. const struct nfs_symlinkargs *args)
  478. {
  479. struct xdr_stream xdr;
  480. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  481. encode_diropargs(&xdr, args->fromfh, args->fromname, args->fromlen);
  482. encode_path(&xdr, args->pages, args->pathlen);
  483. encode_sattr(&xdr, args->sattr);
  484. return 0;
  485. }
  486. /*
  487. * 2.2.17. readdirargs
  488. *
  489. * struct readdirargs {
  490. * fhandle dir;
  491. * nfscookie cookie;
  492. * unsigned count;
  493. * };
  494. */
  495. static void encode_readdirargs(struct xdr_stream *xdr,
  496. const struct nfs_readdirargs *args)
  497. {
  498. __be32 *p;
  499. encode_fhandle(xdr, args->fh);
  500. p = xdr_reserve_space(xdr, 4 + 4);
  501. *p++ = cpu_to_be32(args->cookie);
  502. *p = cpu_to_be32(args->count);
  503. }
  504. static int nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, __be32 *p,
  505. const struct nfs_readdirargs *args)
  506. {
  507. struct xdr_stream xdr;
  508. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  509. encode_readdirargs(&xdr, args);
  510. prepare_reply_buffer(req, args->pages, 0,
  511. args->count, NFS_readdirres_sz);
  512. return 0;
  513. }
  514. /*
  515. * Decode the result of a readdir call.
  516. * We're not really decoding anymore, we just leave the buffer untouched
  517. * and only check that it is syntactically correct.
  518. * The real decoding happens in nfs_decode_entry below, called directly
  519. * from nfs_readdir for each entry.
  520. */
  521. static int
  522. nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
  523. {
  524. struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
  525. struct kvec *iov = rcvbuf->head;
  526. struct page **page;
  527. size_t hdrlen;
  528. unsigned int pglen, recvd;
  529. int status;
  530. if ((status = ntohl(*p++)))
  531. return nfs_stat_to_errno(status);
  532. hdrlen = (u8 *) p - (u8 *) iov->iov_base;
  533. if (iov->iov_len < hdrlen) {
  534. dprintk("NFS: READDIR reply header overflowed:"
  535. "length %Zu > %Zu\n", hdrlen, iov->iov_len);
  536. return -errno_NFSERR_IO;
  537. } else if (iov->iov_len != hdrlen) {
  538. dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
  539. xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
  540. }
  541. pglen = rcvbuf->page_len;
  542. recvd = rcvbuf->len - hdrlen;
  543. if (pglen > recvd)
  544. pglen = recvd;
  545. page = rcvbuf->pages;
  546. return pglen;
  547. }
  548. static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
  549. {
  550. dprintk("nfs: %s: prematurely hit end of receive buffer. "
  551. "Remaining buffer length is %tu words.\n",
  552. func, xdr->end - xdr->p);
  553. }
  554. __be32 *
  555. nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus)
  556. {
  557. __be32 *p;
  558. p = xdr_inline_decode(xdr, 4);
  559. if (unlikely(!p))
  560. goto out_overflow;
  561. if (!ntohl(*p++)) {
  562. p = xdr_inline_decode(xdr, 4);
  563. if (unlikely(!p))
  564. goto out_overflow;
  565. if (!ntohl(*p++))
  566. return ERR_PTR(-EAGAIN);
  567. entry->eof = 1;
  568. return ERR_PTR(-EBADCOOKIE);
  569. }
  570. p = xdr_inline_decode(xdr, 8);
  571. if (unlikely(!p))
  572. goto out_overflow;
  573. entry->ino = ntohl(*p++);
  574. entry->len = ntohl(*p++);
  575. p = xdr_inline_decode(xdr, entry->len + 4);
  576. if (unlikely(!p))
  577. goto out_overflow;
  578. entry->name = (const char *) p;
  579. p += XDR_QUADLEN(entry->len);
  580. entry->prev_cookie = entry->cookie;
  581. entry->cookie = ntohl(*p++);
  582. entry->d_type = DT_UNKNOWN;
  583. p = xdr_inline_peek(xdr, 8);
  584. if (p != NULL)
  585. entry->eof = !p[0] && p[1];
  586. else
  587. entry->eof = 0;
  588. return p;
  589. out_overflow:
  590. print_overflow_msg(__func__, xdr);
  591. return ERR_PTR(-EAGAIN);
  592. }
  593. /*
  594. * NFS XDR decode functions
  595. */
  596. /*
  597. * Decode simple status reply
  598. */
  599. static int
  600. nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy)
  601. {
  602. int status;
  603. if ((status = ntohl(*p++)) != 0)
  604. status = nfs_stat_to_errno(status);
  605. return status;
  606. }
  607. /*
  608. * Decode attrstat reply
  609. * GETATTR, SETATTR, WRITE
  610. */
  611. static int
  612. nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
  613. {
  614. int status;
  615. if ((status = ntohl(*p++)))
  616. return nfs_stat_to_errno(status);
  617. xdr_decode_fattr(p, fattr);
  618. return 0;
  619. }
  620. /*
  621. * Decode diropres reply
  622. * LOOKUP, CREATE, MKDIR
  623. */
  624. static int
  625. nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
  626. {
  627. int status;
  628. if ((status = ntohl(*p++)))
  629. return nfs_stat_to_errno(status);
  630. p = xdr_decode_fhandle(p, res->fh);
  631. xdr_decode_fattr(p, res->fattr);
  632. return 0;
  633. }
  634. /*
  635. * Decode READLINK reply
  636. */
  637. static int
  638. nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
  639. {
  640. struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
  641. struct kvec *iov = rcvbuf->head;
  642. size_t hdrlen;
  643. u32 len, recvd;
  644. int status;
  645. if ((status = ntohl(*p++)))
  646. return nfs_stat_to_errno(status);
  647. /* Convert length of symlink */
  648. len = ntohl(*p++);
  649. if (len >= rcvbuf->page_len) {
  650. dprintk("nfs: server returned giant symlink!\n");
  651. return -ENAMETOOLONG;
  652. }
  653. hdrlen = (u8 *) p - (u8 *) iov->iov_base;
  654. if (iov->iov_len < hdrlen) {
  655. dprintk("NFS: READLINK reply header overflowed:"
  656. "length %Zu > %Zu\n", hdrlen, iov->iov_len);
  657. return -errno_NFSERR_IO;
  658. } else if (iov->iov_len != hdrlen) {
  659. dprintk("NFS: READLINK header is short. iovec will be shifted.\n");
  660. xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
  661. }
  662. recvd = req->rq_rcv_buf.len - hdrlen;
  663. if (recvd < len) {
  664. dprintk("NFS: server cheating in readlink reply: "
  665. "count %u > recvd %u\n", len, recvd);
  666. return -EIO;
  667. }
  668. xdr_terminate_string(rcvbuf, len);
  669. return 0;
  670. }
  671. /*
  672. * Decode WRITE reply
  673. */
  674. static int
  675. nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
  676. {
  677. res->verf->committed = NFS_FILE_SYNC;
  678. return nfs_xdr_attrstat(req, p, res->fattr);
  679. }
  680. /*
  681. * Decode STATFS reply
  682. */
  683. static int
  684. nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res)
  685. {
  686. int status;
  687. if ((status = ntohl(*p++)))
  688. return nfs_stat_to_errno(status);
  689. res->tsize = ntohl(*p++);
  690. res->bsize = ntohl(*p++);
  691. res->blocks = ntohl(*p++);
  692. res->bfree = ntohl(*p++);
  693. res->bavail = ntohl(*p++);
  694. return 0;
  695. }
  696. /*
  697. * We need to translate between nfs status return values and
  698. * the local errno values which may not be the same.
  699. */
  700. static struct {
  701. int stat;
  702. int errno;
  703. } nfs_errtbl[] = {
  704. { NFS_OK, 0 },
  705. { NFSERR_PERM, -EPERM },
  706. { NFSERR_NOENT, -ENOENT },
  707. { NFSERR_IO, -errno_NFSERR_IO},
  708. { NFSERR_NXIO, -ENXIO },
  709. /* { NFSERR_EAGAIN, -EAGAIN }, */
  710. { NFSERR_ACCES, -EACCES },
  711. { NFSERR_EXIST, -EEXIST },
  712. { NFSERR_XDEV, -EXDEV },
  713. { NFSERR_NODEV, -ENODEV },
  714. { NFSERR_NOTDIR, -ENOTDIR },
  715. { NFSERR_ISDIR, -EISDIR },
  716. { NFSERR_INVAL, -EINVAL },
  717. { NFSERR_FBIG, -EFBIG },
  718. { NFSERR_NOSPC, -ENOSPC },
  719. { NFSERR_ROFS, -EROFS },
  720. { NFSERR_MLINK, -EMLINK },
  721. { NFSERR_NAMETOOLONG, -ENAMETOOLONG },
  722. { NFSERR_NOTEMPTY, -ENOTEMPTY },
  723. { NFSERR_DQUOT, -EDQUOT },
  724. { NFSERR_STALE, -ESTALE },
  725. { NFSERR_REMOTE, -EREMOTE },
  726. #ifdef EWFLUSH
  727. { NFSERR_WFLUSH, -EWFLUSH },
  728. #endif
  729. { NFSERR_BADHANDLE, -EBADHANDLE },
  730. { NFSERR_NOT_SYNC, -ENOTSYNC },
  731. { NFSERR_BAD_COOKIE, -EBADCOOKIE },
  732. { NFSERR_NOTSUPP, -ENOTSUPP },
  733. { NFSERR_TOOSMALL, -ETOOSMALL },
  734. { NFSERR_SERVERFAULT, -EREMOTEIO },
  735. { NFSERR_BADTYPE, -EBADTYPE },
  736. { NFSERR_JUKEBOX, -EJUKEBOX },
  737. { -1, -EIO }
  738. };
  739. /*
  740. * Convert an NFS error code to a local one.
  741. * This one is used jointly by NFSv2 and NFSv3.
  742. */
  743. int
  744. nfs_stat_to_errno(int stat)
  745. {
  746. int i;
  747. for (i = 0; nfs_errtbl[i].stat != -1; i++) {
  748. if (nfs_errtbl[i].stat == stat)
  749. return nfs_errtbl[i].errno;
  750. }
  751. dprintk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
  752. return nfs_errtbl[i].errno;
  753. }
  754. #define PROC(proc, argtype, restype, timer) \
  755. [NFSPROC_##proc] = { \
  756. .p_proc = NFSPROC_##proc, \
  757. .p_encode = (kxdrproc_t)nfs2_xdr_enc_##argtype, \
  758. .p_decode = (kxdrproc_t) nfs_xdr_##restype, \
  759. .p_arglen = NFS_##argtype##_sz, \
  760. .p_replen = NFS_##restype##_sz, \
  761. .p_timer = timer, \
  762. .p_statidx = NFSPROC_##proc, \
  763. .p_name = #proc, \
  764. }
  765. struct rpc_procinfo nfs_procedures[] = {
  766. PROC(GETATTR, fhandle, attrstat, 1),
  767. PROC(SETATTR, sattrargs, attrstat, 0),
  768. PROC(LOOKUP, diropargs, diropres, 2),
  769. PROC(READLINK, readlinkargs, readlinkres, 3),
  770. PROC(READ, readargs, readres, 3),
  771. PROC(WRITE, writeargs, writeres, 4),
  772. PROC(CREATE, createargs, diropres, 0),
  773. PROC(REMOVE, removeargs, stat, 0),
  774. PROC(RENAME, renameargs, stat, 0),
  775. PROC(LINK, linkargs, stat, 0),
  776. PROC(SYMLINK, symlinkargs, stat, 0),
  777. PROC(MKDIR, createargs, diropres, 0),
  778. PROC(RMDIR, diropargs, stat, 0),
  779. PROC(READDIR, readdirargs, readdirres, 3),
  780. PROC(STATFS, fhandle, statfsres, 0),
  781. };
  782. struct rpc_version nfs_version2 = {
  783. .number = 2,
  784. .nrprocs = ARRAY_SIZE(nfs_procedures),
  785. .procs = nfs_procedures
  786. };