fsclient.c 22 KB

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