nfs2xdr.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * linux/fs/nfs/nfs2xdr.c
  4. *
  5. * XDR functions to encode/decode NFS RPC arguments and results.
  6. *
  7. * Copyright (C) 1992, 1993, 1994 Rick Sladkey
  8. * Copyright (C) 1996 Olaf Kirch
  9. * 04 Aug 1998 Ion Badulescu <ionut@cs.columbia.edu>
  10. * FIFO's need special handling in NFSv2
  11. */
  12. #include <linux/param.h>
  13. #include <linux/time.h>
  14. #include <linux/mm.h>
  15. #include <linux/errno.h>
  16. #include <linux/string.h>
  17. #include <linux/in.h>
  18. #include <linux/pagemap.h>
  19. #include <linux/proc_fs.h>
  20. #include <linux/sunrpc/clnt.h>
  21. #include <linux/nfs.h>
  22. #include <linux/nfs2.h>
  23. #include <linux/nfs_fs.h>
  24. #include "internal.h"
  25. #define NFSDBG_FACILITY NFSDBG_XDR
  26. /* Mapping from NFS error code to "errno" error code. */
  27. #define errno_NFSERR_IO EIO
  28. /*
  29. * Declare the space requirements for NFS arguments and replies as
  30. * number of 32bit-words
  31. */
  32. #define NFS_fhandle_sz (8)
  33. #define NFS_sattr_sz (8)
  34. #define NFS_filename_sz (1+(NFS2_MAXNAMLEN>>2))
  35. #define NFS_path_sz (1+(NFS2_MAXPATHLEN>>2))
  36. #define NFS_fattr_sz (17)
  37. #define NFS_info_sz (5)
  38. #define NFS_entry_sz (NFS_filename_sz+3)
  39. #define NFS_diropargs_sz (NFS_fhandle_sz+NFS_filename_sz)
  40. #define NFS_removeargs_sz (NFS_fhandle_sz+NFS_filename_sz)
  41. #define NFS_sattrargs_sz (NFS_fhandle_sz+NFS_sattr_sz)
  42. #define NFS_readlinkargs_sz (NFS_fhandle_sz)
  43. #define NFS_readargs_sz (NFS_fhandle_sz+3)
  44. #define NFS_writeargs_sz (NFS_fhandle_sz+4)
  45. #define NFS_createargs_sz (NFS_diropargs_sz+NFS_sattr_sz)
  46. #define NFS_renameargs_sz (NFS_diropargs_sz+NFS_diropargs_sz)
  47. #define NFS_linkargs_sz (NFS_fhandle_sz+NFS_diropargs_sz)
  48. #define NFS_symlinkargs_sz (NFS_diropargs_sz+1+NFS_sattr_sz)
  49. #define NFS_readdirargs_sz (NFS_fhandle_sz+2)
  50. #define NFS_attrstat_sz (1+NFS_fattr_sz)
  51. #define NFS_diropres_sz (1+NFS_fhandle_sz+NFS_fattr_sz)
  52. #define NFS_readlinkres_sz (2)
  53. #define NFS_readres_sz (1+NFS_fattr_sz+1)
  54. #define NFS_writeres_sz (NFS_attrstat_sz)
  55. #define NFS_stat_sz (1)
  56. #define NFS_readdirres_sz (1)
  57. #define NFS_statfsres_sz (1+NFS_info_sz)
  58. static int nfs_stat_to_errno(enum nfs_stat);
  59. /*
  60. * While encoding arguments, set up the reply buffer in advance to
  61. * receive reply data directly into the page cache.
  62. */
  63. static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
  64. unsigned int base, unsigned int len,
  65. unsigned int bufsize)
  66. {
  67. struct rpc_auth *auth = req->rq_cred->cr_auth;
  68. unsigned int replen;
  69. replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
  70. xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
  71. }
  72. /*
  73. * Handle decode buffer overflows out-of-line.
  74. */
  75. static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
  76. {
  77. dprintk("NFS: %s prematurely hit the end of our receive buffer. "
  78. "Remaining buffer length is %tu words.\n",
  79. func, xdr->end - xdr->p);
  80. }
  81. /*
  82. * Encode/decode NFSv2 basic data types
  83. *
  84. * Basic NFSv2 data types are defined in section 2.3 of RFC 1094:
  85. * "NFS: Network File System Protocol Specification".
  86. *
  87. * Not all basic data types have their own encoding and decoding
  88. * functions. For run-time efficiency, some data types are encoded
  89. * or decoded inline.
  90. */
  91. /*
  92. * typedef opaque nfsdata<>;
  93. */
  94. static int decode_nfsdata(struct xdr_stream *xdr, struct nfs_pgio_res *result)
  95. {
  96. u32 recvd, count;
  97. __be32 *p;
  98. p = xdr_inline_decode(xdr, 4);
  99. if (unlikely(p == NULL))
  100. goto out_overflow;
  101. count = be32_to_cpup(p);
  102. recvd = xdr_read_pages(xdr, count);
  103. if (unlikely(count > recvd))
  104. goto out_cheating;
  105. out:
  106. result->eof = 0; /* NFSv2 does not pass EOF flag on the wire. */
  107. result->count = count;
  108. return count;
  109. out_cheating:
  110. dprintk("NFS: server cheating in read result: "
  111. "count %u > recvd %u\n", count, recvd);
  112. count = recvd;
  113. goto out;
  114. out_overflow:
  115. print_overflow_msg(__func__, xdr);
  116. return -EIO;
  117. }
  118. /*
  119. * enum stat {
  120. * NFS_OK = 0,
  121. * NFSERR_PERM = 1,
  122. * NFSERR_NOENT = 2,
  123. * NFSERR_IO = 5,
  124. * NFSERR_NXIO = 6,
  125. * NFSERR_ACCES = 13,
  126. * NFSERR_EXIST = 17,
  127. * NFSERR_NODEV = 19,
  128. * NFSERR_NOTDIR = 20,
  129. * NFSERR_ISDIR = 21,
  130. * NFSERR_FBIG = 27,
  131. * NFSERR_NOSPC = 28,
  132. * NFSERR_ROFS = 30,
  133. * NFSERR_NAMETOOLONG = 63,
  134. * NFSERR_NOTEMPTY = 66,
  135. * NFSERR_DQUOT = 69,
  136. * NFSERR_STALE = 70,
  137. * NFSERR_WFLUSH = 99
  138. * };
  139. */
  140. static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status)
  141. {
  142. __be32 *p;
  143. p = xdr_inline_decode(xdr, 4);
  144. if (unlikely(p == NULL))
  145. goto out_overflow;
  146. *status = be32_to_cpup(p);
  147. return 0;
  148. out_overflow:
  149. print_overflow_msg(__func__, xdr);
  150. return -EIO;
  151. }
  152. /*
  153. * 2.3.2. ftype
  154. *
  155. * enum ftype {
  156. * NFNON = 0,
  157. * NFREG = 1,
  158. * NFDIR = 2,
  159. * NFBLK = 3,
  160. * NFCHR = 4,
  161. * NFLNK = 5
  162. * };
  163. *
  164. */
  165. static __be32 *xdr_decode_ftype(__be32 *p, u32 *type)
  166. {
  167. *type = be32_to_cpup(p++);
  168. if (unlikely(*type > NF2FIFO))
  169. *type = NFBAD;
  170. return p;
  171. }
  172. /*
  173. * 2.3.3. fhandle
  174. *
  175. * typedef opaque fhandle[FHSIZE];
  176. */
  177. static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
  178. {
  179. __be32 *p;
  180. p = xdr_reserve_space(xdr, NFS2_FHSIZE);
  181. memcpy(p, fh->data, NFS2_FHSIZE);
  182. }
  183. static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh)
  184. {
  185. __be32 *p;
  186. p = xdr_inline_decode(xdr, NFS2_FHSIZE);
  187. if (unlikely(p == NULL))
  188. goto out_overflow;
  189. fh->size = NFS2_FHSIZE;
  190. memcpy(fh->data, p, NFS2_FHSIZE);
  191. return 0;
  192. out_overflow:
  193. print_overflow_msg(__func__, xdr);
  194. return -EIO;
  195. }
  196. /*
  197. * 2.3.4. timeval
  198. *
  199. * struct timeval {
  200. * unsigned int seconds;
  201. * unsigned int useconds;
  202. * };
  203. */
  204. static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep)
  205. {
  206. *p++ = cpu_to_be32(timep->tv_sec);
  207. if (timep->tv_nsec != 0)
  208. *p++ = cpu_to_be32(timep->tv_nsec / NSEC_PER_USEC);
  209. else
  210. *p++ = cpu_to_be32(0);
  211. return p;
  212. }
  213. /*
  214. * Passing the invalid value useconds=1000000 is a Sun convention for
  215. * "set to current server time". It's needed to make permissions checks
  216. * for the "touch" program across v2 mounts to Solaris and Irix servers
  217. * work correctly. See description of sattr in section 6.1 of "NFS
  218. * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5.
  219. */
  220. static __be32 *xdr_encode_current_server_time(__be32 *p,
  221. const struct timespec *timep)
  222. {
  223. *p++ = cpu_to_be32(timep->tv_sec);
  224. *p++ = cpu_to_be32(1000000);
  225. return p;
  226. }
  227. static __be32 *xdr_decode_time(__be32 *p, struct timespec *timep)
  228. {
  229. timep->tv_sec = be32_to_cpup(p++);
  230. timep->tv_nsec = be32_to_cpup(p++) * NSEC_PER_USEC;
  231. return p;
  232. }
  233. /*
  234. * 2.3.5. fattr
  235. *
  236. * struct fattr {
  237. * ftype type;
  238. * unsigned int mode;
  239. * unsigned int nlink;
  240. * unsigned int uid;
  241. * unsigned int gid;
  242. * unsigned int size;
  243. * unsigned int blocksize;
  244. * unsigned int rdev;
  245. * unsigned int blocks;
  246. * unsigned int fsid;
  247. * unsigned int fileid;
  248. * timeval atime;
  249. * timeval mtime;
  250. * timeval ctime;
  251. * };
  252. *
  253. */
  254. static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
  255. {
  256. u32 rdev, type;
  257. __be32 *p;
  258. p = xdr_inline_decode(xdr, NFS_fattr_sz << 2);
  259. if (unlikely(p == NULL))
  260. goto out_overflow;
  261. fattr->valid |= NFS_ATTR_FATTR_V2;
  262. p = xdr_decode_ftype(p, &type);
  263. fattr->mode = be32_to_cpup(p++);
  264. fattr->nlink = be32_to_cpup(p++);
  265. fattr->uid = make_kuid(&init_user_ns, be32_to_cpup(p++));
  266. if (!uid_valid(fattr->uid))
  267. goto out_uid;
  268. fattr->gid = make_kgid(&init_user_ns, be32_to_cpup(p++));
  269. if (!gid_valid(fattr->gid))
  270. goto out_gid;
  271. fattr->size = be32_to_cpup(p++);
  272. fattr->du.nfs2.blocksize = be32_to_cpup(p++);
  273. rdev = be32_to_cpup(p++);
  274. fattr->rdev = new_decode_dev(rdev);
  275. if (type == (u32)NFCHR && rdev == (u32)NFS2_FIFO_DEV) {
  276. fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
  277. fattr->rdev = 0;
  278. }
  279. fattr->du.nfs2.blocks = be32_to_cpup(p++);
  280. fattr->fsid.major = be32_to_cpup(p++);
  281. fattr->fsid.minor = 0;
  282. fattr->fileid = be32_to_cpup(p++);
  283. p = xdr_decode_time(p, &fattr->atime);
  284. p = xdr_decode_time(p, &fattr->mtime);
  285. xdr_decode_time(p, &fattr->ctime);
  286. fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime);
  287. return 0;
  288. out_uid:
  289. dprintk("NFS: returned invalid uid\n");
  290. return -EINVAL;
  291. out_gid:
  292. dprintk("NFS: returned invalid gid\n");
  293. return -EINVAL;
  294. out_overflow:
  295. print_overflow_msg(__func__, xdr);
  296. return -EIO;
  297. }
  298. /*
  299. * 2.3.6. sattr
  300. *
  301. * struct sattr {
  302. * unsigned int mode;
  303. * unsigned int uid;
  304. * unsigned int gid;
  305. * unsigned int size;
  306. * timeval atime;
  307. * timeval mtime;
  308. * };
  309. */
  310. #define NFS2_SATTR_NOT_SET (0xffffffff)
  311. static __be32 *xdr_time_not_set(__be32 *p)
  312. {
  313. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  314. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  315. return p;
  316. }
  317. static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
  318. {
  319. struct timespec ts;
  320. __be32 *p;
  321. p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
  322. if (attr->ia_valid & ATTR_MODE)
  323. *p++ = cpu_to_be32(attr->ia_mode);
  324. else
  325. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  326. if (attr->ia_valid & ATTR_UID)
  327. *p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
  328. else
  329. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  330. if (attr->ia_valid & ATTR_GID)
  331. *p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
  332. else
  333. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  334. if (attr->ia_valid & ATTR_SIZE)
  335. *p++ = cpu_to_be32((u32)attr->ia_size);
  336. else
  337. *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
  338. if (attr->ia_valid & ATTR_ATIME_SET) {
  339. ts = timespec64_to_timespec(attr->ia_atime);
  340. p = xdr_encode_time(p, &ts);
  341. } else if (attr->ia_valid & ATTR_ATIME) {
  342. ts = timespec64_to_timespec(attr->ia_atime);
  343. p = xdr_encode_current_server_time(p, &ts);
  344. } else
  345. p = xdr_time_not_set(p);
  346. if (attr->ia_valid & ATTR_MTIME_SET) {
  347. ts = timespec64_to_timespec(attr->ia_mtime);
  348. xdr_encode_time(p, &ts);
  349. } else if (attr->ia_valid & ATTR_MTIME) {
  350. ts = timespec64_to_timespec(attr->ia_mtime);
  351. xdr_encode_current_server_time(p, &ts);
  352. } else
  353. xdr_time_not_set(p);
  354. }
  355. /*
  356. * 2.3.7. filename
  357. *
  358. * typedef string filename<MAXNAMLEN>;
  359. */
  360. static void encode_filename(struct xdr_stream *xdr,
  361. const char *name, u32 length)
  362. {
  363. __be32 *p;
  364. WARN_ON_ONCE(length > NFS2_MAXNAMLEN);
  365. p = xdr_reserve_space(xdr, 4 + length);
  366. xdr_encode_opaque(p, name, length);
  367. }
  368. static int decode_filename_inline(struct xdr_stream *xdr,
  369. const char **name, u32 *length)
  370. {
  371. __be32 *p;
  372. u32 count;
  373. p = xdr_inline_decode(xdr, 4);
  374. if (unlikely(p == NULL))
  375. goto out_overflow;
  376. count = be32_to_cpup(p);
  377. if (count > NFS3_MAXNAMLEN)
  378. goto out_nametoolong;
  379. p = xdr_inline_decode(xdr, count);
  380. if (unlikely(p == NULL))
  381. goto out_overflow;
  382. *name = (const char *)p;
  383. *length = count;
  384. return 0;
  385. out_nametoolong:
  386. dprintk("NFS: returned filename too long: %u\n", count);
  387. return -ENAMETOOLONG;
  388. out_overflow:
  389. print_overflow_msg(__func__, xdr);
  390. return -EIO;
  391. }
  392. /*
  393. * 2.3.8. path
  394. *
  395. * typedef string path<MAXPATHLEN>;
  396. */
  397. static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
  398. {
  399. __be32 *p;
  400. p = xdr_reserve_space(xdr, 4);
  401. *p = cpu_to_be32(length);
  402. xdr_write_pages(xdr, pages, 0, length);
  403. }
  404. static int decode_path(struct xdr_stream *xdr)
  405. {
  406. u32 length, recvd;
  407. __be32 *p;
  408. p = xdr_inline_decode(xdr, 4);
  409. if (unlikely(p == NULL))
  410. goto out_overflow;
  411. length = be32_to_cpup(p);
  412. if (unlikely(length >= xdr->buf->page_len || length > NFS_MAXPATHLEN))
  413. goto out_size;
  414. recvd = xdr_read_pages(xdr, length);
  415. if (unlikely(length > recvd))
  416. goto out_cheating;
  417. xdr_terminate_string(xdr->buf, length);
  418. return 0;
  419. out_size:
  420. dprintk("NFS: returned pathname too long: %u\n", length);
  421. return -ENAMETOOLONG;
  422. out_cheating:
  423. dprintk("NFS: server cheating in pathname result: "
  424. "length %u > received %u\n", length, recvd);
  425. return -EIO;
  426. out_overflow:
  427. print_overflow_msg(__func__, xdr);
  428. return -EIO;
  429. }
  430. /*
  431. * 2.3.9. attrstat
  432. *
  433. * union attrstat switch (stat status) {
  434. * case NFS_OK:
  435. * fattr attributes;
  436. * default:
  437. * void;
  438. * };
  439. */
  440. static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result,
  441. __u32 *op_status)
  442. {
  443. enum nfs_stat status;
  444. int error;
  445. error = decode_stat(xdr, &status);
  446. if (unlikely(error))
  447. goto out;
  448. if (op_status)
  449. *op_status = status;
  450. if (status != NFS_OK)
  451. goto out_default;
  452. error = decode_fattr(xdr, result);
  453. out:
  454. return error;
  455. out_default:
  456. return nfs_stat_to_errno(status);
  457. }
  458. /*
  459. * 2.3.10. diropargs
  460. *
  461. * struct diropargs {
  462. * fhandle dir;
  463. * filename name;
  464. * };
  465. */
  466. static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
  467. const char *name, u32 length)
  468. {
  469. encode_fhandle(xdr, fh);
  470. encode_filename(xdr, name, length);
  471. }
  472. /*
  473. * 2.3.11. diropres
  474. *
  475. * union diropres switch (stat status) {
  476. * case NFS_OK:
  477. * struct {
  478. * fhandle file;
  479. * fattr attributes;
  480. * } diropok;
  481. * default:
  482. * void;
  483. * };
  484. */
  485. static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result)
  486. {
  487. int error;
  488. error = decode_fhandle(xdr, result->fh);
  489. if (unlikely(error))
  490. goto out;
  491. error = decode_fattr(xdr, result->fattr);
  492. out:
  493. return error;
  494. }
  495. static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result)
  496. {
  497. enum nfs_stat status;
  498. int error;
  499. error = decode_stat(xdr, &status);
  500. if (unlikely(error))
  501. goto out;
  502. if (status != NFS_OK)
  503. goto out_default;
  504. error = decode_diropok(xdr, result);
  505. out:
  506. return error;
  507. out_default:
  508. return nfs_stat_to_errno(status);
  509. }
  510. /*
  511. * NFSv2 XDR encode functions
  512. *
  513. * NFSv2 argument types are defined in section 2.2 of RFC 1094:
  514. * "NFS: Network File System Protocol Specification".
  515. */
  516. static void nfs2_xdr_enc_fhandle(struct rpc_rqst *req,
  517. struct xdr_stream *xdr,
  518. const void *data)
  519. {
  520. const struct nfs_fh *fh = data;
  521. encode_fhandle(xdr, fh);
  522. }
  523. /*
  524. * 2.2.3. sattrargs
  525. *
  526. * struct sattrargs {
  527. * fhandle file;
  528. * sattr attributes;
  529. * };
  530. */
  531. static void nfs2_xdr_enc_sattrargs(struct rpc_rqst *req,
  532. struct xdr_stream *xdr,
  533. const void *data)
  534. {
  535. const struct nfs_sattrargs *args = data;
  536. encode_fhandle(xdr, args->fh);
  537. encode_sattr(xdr, args->sattr);
  538. }
  539. static void nfs2_xdr_enc_diropargs(struct rpc_rqst *req,
  540. struct xdr_stream *xdr,
  541. const void *data)
  542. {
  543. const struct nfs_diropargs *args = data;
  544. encode_diropargs(xdr, args->fh, args->name, args->len);
  545. }
  546. static void nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req,
  547. struct xdr_stream *xdr,
  548. const void *data)
  549. {
  550. const struct nfs_readlinkargs *args = data;
  551. encode_fhandle(xdr, args->fh);
  552. prepare_reply_buffer(req, args->pages, args->pgbase,
  553. args->pglen, NFS_readlinkres_sz);
  554. }
  555. /*
  556. * 2.2.7. readargs
  557. *
  558. * struct readargs {
  559. * fhandle file;
  560. * unsigned offset;
  561. * unsigned count;
  562. * unsigned totalcount;
  563. * };
  564. */
  565. static void encode_readargs(struct xdr_stream *xdr,
  566. const struct nfs_pgio_args *args)
  567. {
  568. u32 offset = args->offset;
  569. u32 count = args->count;
  570. __be32 *p;
  571. encode_fhandle(xdr, args->fh);
  572. p = xdr_reserve_space(xdr, 4 + 4 + 4);
  573. *p++ = cpu_to_be32(offset);
  574. *p++ = cpu_to_be32(count);
  575. *p = cpu_to_be32(count);
  576. }
  577. static void nfs2_xdr_enc_readargs(struct rpc_rqst *req,
  578. struct xdr_stream *xdr,
  579. const void *data)
  580. {
  581. const struct nfs_pgio_args *args = data;
  582. encode_readargs(xdr, args);
  583. prepare_reply_buffer(req, args->pages, args->pgbase,
  584. args->count, NFS_readres_sz);
  585. req->rq_rcv_buf.flags |= XDRBUF_READ;
  586. }
  587. /*
  588. * 2.2.9. writeargs
  589. *
  590. * struct writeargs {
  591. * fhandle file;
  592. * unsigned beginoffset;
  593. * unsigned offset;
  594. * unsigned totalcount;
  595. * nfsdata data;
  596. * };
  597. */
  598. static void encode_writeargs(struct xdr_stream *xdr,
  599. const struct nfs_pgio_args *args)
  600. {
  601. u32 offset = args->offset;
  602. u32 count = args->count;
  603. __be32 *p;
  604. encode_fhandle(xdr, args->fh);
  605. p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
  606. *p++ = cpu_to_be32(offset);
  607. *p++ = cpu_to_be32(offset);
  608. *p++ = cpu_to_be32(count);
  609. /* nfsdata */
  610. *p = cpu_to_be32(count);
  611. xdr_write_pages(xdr, args->pages, args->pgbase, count);
  612. }
  613. static void nfs2_xdr_enc_writeargs(struct rpc_rqst *req,
  614. struct xdr_stream *xdr,
  615. const void *data)
  616. {
  617. const struct nfs_pgio_args *args = data;
  618. encode_writeargs(xdr, args);
  619. xdr->buf->flags |= XDRBUF_WRITE;
  620. }
  621. /*
  622. * 2.2.10. createargs
  623. *
  624. * struct createargs {
  625. * diropargs where;
  626. * sattr attributes;
  627. * };
  628. */
  629. static void nfs2_xdr_enc_createargs(struct rpc_rqst *req,
  630. struct xdr_stream *xdr,
  631. const void *data)
  632. {
  633. const struct nfs_createargs *args = data;
  634. encode_diropargs(xdr, args->fh, args->name, args->len);
  635. encode_sattr(xdr, args->sattr);
  636. }
  637. static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req,
  638. struct xdr_stream *xdr,
  639. const void *data)
  640. {
  641. const struct nfs_removeargs *args = data;
  642. encode_diropargs(xdr, args->fh, args->name.name, args->name.len);
  643. }
  644. /*
  645. * 2.2.12. renameargs
  646. *
  647. * struct renameargs {
  648. * diropargs from;
  649. * diropargs to;
  650. * };
  651. */
  652. static void nfs2_xdr_enc_renameargs(struct rpc_rqst *req,
  653. struct xdr_stream *xdr,
  654. const void *data)
  655. {
  656. const struct nfs_renameargs *args = data;
  657. const struct qstr *old = args->old_name;
  658. const struct qstr *new = args->new_name;
  659. encode_diropargs(xdr, args->old_dir, old->name, old->len);
  660. encode_diropargs(xdr, args->new_dir, new->name, new->len);
  661. }
  662. /*
  663. * 2.2.13. linkargs
  664. *
  665. * struct linkargs {
  666. * fhandle from;
  667. * diropargs to;
  668. * };
  669. */
  670. static void nfs2_xdr_enc_linkargs(struct rpc_rqst *req,
  671. struct xdr_stream *xdr,
  672. const void *data)
  673. {
  674. const struct nfs_linkargs *args = data;
  675. encode_fhandle(xdr, args->fromfh);
  676. encode_diropargs(xdr, args->tofh, args->toname, args->tolen);
  677. }
  678. /*
  679. * 2.2.14. symlinkargs
  680. *
  681. * struct symlinkargs {
  682. * diropargs from;
  683. * path to;
  684. * sattr attributes;
  685. * };
  686. */
  687. static void nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req,
  688. struct xdr_stream *xdr,
  689. const void *data)
  690. {
  691. const struct nfs_symlinkargs *args = data;
  692. encode_diropargs(xdr, args->fromfh, args->fromname, args->fromlen);
  693. encode_path(xdr, args->pages, args->pathlen);
  694. encode_sattr(xdr, args->sattr);
  695. }
  696. /*
  697. * 2.2.17. readdirargs
  698. *
  699. * struct readdirargs {
  700. * fhandle dir;
  701. * nfscookie cookie;
  702. * unsigned count;
  703. * };
  704. */
  705. static void encode_readdirargs(struct xdr_stream *xdr,
  706. const struct nfs_readdirargs *args)
  707. {
  708. __be32 *p;
  709. encode_fhandle(xdr, args->fh);
  710. p = xdr_reserve_space(xdr, 4 + 4);
  711. *p++ = cpu_to_be32(args->cookie);
  712. *p = cpu_to_be32(args->count);
  713. }
  714. static void nfs2_xdr_enc_readdirargs(struct rpc_rqst *req,
  715. struct xdr_stream *xdr,
  716. const void *data)
  717. {
  718. const struct nfs_readdirargs *args = data;
  719. encode_readdirargs(xdr, args);
  720. prepare_reply_buffer(req, args->pages, 0,
  721. args->count, NFS_readdirres_sz);
  722. }
  723. /*
  724. * NFSv2 XDR decode functions
  725. *
  726. * NFSv2 result types are defined in section 2.2 of RFC 1094:
  727. * "NFS: Network File System Protocol Specification".
  728. */
  729. static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr,
  730. void *__unused)
  731. {
  732. enum nfs_stat status;
  733. int error;
  734. error = decode_stat(xdr, &status);
  735. if (unlikely(error))
  736. goto out;
  737. if (status != NFS_OK)
  738. goto out_default;
  739. out:
  740. return error;
  741. out_default:
  742. return nfs_stat_to_errno(status);
  743. }
  744. static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr,
  745. void *result)
  746. {
  747. return decode_attrstat(xdr, result, NULL);
  748. }
  749. static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr,
  750. void *result)
  751. {
  752. return decode_diropres(xdr, result);
  753. }
  754. /*
  755. * 2.2.6. readlinkres
  756. *
  757. * union readlinkres switch (stat status) {
  758. * case NFS_OK:
  759. * path data;
  760. * default:
  761. * void;
  762. * };
  763. */
  764. static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req,
  765. struct xdr_stream *xdr, void *__unused)
  766. {
  767. enum nfs_stat status;
  768. int error;
  769. error = decode_stat(xdr, &status);
  770. if (unlikely(error))
  771. goto out;
  772. if (status != NFS_OK)
  773. goto out_default;
  774. error = decode_path(xdr);
  775. out:
  776. return error;
  777. out_default:
  778. return nfs_stat_to_errno(status);
  779. }
  780. /*
  781. * 2.2.7. readres
  782. *
  783. * union readres switch (stat status) {
  784. * case NFS_OK:
  785. * fattr attributes;
  786. * nfsdata data;
  787. * default:
  788. * void;
  789. * };
  790. */
  791. static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr,
  792. void *data)
  793. {
  794. struct nfs_pgio_res *result = data;
  795. enum nfs_stat status;
  796. int error;
  797. error = decode_stat(xdr, &status);
  798. if (unlikely(error))
  799. goto out;
  800. result->op_status = status;
  801. if (status != NFS_OK)
  802. goto out_default;
  803. error = decode_fattr(xdr, result->fattr);
  804. if (unlikely(error))
  805. goto out;
  806. error = decode_nfsdata(xdr, result);
  807. out:
  808. return error;
  809. out_default:
  810. return nfs_stat_to_errno(status);
  811. }
  812. static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr,
  813. void *data)
  814. {
  815. struct nfs_pgio_res *result = data;
  816. /* All NFSv2 writes are "file sync" writes */
  817. result->verf->committed = NFS_FILE_SYNC;
  818. return decode_attrstat(xdr, result->fattr, &result->op_status);
  819. }
  820. /**
  821. * nfs2_decode_dirent - Decode a single NFSv2 directory entry stored in
  822. * the local page cache.
  823. * @xdr: XDR stream where entry resides
  824. * @entry: buffer to fill in with entry data
  825. * @plus: boolean indicating whether this should be a readdirplus entry
  826. *
  827. * Returns zero if successful, otherwise a negative errno value is
  828. * returned.
  829. *
  830. * This function is not invoked during READDIR reply decoding, but
  831. * rather whenever an application invokes the getdents(2) system call
  832. * on a directory already in our cache.
  833. *
  834. * 2.2.17. entry
  835. *
  836. * struct entry {
  837. * unsigned fileid;
  838. * filename name;
  839. * nfscookie cookie;
  840. * entry *nextentry;
  841. * };
  842. */
  843. int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
  844. bool plus)
  845. {
  846. __be32 *p;
  847. int error;
  848. p = xdr_inline_decode(xdr, 4);
  849. if (unlikely(p == NULL))
  850. goto out_overflow;
  851. if (*p++ == xdr_zero) {
  852. p = xdr_inline_decode(xdr, 4);
  853. if (unlikely(p == NULL))
  854. goto out_overflow;
  855. if (*p++ == xdr_zero)
  856. return -EAGAIN;
  857. entry->eof = 1;
  858. return -EBADCOOKIE;
  859. }
  860. p = xdr_inline_decode(xdr, 4);
  861. if (unlikely(p == NULL))
  862. goto out_overflow;
  863. entry->ino = be32_to_cpup(p);
  864. error = decode_filename_inline(xdr, &entry->name, &entry->len);
  865. if (unlikely(error))
  866. return error;
  867. /*
  868. * The type (size and byte order) of nfscookie isn't defined in
  869. * RFC 1094. This implementation assumes that it's an XDR uint32.
  870. */
  871. entry->prev_cookie = entry->cookie;
  872. p = xdr_inline_decode(xdr, 4);
  873. if (unlikely(p == NULL))
  874. goto out_overflow;
  875. entry->cookie = be32_to_cpup(p);
  876. entry->d_type = DT_UNKNOWN;
  877. return 0;
  878. out_overflow:
  879. print_overflow_msg(__func__, xdr);
  880. return -EAGAIN;
  881. }
  882. /*
  883. * 2.2.17. readdirres
  884. *
  885. * union readdirres switch (stat status) {
  886. * case NFS_OK:
  887. * struct {
  888. * entry *entries;
  889. * bool eof;
  890. * } readdirok;
  891. * default:
  892. * void;
  893. * };
  894. *
  895. * Read the directory contents into the page cache, but don't
  896. * touch them. The actual decoding is done by nfs2_decode_dirent()
  897. * during subsequent nfs_readdir() calls.
  898. */
  899. static int decode_readdirok(struct xdr_stream *xdr)
  900. {
  901. return xdr_read_pages(xdr, xdr->buf->page_len);
  902. }
  903. static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req,
  904. struct xdr_stream *xdr, void *__unused)
  905. {
  906. enum nfs_stat status;
  907. int error;
  908. error = decode_stat(xdr, &status);
  909. if (unlikely(error))
  910. goto out;
  911. if (status != NFS_OK)
  912. goto out_default;
  913. error = decode_readdirok(xdr);
  914. out:
  915. return error;
  916. out_default:
  917. return nfs_stat_to_errno(status);
  918. }
  919. /*
  920. * 2.2.18. statfsres
  921. *
  922. * union statfsres (stat status) {
  923. * case NFS_OK:
  924. * struct {
  925. * unsigned tsize;
  926. * unsigned bsize;
  927. * unsigned blocks;
  928. * unsigned bfree;
  929. * unsigned bavail;
  930. * } info;
  931. * default:
  932. * void;
  933. * };
  934. */
  935. static int decode_info(struct xdr_stream *xdr, struct nfs2_fsstat *result)
  936. {
  937. __be32 *p;
  938. p = xdr_inline_decode(xdr, NFS_info_sz << 2);
  939. if (unlikely(p == NULL))
  940. goto out_overflow;
  941. result->tsize = be32_to_cpup(p++);
  942. result->bsize = be32_to_cpup(p++);
  943. result->blocks = be32_to_cpup(p++);
  944. result->bfree = be32_to_cpup(p++);
  945. result->bavail = be32_to_cpup(p);
  946. return 0;
  947. out_overflow:
  948. print_overflow_msg(__func__, xdr);
  949. return -EIO;
  950. }
  951. static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr,
  952. void *result)
  953. {
  954. enum nfs_stat status;
  955. int error;
  956. error = decode_stat(xdr, &status);
  957. if (unlikely(error))
  958. goto out;
  959. if (status != NFS_OK)
  960. goto out_default;
  961. error = decode_info(xdr, result);
  962. out:
  963. return error;
  964. out_default:
  965. return nfs_stat_to_errno(status);
  966. }
  967. /*
  968. * We need to translate between nfs status return values and
  969. * the local errno values which may not be the same.
  970. */
  971. static const struct {
  972. int stat;
  973. int errno;
  974. } nfs_errtbl[] = {
  975. { NFS_OK, 0 },
  976. { NFSERR_PERM, -EPERM },
  977. { NFSERR_NOENT, -ENOENT },
  978. { NFSERR_IO, -errno_NFSERR_IO},
  979. { NFSERR_NXIO, -ENXIO },
  980. /* { NFSERR_EAGAIN, -EAGAIN }, */
  981. { NFSERR_ACCES, -EACCES },
  982. { NFSERR_EXIST, -EEXIST },
  983. { NFSERR_XDEV, -EXDEV },
  984. { NFSERR_NODEV, -ENODEV },
  985. { NFSERR_NOTDIR, -ENOTDIR },
  986. { NFSERR_ISDIR, -EISDIR },
  987. { NFSERR_INVAL, -EINVAL },
  988. { NFSERR_FBIG, -EFBIG },
  989. { NFSERR_NOSPC, -ENOSPC },
  990. { NFSERR_ROFS, -EROFS },
  991. { NFSERR_MLINK, -EMLINK },
  992. { NFSERR_NAMETOOLONG, -ENAMETOOLONG },
  993. { NFSERR_NOTEMPTY, -ENOTEMPTY },
  994. { NFSERR_DQUOT, -EDQUOT },
  995. { NFSERR_STALE, -ESTALE },
  996. { NFSERR_REMOTE, -EREMOTE },
  997. #ifdef EWFLUSH
  998. { NFSERR_WFLUSH, -EWFLUSH },
  999. #endif
  1000. { NFSERR_BADHANDLE, -EBADHANDLE },
  1001. { NFSERR_NOT_SYNC, -ENOTSYNC },
  1002. { NFSERR_BAD_COOKIE, -EBADCOOKIE },
  1003. { NFSERR_NOTSUPP, -ENOTSUPP },
  1004. { NFSERR_TOOSMALL, -ETOOSMALL },
  1005. { NFSERR_SERVERFAULT, -EREMOTEIO },
  1006. { NFSERR_BADTYPE, -EBADTYPE },
  1007. { NFSERR_JUKEBOX, -EJUKEBOX },
  1008. { -1, -EIO }
  1009. };
  1010. /**
  1011. * nfs_stat_to_errno - convert an NFS status code to a local errno
  1012. * @status: NFS status code to convert
  1013. *
  1014. * Returns a local errno value, or -EIO if the NFS status code is
  1015. * not recognized. This function is used jointly by NFSv2 and NFSv3.
  1016. */
  1017. static int nfs_stat_to_errno(enum nfs_stat status)
  1018. {
  1019. int i;
  1020. for (i = 0; nfs_errtbl[i].stat != -1; i++) {
  1021. if (nfs_errtbl[i].stat == (int)status)
  1022. return nfs_errtbl[i].errno;
  1023. }
  1024. dprintk("NFS: Unrecognized nfs status value: %u\n", status);
  1025. return nfs_errtbl[i].errno;
  1026. }
  1027. #define PROC(proc, argtype, restype, timer) \
  1028. [NFSPROC_##proc] = { \
  1029. .p_proc = NFSPROC_##proc, \
  1030. .p_encode = nfs2_xdr_enc_##argtype, \
  1031. .p_decode = nfs2_xdr_dec_##restype, \
  1032. .p_arglen = NFS_##argtype##_sz, \
  1033. .p_replen = NFS_##restype##_sz, \
  1034. .p_timer = timer, \
  1035. .p_statidx = NFSPROC_##proc, \
  1036. .p_name = #proc, \
  1037. }
  1038. const struct rpc_procinfo nfs_procedures[] = {
  1039. PROC(GETATTR, fhandle, attrstat, 1),
  1040. PROC(SETATTR, sattrargs, attrstat, 0),
  1041. PROC(LOOKUP, diropargs, diropres, 2),
  1042. PROC(READLINK, readlinkargs, readlinkres, 3),
  1043. PROC(READ, readargs, readres, 3),
  1044. PROC(WRITE, writeargs, writeres, 4),
  1045. PROC(CREATE, createargs, diropres, 0),
  1046. PROC(REMOVE, removeargs, stat, 0),
  1047. PROC(RENAME, renameargs, stat, 0),
  1048. PROC(LINK, linkargs, stat, 0),
  1049. PROC(SYMLINK, symlinkargs, stat, 0),
  1050. PROC(MKDIR, createargs, diropres, 0),
  1051. PROC(RMDIR, diropargs, stat, 0),
  1052. PROC(READDIR, readdirargs, readdirres, 3),
  1053. PROC(STATFS, fhandle, statfsres, 0),
  1054. };
  1055. static unsigned int nfs_version2_counts[ARRAY_SIZE(nfs_procedures)];
  1056. const struct rpc_version nfs_version2 = {
  1057. .number = 2,
  1058. .nrprocs = ARRAY_SIZE(nfs_procedures),
  1059. .procs = nfs_procedures,
  1060. .counts = nfs_version2_counts,
  1061. };