nfs3xdr.c 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721
  1. /*
  2. * linux/fs/nfs/nfs3xdr.c
  3. *
  4. * XDR functions to encode/decode NFSv3 RPC arguments and results.
  5. *
  6. * Copyright (C) 1996, 1997 Olaf Kirch
  7. */
  8. #include <linux/param.h>
  9. #include <linux/time.h>
  10. #include <linux/mm.h>
  11. #include <linux/errno.h>
  12. #include <linux/string.h>
  13. #include <linux/in.h>
  14. #include <linux/pagemap.h>
  15. #include <linux/proc_fs.h>
  16. #include <linux/kdev_t.h>
  17. #include <linux/sunrpc/clnt.h>
  18. #include <linux/nfs.h>
  19. #include <linux/nfs3.h>
  20. #include <linux/nfs_fs.h>
  21. #include <linux/nfsacl.h>
  22. #include "internal.h"
  23. #define NFSDBG_FACILITY NFSDBG_XDR
  24. /* Mapping from NFS error code to "errno" error code. */
  25. #define errno_NFSERR_IO EIO
  26. /*
  27. * Declare the space requirements for NFS arguments and replies as
  28. * number of 32bit-words
  29. */
  30. #define NFS3_fhandle_sz (1+16)
  31. #define NFS3_fh_sz (NFS3_fhandle_sz) /* shorthand */
  32. #define NFS3_sattr_sz (15)
  33. #define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2))
  34. #define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2))
  35. #define NFS3_fattr_sz (21)
  36. #define NFS3_cookieverf_sz (NFS3_COOKIEVERFSIZE>>2)
  37. #define NFS3_wcc_attr_sz (6)
  38. #define NFS3_pre_op_attr_sz (1+NFS3_wcc_attr_sz)
  39. #define NFS3_post_op_attr_sz (1+NFS3_fattr_sz)
  40. #define NFS3_wcc_data_sz (NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz)
  41. #define NFS3_fsstat_sz
  42. #define NFS3_fsinfo_sz
  43. #define NFS3_pathconf_sz
  44. #define NFS3_entry_sz (NFS3_filename_sz+3)
  45. #define NFS3_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz)
  46. #define NFS3_getattrargs_sz (NFS3_fh_sz)
  47. #define NFS3_setattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3)
  48. #define NFS3_lookupargs_sz (NFS3_fh_sz+NFS3_filename_sz)
  49. #define NFS3_accessargs_sz (NFS3_fh_sz+1)
  50. #define NFS3_readlinkargs_sz (NFS3_fh_sz)
  51. #define NFS3_readargs_sz (NFS3_fh_sz+3)
  52. #define NFS3_writeargs_sz (NFS3_fh_sz+5)
  53. #define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
  54. #define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
  55. #define NFS3_symlinkargs_sz (NFS3_diropargs_sz+1+NFS3_sattr_sz)
  56. #define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz)
  57. #define NFS3_removeargs_sz (NFS3_fh_sz+NFS3_filename_sz)
  58. #define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz)
  59. #define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz)
  60. #define NFS3_readdirargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+3)
  61. #define NFS3_readdirplusargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+4)
  62. #define NFS3_commitargs_sz (NFS3_fh_sz+3)
  63. #define NFS3_attrstat_sz (1+NFS3_fattr_sz)
  64. #define NFS3_wccstat_sz (1+NFS3_wcc_data_sz)
  65. #define NFS3_removeres_sz (NFS3_wccstat_sz)
  66. #define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
  67. #define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1)
  68. #define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1)
  69. #define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3)
  70. #define NFS3_writeres_sz (1+NFS3_wcc_data_sz+4)
  71. #define NFS3_createres_sz (1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
  72. #define NFS3_renameres_sz (1+(2 * NFS3_wcc_data_sz))
  73. #define NFS3_linkres_sz (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
  74. #define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2)
  75. #define NFS3_fsstatres_sz (1+NFS3_post_op_attr_sz+13)
  76. #define NFS3_fsinfores_sz (1+NFS3_post_op_attr_sz+12)
  77. #define NFS3_pathconfres_sz (1+NFS3_post_op_attr_sz+6)
  78. #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2)
  79. #define ACL3_getaclargs_sz (NFS3_fh_sz+1)
  80. #define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \
  81. XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
  82. #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \
  83. XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
  84. #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz)
  85. /*
  86. * Map file type to S_IFMT bits
  87. */
  88. static const umode_t nfs_type2fmt[] = {
  89. [NF3BAD] = 0,
  90. [NF3REG] = S_IFREG,
  91. [NF3DIR] = S_IFDIR,
  92. [NF3BLK] = S_IFBLK,
  93. [NF3CHR] = S_IFCHR,
  94. [NF3LNK] = S_IFLNK,
  95. [NF3SOCK] = S_IFSOCK,
  96. [NF3FIFO] = S_IFIFO,
  97. };
  98. static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
  99. {
  100. dprintk("nfs: %s: prematurely hit end of receive buffer. "
  101. "Remaining buffer length is %tu words.\n",
  102. func, xdr->end - xdr->p);
  103. }
  104. /*
  105. * While encoding arguments, set up the reply buffer in advance to
  106. * receive reply data directly into the page cache.
  107. */
  108. static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
  109. unsigned int base, unsigned int len,
  110. unsigned int bufsize)
  111. {
  112. struct rpc_auth *auth = req->rq_cred->cr_auth;
  113. unsigned int replen;
  114. replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
  115. xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
  116. }
  117. /*
  118. * Common NFS XDR functions as inlines
  119. */
  120. static inline __be32 *
  121. xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh)
  122. {
  123. if ((fh->size = ntohl(*p++)) <= NFS3_FHSIZE) {
  124. memcpy(fh->data, p, fh->size);
  125. return p + XDR_QUADLEN(fh->size);
  126. }
  127. return NULL;
  128. }
  129. static inline __be32 *
  130. xdr_decode_fhandle_stream(struct xdr_stream *xdr, struct nfs_fh *fh)
  131. {
  132. __be32 *p;
  133. p = xdr_inline_decode(xdr, 4);
  134. if (unlikely(!p))
  135. goto out_overflow;
  136. fh->size = ntohl(*p++);
  137. if (fh->size <= NFS3_FHSIZE) {
  138. p = xdr_inline_decode(xdr, fh->size);
  139. if (unlikely(!p))
  140. goto out_overflow;
  141. memcpy(fh->data, p, fh->size);
  142. return p + XDR_QUADLEN(fh->size);
  143. }
  144. return NULL;
  145. out_overflow:
  146. print_overflow_msg(__func__, xdr);
  147. return ERR_PTR(-EIO);
  148. }
  149. /*
  150. * Encode/decode time.
  151. */
  152. static inline __be32 *
  153. xdr_encode_time3(__be32 *p, const struct timespec *timep)
  154. {
  155. *p++ = htonl(timep->tv_sec);
  156. *p++ = htonl(timep->tv_nsec);
  157. return p;
  158. }
  159. static inline __be32 *
  160. xdr_decode_time3(__be32 *p, struct timespec *timep)
  161. {
  162. timep->tv_sec = ntohl(*p++);
  163. timep->tv_nsec = ntohl(*p++);
  164. return p;
  165. }
  166. static __be32 *
  167. xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
  168. {
  169. unsigned int type, major, minor;
  170. umode_t fmode;
  171. type = ntohl(*p++);
  172. if (type > NF3FIFO)
  173. type = NF3NON;
  174. fmode = nfs_type2fmt[type];
  175. fattr->mode = (ntohl(*p++) & ~S_IFMT) | fmode;
  176. fattr->nlink = ntohl(*p++);
  177. fattr->uid = ntohl(*p++);
  178. fattr->gid = ntohl(*p++);
  179. p = xdr_decode_hyper(p, &fattr->size);
  180. p = xdr_decode_hyper(p, &fattr->du.nfs3.used);
  181. /* Turn remote device info into Linux-specific dev_t */
  182. major = ntohl(*p++);
  183. minor = ntohl(*p++);
  184. fattr->rdev = MKDEV(major, minor);
  185. if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
  186. fattr->rdev = 0;
  187. p = xdr_decode_hyper(p, &fattr->fsid.major);
  188. fattr->fsid.minor = 0;
  189. p = xdr_decode_hyper(p, &fattr->fileid);
  190. p = xdr_decode_time3(p, &fattr->atime);
  191. p = xdr_decode_time3(p, &fattr->mtime);
  192. p = xdr_decode_time3(p, &fattr->ctime);
  193. /* Update the mode bits */
  194. fattr->valid |= NFS_ATTR_FATTR_V3;
  195. return p;
  196. }
  197. static inline __be32 *
  198. xdr_encode_sattr(__be32 *p, const struct iattr *attr)
  199. {
  200. if (attr->ia_valid & ATTR_MODE) {
  201. *p++ = xdr_one;
  202. *p++ = htonl(attr->ia_mode & S_IALLUGO);
  203. } else {
  204. *p++ = xdr_zero;
  205. }
  206. if (attr->ia_valid & ATTR_UID) {
  207. *p++ = xdr_one;
  208. *p++ = htonl(attr->ia_uid);
  209. } else {
  210. *p++ = xdr_zero;
  211. }
  212. if (attr->ia_valid & ATTR_GID) {
  213. *p++ = xdr_one;
  214. *p++ = htonl(attr->ia_gid);
  215. } else {
  216. *p++ = xdr_zero;
  217. }
  218. if (attr->ia_valid & ATTR_SIZE) {
  219. *p++ = xdr_one;
  220. p = xdr_encode_hyper(p, (__u64) attr->ia_size);
  221. } else {
  222. *p++ = xdr_zero;
  223. }
  224. if (attr->ia_valid & ATTR_ATIME_SET) {
  225. *p++ = xdr_two;
  226. p = xdr_encode_time3(p, &attr->ia_atime);
  227. } else if (attr->ia_valid & ATTR_ATIME) {
  228. *p++ = xdr_one;
  229. } else {
  230. *p++ = xdr_zero;
  231. }
  232. if (attr->ia_valid & ATTR_MTIME_SET) {
  233. *p++ = xdr_two;
  234. p = xdr_encode_time3(p, &attr->ia_mtime);
  235. } else if (attr->ia_valid & ATTR_MTIME) {
  236. *p++ = xdr_one;
  237. } else {
  238. *p++ = xdr_zero;
  239. }
  240. return p;
  241. }
  242. static inline __be32 *
  243. xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr)
  244. {
  245. p = xdr_decode_hyper(p, &fattr->pre_size);
  246. p = xdr_decode_time3(p, &fattr->pre_mtime);
  247. p = xdr_decode_time3(p, &fattr->pre_ctime);
  248. fattr->valid |= NFS_ATTR_FATTR_PRESIZE
  249. | NFS_ATTR_FATTR_PREMTIME
  250. | NFS_ATTR_FATTR_PRECTIME;
  251. return p;
  252. }
  253. static inline __be32 *
  254. xdr_decode_post_op_attr(__be32 *p, struct nfs_fattr *fattr)
  255. {
  256. if (*p++)
  257. p = xdr_decode_fattr(p, fattr);
  258. return p;
  259. }
  260. static inline __be32 *
  261. xdr_decode_post_op_attr_stream(struct xdr_stream *xdr, struct nfs_fattr *fattr)
  262. {
  263. __be32 *p;
  264. p = xdr_inline_decode(xdr, 4);
  265. if (unlikely(!p))
  266. goto out_overflow;
  267. if (ntohl(*p++)) {
  268. p = xdr_inline_decode(xdr, 84);
  269. if (unlikely(!p))
  270. goto out_overflow;
  271. p = xdr_decode_fattr(p, fattr);
  272. }
  273. return p;
  274. out_overflow:
  275. print_overflow_msg(__func__, xdr);
  276. return ERR_PTR(-EIO);
  277. }
  278. static inline __be32 *
  279. xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr)
  280. {
  281. if (*p++)
  282. return xdr_decode_wcc_attr(p, fattr);
  283. return p;
  284. }
  285. static inline __be32 *
  286. xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr)
  287. {
  288. p = xdr_decode_pre_op_attr(p, fattr);
  289. return xdr_decode_post_op_attr(p, fattr);
  290. }
  291. /*
  292. * Encode/decode NFSv3 basic data types
  293. *
  294. * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
  295. * "NFS Version 3 Protocol Specification".
  296. *
  297. * Not all basic data types have their own encoding and decoding
  298. * functions. For run-time efficiency, some data types are encoded
  299. * or decoded inline.
  300. */
  301. static void encode_uint32(struct xdr_stream *xdr, u32 value)
  302. {
  303. __be32 *p = xdr_reserve_space(xdr, 4);
  304. *p = cpu_to_be32(value);
  305. }
  306. /*
  307. * filename3
  308. *
  309. * typedef string filename3<>;
  310. */
  311. static void encode_filename3(struct xdr_stream *xdr,
  312. const char *name, u32 length)
  313. {
  314. __be32 *p;
  315. BUG_ON(length > NFS3_MAXNAMLEN);
  316. p = xdr_reserve_space(xdr, 4 + length);
  317. xdr_encode_opaque(p, name, length);
  318. }
  319. /*
  320. * nfspath3
  321. *
  322. * typedef string nfspath3<>;
  323. */
  324. static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
  325. const u32 length)
  326. {
  327. BUG_ON(length > NFS3_MAXPATHLEN);
  328. encode_uint32(xdr, length);
  329. xdr_write_pages(xdr, pages, 0, length);
  330. }
  331. /*
  332. * cookie3
  333. *
  334. * typedef uint64 cookie3
  335. */
  336. static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
  337. {
  338. return xdr_encode_hyper(p, cookie);
  339. }
  340. /*
  341. * cookieverf3
  342. *
  343. * typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
  344. */
  345. static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
  346. {
  347. memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
  348. return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
  349. }
  350. /*
  351. * createverf3
  352. *
  353. * typedef opaque createverf3[NFS3_CREATEVERFSIZE];
  354. */
  355. static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
  356. {
  357. __be32 *p;
  358. p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
  359. memcpy(p, verifier, NFS3_CREATEVERFSIZE);
  360. }
  361. /*
  362. * ftype3
  363. *
  364. * enum ftype3 {
  365. * NF3REG = 1,
  366. * NF3DIR = 2,
  367. * NF3BLK = 3,
  368. * NF3CHR = 4,
  369. * NF3LNK = 5,
  370. * NF3SOCK = 6,
  371. * NF3FIFO = 7
  372. * };
  373. */
  374. static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
  375. {
  376. BUG_ON(type > NF3FIFO);
  377. encode_uint32(xdr, type);
  378. }
  379. /*
  380. * specdata3
  381. *
  382. * struct specdata3 {
  383. * uint32 specdata1;
  384. * uint32 specdata2;
  385. * };
  386. */
  387. static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
  388. {
  389. __be32 *p;
  390. p = xdr_reserve_space(xdr, 8);
  391. *p++ = cpu_to_be32(MAJOR(rdev));
  392. *p = cpu_to_be32(MINOR(rdev));
  393. }
  394. /*
  395. * nfs_fh3
  396. *
  397. * struct nfs_fh3 {
  398. * opaque data<NFS3_FHSIZE>;
  399. * };
  400. */
  401. static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
  402. {
  403. __be32 *p;
  404. BUG_ON(fh->size > NFS3_FHSIZE);
  405. p = xdr_reserve_space(xdr, 4 + fh->size);
  406. xdr_encode_opaque(p, fh->data, fh->size);
  407. }
  408. /*
  409. * sattr3
  410. *
  411. * enum time_how {
  412. * DONT_CHANGE = 0,
  413. * SET_TO_SERVER_TIME = 1,
  414. * SET_TO_CLIENT_TIME = 2
  415. * };
  416. *
  417. * union set_mode3 switch (bool set_it) {
  418. * case TRUE:
  419. * mode3 mode;
  420. * default:
  421. * void;
  422. * };
  423. *
  424. * union set_uid3 switch (bool set_it) {
  425. * case TRUE:
  426. * uid3 uid;
  427. * default:
  428. * void;
  429. * };
  430. *
  431. * union set_gid3 switch (bool set_it) {
  432. * case TRUE:
  433. * gid3 gid;
  434. * default:
  435. * void;
  436. * };
  437. *
  438. * union set_size3 switch (bool set_it) {
  439. * case TRUE:
  440. * size3 size;
  441. * default:
  442. * void;
  443. * };
  444. *
  445. * union set_atime switch (time_how set_it) {
  446. * case SET_TO_CLIENT_TIME:
  447. * nfstime3 atime;
  448. * default:
  449. * void;
  450. * };
  451. *
  452. * union set_mtime switch (time_how set_it) {
  453. * case SET_TO_CLIENT_TIME:
  454. * nfstime3 mtime;
  455. * default:
  456. * void;
  457. * };
  458. *
  459. * struct sattr3 {
  460. * set_mode3 mode;
  461. * set_uid3 uid;
  462. * set_gid3 gid;
  463. * set_size3 size;
  464. * set_atime atime;
  465. * set_mtime mtime;
  466. * };
  467. */
  468. static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
  469. {
  470. u32 nbytes;
  471. __be32 *p;
  472. /*
  473. * In order to make only a single xdr_reserve_space() call,
  474. * pre-compute the total number of bytes to be reserved.
  475. * Six boolean values, one for each set_foo field, are always
  476. * present in the encoded result, so start there.
  477. */
  478. nbytes = 6 * 4;
  479. if (attr->ia_valid & ATTR_MODE)
  480. nbytes += 4;
  481. if (attr->ia_valid & ATTR_UID)
  482. nbytes += 4;
  483. if (attr->ia_valid & ATTR_GID)
  484. nbytes += 4;
  485. if (attr->ia_valid & ATTR_SIZE)
  486. nbytes += 8;
  487. if (attr->ia_valid & ATTR_ATIME_SET)
  488. nbytes += 8;
  489. if (attr->ia_valid & ATTR_MTIME_SET)
  490. nbytes += 8;
  491. p = xdr_reserve_space(xdr, nbytes);
  492. xdr_encode_sattr(p, attr);
  493. }
  494. /*
  495. * diropargs3
  496. *
  497. * struct diropargs3 {
  498. * nfs_fh3 dir;
  499. * filename3 name;
  500. * };
  501. */
  502. static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
  503. const char *name, u32 length)
  504. {
  505. encode_nfs_fh3(xdr, fh);
  506. encode_filename3(xdr, name, length);
  507. }
  508. /*
  509. * NFSv3 XDR encode functions
  510. *
  511. * NFSv3 argument types are defined in section 3.3 of RFC 1813:
  512. * "NFS Version 3 Protocol Specification".
  513. */
  514. /*
  515. * 3.3.1 GETATTR3args
  516. *
  517. * struct GETATTR3args {
  518. * nfs_fh3 object;
  519. * };
  520. */
  521. static int nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, __be32 *p,
  522. const struct nfs_fh *fh)
  523. {
  524. struct xdr_stream xdr;
  525. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  526. encode_nfs_fh3(&xdr, fh);
  527. return 0;
  528. }
  529. /*
  530. * 3.3.2 SETATTR3args
  531. *
  532. * union sattrguard3 switch (bool check) {
  533. * case TRUE:
  534. * nfstime3 obj_ctime;
  535. * case FALSE:
  536. * void;
  537. * };
  538. *
  539. * struct SETATTR3args {
  540. * nfs_fh3 object;
  541. * sattr3 new_attributes;
  542. * sattrguard3 guard;
  543. * };
  544. */
  545. static void encode_sattrguard3(struct xdr_stream *xdr,
  546. const struct nfs3_sattrargs *args)
  547. {
  548. __be32 *p;
  549. if (args->guard) {
  550. p = xdr_reserve_space(xdr, 4 + 8);
  551. *p++ = xdr_one;
  552. xdr_encode_time3(p, &args->guardtime);
  553. } else {
  554. p = xdr_reserve_space(xdr, 4);
  555. *p = xdr_zero;
  556. }
  557. }
  558. static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p,
  559. const struct nfs3_sattrargs *args)
  560. {
  561. struct xdr_stream xdr;
  562. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  563. encode_nfs_fh3(&xdr, args->fh);
  564. encode_sattr3(&xdr, args->sattr);
  565. encode_sattrguard3(&xdr, args);
  566. return 0;
  567. }
  568. /*
  569. * 3.3.3 LOOKUP3args
  570. *
  571. * struct LOOKUP3args {
  572. * diropargs3 what;
  573. * };
  574. */
  575. static int nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, __be32 *p,
  576. const struct nfs3_diropargs *args)
  577. {
  578. struct xdr_stream xdr;
  579. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  580. encode_diropargs3(&xdr, args->fh, args->name, args->len);
  581. return 0;
  582. }
  583. /*
  584. * 3.3.4 ACCESS3args
  585. *
  586. * struct ACCESS3args {
  587. * nfs_fh3 object;
  588. * uint32 access;
  589. * };
  590. */
  591. static void encode_access3args(struct xdr_stream *xdr,
  592. const struct nfs3_accessargs *args)
  593. {
  594. encode_nfs_fh3(xdr, args->fh);
  595. encode_uint32(xdr, args->access);
  596. }
  597. static int nfs3_xdr_enc_access3args(struct rpc_rqst *req, __be32 *p,
  598. const struct nfs3_accessargs *args)
  599. {
  600. struct xdr_stream xdr;
  601. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  602. encode_access3args(&xdr, args);
  603. return 0;
  604. }
  605. /*
  606. * 3.3.5 READLINK3args
  607. *
  608. * struct READLINK3args {
  609. * nfs_fh3 symlink;
  610. * };
  611. */
  612. static int nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, __be32 *p,
  613. const struct nfs3_readlinkargs *args)
  614. {
  615. struct xdr_stream xdr;
  616. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  617. encode_nfs_fh3(&xdr, args->fh);
  618. prepare_reply_buffer(req, args->pages, args->pgbase,
  619. args->pglen, NFS3_readlinkres_sz);
  620. return 0;
  621. }
  622. /*
  623. * 3.3.6 READ3args
  624. *
  625. * struct READ3args {
  626. * nfs_fh3 file;
  627. * offset3 offset;
  628. * count3 count;
  629. * };
  630. */
  631. static void encode_read3args(struct xdr_stream *xdr,
  632. const struct nfs_readargs *args)
  633. {
  634. __be32 *p;
  635. encode_nfs_fh3(xdr, args->fh);
  636. p = xdr_reserve_space(xdr, 8 + 4);
  637. p = xdr_encode_hyper(p, args->offset);
  638. *p = cpu_to_be32(args->count);
  639. }
  640. static int nfs3_xdr_enc_read3args(struct rpc_rqst *req, __be32 *p,
  641. const struct nfs_readargs *args)
  642. {
  643. struct xdr_stream xdr;
  644. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  645. encode_read3args(&xdr, args);
  646. prepare_reply_buffer(req, args->pages, args->pgbase,
  647. args->count, NFS3_readres_sz);
  648. req->rq_rcv_buf.flags |= XDRBUF_READ;
  649. return 0;
  650. }
  651. /*
  652. * 3.3.7 WRITE3args
  653. *
  654. * enum stable_how {
  655. * UNSTABLE = 0,
  656. * DATA_SYNC = 1,
  657. * FILE_SYNC = 2
  658. * };
  659. *
  660. * struct WRITE3args {
  661. * nfs_fh3 file;
  662. * offset3 offset;
  663. * count3 count;
  664. * stable_how stable;
  665. * opaque data<>;
  666. * };
  667. */
  668. static void encode_write3args(struct xdr_stream *xdr,
  669. const struct nfs_writeargs *args)
  670. {
  671. __be32 *p;
  672. encode_nfs_fh3(xdr, args->fh);
  673. p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
  674. p = xdr_encode_hyper(p, args->offset);
  675. *p++ = cpu_to_be32(args->count);
  676. BUG_ON(args->stable > NFS_FILE_SYNC);
  677. *p++ = cpu_to_be32(args->stable);
  678. *p = cpu_to_be32(args->count);
  679. xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
  680. }
  681. static int nfs3_xdr_enc_write3args(struct rpc_rqst *req, __be32 *p,
  682. const struct nfs_writeargs *args)
  683. {
  684. struct xdr_stream xdr;
  685. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  686. encode_write3args(&xdr, args);
  687. xdr.buf->flags |= XDRBUF_WRITE;
  688. return 0;
  689. }
  690. /*
  691. * 3.3.8 CREATE3args
  692. *
  693. * enum createmode3 {
  694. * UNCHECKED = 0,
  695. * GUARDED = 1,
  696. * EXCLUSIVE = 2
  697. * };
  698. *
  699. * union createhow3 switch (createmode3 mode) {
  700. * case UNCHECKED:
  701. * case GUARDED:
  702. * sattr3 obj_attributes;
  703. * case EXCLUSIVE:
  704. * createverf3 verf;
  705. * };
  706. *
  707. * struct CREATE3args {
  708. * diropargs3 where;
  709. * createhow3 how;
  710. * };
  711. */
  712. static void encode_createhow3(struct xdr_stream *xdr,
  713. const struct nfs3_createargs *args)
  714. {
  715. encode_uint32(xdr, args->createmode);
  716. switch (args->createmode) {
  717. case NFS3_CREATE_UNCHECKED:
  718. case NFS3_CREATE_GUARDED:
  719. encode_sattr3(xdr, args->sattr);
  720. break;
  721. case NFS3_CREATE_EXCLUSIVE:
  722. encode_createverf3(xdr, args->verifier);
  723. break;
  724. default:
  725. BUG();
  726. }
  727. }
  728. static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p,
  729. const struct nfs3_createargs *args)
  730. {
  731. struct xdr_stream xdr;
  732. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  733. encode_diropargs3(&xdr, args->fh, args->name, args->len);
  734. encode_createhow3(&xdr, args);
  735. return 0;
  736. }
  737. /*
  738. * 3.3.9 MKDIR3args
  739. *
  740. * struct MKDIR3args {
  741. * diropargs3 where;
  742. * sattr3 attributes;
  743. * };
  744. */
  745. static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, __be32 *p,
  746. const struct nfs3_mkdirargs *args)
  747. {
  748. struct xdr_stream xdr;
  749. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  750. encode_diropargs3(&xdr, args->fh, args->name, args->len);
  751. encode_sattr3(&xdr, args->sattr);
  752. return 0;
  753. }
  754. /*
  755. * 3.3.10 SYMLINK3args
  756. *
  757. * struct symlinkdata3 {
  758. * sattr3 symlink_attributes;
  759. * nfspath3 symlink_data;
  760. * };
  761. *
  762. * struct SYMLINK3args {
  763. * diropargs3 where;
  764. * symlinkdata3 symlink;
  765. * };
  766. */
  767. static void encode_symlinkdata3(struct xdr_stream *xdr,
  768. const struct nfs3_symlinkargs *args)
  769. {
  770. encode_sattr3(xdr, args->sattr);
  771. encode_nfspath3(xdr, args->pages, args->pathlen);
  772. }
  773. static int nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, __be32 *p,
  774. const struct nfs3_symlinkargs *args)
  775. {
  776. struct xdr_stream xdr;
  777. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  778. encode_diropargs3(&xdr, args->fromfh, args->fromname, args->fromlen);
  779. encode_symlinkdata3(&xdr, args);
  780. return 0;
  781. }
  782. /*
  783. * 3.3.11 MKNOD3args
  784. *
  785. * struct devicedata3 {
  786. * sattr3 dev_attributes;
  787. * specdata3 spec;
  788. * };
  789. *
  790. * union mknoddata3 switch (ftype3 type) {
  791. * case NF3CHR:
  792. * case NF3BLK:
  793. * devicedata3 device;
  794. * case NF3SOCK:
  795. * case NF3FIFO:
  796. * sattr3 pipe_attributes;
  797. * default:
  798. * void;
  799. * };
  800. *
  801. * struct MKNOD3args {
  802. * diropargs3 where;
  803. * mknoddata3 what;
  804. * };
  805. */
  806. static void encode_devicedata3(struct xdr_stream *xdr,
  807. const struct nfs3_mknodargs *args)
  808. {
  809. encode_sattr3(xdr, args->sattr);
  810. encode_specdata3(xdr, args->rdev);
  811. }
  812. static void encode_mknoddata3(struct xdr_stream *xdr,
  813. const struct nfs3_mknodargs *args)
  814. {
  815. encode_ftype3(xdr, args->type);
  816. switch (args->type) {
  817. case NF3CHR:
  818. case NF3BLK:
  819. encode_devicedata3(xdr, args);
  820. break;
  821. case NF3SOCK:
  822. case NF3FIFO:
  823. encode_sattr3(xdr, args->sattr);
  824. break;
  825. case NF3REG:
  826. case NF3DIR:
  827. break;
  828. default:
  829. BUG();
  830. }
  831. }
  832. static int nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, __be32 *p,
  833. const struct nfs3_mknodargs *args)
  834. {
  835. struct xdr_stream xdr;
  836. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  837. encode_diropargs3(&xdr, args->fh, args->name, args->len);
  838. encode_mknoddata3(&xdr, args);
  839. return 0;
  840. }
  841. /*
  842. * 3.3.12 REMOVE3args
  843. *
  844. * struct REMOVE3args {
  845. * diropargs3 object;
  846. * };
  847. */
  848. static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p,
  849. const struct nfs_removeargs *args)
  850. {
  851. struct xdr_stream xdr;
  852. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  853. encode_diropargs3(&xdr, args->fh, args->name.name, args->name.len);
  854. return 0;
  855. }
  856. /*
  857. * 3.3.14 RENAME3args
  858. *
  859. * struct RENAME3args {
  860. * diropargs3 from;
  861. * diropargs3 to;
  862. * };
  863. */
  864. static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p,
  865. const struct nfs_renameargs *args)
  866. {
  867. const struct qstr *old = args->old_name;
  868. const struct qstr *new = args->new_name;
  869. struct xdr_stream xdr;
  870. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  871. encode_diropargs3(&xdr, args->old_dir, old->name, old->len);
  872. encode_diropargs3(&xdr, args->new_dir, new->name, new->len);
  873. return 0;
  874. }
  875. /*
  876. * 3.3.15 LINK3args
  877. *
  878. * struct LINK3args {
  879. * nfs_fh3 file;
  880. * diropargs3 link;
  881. * };
  882. */
  883. static int nfs3_xdr_enc_link3args(struct rpc_rqst *req, __be32 *p,
  884. const struct nfs3_linkargs *args)
  885. {
  886. struct xdr_stream xdr;
  887. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  888. encode_nfs_fh3(&xdr, args->fromfh);
  889. encode_diropargs3(&xdr, args->tofh, args->toname, args->tolen);
  890. return 0;
  891. }
  892. /*
  893. * 3.3.16 READDIR3args
  894. *
  895. * struct READDIR3args {
  896. * nfs_fh3 dir;
  897. * cookie3 cookie;
  898. * cookieverf3 cookieverf;
  899. * count3 count;
  900. * };
  901. */
  902. static void encode_readdir3args(struct xdr_stream *xdr,
  903. const struct nfs3_readdirargs *args)
  904. {
  905. __be32 *p;
  906. encode_nfs_fh3(xdr, args->fh);
  907. p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
  908. p = xdr_encode_cookie3(p, args->cookie);
  909. p = xdr_encode_cookieverf3(p, args->verf);
  910. *p = cpu_to_be32(args->count);
  911. }
  912. static int nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, __be32 *p,
  913. const struct nfs3_readdirargs *args)
  914. {
  915. struct xdr_stream xdr;
  916. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  917. encode_readdir3args(&xdr, args);
  918. prepare_reply_buffer(req, args->pages, 0,
  919. args->count, NFS3_readdirres_sz);
  920. return 0;
  921. }
  922. /*
  923. * 3.3.17 READDIRPLUS3args
  924. *
  925. * struct READDIRPLUS3args {
  926. * nfs_fh3 dir;
  927. * cookie3 cookie;
  928. * cookieverf3 cookieverf;
  929. * count3 dircount;
  930. * count3 maxcount;
  931. * };
  932. */
  933. static void encode_readdirplus3args(struct xdr_stream *xdr,
  934. const struct nfs3_readdirargs *args)
  935. {
  936. __be32 *p;
  937. encode_nfs_fh3(xdr, args->fh);
  938. p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
  939. p = xdr_encode_cookie3(p, args->cookie);
  940. p = xdr_encode_cookieverf3(p, args->verf);
  941. /*
  942. * readdirplus: need dircount + buffer size.
  943. * We just make sure we make dircount big enough
  944. */
  945. *p++ = cpu_to_be32(args->count >> 3);
  946. *p = cpu_to_be32(args->count);
  947. }
  948. static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, __be32 *p,
  949. const struct nfs3_readdirargs *args)
  950. {
  951. struct xdr_stream xdr;
  952. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  953. encode_readdirplus3args(&xdr, args);
  954. prepare_reply_buffer(req, args->pages, 0,
  955. args->count, NFS3_readdirres_sz);
  956. return 0;
  957. }
  958. /*
  959. * Decode the result of a readdir call.
  960. * We just check for syntactical correctness.
  961. */
  962. static int
  963. nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res)
  964. {
  965. struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
  966. struct kvec *iov = rcvbuf->head;
  967. struct page **page;
  968. size_t hdrlen;
  969. u32 recvd, pglen;
  970. int status;
  971. status = ntohl(*p++);
  972. /* Decode post_op_attrs */
  973. p = xdr_decode_post_op_attr(p, res->dir_attr);
  974. if (status)
  975. return nfs_stat_to_errno(status);
  976. /* Decode verifier cookie */
  977. if (res->verf) {
  978. res->verf[0] = *p++;
  979. res->verf[1] = *p++;
  980. } else {
  981. p += 2;
  982. }
  983. hdrlen = (u8 *) p - (u8 *) iov->iov_base;
  984. if (iov->iov_len < hdrlen) {
  985. dprintk("NFS: READDIR reply header overflowed:"
  986. "length %Zu > %Zu\n", hdrlen, iov->iov_len);
  987. return -errno_NFSERR_IO;
  988. } else if (iov->iov_len != hdrlen) {
  989. dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
  990. xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
  991. }
  992. pglen = rcvbuf->page_len;
  993. recvd = rcvbuf->len - hdrlen;
  994. if (pglen > recvd)
  995. pglen = recvd;
  996. page = rcvbuf->pages;
  997. return pglen;
  998. }
  999. __be32 *
  1000. nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus)
  1001. {
  1002. __be32 *p;
  1003. struct nfs_entry old = *entry;
  1004. p = xdr_inline_decode(xdr, 4);
  1005. if (unlikely(!p))
  1006. goto out_overflow;
  1007. if (!ntohl(*p++)) {
  1008. p = xdr_inline_decode(xdr, 4);
  1009. if (unlikely(!p))
  1010. goto out_overflow;
  1011. if (!ntohl(*p++))
  1012. return ERR_PTR(-EAGAIN);
  1013. entry->eof = 1;
  1014. return ERR_PTR(-EBADCOOKIE);
  1015. }
  1016. p = xdr_inline_decode(xdr, 12);
  1017. if (unlikely(!p))
  1018. goto out_overflow;
  1019. p = xdr_decode_hyper(p, &entry->ino);
  1020. entry->len = ntohl(*p++);
  1021. p = xdr_inline_decode(xdr, entry->len + 8);
  1022. if (unlikely(!p))
  1023. goto out_overflow;
  1024. entry->name = (const char *) p;
  1025. p += XDR_QUADLEN(entry->len);
  1026. entry->prev_cookie = entry->cookie;
  1027. p = xdr_decode_hyper(p, &entry->cookie);
  1028. entry->d_type = DT_UNKNOWN;
  1029. if (plus) {
  1030. entry->fattr->valid = 0;
  1031. p = xdr_decode_post_op_attr_stream(xdr, entry->fattr);
  1032. if (IS_ERR(p))
  1033. goto out_overflow_exit;
  1034. entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
  1035. /* In fact, a post_op_fh3: */
  1036. p = xdr_inline_decode(xdr, 4);
  1037. if (unlikely(!p))
  1038. goto out_overflow;
  1039. if (*p++) {
  1040. p = xdr_decode_fhandle_stream(xdr, entry->fh);
  1041. if (IS_ERR(p))
  1042. goto out_overflow_exit;
  1043. /* Ugh -- server reply was truncated */
  1044. if (p == NULL) {
  1045. dprintk("NFS: FH truncated\n");
  1046. *entry = old;
  1047. return ERR_PTR(-EAGAIN);
  1048. }
  1049. } else
  1050. memset((u8*)(entry->fh), 0, sizeof(*entry->fh));
  1051. }
  1052. p = xdr_inline_peek(xdr, 8);
  1053. if (p != NULL)
  1054. entry->eof = !p[0] && p[1];
  1055. else
  1056. entry->eof = 0;
  1057. return p;
  1058. out_overflow:
  1059. print_overflow_msg(__func__, xdr);
  1060. out_overflow_exit:
  1061. return ERR_PTR(-EAGAIN);
  1062. }
  1063. /*
  1064. * 3.3.21 COMMIT3args
  1065. *
  1066. * struct COMMIT3args {
  1067. * nfs_fh3 file;
  1068. * offset3 offset;
  1069. * count3 count;
  1070. * };
  1071. */
  1072. static void encode_commit3args(struct xdr_stream *xdr,
  1073. const struct nfs_writeargs *args)
  1074. {
  1075. __be32 *p;
  1076. encode_nfs_fh3(xdr, args->fh);
  1077. p = xdr_reserve_space(xdr, 8 + 4);
  1078. p = xdr_encode_hyper(p, args->offset);
  1079. *p = cpu_to_be32(args->count);
  1080. }
  1081. static int nfs3_xdr_enc_commit3args(struct rpc_rqst *req, __be32 *p,
  1082. const struct nfs_writeargs *args)
  1083. {
  1084. struct xdr_stream xdr;
  1085. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  1086. encode_commit3args(&xdr, args);
  1087. return 0;
  1088. }
  1089. #ifdef CONFIG_NFS_V3_ACL
  1090. static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p,
  1091. const struct nfs3_getaclargs *args)
  1092. {
  1093. struct xdr_stream xdr;
  1094. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  1095. encode_nfs_fh3(&xdr, args->fh);
  1096. encode_uint32(&xdr, args->mask);
  1097. if (args->mask & (NFS_ACL | NFS_DFACL))
  1098. prepare_reply_buffer(req, args->pages, 0,
  1099. NFSACL_MAXPAGES << PAGE_SHIFT,
  1100. ACL3_getaclres_sz);
  1101. return 0;
  1102. }
  1103. static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p,
  1104. const struct nfs3_setaclargs *args)
  1105. {
  1106. struct xdr_stream xdr;
  1107. unsigned int base;
  1108. int error;
  1109. xdr_init_encode(&xdr, &req->rq_snd_buf, p);
  1110. encode_nfs_fh3(&xdr, NFS_FH(args->inode));
  1111. encode_uint32(&xdr, args->mask);
  1112. if (args->npages != 0)
  1113. xdr_write_pages(&xdr, args->pages, 0, args->len);
  1114. base = req->rq_slen;
  1115. error = nfsacl_encode(xdr.buf, base, args->inode,
  1116. (args->mask & NFS_ACL) ?
  1117. args->acl_access : NULL, 1, 0);
  1118. BUG_ON(error < 0);
  1119. error = nfsacl_encode(xdr.buf, base + error, args->inode,
  1120. (args->mask & NFS_DFACL) ?
  1121. args->acl_default : NULL, 1,
  1122. NFS_ACL_DEFAULT);
  1123. BUG_ON(error < 0);
  1124. return 0;
  1125. }
  1126. #endif /* CONFIG_NFS_V3_ACL */
  1127. /*
  1128. * NFS XDR decode functions
  1129. */
  1130. /*
  1131. * Decode attrstat reply.
  1132. */
  1133. static int
  1134. nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
  1135. {
  1136. int status;
  1137. if ((status = ntohl(*p++)))
  1138. return nfs_stat_to_errno(status);
  1139. xdr_decode_fattr(p, fattr);
  1140. return 0;
  1141. }
  1142. /*
  1143. * Decode status+wcc_data reply
  1144. * SATTR, REMOVE, RMDIR
  1145. */
  1146. static int
  1147. nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
  1148. {
  1149. int status;
  1150. if ((status = ntohl(*p++)))
  1151. status = nfs_stat_to_errno(status);
  1152. xdr_decode_wcc_data(p, fattr);
  1153. return status;
  1154. }
  1155. static int
  1156. nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res)
  1157. {
  1158. return nfs3_xdr_wccstat(req, p, res->dir_attr);
  1159. }
  1160. /*
  1161. * Decode LOOKUP reply
  1162. */
  1163. static int
  1164. nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
  1165. {
  1166. int status;
  1167. if ((status = ntohl(*p++))) {
  1168. status = nfs_stat_to_errno(status);
  1169. } else {
  1170. if (!(p = xdr_decode_fhandle(p, res->fh)))
  1171. return -errno_NFSERR_IO;
  1172. p = xdr_decode_post_op_attr(p, res->fattr);
  1173. }
  1174. xdr_decode_post_op_attr(p, res->dir_attr);
  1175. return status;
  1176. }
  1177. /*
  1178. * Decode ACCESS reply
  1179. */
  1180. static int
  1181. nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
  1182. {
  1183. int status = ntohl(*p++);
  1184. p = xdr_decode_post_op_attr(p, res->fattr);
  1185. if (status)
  1186. return nfs_stat_to_errno(status);
  1187. res->access = ntohl(*p++);
  1188. return 0;
  1189. }
  1190. /*
  1191. * Decode READLINK reply
  1192. */
  1193. static int
  1194. nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
  1195. {
  1196. struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
  1197. struct kvec *iov = rcvbuf->head;
  1198. size_t hdrlen;
  1199. u32 len, recvd;
  1200. int status;
  1201. status = ntohl(*p++);
  1202. p = xdr_decode_post_op_attr(p, fattr);
  1203. if (status != 0)
  1204. return nfs_stat_to_errno(status);
  1205. /* Convert length of symlink */
  1206. len = ntohl(*p++);
  1207. if (len >= rcvbuf->page_len) {
  1208. dprintk("nfs: server returned giant symlink!\n");
  1209. return -ENAMETOOLONG;
  1210. }
  1211. hdrlen = (u8 *) p - (u8 *) iov->iov_base;
  1212. if (iov->iov_len < hdrlen) {
  1213. dprintk("NFS: READLINK reply header overflowed:"
  1214. "length %Zu > %Zu\n", hdrlen, iov->iov_len);
  1215. return -errno_NFSERR_IO;
  1216. } else if (iov->iov_len != hdrlen) {
  1217. dprintk("NFS: READLINK header is short. "
  1218. "iovec will be shifted.\n");
  1219. xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
  1220. }
  1221. recvd = req->rq_rcv_buf.len - hdrlen;
  1222. if (recvd < len) {
  1223. dprintk("NFS: server cheating in readlink reply: "
  1224. "count %u > recvd %u\n", len, recvd);
  1225. return -EIO;
  1226. }
  1227. xdr_terminate_string(rcvbuf, len);
  1228. return 0;
  1229. }
  1230. /*
  1231. * Decode READ reply
  1232. */
  1233. static int
  1234. nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
  1235. {
  1236. struct kvec *iov = req->rq_rcv_buf.head;
  1237. size_t hdrlen;
  1238. u32 count, ocount, recvd;
  1239. int status;
  1240. status = ntohl(*p++);
  1241. p = xdr_decode_post_op_attr(p, res->fattr);
  1242. if (status != 0)
  1243. return nfs_stat_to_errno(status);
  1244. /* Decode reply count and EOF flag. NFSv3 is somewhat redundant
  1245. * in that it puts the count both in the res struct and in the
  1246. * opaque data count. */
  1247. count = ntohl(*p++);
  1248. res->eof = ntohl(*p++);
  1249. ocount = ntohl(*p++);
  1250. if (ocount != count) {
  1251. dprintk("NFS: READ count doesn't match RPC opaque count.\n");
  1252. return -errno_NFSERR_IO;
  1253. }
  1254. hdrlen = (u8 *) p - (u8 *) iov->iov_base;
  1255. if (iov->iov_len < hdrlen) {
  1256. dprintk("NFS: READ reply header overflowed:"
  1257. "length %Zu > %Zu\n", hdrlen, iov->iov_len);
  1258. return -errno_NFSERR_IO;
  1259. } else if (iov->iov_len != hdrlen) {
  1260. dprintk("NFS: READ header is short. iovec will be shifted.\n");
  1261. xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
  1262. }
  1263. recvd = req->rq_rcv_buf.len - hdrlen;
  1264. if (count > recvd) {
  1265. dprintk("NFS: server cheating in read reply: "
  1266. "count %u > recvd %u\n", count, recvd);
  1267. count = recvd;
  1268. res->eof = 0;
  1269. }
  1270. if (count < res->count)
  1271. res->count = count;
  1272. return count;
  1273. }
  1274. /*
  1275. * Decode WRITE response
  1276. */
  1277. static int
  1278. nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
  1279. {
  1280. int status;
  1281. status = ntohl(*p++);
  1282. p = xdr_decode_wcc_data(p, res->fattr);
  1283. if (status != 0)
  1284. return nfs_stat_to_errno(status);
  1285. res->count = ntohl(*p++);
  1286. res->verf->committed = (enum nfs3_stable_how)ntohl(*p++);
  1287. res->verf->verifier[0] = *p++;
  1288. res->verf->verifier[1] = *p++;
  1289. return res->count;
  1290. }
  1291. /*
  1292. * Decode a CREATE response
  1293. */
  1294. static int
  1295. nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
  1296. {
  1297. int status;
  1298. status = ntohl(*p++);
  1299. if (status == 0) {
  1300. if (*p++) {
  1301. if (!(p = xdr_decode_fhandle(p, res->fh)))
  1302. return -errno_NFSERR_IO;
  1303. p = xdr_decode_post_op_attr(p, res->fattr);
  1304. } else {
  1305. memset(res->fh, 0, sizeof(*res->fh));
  1306. /* Do decode post_op_attr but set it to NULL */
  1307. p = xdr_decode_post_op_attr(p, res->fattr);
  1308. res->fattr->valid = 0;
  1309. }
  1310. } else {
  1311. status = nfs_stat_to_errno(status);
  1312. }
  1313. p = xdr_decode_wcc_data(p, res->dir_attr);
  1314. return status;
  1315. }
  1316. /*
  1317. * Decode RENAME reply
  1318. */
  1319. static int
  1320. nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs_renameres *res)
  1321. {
  1322. int status;
  1323. if ((status = ntohl(*p++)) != 0)
  1324. status = nfs_stat_to_errno(status);
  1325. p = xdr_decode_wcc_data(p, res->old_fattr);
  1326. p = xdr_decode_wcc_data(p, res->new_fattr);
  1327. return status;
  1328. }
  1329. /*
  1330. * Decode LINK reply
  1331. */
  1332. static int
  1333. nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res)
  1334. {
  1335. int status;
  1336. if ((status = ntohl(*p++)) != 0)
  1337. status = nfs_stat_to_errno(status);
  1338. p = xdr_decode_post_op_attr(p, res->fattr);
  1339. p = xdr_decode_wcc_data(p, res->dir_attr);
  1340. return status;
  1341. }
  1342. /*
  1343. * Decode FSSTAT reply
  1344. */
  1345. static int
  1346. nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res)
  1347. {
  1348. int status;
  1349. status = ntohl(*p++);
  1350. p = xdr_decode_post_op_attr(p, res->fattr);
  1351. if (status != 0)
  1352. return nfs_stat_to_errno(status);
  1353. p = xdr_decode_hyper(p, &res->tbytes);
  1354. p = xdr_decode_hyper(p, &res->fbytes);
  1355. p = xdr_decode_hyper(p, &res->abytes);
  1356. p = xdr_decode_hyper(p, &res->tfiles);
  1357. p = xdr_decode_hyper(p, &res->ffiles);
  1358. p = xdr_decode_hyper(p, &res->afiles);
  1359. /* ignore invarsec */
  1360. return 0;
  1361. }
  1362. /*
  1363. * Decode FSINFO reply
  1364. */
  1365. static int
  1366. nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res)
  1367. {
  1368. int status;
  1369. status = ntohl(*p++);
  1370. p = xdr_decode_post_op_attr(p, res->fattr);
  1371. if (status != 0)
  1372. return nfs_stat_to_errno(status);
  1373. res->rtmax = ntohl(*p++);
  1374. res->rtpref = ntohl(*p++);
  1375. res->rtmult = ntohl(*p++);
  1376. res->wtmax = ntohl(*p++);
  1377. res->wtpref = ntohl(*p++);
  1378. res->wtmult = ntohl(*p++);
  1379. res->dtpref = ntohl(*p++);
  1380. p = xdr_decode_hyper(p, &res->maxfilesize);
  1381. p = xdr_decode_time3(p, &res->time_delta);
  1382. /* ignore properties */
  1383. res->lease_time = 0;
  1384. return 0;
  1385. }
  1386. /*
  1387. * Decode PATHCONF reply
  1388. */
  1389. static int
  1390. nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res)
  1391. {
  1392. int status;
  1393. status = ntohl(*p++);
  1394. p = xdr_decode_post_op_attr(p, res->fattr);
  1395. if (status != 0)
  1396. return nfs_stat_to_errno(status);
  1397. res->max_link = ntohl(*p++);
  1398. res->max_namelen = ntohl(*p++);
  1399. /* ignore remaining fields */
  1400. return 0;
  1401. }
  1402. /*
  1403. * Decode COMMIT reply
  1404. */
  1405. static int
  1406. nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
  1407. {
  1408. int status;
  1409. status = ntohl(*p++);
  1410. p = xdr_decode_wcc_data(p, res->fattr);
  1411. if (status != 0)
  1412. return nfs_stat_to_errno(status);
  1413. res->verf->verifier[0] = *p++;
  1414. res->verf->verifier[1] = *p++;
  1415. return 0;
  1416. }
  1417. #ifdef CONFIG_NFS_V3_ACL
  1418. /*
  1419. * Decode GETACL reply
  1420. */
  1421. static int
  1422. nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p,
  1423. struct nfs3_getaclres *res)
  1424. {
  1425. struct xdr_buf *buf = &req->rq_rcv_buf;
  1426. int status = ntohl(*p++);
  1427. struct posix_acl **acl;
  1428. unsigned int *aclcnt;
  1429. int err, base;
  1430. if (status != 0)
  1431. return nfs_stat_to_errno(status);
  1432. p = xdr_decode_post_op_attr(p, res->fattr);
  1433. res->mask = ntohl(*p++);
  1434. if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
  1435. return -EINVAL;
  1436. base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base;
  1437. acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL;
  1438. aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL;
  1439. err = nfsacl_decode(buf, base, aclcnt, acl);
  1440. acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL;
  1441. aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL;
  1442. if (err > 0)
  1443. err = nfsacl_decode(buf, base + err, aclcnt, acl);
  1444. return (err > 0) ? 0 : err;
  1445. }
  1446. /*
  1447. * Decode setacl reply.
  1448. */
  1449. static int
  1450. nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
  1451. {
  1452. int status = ntohl(*p++);
  1453. if (status)
  1454. return nfs_stat_to_errno(status);
  1455. xdr_decode_post_op_attr(p, fattr);
  1456. return 0;
  1457. }
  1458. #endif /* CONFIG_NFS_V3_ACL */
  1459. #define PROC(proc, argtype, restype, timer) \
  1460. [NFS3PROC_##proc] = { \
  1461. .p_proc = NFS3PROC_##proc, \
  1462. .p_encode = (kxdrproc_t)nfs3_xdr_enc_##argtype##3args, \
  1463. .p_decode = (kxdrproc_t) nfs3_xdr_##restype, \
  1464. .p_arglen = NFS3_##argtype##args_sz, \
  1465. .p_replen = NFS3_##restype##_sz, \
  1466. .p_timer = timer, \
  1467. .p_statidx = NFS3PROC_##proc, \
  1468. .p_name = #proc, \
  1469. }
  1470. struct rpc_procinfo nfs3_procedures[] = {
  1471. PROC(GETATTR, getattr, attrstat, 1),
  1472. PROC(SETATTR, setattr, wccstat, 0),
  1473. PROC(LOOKUP, lookup, lookupres, 2),
  1474. PROC(ACCESS, access, accessres, 1),
  1475. PROC(READLINK, readlink, readlinkres, 3),
  1476. PROC(READ, read, readres, 3),
  1477. PROC(WRITE, write, writeres, 4),
  1478. PROC(CREATE, create, createres, 0),
  1479. PROC(MKDIR, mkdir, createres, 0),
  1480. PROC(SYMLINK, symlink, createres, 0),
  1481. PROC(MKNOD, mknod, createres, 0),
  1482. PROC(REMOVE, remove, removeres, 0),
  1483. PROC(RMDIR, lookup, wccstat, 0),
  1484. PROC(RENAME, rename, renameres, 0),
  1485. PROC(LINK, link, linkres, 0),
  1486. PROC(READDIR, readdir, readdirres, 3),
  1487. PROC(READDIRPLUS, readdirplus, readdirres, 3),
  1488. PROC(FSSTAT, getattr, fsstatres, 0),
  1489. PROC(FSINFO, getattr, fsinfores, 0),
  1490. PROC(PATHCONF, getattr, pathconfres, 0),
  1491. PROC(COMMIT, commit, commitres, 5),
  1492. };
  1493. struct rpc_version nfs_version3 = {
  1494. .number = 3,
  1495. .nrprocs = ARRAY_SIZE(nfs3_procedures),
  1496. .procs = nfs3_procedures
  1497. };
  1498. #ifdef CONFIG_NFS_V3_ACL
  1499. static struct rpc_procinfo nfs3_acl_procedures[] = {
  1500. [ACLPROC3_GETACL] = {
  1501. .p_proc = ACLPROC3_GETACL,
  1502. .p_encode = (kxdrproc_t)nfs3_xdr_enc_getacl3args,
  1503. .p_decode = (kxdrproc_t) nfs3_xdr_getaclres,
  1504. .p_arglen = ACL3_getaclargs_sz,
  1505. .p_replen = ACL3_getaclres_sz,
  1506. .p_timer = 1,
  1507. .p_name = "GETACL",
  1508. },
  1509. [ACLPROC3_SETACL] = {
  1510. .p_proc = ACLPROC3_SETACL,
  1511. .p_encode = (kxdrproc_t)nfs3_xdr_enc_setacl3args,
  1512. .p_decode = (kxdrproc_t) nfs3_xdr_setaclres,
  1513. .p_arglen = ACL3_setaclargs_sz,
  1514. .p_replen = ACL3_setaclres_sz,
  1515. .p_timer = 0,
  1516. .p_name = "SETACL",
  1517. },
  1518. };
  1519. struct rpc_version nfsacl_version3 = {
  1520. .number = 3,
  1521. .nrprocs = sizeof(nfs3_acl_procedures)/
  1522. sizeof(nfs3_acl_procedures[0]),
  1523. .procs = nfs3_acl_procedures,
  1524. };
  1525. #endif /* CONFIG_NFS_V3_ACL */