fsclient.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  1. /* AFS File Server client stubs
  2. *
  3. * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. */
  11. #include <linux/init.h>
  12. #include <linux/sched.h>
  13. #include <linux/circ_buf.h>
  14. #include "internal.h"
  15. #include "afs_fs.h"
  16. /*
  17. * decode an AFSFid block
  18. */
  19. static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
  20. {
  21. const __be32 *bp = *_bp;
  22. fid->vid = ntohl(*bp++);
  23. fid->vnode = ntohl(*bp++);
  24. fid->unique = ntohl(*bp++);
  25. *_bp = bp;
  26. }
  27. /*
  28. * decode an AFSFetchStatus block
  29. */
  30. static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
  31. struct afs_file_status *status,
  32. struct afs_vnode *vnode)
  33. {
  34. const __be32 *bp = *_bp;
  35. umode_t mode;
  36. u64 data_version, size;
  37. u32 changed = 0; /* becomes non-zero if ctime-type changes seen */
  38. #define EXTRACT(DST) \
  39. do { \
  40. u32 x = ntohl(*bp++); \
  41. changed |= DST - x; \
  42. DST = x; \
  43. } while (0)
  44. status->if_version = ntohl(*bp++);
  45. EXTRACT(status->type);
  46. EXTRACT(status->nlink);
  47. size = ntohl(*bp++);
  48. data_version = ntohl(*bp++);
  49. EXTRACT(status->author);
  50. EXTRACT(status->owner);
  51. EXTRACT(status->caller_access); /* call ticket dependent */
  52. EXTRACT(status->anon_access);
  53. EXTRACT(status->mode);
  54. EXTRACT(status->parent.vnode);
  55. EXTRACT(status->parent.unique);
  56. bp++; /* seg size */
  57. status->mtime_client = ntohl(*bp++);
  58. status->mtime_server = ntohl(*bp++);
  59. EXTRACT(status->group);
  60. bp++; /* sync counter */
  61. data_version |= (u64) ntohl(*bp++) << 32;
  62. bp++; /* lock count */
  63. size |= (u64) ntohl(*bp++) << 32;
  64. bp++; /* spare 4 */
  65. *_bp = bp;
  66. if (size != status->size) {
  67. status->size = size;
  68. changed |= true;
  69. }
  70. status->mode &= S_IALLUGO;
  71. _debug("vnode time %lx, %lx",
  72. status->mtime_client, status->mtime_server);
  73. if (vnode) {
  74. status->parent.vid = vnode->fid.vid;
  75. if (changed && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
  76. _debug("vnode changed");
  77. i_size_write(&vnode->vfs_inode, size);
  78. vnode->vfs_inode.i_uid = status->owner;
  79. vnode->vfs_inode.i_gid = status->group;
  80. vnode->vfs_inode.i_version = vnode->fid.unique;
  81. vnode->vfs_inode.i_nlink = status->nlink;
  82. mode = vnode->vfs_inode.i_mode;
  83. mode &= ~S_IALLUGO;
  84. mode |= status->mode;
  85. barrier();
  86. vnode->vfs_inode.i_mode = mode;
  87. }
  88. vnode->vfs_inode.i_ctime.tv_sec = status->mtime_server;
  89. vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime;
  90. vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime;
  91. }
  92. if (status->data_version != data_version) {
  93. status->data_version = data_version;
  94. if (vnode && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
  95. _debug("vnode modified %llx on {%x:%u}",
  96. data_version, vnode->fid.vid, vnode->fid.vnode);
  97. set_bit(AFS_VNODE_MODIFIED, &vnode->flags);
  98. set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
  99. }
  100. }
  101. }
  102. /*
  103. * decode an AFSCallBack block
  104. */
  105. static void xdr_decode_AFSCallBack(const __be32 **_bp, struct afs_vnode *vnode)
  106. {
  107. const __be32 *bp = *_bp;
  108. vnode->cb_version = ntohl(*bp++);
  109. vnode->cb_expiry = ntohl(*bp++);
  110. vnode->cb_type = ntohl(*bp++);
  111. vnode->cb_expires = vnode->cb_expiry + get_seconds();
  112. *_bp = bp;
  113. }
  114. static void xdr_decode_AFSCallBack_raw(const __be32 **_bp,
  115. struct afs_callback *cb)
  116. {
  117. const __be32 *bp = *_bp;
  118. cb->version = ntohl(*bp++);
  119. cb->expiry = ntohl(*bp++);
  120. cb->type = ntohl(*bp++);
  121. *_bp = bp;
  122. }
  123. /*
  124. * decode an AFSVolSync block
  125. */
  126. static void xdr_decode_AFSVolSync(const __be32 **_bp,
  127. struct afs_volsync *volsync)
  128. {
  129. const __be32 *bp = *_bp;
  130. volsync->creation = ntohl(*bp++);
  131. bp++; /* spare2 */
  132. bp++; /* spare3 */
  133. bp++; /* spare4 */
  134. bp++; /* spare5 */
  135. bp++; /* spare6 */
  136. *_bp = bp;
  137. }
  138. /*
  139. * deliver reply data to an FS.FetchStatus
  140. */
  141. static int afs_deliver_fs_fetch_status(struct afs_call *call,
  142. struct sk_buff *skb, bool last)
  143. {
  144. struct afs_vnode *vnode = call->reply;
  145. const __be32 *bp;
  146. _enter(",,%u", last);
  147. afs_transfer_reply(call, skb);
  148. if (!last)
  149. return 0;
  150. if (call->reply_size != call->reply_max)
  151. return -EBADMSG;
  152. /* unmarshall the reply once we've received all of it */
  153. bp = call->buffer;
  154. xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode);
  155. xdr_decode_AFSCallBack(&bp, vnode);
  156. if (call->reply2)
  157. xdr_decode_AFSVolSync(&bp, call->reply2);
  158. _leave(" = 0 [done]");
  159. return 0;
  160. }
  161. /*
  162. * FS.FetchStatus operation type
  163. */
  164. static const struct afs_call_type afs_RXFSFetchStatus = {
  165. .name = "FS.FetchStatus",
  166. .deliver = afs_deliver_fs_fetch_status,
  167. .abort_to_error = afs_abort_to_error,
  168. .destructor = afs_flat_call_destructor,
  169. };
  170. /*
  171. * fetch the status information for a file
  172. */
  173. int afs_fs_fetch_file_status(struct afs_server *server,
  174. struct key *key,
  175. struct afs_vnode *vnode,
  176. struct afs_volsync *volsync,
  177. const struct afs_wait_mode *wait_mode)
  178. {
  179. struct afs_call *call;
  180. __be32 *bp;
  181. _enter(",%x,{%x:%d},,",
  182. key_serial(key), vnode->fid.vid, vnode->fid.vnode);
  183. call = afs_alloc_flat_call(&afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
  184. if (!call)
  185. return -ENOMEM;
  186. call->key = key;
  187. call->reply = vnode;
  188. call->reply2 = volsync;
  189. call->service_id = FS_SERVICE;
  190. call->port = htons(AFS_FS_PORT);
  191. /* marshall the parameters */
  192. bp = call->request;
  193. bp[0] = htonl(FSFETCHSTATUS);
  194. bp[1] = htonl(vnode->fid.vid);
  195. bp[2] = htonl(vnode->fid.vnode);
  196. bp[3] = htonl(vnode->fid.unique);
  197. return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
  198. }
  199. /*
  200. * deliver reply data to an FS.FetchData
  201. */
  202. static int afs_deliver_fs_fetch_data(struct afs_call *call,
  203. struct sk_buff *skb, bool last)
  204. {
  205. struct afs_vnode *vnode = call->reply;
  206. const __be32 *bp;
  207. struct page *page;
  208. void *buffer;
  209. int ret;
  210. _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
  211. switch (call->unmarshall) {
  212. case 0:
  213. call->offset = 0;
  214. call->unmarshall++;
  215. /* extract the returned data length */
  216. case 1:
  217. _debug("extract data length");
  218. ret = afs_extract_data(call, skb, last, &call->tmp, 4);
  219. switch (ret) {
  220. case 0: break;
  221. case -EAGAIN: return 0;
  222. default: return ret;
  223. }
  224. call->count = ntohl(call->tmp);
  225. _debug("DATA length: %u", call->count);
  226. if (call->count > PAGE_SIZE)
  227. return -EBADMSG;
  228. call->offset = 0;
  229. call->unmarshall++;
  230. if (call->count < PAGE_SIZE) {
  231. buffer = kmap_atomic(call->reply3, KM_USER0);
  232. memset(buffer + PAGE_SIZE - call->count, 0,
  233. call->count);
  234. kunmap_atomic(buffer, KM_USER0);
  235. }
  236. /* extract the returned data */
  237. case 2:
  238. _debug("extract data");
  239. page = call->reply3;
  240. buffer = kmap_atomic(page, KM_USER0);
  241. ret = afs_extract_data(call, skb, last, buffer, call->count);
  242. kunmap_atomic(buffer, KM_USER0);
  243. switch (ret) {
  244. case 0: break;
  245. case -EAGAIN: return 0;
  246. default: return ret;
  247. }
  248. call->offset = 0;
  249. call->unmarshall++;
  250. /* extract the metadata */
  251. case 3:
  252. ret = afs_extract_data(call, skb, last, call->buffer,
  253. (21 + 3 + 6) * 4);
  254. switch (ret) {
  255. case 0: break;
  256. case -EAGAIN: return 0;
  257. default: return ret;
  258. }
  259. bp = call->buffer;
  260. xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode);
  261. xdr_decode_AFSCallBack(&bp, vnode);
  262. if (call->reply2)
  263. xdr_decode_AFSVolSync(&bp, call->reply2);
  264. call->offset = 0;
  265. call->unmarshall++;
  266. case 4:
  267. _debug("trailer");
  268. if (skb->len != 0)
  269. return -EBADMSG;
  270. break;
  271. }
  272. if (!last)
  273. return 0;
  274. _leave(" = 0 [done]");
  275. return 0;
  276. }
  277. /*
  278. * FS.FetchData operation type
  279. */
  280. static const struct afs_call_type afs_RXFSFetchData = {
  281. .name = "FS.FetchData",
  282. .deliver = afs_deliver_fs_fetch_data,
  283. .abort_to_error = afs_abort_to_error,
  284. .destructor = afs_flat_call_destructor,
  285. };
  286. /*
  287. * fetch data from a file
  288. */
  289. int afs_fs_fetch_data(struct afs_server *server,
  290. struct key *key,
  291. struct afs_vnode *vnode,
  292. off_t offset, size_t length,
  293. struct page *buffer,
  294. const struct afs_wait_mode *wait_mode)
  295. {
  296. struct afs_call *call;
  297. __be32 *bp;
  298. _enter("");
  299. call = afs_alloc_flat_call(&afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
  300. if (!call)
  301. return -ENOMEM;
  302. call->key = key;
  303. call->reply = vnode;
  304. call->reply2 = NULL; /* volsync */
  305. call->reply3 = buffer;
  306. call->service_id = FS_SERVICE;
  307. call->port = htons(AFS_FS_PORT);
  308. /* marshall the parameters */
  309. bp = call->request;
  310. bp[0] = htonl(FSFETCHDATA);
  311. bp[1] = htonl(vnode->fid.vid);
  312. bp[2] = htonl(vnode->fid.vnode);
  313. bp[3] = htonl(vnode->fid.unique);
  314. bp[4] = htonl(offset);
  315. bp[5] = htonl(length);
  316. return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
  317. }
  318. /*
  319. * deliver reply data to an FS.GiveUpCallBacks
  320. */
  321. static int afs_deliver_fs_give_up_callbacks(struct afs_call *call,
  322. struct sk_buff *skb, bool last)
  323. {
  324. _enter(",{%u},%d", skb->len, last);
  325. if (skb->len > 0)
  326. return -EBADMSG; /* shouldn't be any reply data */
  327. return 0;
  328. }
  329. /*
  330. * FS.GiveUpCallBacks operation type
  331. */
  332. static const struct afs_call_type afs_RXFSGiveUpCallBacks = {
  333. .name = "FS.GiveUpCallBacks",
  334. .deliver = afs_deliver_fs_give_up_callbacks,
  335. .abort_to_error = afs_abort_to_error,
  336. .destructor = afs_flat_call_destructor,
  337. };
  338. /*
  339. * give up a set of callbacks
  340. * - the callbacks are held in the server->cb_break ring
  341. */
  342. int afs_fs_give_up_callbacks(struct afs_server *server,
  343. const struct afs_wait_mode *wait_mode)
  344. {
  345. struct afs_call *call;
  346. size_t ncallbacks;
  347. __be32 *bp, *tp;
  348. int loop;
  349. ncallbacks = CIRC_CNT(server->cb_break_head, server->cb_break_tail,
  350. ARRAY_SIZE(server->cb_break));
  351. _enter("{%zu},", ncallbacks);
  352. if (ncallbacks == 0)
  353. return 0;
  354. if (ncallbacks > AFSCBMAX)
  355. ncallbacks = AFSCBMAX;
  356. _debug("break %zu callbacks", ncallbacks);
  357. call = afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks,
  358. 12 + ncallbacks * 6 * 4, 0);
  359. if (!call)
  360. return -ENOMEM;
  361. call->service_id = FS_SERVICE;
  362. call->port = htons(AFS_FS_PORT);
  363. /* marshall the parameters */
  364. bp = call->request;
  365. tp = bp + 2 + ncallbacks * 3;
  366. *bp++ = htonl(FSGIVEUPCALLBACKS);
  367. *bp++ = htonl(ncallbacks);
  368. *tp++ = htonl(ncallbacks);
  369. atomic_sub(ncallbacks, &server->cb_break_n);
  370. for (loop = ncallbacks; loop > 0; loop--) {
  371. struct afs_callback *cb =
  372. &server->cb_break[server->cb_break_tail];
  373. *bp++ = htonl(cb->fid.vid);
  374. *bp++ = htonl(cb->fid.vnode);
  375. *bp++ = htonl(cb->fid.unique);
  376. *tp++ = htonl(cb->version);
  377. *tp++ = htonl(cb->expiry);
  378. *tp++ = htonl(cb->type);
  379. smp_mb();
  380. server->cb_break_tail =
  381. (server->cb_break_tail + 1) &
  382. (ARRAY_SIZE(server->cb_break) - 1);
  383. }
  384. ASSERT(ncallbacks > 0);
  385. wake_up_nr(&server->cb_break_waitq, ncallbacks);
  386. return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
  387. }
  388. /*
  389. * deliver reply data to an FS.CreateFile or an FS.MakeDir
  390. */
  391. static int afs_deliver_fs_create_vnode(struct afs_call *call,
  392. struct sk_buff *skb, bool last)
  393. {
  394. struct afs_vnode *vnode = call->reply;
  395. const __be32 *bp;
  396. _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
  397. afs_transfer_reply(call, skb);
  398. if (!last)
  399. return 0;
  400. if (call->reply_size != call->reply_max)
  401. return -EBADMSG;
  402. /* unmarshall the reply once we've received all of it */
  403. bp = call->buffer;
  404. xdr_decode_AFSFid(&bp, call->reply2);
  405. xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL);
  406. xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode);
  407. xdr_decode_AFSCallBack_raw(&bp, call->reply4);
  408. /* xdr_decode_AFSVolSync(&bp, call->replyX); */
  409. _leave(" = 0 [done]");
  410. return 0;
  411. }
  412. /*
  413. * FS.CreateFile and FS.MakeDir operation type
  414. */
  415. static const struct afs_call_type afs_RXFSCreateXXXX = {
  416. .name = "FS.CreateXXXX",
  417. .deliver = afs_deliver_fs_create_vnode,
  418. .abort_to_error = afs_abort_to_error,
  419. .destructor = afs_flat_call_destructor,
  420. };
  421. /*
  422. * create a file or make a directory
  423. */
  424. int afs_fs_create(struct afs_server *server,
  425. struct key *key,
  426. struct afs_vnode *vnode,
  427. const char *name,
  428. umode_t mode,
  429. struct afs_fid *newfid,
  430. struct afs_file_status *newstatus,
  431. struct afs_callback *newcb,
  432. const struct afs_wait_mode *wait_mode)
  433. {
  434. struct afs_call *call;
  435. size_t namesz, reqsz, padsz;
  436. __be32 *bp;
  437. _enter("");
  438. namesz = strlen(name);
  439. padsz = (4 - (namesz & 3)) & 3;
  440. reqsz = (5 * 4) + namesz + padsz + (6 * 4);
  441. call = afs_alloc_flat_call(&afs_RXFSCreateXXXX, reqsz,
  442. (3 + 21 + 21 + 3 + 6) * 4);
  443. if (!call)
  444. return -ENOMEM;
  445. call->key = key;
  446. call->reply = vnode;
  447. call->reply2 = newfid;
  448. call->reply3 = newstatus;
  449. call->reply4 = newcb;
  450. call->service_id = FS_SERVICE;
  451. call->port = htons(AFS_FS_PORT);
  452. /* marshall the parameters */
  453. bp = call->request;
  454. *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
  455. *bp++ = htonl(vnode->fid.vid);
  456. *bp++ = htonl(vnode->fid.vnode);
  457. *bp++ = htonl(vnode->fid.unique);
  458. *bp++ = htonl(namesz);
  459. memcpy(bp, name, namesz);
  460. bp = (void *) bp + namesz;
  461. if (padsz > 0) {
  462. memset(bp, 0, padsz);
  463. bp = (void *) bp + padsz;
  464. }
  465. *bp++ = htonl(AFS_SET_MODE);
  466. *bp++ = 0; /* mtime */
  467. *bp++ = 0; /* owner */
  468. *bp++ = 0; /* group */
  469. *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
  470. *bp++ = 0; /* segment size */
  471. return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
  472. }
  473. /*
  474. * deliver reply data to an FS.RemoveFile or FS.RemoveDir
  475. */
  476. static int afs_deliver_fs_remove(struct afs_call *call,
  477. struct sk_buff *skb, bool last)
  478. {
  479. struct afs_vnode *vnode = call->reply;
  480. const __be32 *bp;
  481. _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
  482. afs_transfer_reply(call, skb);
  483. if (!last)
  484. return 0;
  485. if (call->reply_size != call->reply_max)
  486. return -EBADMSG;
  487. /* unmarshall the reply once we've received all of it */
  488. bp = call->buffer;
  489. xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode);
  490. /* xdr_decode_AFSVolSync(&bp, call->replyX); */
  491. _leave(" = 0 [done]");
  492. return 0;
  493. }
  494. /*
  495. * FS.RemoveDir/FS.RemoveFile operation type
  496. */
  497. static const struct afs_call_type afs_RXFSRemoveXXXX = {
  498. .name = "FS.RemoveXXXX",
  499. .deliver = afs_deliver_fs_remove,
  500. .abort_to_error = afs_abort_to_error,
  501. .destructor = afs_flat_call_destructor,
  502. };
  503. /*
  504. * remove a file or directory
  505. */
  506. int afs_fs_remove(struct afs_server *server,
  507. struct key *key,
  508. struct afs_vnode *vnode,
  509. const char *name,
  510. bool isdir,
  511. const struct afs_wait_mode *wait_mode)
  512. {
  513. struct afs_call *call;
  514. size_t namesz, reqsz, padsz;
  515. __be32 *bp;
  516. _enter("");
  517. namesz = strlen(name);
  518. padsz = (4 - (namesz & 3)) & 3;
  519. reqsz = (5 * 4) + namesz + padsz;
  520. call = afs_alloc_flat_call(&afs_RXFSRemoveXXXX, reqsz, (21 + 6) * 4);
  521. if (!call)
  522. return -ENOMEM;
  523. call->key = key;
  524. call->reply = vnode;
  525. call->service_id = FS_SERVICE;
  526. call->port = htons(AFS_FS_PORT);
  527. /* marshall the parameters */
  528. bp = call->request;
  529. *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
  530. *bp++ = htonl(vnode->fid.vid);
  531. *bp++ = htonl(vnode->fid.vnode);
  532. *bp++ = htonl(vnode->fid.unique);
  533. *bp++ = htonl(namesz);
  534. memcpy(bp, name, namesz);
  535. bp = (void *) bp + namesz;
  536. if (padsz > 0) {
  537. memset(bp, 0, padsz);
  538. bp = (void *) bp + padsz;
  539. }
  540. return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
  541. }
  542. /*
  543. * deliver reply data to an FS.Link
  544. */
  545. static int afs_deliver_fs_link(struct afs_call *call,
  546. struct sk_buff *skb, bool last)
  547. {
  548. struct afs_vnode *dvnode = call->reply, *vnode = call->reply2;
  549. const __be32 *bp;
  550. _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
  551. afs_transfer_reply(call, skb);
  552. if (!last)
  553. return 0;
  554. if (call->reply_size != call->reply_max)
  555. return -EBADMSG;
  556. /* unmarshall the reply once we've received all of it */
  557. bp = call->buffer;
  558. xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode);
  559. xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode);
  560. /* xdr_decode_AFSVolSync(&bp, call->replyX); */
  561. _leave(" = 0 [done]");
  562. return 0;
  563. }
  564. /*
  565. * FS.Link operation type
  566. */
  567. static const struct afs_call_type afs_RXFSLink = {
  568. .name = "FS.Link",
  569. .deliver = afs_deliver_fs_link,
  570. .abort_to_error = afs_abort_to_error,
  571. .destructor = afs_flat_call_destructor,
  572. };
  573. /*
  574. * make a hard link
  575. */
  576. int afs_fs_link(struct afs_server *server,
  577. struct key *key,
  578. struct afs_vnode *dvnode,
  579. struct afs_vnode *vnode,
  580. const char *name,
  581. const struct afs_wait_mode *wait_mode)
  582. {
  583. struct afs_call *call;
  584. size_t namesz, reqsz, padsz;
  585. __be32 *bp;
  586. _enter("");
  587. namesz = strlen(name);
  588. padsz = (4 - (namesz & 3)) & 3;
  589. reqsz = (5 * 4) + namesz + padsz + (3 * 4);
  590. call = afs_alloc_flat_call(&afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
  591. if (!call)
  592. return -ENOMEM;
  593. call->key = key;
  594. call->reply = dvnode;
  595. call->reply2 = vnode;
  596. call->service_id = FS_SERVICE;
  597. call->port = htons(AFS_FS_PORT);
  598. /* marshall the parameters */
  599. bp = call->request;
  600. *bp++ = htonl(FSLINK);
  601. *bp++ = htonl(dvnode->fid.vid);
  602. *bp++ = htonl(dvnode->fid.vnode);
  603. *bp++ = htonl(dvnode->fid.unique);
  604. *bp++ = htonl(namesz);
  605. memcpy(bp, name, namesz);
  606. bp = (void *) bp + namesz;
  607. if (padsz > 0) {
  608. memset(bp, 0, padsz);
  609. bp = (void *) bp + padsz;
  610. }
  611. *bp++ = htonl(vnode->fid.vid);
  612. *bp++ = htonl(vnode->fid.vnode);
  613. *bp++ = htonl(vnode->fid.unique);
  614. return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
  615. }
  616. /*
  617. * deliver reply data to an FS.Symlink
  618. */
  619. static int afs_deliver_fs_symlink(struct afs_call *call,
  620. struct sk_buff *skb, bool last)
  621. {
  622. struct afs_vnode *vnode = call->reply;
  623. const __be32 *bp;
  624. _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
  625. afs_transfer_reply(call, skb);
  626. if (!last)
  627. return 0;
  628. if (call->reply_size != call->reply_max)
  629. return -EBADMSG;
  630. /* unmarshall the reply once we've received all of it */
  631. bp = call->buffer;
  632. xdr_decode_AFSFid(&bp, call->reply2);
  633. xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL);
  634. xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode);
  635. /* xdr_decode_AFSVolSync(&bp, call->replyX); */
  636. _leave(" = 0 [done]");
  637. return 0;
  638. }
  639. /*
  640. * FS.Symlink operation type
  641. */
  642. static const struct afs_call_type afs_RXFSSymlink = {
  643. .name = "FS.Symlink",
  644. .deliver = afs_deliver_fs_symlink,
  645. .abort_to_error = afs_abort_to_error,
  646. .destructor = afs_flat_call_destructor,
  647. };
  648. /*
  649. * create a symbolic link
  650. */
  651. int afs_fs_symlink(struct afs_server *server,
  652. struct key *key,
  653. struct afs_vnode *vnode,
  654. const char *name,
  655. const char *contents,
  656. struct afs_fid *newfid,
  657. struct afs_file_status *newstatus,
  658. const struct afs_wait_mode *wait_mode)
  659. {
  660. struct afs_call *call;
  661. size_t namesz, reqsz, padsz, c_namesz, c_padsz;
  662. __be32 *bp;
  663. _enter("");
  664. namesz = strlen(name);
  665. padsz = (4 - (namesz & 3)) & 3;
  666. c_namesz = strlen(contents);
  667. c_padsz = (4 - (c_namesz & 3)) & 3;
  668. reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
  669. call = afs_alloc_flat_call(&afs_RXFSSymlink, reqsz,
  670. (3 + 21 + 21 + 6) * 4);
  671. if (!call)
  672. return -ENOMEM;
  673. call->key = key;
  674. call->reply = vnode;
  675. call->reply2 = newfid;
  676. call->reply3 = newstatus;
  677. call->service_id = FS_SERVICE;
  678. call->port = htons(AFS_FS_PORT);
  679. /* marshall the parameters */
  680. bp = call->request;
  681. *bp++ = htonl(FSSYMLINK);
  682. *bp++ = htonl(vnode->fid.vid);
  683. *bp++ = htonl(vnode->fid.vnode);
  684. *bp++ = htonl(vnode->fid.unique);
  685. *bp++ = htonl(namesz);
  686. memcpy(bp, name, namesz);
  687. bp = (void *) bp + namesz;
  688. if (padsz > 0) {
  689. memset(bp, 0, padsz);
  690. bp = (void *) bp + padsz;
  691. }
  692. *bp++ = htonl(c_namesz);
  693. memcpy(bp, contents, c_namesz);
  694. bp = (void *) bp + c_namesz;
  695. if (c_padsz > 0) {
  696. memset(bp, 0, c_padsz);
  697. bp = (void *) bp + c_padsz;
  698. }
  699. *bp++ = htonl(AFS_SET_MODE);
  700. *bp++ = 0; /* mtime */
  701. *bp++ = 0; /* owner */
  702. *bp++ = 0; /* group */
  703. *bp++ = htonl(S_IRWXUGO); /* unix mode */
  704. *bp++ = 0; /* segment size */
  705. return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
  706. }
  707. /*
  708. * deliver reply data to an FS.Rename
  709. */
  710. static int afs_deliver_fs_rename(struct afs_call *call,
  711. struct sk_buff *skb, bool last)
  712. {
  713. struct afs_vnode *orig_dvnode = call->reply, *new_dvnode = call->reply2;
  714. const __be32 *bp;
  715. _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
  716. afs_transfer_reply(call, skb);
  717. if (!last)
  718. return 0;
  719. if (call->reply_size != call->reply_max)
  720. return -EBADMSG;
  721. /* unmarshall the reply once we've received all of it */
  722. bp = call->buffer;
  723. xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode);
  724. if (new_dvnode != orig_dvnode)
  725. xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode);
  726. /* xdr_decode_AFSVolSync(&bp, call->replyX); */
  727. _leave(" = 0 [done]");
  728. return 0;
  729. }
  730. /*
  731. * FS.Rename operation type
  732. */
  733. static const struct afs_call_type afs_RXFSRename = {
  734. .name = "FS.Rename",
  735. .deliver = afs_deliver_fs_rename,
  736. .abort_to_error = afs_abort_to_error,
  737. .destructor = afs_flat_call_destructor,
  738. };
  739. /*
  740. * create a symbolic link
  741. */
  742. int afs_fs_rename(struct afs_server *server,
  743. struct key *key,
  744. struct afs_vnode *orig_dvnode,
  745. const char *orig_name,
  746. struct afs_vnode *new_dvnode,
  747. const char *new_name,
  748. const struct afs_wait_mode *wait_mode)
  749. {
  750. struct afs_call *call;
  751. size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
  752. __be32 *bp;
  753. _enter("");
  754. o_namesz = strlen(orig_name);
  755. o_padsz = (4 - (o_namesz & 3)) & 3;
  756. n_namesz = strlen(new_name);
  757. n_padsz = (4 - (n_namesz & 3)) & 3;
  758. reqsz = (4 * 4) +
  759. 4 + o_namesz + o_padsz +
  760. (3 * 4) +
  761. 4 + n_namesz + n_padsz;
  762. call = afs_alloc_flat_call(&afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
  763. if (!call)
  764. return -ENOMEM;
  765. call->key = key;
  766. call->reply = orig_dvnode;
  767. call->reply2 = new_dvnode;
  768. call->service_id = FS_SERVICE;
  769. call->port = htons(AFS_FS_PORT);
  770. /* marshall the parameters */
  771. bp = call->request;
  772. *bp++ = htonl(FSRENAME);
  773. *bp++ = htonl(orig_dvnode->fid.vid);
  774. *bp++ = htonl(orig_dvnode->fid.vnode);
  775. *bp++ = htonl(orig_dvnode->fid.unique);
  776. *bp++ = htonl(o_namesz);
  777. memcpy(bp, orig_name, o_namesz);
  778. bp = (void *) bp + o_namesz;
  779. if (o_padsz > 0) {
  780. memset(bp, 0, o_padsz);
  781. bp = (void *) bp + o_padsz;
  782. }
  783. *bp++ = htonl(new_dvnode->fid.vid);
  784. *bp++ = htonl(new_dvnode->fid.vnode);
  785. *bp++ = htonl(new_dvnode->fid.unique);
  786. *bp++ = htonl(n_namesz);
  787. memcpy(bp, new_name, n_namesz);
  788. bp = (void *) bp + n_namesz;
  789. if (n_padsz > 0) {
  790. memset(bp, 0, n_padsz);
  791. bp = (void *) bp + n_padsz;
  792. }
  793. return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
  794. }