fsclient.c 22 KB

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