nfs.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. /*
  2. Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2010
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include <stdio.h>
  15. #include <errno.h>
  16. #include <sys/stat.h>
  17. #include <rpc/xdr.h>
  18. #include "nfs.h"
  19. #include "libnfs-raw.h"
  20. #include "libnfs-private.h"
  21. #include "rpc/nfs.h"
  22. char *nfsstat3_to_str(int error)
  23. {
  24. switch (error) {
  25. case NFS3_OK: return "NFS3_OK"; break;
  26. case NFS3ERR_PERM: return "NFS3ERR_PERM"; break;
  27. case NFS3ERR_NOENT: return "NFS3ERR_NOENT"; break;
  28. case NFS3ERR_IO: return "NFS3ERR_IO"; break;
  29. case NFS3ERR_NXIO: return "NFS3ERR_NXIO"; break;
  30. case NFS3ERR_ACCES: return "NFS3ERR_ACCES"; break;
  31. case NFS3ERR_EXIST: return "NFS3ERR_EXIST"; break;
  32. case NFS3ERR_XDEV: return "NFS3ERR_XDEV"; break;
  33. case NFS3ERR_NODEV: return "NFS3ERR_NODEV"; break;
  34. case NFS3ERR_NOTDIR: return "NFS3ERR_NOTDIR"; break;
  35. case NFS3ERR_ISDIR: return "NFS3ERR_ISDIR"; break;
  36. case NFS3ERR_INVAL: return "NFS3ERR_INVAL"; break;
  37. case NFS3ERR_FBIG: return "NFS3ERR_FBIG"; break;
  38. case NFS3ERR_NOSPC: return "NFS3ERR_NOSPC"; break;
  39. case NFS3ERR_ROFS: return "NFS3ERR_ROFS"; break;
  40. case NFS3ERR_MLINK: return "NFS3ERR_MLINK"; break;
  41. case NFS3ERR_NAMETOOLONG: return "NFS3ERR_NAMETOOLONG"; break;
  42. case NFS3ERR_NOTEMPTY: return "NFS3ERR_NOTEMPTY"; break;
  43. case NFS3ERR_DQUOT: return "NFS3ERR_DQUOT"; break;
  44. case NFS3ERR_STALE: return "NFS3ERR_STALE"; break;
  45. case NFS3ERR_REMOTE: return "NFS3ERR_REMOTE"; break;
  46. case NFS3ERR_BADHANDLE: return "NFS3ERR_BADHANDLE"; break;
  47. case NFS3ERR_NOT_SYNC: return "NFS3ERR_NOT_SYNC"; break;
  48. case NFS3ERR_BAD_COOKIE: return "NFS3ERR_BAD_COOKIE"; break;
  49. case NFS3ERR_NOTSUPP: return "NFS3ERR_NOTSUPP"; break;
  50. case NFS3ERR_TOOSMALL: return "NFS3ERR_TOOSMALL"; break;
  51. case NFS3ERR_SERVERFAULT: return "NFS3ERR_SERVERFAULT"; break;
  52. case NFS3ERR_BADTYPE: return "NFS3ERR_BADTYPE"; break;
  53. case NFS3ERR_JUKEBOX: return "NFS3ERR_JUKEBOX"; break;
  54. };
  55. return "unknown nfs error";
  56. }
  57. int nfsstat3_to_errno(int error)
  58. {
  59. switch (error) {
  60. case NFS3_OK: return 0; break;
  61. case NFS3ERR_PERM: return -EPERM; break;
  62. case NFS3ERR_NOENT: return -ENOENT; break;
  63. case NFS3ERR_IO: return -EIO; break;
  64. case NFS3ERR_NXIO: return -ENXIO; break;
  65. case NFS3ERR_ACCES: return -EACCES; break;
  66. case NFS3ERR_EXIST: return -EEXIST; break;
  67. case NFS3ERR_XDEV: return -EXDEV; break;
  68. case NFS3ERR_NODEV: return -ENODEV; break;
  69. case NFS3ERR_NOTDIR: return -ENOTDIR; break;
  70. case NFS3ERR_ISDIR: return -EISDIR; break;
  71. case NFS3ERR_INVAL: return -EINVAL; break;
  72. case NFS3ERR_FBIG: return -EFBIG; break;
  73. case NFS3ERR_NOSPC: return -ENOSPC; break;
  74. case NFS3ERR_ROFS: return -EROFS; break;
  75. case NFS3ERR_MLINK: return -EMLINK; break;
  76. case NFS3ERR_NAMETOOLONG: return -ENAMETOOLONG; break;
  77. case NFS3ERR_NOTEMPTY: return -EEXIST; break;
  78. case NFS3ERR_DQUOT: return -ERANGE; break;
  79. case NFS3ERR_STALE: return -EIO; break;
  80. case NFS3ERR_REMOTE: return -EIO; break;
  81. case NFS3ERR_BADHANDLE: return -EIO; break;
  82. case NFS3ERR_NOT_SYNC: return -EIO; break;
  83. case NFS3ERR_BAD_COOKIE: return -EIO; break;
  84. case NFS3ERR_NOTSUPP: return -EINVAL; break;
  85. case NFS3ERR_TOOSMALL: return -EIO; break;
  86. case NFS3ERR_SERVERFAULT: return -EIO; break;
  87. case NFS3ERR_BADTYPE: return -EINVAL; break;
  88. case NFS3ERR_JUKEBOX: return -EAGAIN; break;
  89. };
  90. return -ERANGE;
  91. }
  92. int rpc_nfs_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data)
  93. {
  94. struct rpc_pdu *pdu;
  95. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_NULL, cb, private_data, (xdrproc_t)xdr_void, 0);
  96. if (pdu == NULL) {
  97. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/null call");
  98. return -1;
  99. }
  100. if (rpc_queue_pdu(rpc, pdu) != 0) {
  101. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/null call");
  102. rpc_free_pdu(rpc, pdu);
  103. return -2;
  104. }
  105. return 0;
  106. }
  107. int rpc_nfs_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data)
  108. {
  109. struct rpc_pdu *pdu;
  110. GETATTR3args args;
  111. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_GETATTR, cb, private_data, (xdrproc_t)xdr_GETATTR3res, sizeof(GETATTR3res));
  112. if (pdu == NULL) {
  113. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/null call");
  114. return -1;
  115. }
  116. args.object.data.data_len = fh->data.data_len;
  117. args.object.data.data_val = fh->data.data_val;
  118. if (xdr_GETATTR3args(&pdu->xdr, &args) == 0) {
  119. rpc_set_error(rpc, "XDR error: Failed to encode GETATTR3args");
  120. rpc_free_pdu(rpc, pdu);
  121. return -2;
  122. }
  123. if (rpc_queue_pdu(rpc, pdu) != 0) {
  124. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/null call");
  125. rpc_free_pdu(rpc, pdu);
  126. return -3;
  127. }
  128. return 0;
  129. }
  130. int rpc_nfs_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *name, void *private_data)
  131. {
  132. struct rpc_pdu *pdu;
  133. LOOKUP3args args;
  134. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_LOOKUP, cb, private_data, (xdrproc_t)xdr_LOOKUP3res, sizeof(LOOKUP3res));
  135. if (pdu == NULL) {
  136. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/lookup call");
  137. return -1;
  138. }
  139. args.what.dir.data.data_len = fh->data.data_len;
  140. args.what.dir.data.data_val = fh->data.data_val;
  141. args.what.name = name;
  142. if (xdr_LOOKUP3args(&pdu->xdr, &args) == 0) {
  143. rpc_set_error(rpc, "XDR error: Failed to encode LOOKUP3args");
  144. rpc_free_pdu(rpc, pdu);
  145. return -2;
  146. }
  147. if (rpc_queue_pdu(rpc, pdu) != 0) {
  148. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/lookup call");
  149. rpc_free_pdu(rpc, pdu);
  150. return -3;
  151. }
  152. return 0;
  153. }
  154. int rpc_nfs_access_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, int access, void *private_data)
  155. {
  156. struct rpc_pdu *pdu;
  157. ACCESS3args args;
  158. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_ACCESS, cb, private_data, (xdrproc_t)xdr_ACCESS3res, sizeof(ACCESS3res));
  159. if (pdu == NULL) {
  160. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/access call");
  161. return -1;
  162. }
  163. args.object.data.data_len = fh->data.data_len;
  164. args.object.data.data_val = fh->data.data_val;
  165. args.access = access;
  166. if (xdr_ACCESS3args(&pdu->xdr, &args) == 0) {
  167. rpc_set_error(rpc, "XDR error: Failed to encode ACCESS3args");
  168. rpc_free_pdu(rpc, pdu);
  169. return -2;
  170. }
  171. if (rpc_queue_pdu(rpc, pdu) != 0) {
  172. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/access call");
  173. rpc_free_pdu(rpc, pdu);
  174. return -3;
  175. }
  176. return 0;
  177. }
  178. int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, nfs_off_t offset, size_t count, void *private_data)
  179. {
  180. struct rpc_pdu *pdu;
  181. READ3args args;
  182. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READ, cb, private_data, (xdrproc_t)xdr_READ3res, sizeof(READ3res));
  183. if (pdu == NULL) {
  184. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/read call");
  185. return -1;
  186. }
  187. args.file.data.data_len = fh->data.data_len;
  188. args.file.data.data_val = fh->data.data_val;
  189. args.offset = offset;
  190. args.count = count;
  191. if (xdr_READ3args(&pdu->xdr, &args) == 0) {
  192. rpc_set_error(rpc, "XDR error: Failed to encode READ3args");
  193. rpc_free_pdu(rpc, pdu);
  194. return -2;
  195. }
  196. if (rpc_queue_pdu(rpc, pdu) != 0) {
  197. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/read call");
  198. rpc_free_pdu(rpc, pdu);
  199. return -3;
  200. }
  201. return 0;
  202. }
  203. int rpc_nfs_write_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *buf, nfs_off_t offset, size_t count, int stable_how, void *private_data)
  204. {
  205. struct rpc_pdu *pdu;
  206. WRITE3args args;
  207. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_WRITE, cb, private_data, (xdrproc_t)xdr_WRITE3res, sizeof(WRITE3res));
  208. if (pdu == NULL) {
  209. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/write call");
  210. return -1;
  211. }
  212. args.file.data.data_len = fh->data.data_len;
  213. args.file.data.data_val = fh->data.data_val;
  214. args.offset = offset;
  215. args.count = count;
  216. args.stable = stable_how;;
  217. args.data.data_len = count;
  218. args.data.data_val = buf;
  219. if (xdr_WRITE3args(&pdu->xdr, &args) == 0) {
  220. rpc_set_error(rpc, "XDR error: Failed to encode WRITE3args");
  221. rpc_free_pdu(rpc, pdu);
  222. return -2;
  223. }
  224. if (rpc_queue_pdu(rpc, pdu) != 0) {
  225. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/write call");
  226. rpc_free_pdu(rpc, pdu);
  227. return -3;
  228. }
  229. return 0;
  230. }
  231. int rpc_nfs_commit_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data)
  232. {
  233. struct rpc_pdu *pdu;
  234. COMMIT3args args;
  235. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_COMMIT, cb, private_data, (xdrproc_t)xdr_COMMIT3res, sizeof(COMMIT3res));
  236. if (pdu == NULL) {
  237. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/commit call");
  238. return -1;
  239. }
  240. args.file.data.data_len = fh->data.data_len;
  241. args.file.data.data_val = fh->data.data_val;
  242. args.offset = 0;
  243. args.count = 0;
  244. if (xdr_COMMIT3args(&pdu->xdr, &args) == 0) {
  245. rpc_set_error(rpc, "XDR error: Failed to encode WRITE3args");
  246. rpc_free_pdu(rpc, pdu);
  247. return -2;
  248. }
  249. if (rpc_queue_pdu(rpc, pdu) != 0) {
  250. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/commit call");
  251. rpc_free_pdu(rpc, pdu);
  252. return -3;
  253. }
  254. return 0;
  255. }
  256. int rpc_nfs_setattr_async(struct rpc_context *rpc, rpc_cb cb, SETATTR3args *args, void *private_data)
  257. {
  258. struct rpc_pdu *pdu;
  259. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_SETATTR, cb, private_data, (xdrproc_t)xdr_SETATTR3res, sizeof(SETATTR3res));
  260. if (pdu == NULL) {
  261. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/setattr call");
  262. return -1;
  263. }
  264. if (xdr_SETATTR3args(&pdu->xdr, args) == 0) {
  265. rpc_set_error(rpc, "XDR error: Failed to encode SETATTR3args");
  266. rpc_free_pdu(rpc, pdu);
  267. return -2;
  268. }
  269. if (rpc_queue_pdu(rpc, pdu) != 0) {
  270. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/setattr call");
  271. rpc_free_pdu(rpc, pdu);
  272. return -3;
  273. }
  274. return 0;
  275. }
  276. int rpc_nfs_mkdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *dir, void *private_data)
  277. {
  278. struct rpc_pdu *pdu;
  279. MKDIR3args args;
  280. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_MKDIR, cb, private_data, (xdrproc_t)xdr_MKDIR3res, sizeof(MKDIR3res));
  281. if (pdu == NULL) {
  282. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/setattr call");
  283. return -1;
  284. }
  285. bzero(&args, sizeof(MKDIR3args));
  286. args.where.dir.data.data_len = fh->data.data_len;
  287. args.where.dir.data.data_val = fh->data.data_val;
  288. args.where.name = dir;
  289. args.attributes.mode.set_it = 1;
  290. args.attributes.mode.set_mode3_u.mode = 0755;
  291. if (xdr_MKDIR3args(&pdu->xdr, &args) == 0) {
  292. rpc_set_error(rpc, "XDR error: Failed to encode MKDIR3args");
  293. rpc_free_pdu(rpc, pdu);
  294. return -2;
  295. }
  296. if (rpc_queue_pdu(rpc, pdu) != 0) {
  297. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/mkdir call");
  298. rpc_free_pdu(rpc, pdu);
  299. return -3;
  300. }
  301. return 0;
  302. }
  303. int rpc_nfs_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *dir, void *private_data)
  304. {
  305. struct rpc_pdu *pdu;
  306. RMDIR3args args;
  307. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_RMDIR, cb, private_data, (xdrproc_t)xdr_RMDIR3res, sizeof(RMDIR3res));
  308. if (pdu == NULL) {
  309. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/rmdir call");
  310. return -1;
  311. }
  312. bzero(&args, sizeof(RMDIR3args));
  313. args.object.dir.data.data_len = fh->data.data_len;
  314. args.object.dir.data.data_val = fh->data.data_val;
  315. args.object.name = dir;
  316. if (xdr_RMDIR3args(&pdu->xdr, &args) == 0) {
  317. rpc_set_error(rpc, "XDR error: Failed to encode RMDIR3args");
  318. rpc_free_pdu(rpc, pdu);
  319. return -2;
  320. }
  321. if (rpc_queue_pdu(rpc, pdu) != 0) {
  322. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/rmdir call");
  323. rpc_free_pdu(rpc, pdu);
  324. return -3;
  325. }
  326. return 0;
  327. }
  328. int rpc_nfs_create_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, int mode, void *private_data)
  329. {
  330. struct rpc_pdu *pdu;
  331. CREATE3args args;
  332. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_CREATE, cb, private_data, (xdrproc_t)xdr_CREATE3res, sizeof(CREATE3res));
  333. if (pdu == NULL) {
  334. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/create call");
  335. return -1;
  336. }
  337. bzero(&args, sizeof(CREATE3args));
  338. args.where.dir.data.data_len = fh->data.data_len;
  339. args.where.dir.data.data_val = fh->data.data_val;
  340. args.where.name = file;
  341. args.how.mode = UNCHECKED;
  342. args.how.createhow3_u.obj_attributes.mode.set_it = 1;
  343. args.how.createhow3_u.obj_attributes.mode.set_mode3_u.mode = mode;
  344. if (xdr_CREATE3args(&pdu->xdr, &args) == 0) {
  345. rpc_set_error(rpc, "XDR error: Failed to encode CREATE3args");
  346. rpc_free_pdu(rpc, pdu);
  347. return -2;
  348. }
  349. if (rpc_queue_pdu(rpc, pdu) != 0) {
  350. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/create call");
  351. rpc_free_pdu(rpc, pdu);
  352. return -3;
  353. }
  354. return 0;
  355. }
  356. int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, void *private_data)
  357. {
  358. struct rpc_pdu *pdu;
  359. REMOVE3args args;
  360. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_REMOVE, cb, private_data, (xdrproc_t)xdr_REMOVE3res, sizeof(REMOVE3res));
  361. if (pdu == NULL) {
  362. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/remove call");
  363. return -1;
  364. }
  365. bzero(&args, sizeof(REMOVE3args));
  366. args.object.dir.data.data_len = fh->data.data_len;
  367. args.object.dir.data.data_val = fh->data.data_val;
  368. args.object.name = file;
  369. if (xdr_REMOVE3args(&pdu->xdr, &args) == 0) {
  370. rpc_set_error(rpc, "XDR error: Failed to encode REMOVE3args");
  371. rpc_free_pdu(rpc, pdu);
  372. return -2;
  373. }
  374. if (rpc_queue_pdu(rpc, pdu) != 0) {
  375. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/remove call");
  376. rpc_free_pdu(rpc, pdu);
  377. return -3;
  378. }
  379. return 0;
  380. }
  381. int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data)
  382. {
  383. struct rpc_pdu *pdu;
  384. READDIR3args args;
  385. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READDIR, cb, private_data, (xdrproc_t)xdr_READDIR3res, sizeof(READDIR3res));
  386. if (pdu == NULL) {
  387. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/readdir call");
  388. return -1;
  389. }
  390. bzero(&args, sizeof(READDIR3args));
  391. args.dir.data.data_len = fh->data.data_len;
  392. args.dir.data.data_val = fh->data.data_val;
  393. args.cookie = cookie;
  394. memcpy(&args.cookieverf, cookieverf, sizeof(cookieverf3));
  395. args.count = count;
  396. if (xdr_READDIR3args(&pdu->xdr, &args) == 0) {
  397. rpc_set_error(rpc, "XDR error: Failed to encode READDIR3args");
  398. rpc_free_pdu(rpc, pdu);
  399. return -2;
  400. }
  401. if (rpc_queue_pdu(rpc, pdu) != 0) {
  402. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/readdir call");
  403. rpc_free_pdu(rpc, pdu);
  404. return -3;
  405. }
  406. return 0;
  407. }
  408. int rpc_nfs_fsstat_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data)
  409. {
  410. struct rpc_pdu *pdu;
  411. FSSTAT3args args;
  412. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_FSSTAT, cb, private_data, (xdrproc_t)xdr_FSSTAT3res, sizeof(FSSTAT3res));
  413. if (pdu == NULL) {
  414. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/fsstat call");
  415. return -1;
  416. }
  417. args.fsroot.data.data_len = fh->data.data_len;
  418. args.fsroot.data.data_val = fh->data.data_val;
  419. if (xdr_FSSTAT3args(&pdu->xdr, &args) == 0) {
  420. rpc_set_error(rpc, "XDR error: Failed to encode FSSTAT3args");
  421. rpc_free_pdu(rpc, pdu);
  422. return -2;
  423. }
  424. if (rpc_queue_pdu(rpc, pdu) != 0) {
  425. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/fsstat call");
  426. rpc_free_pdu(rpc, pdu);
  427. return -3;
  428. }
  429. return 0;
  430. }
  431. int rpc_nfs_readlink_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data)
  432. {
  433. struct rpc_pdu *pdu;
  434. READLINK3args args;
  435. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READLINK, cb, private_data, (xdrproc_t)xdr_READLINK3res, sizeof(READLINK3res));
  436. if (pdu == NULL) {
  437. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/readlink call");
  438. return -1;
  439. }
  440. args.symlink.data.data_len = fh->data.data_len;
  441. args.symlink.data.data_val = fh->data.data_val;
  442. if (xdr_READLINK3args(&pdu->xdr, &args) == 0) {
  443. rpc_set_error(rpc, "XDR error: Failed to encode READLINK3args");
  444. rpc_free_pdu(rpc, pdu);
  445. return -2;
  446. }
  447. if (rpc_queue_pdu(rpc, pdu) != 0) {
  448. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/readlink call");
  449. rpc_free_pdu(rpc, pdu);
  450. return -3;
  451. }
  452. return 0;
  453. }
  454. int rpc_nfs_symlink_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *newname, char *oldpath, void *private_data)
  455. {
  456. struct rpc_pdu *pdu;
  457. SYMLINK3args args;
  458. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_SYMLINK, cb, private_data, (xdrproc_t)xdr_SYMLINK3res, sizeof(SYMLINK3res));
  459. if (pdu == NULL) {
  460. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/symlink call");
  461. return -1;
  462. }
  463. bzero(&args, sizeof(SYMLINK3args));
  464. args.where.dir.data.data_len = fh->data.data_len;
  465. args.where.dir.data.data_val = fh->data.data_val;
  466. args.where.name = newname;
  467. args.symlink.symlink_attributes.mode.set_it = 1;
  468. args.symlink.symlink_attributes.mode.set_mode3_u.mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH;
  469. args.symlink.symlink_data = oldpath;
  470. if (xdr_SYMLINK3args(&pdu->xdr, &args) == 0) {
  471. rpc_set_error(rpc, "XDR error: Failed to encode SYMLINK3args");
  472. rpc_free_pdu(rpc, pdu);
  473. return -2;
  474. }
  475. if (rpc_queue_pdu(rpc, pdu) != 0) {
  476. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/symlink call");
  477. rpc_free_pdu(rpc, pdu);
  478. return -3;
  479. }
  480. return 0;
  481. }
  482. int rpc_nfs_rename_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *olddir, char *oldname, struct nfs_fh3 *newdir, char *newname, void *private_data)
  483. {
  484. struct rpc_pdu *pdu;
  485. RENAME3args args;
  486. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_RENAME, cb, private_data, (xdrproc_t)xdr_RENAME3res, sizeof(RENAME3res));
  487. if (pdu == NULL) {
  488. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/rename call");
  489. return -1;
  490. }
  491. bzero(&args, sizeof(RENAME3args));
  492. args.from.dir.data.data_len = olddir->data.data_len;
  493. args.from.dir.data.data_val = olddir->data.data_val;
  494. args.from.name = oldname;
  495. args.to.dir.data.data_len = newdir->data.data_len;
  496. args.to.dir.data.data_val = newdir->data.data_val;
  497. args.to.name = newname;
  498. if (xdr_RENAME3args(&pdu->xdr, &args) == 0) {
  499. rpc_set_error(rpc, "XDR error: Failed to encode RENAME3args");
  500. rpc_free_pdu(rpc, pdu);
  501. return -2;
  502. }
  503. if (rpc_queue_pdu(rpc, pdu) != 0) {
  504. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/rename call");
  505. rpc_free_pdu(rpc, pdu);
  506. return -3;
  507. }
  508. return 0;
  509. }
  510. int rpc_nfs_link_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *file, struct nfs_fh3 *newdir, char *newname, void *private_data)
  511. {
  512. struct rpc_pdu *pdu;
  513. LINK3args args;
  514. pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_LINK, cb, private_data, (xdrproc_t)xdr_LINK3res, sizeof(LINK3res));
  515. if (pdu == NULL) {
  516. rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/link call");
  517. return -1;
  518. }
  519. bzero(&args, sizeof(LINK3args));
  520. args.file.data.data_len = file->data.data_len;
  521. args.file.data.data_val = file->data.data_val;
  522. args.link.dir.data.data_len = newdir->data.data_len;
  523. args.link.dir.data.data_val = newdir->data.data_val;
  524. args.link.name = newname;
  525. if (xdr_LINK3args(&pdu->xdr, &args) == 0) {
  526. rpc_set_error(rpc, "XDR error: Failed to encode LINK3args");
  527. rpc_free_pdu(rpc, pdu);
  528. return -2;
  529. }
  530. if (rpc_queue_pdu(rpc, pdu) != 0) {
  531. rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/link call");
  532. rpc_free_pdu(rpc, pdu);
  533. return -3;
  534. }
  535. return 0;
  536. }