nfs2xdr.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131
  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_encode_fhandle(__be32 *p, const struct nfs_fh *fhandle)
  75. {
  76. memcpy(p, fhandle->data, NFS2_FHSIZE);
  77. return p + XDR_QUADLEN(NFS2_FHSIZE);
  78. }
  79. static inline __be32 *
  80. xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle)
  81. {
  82. /* NFSv2 handles have a fixed length */
  83. fhandle->size = NFS2_FHSIZE;
  84. memcpy(fhandle->data, p, NFS2_FHSIZE);
  85. return p + XDR_QUADLEN(NFS2_FHSIZE);
  86. }
  87. static inline __be32*
  88. xdr_encode_time(__be32 *p, const struct timespec *timep)
  89. {
  90. *p++ = htonl(timep->tv_sec);
  91. /* Convert nanoseconds into microseconds */
  92. *p++ = htonl(timep->tv_nsec ? timep->tv_nsec / 1000 : 0);
  93. return p;
  94. }
  95. static inline __be32*
  96. xdr_encode_current_server_time(__be32 *p, const struct timespec *timep)
  97. {
  98. /*
  99. * Passing the invalid value useconds=1000000 is a
  100. * Sun convention for "set to current server time".
  101. * It's needed to make permissions checks for the
  102. * "touch" program across v2 mounts to Solaris and
  103. * Irix boxes work correctly. See description of
  104. * sattr in section 6.1 of "NFS Illustrated" by
  105. * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5
  106. */
  107. *p++ = htonl(timep->tv_sec);
  108. *p++ = htonl(1000000);
  109. return p;
  110. }
  111. static inline __be32*
  112. xdr_decode_time(__be32 *p, struct timespec *timep)
  113. {
  114. timep->tv_sec = ntohl(*p++);
  115. /* Convert microseconds into nanoseconds */
  116. timep->tv_nsec = ntohl(*p++) * 1000;
  117. return p;
  118. }
  119. static __be32 *
  120. xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
  121. {
  122. u32 rdev, type;
  123. type = ntohl(*p++);
  124. fattr->mode = ntohl(*p++);
  125. fattr->nlink = ntohl(*p++);
  126. fattr->uid = ntohl(*p++);
  127. fattr->gid = ntohl(*p++);
  128. fattr->size = ntohl(*p++);
  129. fattr->du.nfs2.blocksize = ntohl(*p++);
  130. rdev = ntohl(*p++);
  131. fattr->du.nfs2.blocks = ntohl(*p++);
  132. fattr->fsid.major = ntohl(*p++);
  133. fattr->fsid.minor = 0;
  134. fattr->fileid = ntohl(*p++);
  135. p = xdr_decode_time(p, &fattr->atime);
  136. p = xdr_decode_time(p, &fattr->mtime);
  137. p = xdr_decode_time(p, &fattr->ctime);
  138. fattr->valid |= NFS_ATTR_FATTR_V2;
  139. fattr->rdev = new_decode_dev(rdev);
  140. if (type == NFCHR && rdev == NFS2_FIFO_DEV) {
  141. fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
  142. fattr->rdev = 0;
  143. }
  144. return p;
  145. }
  146. static inline __be32 *
  147. xdr_encode_sattr(__be32 *p, struct iattr *attr)
  148. {
  149. const __be32 not_set = __constant_htonl(0xFFFFFFFF);
  150. *p++ = (attr->ia_valid & ATTR_MODE) ? htonl(attr->ia_mode) : not_set;
  151. *p++ = (attr->ia_valid & ATTR_UID) ? htonl(attr->ia_uid) : not_set;
  152. *p++ = (attr->ia_valid & ATTR_GID) ? htonl(attr->ia_gid) : not_set;
  153. *p++ = (attr->ia_valid & ATTR_SIZE) ? htonl(attr->ia_size) : not_set;
  154. if (attr->ia_valid & ATTR_ATIME_SET) {
  155. p = xdr_encode_time(p, &attr->ia_atime);
  156. } else if (attr->ia_valid & ATTR_ATIME) {
  157. p = xdr_encode_current_server_time(p, &attr->ia_atime);
  158. } else {
  159. *p++ = not_set;
  160. *p++ = not_set;
  161. }
  162. if (attr->ia_valid & ATTR_MTIME_SET) {
  163. p = xdr_encode_time(p, &attr->ia_mtime);
  164. } else if (attr->ia_valid & ATTR_MTIME) {
  165. p = xdr_encode_current_server_time(p, &attr->ia_mtime);
  166. } else {
  167. *p++ = not_set;
  168. *p++ = not_set;
  169. }
  170. return p;
  171. }
  172. /*
  173. * Encode/decode NFSv2 basic data types
  174. *
  175. * Basic NFSv2 data types are defined in section 2.3 of RFC 1094:
  176. * "NFS: Network File System Protocol Specification".
  177. *
  178. * Not all basic data types have their own encoding and decoding
  179. * functions. For run-time efficiency, some data types are encoded
  180. * or decoded inline.
  181. */
  182. /*
  183. * 2.3.3. fhandle
  184. *
  185. * typedef opaque fhandle[FHSIZE];
  186. */
  187. static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
  188. {
  189. __be32 *p;
  190. BUG_ON(fh->size != NFS2_FHSIZE);
  191. p = xdr_reserve_space(xdr, NFS2_FHSIZE);
  192. memcpy(p, fh->data, NFS2_FHSIZE);
  193. }
  194. /*
  195. * 2.3.6. sattr
  196. *
  197. * struct sattr {
  198. * unsigned int mode;
  199. * unsigned int uid;
  200. * unsigned int gid;
  201. * unsigned int size;
  202. * timeval atime;
  203. * timeval mtime;
  204. * };
  205. */
  206. #define NFS2_SATTR_NOT_SET (0xffffffff)
  207. static __be32 *xdr_time_not_set(__be32 *p)
  208. {
  209. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  210. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  211. return p;
  212. }
  213. static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
  214. {
  215. __be32 *p;
  216. p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
  217. if (attr->ia_valid & ATTR_MODE)
  218. *p++ = cpu_to_be32(attr->ia_mode);
  219. else
  220. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  221. if (attr->ia_valid & ATTR_UID)
  222. *p++ = cpu_to_be32(attr->ia_uid);
  223. else
  224. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  225. if (attr->ia_valid & ATTR_GID)
  226. *p++ = cpu_to_be32(attr->ia_gid);
  227. else
  228. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  229. if (attr->ia_valid & ATTR_SIZE)
  230. *p++ = cpu_to_be32((u32)attr->ia_size);
  231. else
  232. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  233. if (attr->ia_valid & ATTR_ATIME_SET)
  234. p = xdr_encode_time(p, &attr->ia_atime);
  235. else if (attr->ia_valid & ATTR_ATIME)
  236. p = xdr_encode_current_server_time(p, &attr->ia_atime);
  237. else
  238. p = xdr_time_not_set(p);
  239. if (attr->ia_valid & ATTR_MTIME_SET)
  240. xdr_encode_time(p, &attr->ia_mtime);
  241. else if (attr->ia_valid & ATTR_MTIME)
  242. xdr_encode_current_server_time(p, &attr->ia_mtime);
  243. else
  244. xdr_time_not_set(p);
  245. }
  246. /*
  247. * 2.3.7. filename
  248. *
  249. * typedef string filename<MAXNAMLEN>;
  250. */
  251. static void encode_filename(struct xdr_stream *xdr,
  252. const char *name, u32 length)
  253. {
  254. __be32 *p;
  255. BUG_ON(length > NFS2_MAXNAMLEN);
  256. p = xdr_reserve_space(xdr, 4 + length);
  257. xdr_encode_opaque(p, name, length);
  258. }
  259. /*
  260. * 2.3.8. path
  261. *
  262. * typedef string path<MAXPATHLEN>;
  263. */
  264. static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
  265. {
  266. __be32 *p;
  267. BUG_ON(length > NFS2_MAXPATHLEN);
  268. p = xdr_reserve_space(xdr, 4);
  269. *p = cpu_to_be32(length);
  270. xdr_write_pages(xdr, pages, 0, length);
  271. }
  272. /*
  273. * 2.3.10. diropargs
  274. *
  275. * struct diropargs {
  276. * fhandle dir;
  277. * filename name;
  278. * };
  279. */
  280. static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
  281. const char *name, u32 length)
  282. {
  283. encode_fhandle(xdr, fh);
  284. encode_filename(xdr, name, length);
  285. }
  286. /*
  287. * NFS encode functions
  288. */
  289. /*
  290. * Encode file handle argument
  291. * GETATTR, READLINK, STATFS
  292. */
  293. static int
  294. nfs_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
  295. {
  296. p = xdr_encode_fhandle(p, fh);
  297. req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
  298. return 0;
  299. }
  300. static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p,
  301. const struct nfs_fh *fh)
  302. {
  303. struct xdr_stream xdr;
  304. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  305. encode_fhandle(&xdr, fh);
  306. return 0;
  307. }
  308. /*
  309. * Encode SETATTR arguments
  310. */
  311. static int
  312. nfs_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs_sattrargs *args)
  313. {
  314. p = xdr_encode_fhandle(p, args->fh);
  315. p = xdr_encode_sattr(p, args->sattr);
  316. req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
  317. return 0;
  318. }
  319. /*
  320. * 2.2.3. sattrargs
  321. *
  322. * struct sattrargs {
  323. * fhandle file;
  324. * sattr attributes;
  325. * };
  326. */
  327. static int nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, __be32 *p,
  328. const struct nfs_sattrargs *args)
  329. {
  330. struct xdr_stream xdr;
  331. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  332. encode_fhandle(&xdr, args->fh);
  333. encode_sattr(&xdr, args->sattr);
  334. return 0;
  335. }
  336. /*
  337. * Encode directory ops argument
  338. * LOOKUP, RMDIR
  339. */
  340. static int
  341. nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args)
  342. {
  343. p = xdr_encode_fhandle(p, args->fh);
  344. p = xdr_encode_array(p, args->name, args->len);
  345. req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
  346. return 0;
  347. }
  348. static int nfs2_xdr_enc_diropargs(struct rpc_rqst *req, __be32 *p,
  349. const struct nfs_diropargs *args)
  350. {
  351. struct xdr_stream xdr;
  352. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  353. encode_diropargs(&xdr, args->fh, args->name, args->len);
  354. return 0;
  355. }
  356. /*
  357. * Encode REMOVE argument
  358. */
  359. static int
  360. nfs_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
  361. {
  362. p = xdr_encode_fhandle(p, args->fh);
  363. p = xdr_encode_array(p, args->name.name, args->name.len);
  364. req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
  365. return 0;
  366. }
  367. static int nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, __be32 *p,
  368. const struct nfs_readlinkargs *args)
  369. {
  370. struct xdr_stream xdr;
  371. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  372. encode_fhandle(&xdr, args->fh);
  373. prepare_reply_buffer(req, args->pages, args->pgbase,
  374. args->pglen, NFS_readlinkres_sz);
  375. return 0;
  376. }
  377. /*
  378. * Arguments to a READ call. Since we read data directly into the page
  379. * cache, we also set up the reply iovec here so that iov[1] points
  380. * exactly to the page we want to fetch.
  381. */
  382. static int
  383. nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
  384. {
  385. struct rpc_auth *auth = req->rq_cred->cr_auth;
  386. unsigned int replen;
  387. u32 offset = (u32)args->offset;
  388. u32 count = args->count;
  389. p = xdr_encode_fhandle(p, args->fh);
  390. *p++ = htonl(offset);
  391. *p++ = htonl(count);
  392. *p++ = htonl(count);
  393. req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
  394. /* Inline the page array */
  395. replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readres_sz) << 2;
  396. xdr_inline_pages(&req->rq_rcv_buf, replen,
  397. args->pages, args->pgbase, count);
  398. req->rq_rcv_buf.flags |= XDRBUF_READ;
  399. return 0;
  400. }
  401. /*
  402. * 2.2.7. readargs
  403. *
  404. * struct readargs {
  405. * fhandle file;
  406. * unsigned offset;
  407. * unsigned count;
  408. * unsigned totalcount;
  409. * };
  410. */
  411. static void encode_readargs(struct xdr_stream *xdr,
  412. const struct nfs_readargs *args)
  413. {
  414. u32 offset = args->offset;
  415. u32 count = args->count;
  416. __be32 *p;
  417. encode_fhandle(xdr, args->fh);
  418. p = xdr_reserve_space(xdr, 4 + 4 + 4);
  419. *p++ = cpu_to_be32(offset);
  420. *p++ = cpu_to_be32(count);
  421. *p = cpu_to_be32(count);
  422. }
  423. static int nfs2_xdr_enc_readargs(struct rpc_rqst *req, __be32 *p,
  424. const struct nfs_readargs *args)
  425. {
  426. struct xdr_stream xdr;
  427. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  428. encode_readargs(&xdr, args);
  429. prepare_reply_buffer(req, args->pages, args->pgbase,
  430. args->count, NFS_readres_sz);
  431. req->rq_rcv_buf.flags |= XDRBUF_READ;
  432. return 0;
  433. }
  434. /*
  435. * Decode READ reply
  436. */
  437. static int
  438. nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
  439. {
  440. struct kvec *iov = req->rq_rcv_buf.head;
  441. size_t hdrlen;
  442. u32 count, recvd;
  443. int status;
  444. if ((status = ntohl(*p++)))
  445. return nfs_stat_to_errno(status);
  446. p = xdr_decode_fattr(p, res->fattr);
  447. count = ntohl(*p++);
  448. res->eof = 0;
  449. hdrlen = (u8 *) p - (u8 *) iov->iov_base;
  450. if (iov->iov_len < hdrlen) {
  451. dprintk("NFS: READ reply header overflowed:"
  452. "length %Zu > %Zu\n", hdrlen, iov->iov_len);
  453. return -errno_NFSERR_IO;
  454. } else if (iov->iov_len != hdrlen) {
  455. dprintk("NFS: READ header is short. iovec will be shifted.\n");
  456. xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
  457. }
  458. recvd = req->rq_rcv_buf.len - hdrlen;
  459. if (count > recvd) {
  460. dprintk("NFS: server cheating in read reply: "
  461. "count %u > recvd %u\n", count, recvd);
  462. count = recvd;
  463. }
  464. dprintk("RPC: readres OK count %u\n", count);
  465. if (count < res->count)
  466. res->count = count;
  467. return count;
  468. }
  469. /*
  470. * Write arguments. Splice the buffer to be written into the iovec.
  471. */
  472. static int
  473. nfs_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
  474. {
  475. struct xdr_buf *sndbuf = &req->rq_snd_buf;
  476. u32 offset = (u32)args->offset;
  477. u32 count = args->count;
  478. p = xdr_encode_fhandle(p, args->fh);
  479. *p++ = htonl(offset);
  480. *p++ = htonl(offset);
  481. *p++ = htonl(count);
  482. *p++ = htonl(count);
  483. sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
  484. /* Copy the page array */
  485. xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
  486. sndbuf->flags |= XDRBUF_WRITE;
  487. return 0;
  488. }
  489. /*
  490. * 2.2.9. writeargs
  491. *
  492. * struct writeargs {
  493. * fhandle file;
  494. * unsigned beginoffset;
  495. * unsigned offset;
  496. * unsigned totalcount;
  497. * nfsdata data;
  498. * };
  499. */
  500. static void encode_writeargs(struct xdr_stream *xdr,
  501. const struct nfs_writeargs *args)
  502. {
  503. u32 offset = args->offset;
  504. u32 count = args->count;
  505. __be32 *p;
  506. encode_fhandle(xdr, args->fh);
  507. p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
  508. *p++ = cpu_to_be32(offset);
  509. *p++ = cpu_to_be32(offset);
  510. *p++ = cpu_to_be32(count);
  511. /* nfsdata */
  512. *p = cpu_to_be32(count);
  513. xdr_write_pages(xdr, args->pages, args->pgbase, count);
  514. }
  515. static int nfs2_xdr_enc_writeargs(struct rpc_rqst *req, __be32 *p,
  516. const struct nfs_writeargs *args)
  517. {
  518. struct xdr_stream xdr;
  519. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  520. encode_writeargs(&xdr, args);
  521. xdr.buf->flags |= XDRBUF_WRITE;
  522. return 0;
  523. }
  524. /*
  525. * Encode create arguments
  526. * CREATE, MKDIR
  527. */
  528. static int
  529. nfs_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs_createargs *args)
  530. {
  531. p = xdr_encode_fhandle(p, args->fh);
  532. p = xdr_encode_array(p, args->name, args->len);
  533. p = xdr_encode_sattr(p, args->sattr);
  534. req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
  535. return 0;
  536. }
  537. /*
  538. * 2.2.10. createargs
  539. *
  540. * struct createargs {
  541. * diropargs where;
  542. * sattr attributes;
  543. * };
  544. */
  545. static int nfs2_xdr_enc_createargs(struct rpc_rqst *req, __be32 *p,
  546. const struct nfs_createargs *args)
  547. {
  548. struct xdr_stream xdr;
  549. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  550. encode_diropargs(&xdr, args->fh, args->name, args->len);
  551. encode_sattr(&xdr, args->sattr);
  552. return 0;
  553. }
  554. static int nfs2_xdr_enc_removeargs(struct rpc_rqst *req, __be32 *p,
  555. const struct nfs_removeargs *args)
  556. {
  557. struct xdr_stream xdr;
  558. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  559. encode_diropargs(&xdr, args->fh, args->name.name, args->name.len);
  560. return 0;
  561. }
  562. /*
  563. * Encode RENAME arguments
  564. */
  565. static int
  566. nfs_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args)
  567. {
  568. p = xdr_encode_fhandle(p, args->old_dir);
  569. p = xdr_encode_array(p, args->old_name->name, args->old_name->len);
  570. p = xdr_encode_fhandle(p, args->new_dir);
  571. p = xdr_encode_array(p, args->new_name->name, args->new_name->len);
  572. req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
  573. return 0;
  574. }
  575. /*
  576. * 2.2.12. renameargs
  577. *
  578. * struct renameargs {
  579. * diropargs from;
  580. * diropargs to;
  581. * };
  582. */
  583. static int nfs2_xdr_enc_renameargs(struct rpc_rqst *req, __be32 *p,
  584. const struct nfs_renameargs *args)
  585. {
  586. const struct qstr *old = args->old_name;
  587. const struct qstr *new = args->new_name;
  588. struct xdr_stream xdr;
  589. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  590. encode_diropargs(&xdr, args->old_dir, old->name, old->len);
  591. encode_diropargs(&xdr, args->new_dir, new->name, new->len);
  592. return 0;
  593. }
  594. /*
  595. * Encode LINK arguments
  596. */
  597. static int
  598. nfs_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs_linkargs *args)
  599. {
  600. p = xdr_encode_fhandle(p, args->fromfh);
  601. p = xdr_encode_fhandle(p, args->tofh);
  602. p = xdr_encode_array(p, args->toname, args->tolen);
  603. req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
  604. return 0;
  605. }
  606. /*
  607. * 2.2.13. linkargs
  608. *
  609. * struct linkargs {
  610. * fhandle from;
  611. * diropargs to;
  612. * };
  613. */
  614. static int nfs2_xdr_enc_linkargs(struct rpc_rqst *req, __be32 *p,
  615. const struct nfs_linkargs *args)
  616. {
  617. struct xdr_stream xdr;
  618. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  619. encode_fhandle(&xdr, args->fromfh);
  620. encode_diropargs(&xdr, args->tofh, args->toname, args->tolen);
  621. return 0;
  622. }
  623. /*
  624. * Encode SYMLINK arguments
  625. */
  626. static int
  627. nfs_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_symlinkargs *args)
  628. {
  629. struct xdr_buf *sndbuf = &req->rq_snd_buf;
  630. size_t pad;
  631. p = xdr_encode_fhandle(p, args->fromfh);
  632. p = xdr_encode_array(p, args->fromname, args->fromlen);
  633. *p++ = htonl(args->pathlen);
  634. sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
  635. xdr_encode_pages(sndbuf, args->pages, 0, args->pathlen);
  636. /*
  637. * xdr_encode_pages may have added a few bytes to ensure the
  638. * pathname ends on a 4-byte boundary. Start encoding the
  639. * attributes after the pad bytes.
  640. */
  641. pad = sndbuf->tail->iov_len;
  642. if (pad > 0)
  643. p++;
  644. p = xdr_encode_sattr(p, args->sattr);
  645. sndbuf->len += xdr_adjust_iovec(sndbuf->tail, p) - pad;
  646. return 0;
  647. }
  648. /*
  649. * 2.2.14. symlinkargs
  650. *
  651. * struct symlinkargs {
  652. * diropargs from;
  653. * path to;
  654. * sattr attributes;
  655. * };
  656. */
  657. static int nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, __be32 *p,
  658. const struct nfs_symlinkargs *args)
  659. {
  660. struct xdr_stream xdr;
  661. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  662. encode_diropargs(&xdr, args->fromfh, args->fromname, args->fromlen);
  663. encode_path(&xdr, args->pages, args->pathlen);
  664. encode_sattr(&xdr, args->sattr);
  665. return 0;
  666. }
  667. /*
  668. * Encode arguments to readdir call
  669. */
  670. static int
  671. nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args)
  672. {
  673. struct rpc_auth *auth = req->rq_cred->cr_auth;
  674. unsigned int replen;
  675. u32 count = args->count;
  676. p = xdr_encode_fhandle(p, args->fh);
  677. *p++ = htonl(args->cookie);
  678. *p++ = htonl(count); /* see above */
  679. req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
  680. /* Inline the page array */
  681. replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readdirres_sz) << 2;
  682. xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count);
  683. return 0;
  684. }
  685. /*
  686. * 2.2.17. readdirargs
  687. *
  688. * struct readdirargs {
  689. * fhandle dir;
  690. * nfscookie cookie;
  691. * unsigned count;
  692. * };
  693. */
  694. static void encode_readdirargs(struct xdr_stream *xdr,
  695. const struct nfs_readdirargs *args)
  696. {
  697. __be32 *p;
  698. encode_fhandle(xdr, args->fh);
  699. p = xdr_reserve_space(xdr, 4 + 4);
  700. *p++ = cpu_to_be32(args->cookie);
  701. *p = cpu_to_be32(args->count);
  702. }
  703. static int nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, __be32 *p,
  704. const struct nfs_readdirargs *args)
  705. {
  706. struct xdr_stream xdr;
  707. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  708. encode_readdirargs(&xdr, args);
  709. prepare_reply_buffer(req, args->pages, 0,
  710. args->count, NFS_readdirres_sz);
  711. return 0;
  712. }
  713. /*
  714. * Decode the result of a readdir call.
  715. * We're not really decoding anymore, we just leave the buffer untouched
  716. * and only check that it is syntactically correct.
  717. * The real decoding happens in nfs_decode_entry below, called directly
  718. * from nfs_readdir for each entry.
  719. */
  720. static int
  721. nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
  722. {
  723. struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
  724. struct kvec *iov = rcvbuf->head;
  725. struct page **page;
  726. size_t hdrlen;
  727. unsigned int pglen, recvd;
  728. int status;
  729. if ((status = ntohl(*p++)))
  730. return nfs_stat_to_errno(status);
  731. hdrlen = (u8 *) p - (u8 *) iov->iov_base;
  732. if (iov->iov_len < hdrlen) {
  733. dprintk("NFS: READDIR reply header overflowed:"
  734. "length %Zu > %Zu\n", hdrlen, iov->iov_len);
  735. return -errno_NFSERR_IO;
  736. } else if (iov->iov_len != hdrlen) {
  737. dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
  738. xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
  739. }
  740. pglen = rcvbuf->page_len;
  741. recvd = rcvbuf->len - hdrlen;
  742. if (pglen > recvd)
  743. pglen = recvd;
  744. page = rcvbuf->pages;
  745. return pglen;
  746. }
  747. static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
  748. {
  749. dprintk("nfs: %s: prematurely hit end of receive buffer. "
  750. "Remaining buffer length is %tu words.\n",
  751. func, xdr->end - xdr->p);
  752. }
  753. __be32 *
  754. nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus)
  755. {
  756. __be32 *p;
  757. p = xdr_inline_decode(xdr, 4);
  758. if (unlikely(!p))
  759. goto out_overflow;
  760. if (!ntohl(*p++)) {
  761. p = xdr_inline_decode(xdr, 4);
  762. if (unlikely(!p))
  763. goto out_overflow;
  764. if (!ntohl(*p++))
  765. return ERR_PTR(-EAGAIN);
  766. entry->eof = 1;
  767. return ERR_PTR(-EBADCOOKIE);
  768. }
  769. p = xdr_inline_decode(xdr, 8);
  770. if (unlikely(!p))
  771. goto out_overflow;
  772. entry->ino = ntohl(*p++);
  773. entry->len = ntohl(*p++);
  774. p = xdr_inline_decode(xdr, entry->len + 4);
  775. if (unlikely(!p))
  776. goto out_overflow;
  777. entry->name = (const char *) p;
  778. p += XDR_QUADLEN(entry->len);
  779. entry->prev_cookie = entry->cookie;
  780. entry->cookie = ntohl(*p++);
  781. entry->d_type = DT_UNKNOWN;
  782. p = xdr_inline_peek(xdr, 8);
  783. if (p != NULL)
  784. entry->eof = !p[0] && p[1];
  785. else
  786. entry->eof = 0;
  787. return p;
  788. out_overflow:
  789. print_overflow_msg(__func__, xdr);
  790. return ERR_PTR(-EAGAIN);
  791. }
  792. /*
  793. * NFS XDR decode functions
  794. */
  795. /*
  796. * Decode simple status reply
  797. */
  798. static int
  799. nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy)
  800. {
  801. int status;
  802. if ((status = ntohl(*p++)) != 0)
  803. status = nfs_stat_to_errno(status);
  804. return status;
  805. }
  806. /*
  807. * Decode attrstat reply
  808. * GETATTR, SETATTR, WRITE
  809. */
  810. static int
  811. nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
  812. {
  813. int status;
  814. if ((status = ntohl(*p++)))
  815. return nfs_stat_to_errno(status);
  816. xdr_decode_fattr(p, fattr);
  817. return 0;
  818. }
  819. /*
  820. * Decode diropres reply
  821. * LOOKUP, CREATE, MKDIR
  822. */
  823. static int
  824. nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
  825. {
  826. int status;
  827. if ((status = ntohl(*p++)))
  828. return nfs_stat_to_errno(status);
  829. p = xdr_decode_fhandle(p, res->fh);
  830. xdr_decode_fattr(p, res->fattr);
  831. return 0;
  832. }
  833. /*
  834. * Encode READLINK args
  835. */
  836. static int
  837. nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args)
  838. {
  839. struct rpc_auth *auth = req->rq_cred->cr_auth;
  840. unsigned int replen;
  841. p = xdr_encode_fhandle(p, args->fh);
  842. req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
  843. /* Inline the page array */
  844. replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readlinkres_sz) << 2;
  845. xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->pglen);
  846. return 0;
  847. }
  848. /*
  849. * Decode READLINK reply
  850. */
  851. static int
  852. nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
  853. {
  854. struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
  855. struct kvec *iov = rcvbuf->head;
  856. size_t hdrlen;
  857. u32 len, recvd;
  858. int status;
  859. if ((status = ntohl(*p++)))
  860. return nfs_stat_to_errno(status);
  861. /* Convert length of symlink */
  862. len = ntohl(*p++);
  863. if (len >= rcvbuf->page_len) {
  864. dprintk("nfs: server returned giant symlink!\n");
  865. return -ENAMETOOLONG;
  866. }
  867. hdrlen = (u8 *) p - (u8 *) iov->iov_base;
  868. if (iov->iov_len < hdrlen) {
  869. dprintk("NFS: READLINK reply header overflowed:"
  870. "length %Zu > %Zu\n", hdrlen, iov->iov_len);
  871. return -errno_NFSERR_IO;
  872. } else if (iov->iov_len != hdrlen) {
  873. dprintk("NFS: READLINK header is short. iovec will be shifted.\n");
  874. xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
  875. }
  876. recvd = req->rq_rcv_buf.len - hdrlen;
  877. if (recvd < len) {
  878. dprintk("NFS: server cheating in readlink reply: "
  879. "count %u > recvd %u\n", len, recvd);
  880. return -EIO;
  881. }
  882. xdr_terminate_string(rcvbuf, len);
  883. return 0;
  884. }
  885. /*
  886. * Decode WRITE reply
  887. */
  888. static int
  889. nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
  890. {
  891. res->verf->committed = NFS_FILE_SYNC;
  892. return nfs_xdr_attrstat(req, p, res->fattr);
  893. }
  894. /*
  895. * Decode STATFS reply
  896. */
  897. static int
  898. nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res)
  899. {
  900. int status;
  901. if ((status = ntohl(*p++)))
  902. return nfs_stat_to_errno(status);
  903. res->tsize = ntohl(*p++);
  904. res->bsize = ntohl(*p++);
  905. res->blocks = ntohl(*p++);
  906. res->bfree = ntohl(*p++);
  907. res->bavail = ntohl(*p++);
  908. return 0;
  909. }
  910. /*
  911. * We need to translate between nfs status return values and
  912. * the local errno values which may not be the same.
  913. */
  914. static struct {
  915. int stat;
  916. int errno;
  917. } nfs_errtbl[] = {
  918. { NFS_OK, 0 },
  919. { NFSERR_PERM, -EPERM },
  920. { NFSERR_NOENT, -ENOENT },
  921. { NFSERR_IO, -errno_NFSERR_IO},
  922. { NFSERR_NXIO, -ENXIO },
  923. /* { NFSERR_EAGAIN, -EAGAIN }, */
  924. { NFSERR_ACCES, -EACCES },
  925. { NFSERR_EXIST, -EEXIST },
  926. { NFSERR_XDEV, -EXDEV },
  927. { NFSERR_NODEV, -ENODEV },
  928. { NFSERR_NOTDIR, -ENOTDIR },
  929. { NFSERR_ISDIR, -EISDIR },
  930. { NFSERR_INVAL, -EINVAL },
  931. { NFSERR_FBIG, -EFBIG },
  932. { NFSERR_NOSPC, -ENOSPC },
  933. { NFSERR_ROFS, -EROFS },
  934. { NFSERR_MLINK, -EMLINK },
  935. { NFSERR_NAMETOOLONG, -ENAMETOOLONG },
  936. { NFSERR_NOTEMPTY, -ENOTEMPTY },
  937. { NFSERR_DQUOT, -EDQUOT },
  938. { NFSERR_STALE, -ESTALE },
  939. { NFSERR_REMOTE, -EREMOTE },
  940. #ifdef EWFLUSH
  941. { NFSERR_WFLUSH, -EWFLUSH },
  942. #endif
  943. { NFSERR_BADHANDLE, -EBADHANDLE },
  944. { NFSERR_NOT_SYNC, -ENOTSYNC },
  945. { NFSERR_BAD_COOKIE, -EBADCOOKIE },
  946. { NFSERR_NOTSUPP, -ENOTSUPP },
  947. { NFSERR_TOOSMALL, -ETOOSMALL },
  948. { NFSERR_SERVERFAULT, -EREMOTEIO },
  949. { NFSERR_BADTYPE, -EBADTYPE },
  950. { NFSERR_JUKEBOX, -EJUKEBOX },
  951. { -1, -EIO }
  952. };
  953. /*
  954. * Convert an NFS error code to a local one.
  955. * This one is used jointly by NFSv2 and NFSv3.
  956. */
  957. int
  958. nfs_stat_to_errno(int stat)
  959. {
  960. int i;
  961. for (i = 0; nfs_errtbl[i].stat != -1; i++) {
  962. if (nfs_errtbl[i].stat == stat)
  963. return nfs_errtbl[i].errno;
  964. }
  965. dprintk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
  966. return nfs_errtbl[i].errno;
  967. }
  968. #define PROC(proc, argtype, restype, timer) \
  969. [NFSPROC_##proc] = { \
  970. .p_proc = NFSPROC_##proc, \
  971. .p_encode = (kxdrproc_t)nfs2_xdr_enc_##argtype, \
  972. .p_decode = (kxdrproc_t) nfs_xdr_##restype, \
  973. .p_arglen = NFS_##argtype##_sz, \
  974. .p_replen = NFS_##restype##_sz, \
  975. .p_timer = timer, \
  976. .p_statidx = NFSPROC_##proc, \
  977. .p_name = #proc, \
  978. }
  979. struct rpc_procinfo nfs_procedures[] = {
  980. PROC(GETATTR, fhandle, attrstat, 1),
  981. PROC(SETATTR, sattrargs, attrstat, 0),
  982. PROC(LOOKUP, diropargs, diropres, 2),
  983. PROC(READLINK, readlinkargs, readlinkres, 3),
  984. PROC(READ, readargs, readres, 3),
  985. PROC(WRITE, writeargs, writeres, 4),
  986. PROC(CREATE, createargs, diropres, 0),
  987. PROC(REMOVE, removeargs, stat, 0),
  988. PROC(RENAME, renameargs, stat, 0),
  989. PROC(LINK, linkargs, stat, 0),
  990. PROC(SYMLINK, symlinkargs, stat, 0),
  991. PROC(MKDIR, createargs, diropres, 0),
  992. PROC(RMDIR, diropargs, stat, 0),
  993. PROC(READDIR, readdirargs, readdirres, 3),
  994. PROC(STATFS, fhandle, statfsres, 0),
  995. };
  996. struct rpc_version nfs_version2 = {
  997. .number = 2,
  998. .nrprocs = ARRAY_SIZE(nfs_procedures),
  999. .procs = nfs_procedures
  1000. };