fsclient.c 22 KB

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