vlclient.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. /* vlclient.c: AFS Volume Location Service client
  2. *
  3. * Copyright (C) 2002 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 <rxrpc/rxrpc.h>
  14. #include <rxrpc/transport.h>
  15. #include <rxrpc/connection.h>
  16. #include <rxrpc/call.h>
  17. #include "server.h"
  18. #include "volume.h"
  19. #include "vlclient.h"
  20. #include "kafsasyncd.h"
  21. #include "kafstimod.h"
  22. #include "errors.h"
  23. #include "internal.h"
  24. #define VLGETENTRYBYID 503 /* AFS Get Cache Entry By ID operation ID */
  25. #define VLGETENTRYBYNAME 504 /* AFS Get Cache Entry By Name operation ID */
  26. #define VLPROBE 514 /* AFS Probe Volume Location Service operation ID */
  27. static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call);
  28. static void afs_rxvl_get_entry_by_id_error(struct rxrpc_call *call);
  29. /*****************************************************************************/
  30. /*
  31. * map afs VL abort codes to/from Linux error codes
  32. * - called with call->lock held
  33. */
  34. static void afs_rxvl_aemap(struct rxrpc_call *call)
  35. {
  36. int err;
  37. _enter("{%u,%u,%d}",
  38. call->app_err_state, call->app_abort_code, call->app_errno);
  39. switch (call->app_err_state) {
  40. case RXRPC_ESTATE_LOCAL_ABORT:
  41. call->app_abort_code = -call->app_errno;
  42. return;
  43. case RXRPC_ESTATE_PEER_ABORT:
  44. switch (call->app_abort_code) {
  45. case AFSVL_IDEXIST: err = -EEXIST; break;
  46. case AFSVL_IO: err = -EREMOTEIO; break;
  47. case AFSVL_NAMEEXIST: err = -EEXIST; break;
  48. case AFSVL_CREATEFAIL: err = -EREMOTEIO; break;
  49. case AFSVL_NOENT: err = -ENOMEDIUM; break;
  50. case AFSVL_EMPTY: err = -ENOMEDIUM; break;
  51. case AFSVL_ENTDELETED: err = -ENOMEDIUM; break;
  52. case AFSVL_BADNAME: err = -EINVAL; break;
  53. case AFSVL_BADINDEX: err = -EINVAL; break;
  54. case AFSVL_BADVOLTYPE: err = -EINVAL; break;
  55. case AFSVL_BADSERVER: err = -EINVAL; break;
  56. case AFSVL_BADPARTITION: err = -EINVAL; break;
  57. case AFSVL_REPSFULL: err = -EFBIG; break;
  58. case AFSVL_NOREPSERVER: err = -ENOENT; break;
  59. case AFSVL_DUPREPSERVER: err = -EEXIST; break;
  60. case AFSVL_RWNOTFOUND: err = -ENOENT; break;
  61. case AFSVL_BADREFCOUNT: err = -EINVAL; break;
  62. case AFSVL_SIZEEXCEEDED: err = -EINVAL; break;
  63. case AFSVL_BADENTRY: err = -EINVAL; break;
  64. case AFSVL_BADVOLIDBUMP: err = -EINVAL; break;
  65. case AFSVL_IDALREADYHASHED: err = -EINVAL; break;
  66. case AFSVL_ENTRYLOCKED: err = -EBUSY; break;
  67. case AFSVL_BADVOLOPER: err = -EBADRQC; break;
  68. case AFSVL_BADRELLOCKTYPE: err = -EINVAL; break;
  69. case AFSVL_RERELEASE: err = -EREMOTEIO; break;
  70. case AFSVL_BADSERVERFLAG: err = -EINVAL; break;
  71. case AFSVL_PERM: err = -EACCES; break;
  72. case AFSVL_NOMEM: err = -EREMOTEIO; break;
  73. default:
  74. err = afs_abort_to_error(call->app_abort_code);
  75. break;
  76. }
  77. call->app_errno = err;
  78. return;
  79. default:
  80. return;
  81. }
  82. } /* end afs_rxvl_aemap() */
  83. #if 0
  84. /*****************************************************************************/
  85. /*
  86. * probe a volume location server to see if it is still alive -- unused
  87. */
  88. static int afs_rxvl_probe(struct afs_server *server, int alloc_flags)
  89. {
  90. struct rxrpc_connection *conn;
  91. struct rxrpc_call *call;
  92. struct kvec piov[1];
  93. size_t sent;
  94. int ret;
  95. __be32 param[1];
  96. DECLARE_WAITQUEUE(myself, current);
  97. /* get hold of the vlserver connection */
  98. ret = afs_server_get_vlconn(server, &conn);
  99. if (ret < 0)
  100. goto out;
  101. /* create a call through that connection */
  102. ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call);
  103. if (ret < 0) {
  104. printk("kAFS: Unable to create call: %d\n", ret);
  105. goto out_put_conn;
  106. }
  107. call->app_opcode = VLPROBE;
  108. /* we want to get event notifications from the call */
  109. add_wait_queue(&call->waitq, &myself);
  110. /* marshall the parameters */
  111. param[0] = htonl(VLPROBE);
  112. piov[0].iov_len = sizeof(param);
  113. piov[0].iov_base = param;
  114. /* send the parameters to the server */
  115. ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET,
  116. alloc_flags, 0, &sent);
  117. if (ret < 0)
  118. goto abort;
  119. /* wait for the reply to completely arrive */
  120. for (;;) {
  121. set_current_state(TASK_INTERRUPTIBLE);
  122. if (call->app_call_state != RXRPC_CSTATE_CLNT_RCV_REPLY ||
  123. signal_pending(current))
  124. break;
  125. schedule();
  126. }
  127. set_current_state(TASK_RUNNING);
  128. ret = -EINTR;
  129. if (signal_pending(current))
  130. goto abort;
  131. switch (call->app_call_state) {
  132. case RXRPC_CSTATE_ERROR:
  133. ret = call->app_errno;
  134. goto out_unwait;
  135. case RXRPC_CSTATE_CLNT_GOT_REPLY:
  136. ret = 0;
  137. goto out_unwait;
  138. default:
  139. BUG();
  140. }
  141. abort:
  142. set_current_state(TASK_UNINTERRUPTIBLE);
  143. rxrpc_call_abort(call, ret);
  144. schedule();
  145. out_unwait:
  146. set_current_state(TASK_RUNNING);
  147. remove_wait_queue(&call->waitq, &myself);
  148. rxrpc_put_call(call);
  149. out_put_conn:
  150. rxrpc_put_connection(conn);
  151. out:
  152. return ret;
  153. } /* end afs_rxvl_probe() */
  154. #endif
  155. /*****************************************************************************/
  156. /*
  157. * look up a volume location database entry by name
  158. */
  159. int afs_rxvl_get_entry_by_name(struct afs_server *server,
  160. const char *volname,
  161. unsigned volnamesz,
  162. struct afs_cache_vlocation *entry)
  163. {
  164. DECLARE_WAITQUEUE(myself, current);
  165. struct rxrpc_connection *conn;
  166. struct rxrpc_call *call;
  167. struct kvec piov[3];
  168. unsigned tmp;
  169. size_t sent;
  170. int ret, loop;
  171. __be32 *bp, param[2], zero;
  172. _enter(",%*.*s,%u,", volnamesz, volnamesz, volname, volnamesz);
  173. memset(entry, 0, sizeof(*entry));
  174. /* get hold of the vlserver connection */
  175. ret = afs_server_get_vlconn(server, &conn);
  176. if (ret < 0)
  177. goto out;
  178. /* create a call through that connection */
  179. ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call);
  180. if (ret < 0) {
  181. printk("kAFS: Unable to create call: %d\n", ret);
  182. goto out_put_conn;
  183. }
  184. call->app_opcode = VLGETENTRYBYNAME;
  185. /* we want to get event notifications from the call */
  186. add_wait_queue(&call->waitq, &myself);
  187. /* marshall the parameters */
  188. piov[1].iov_len = volnamesz;
  189. piov[1].iov_base = (char *) volname;
  190. zero = 0;
  191. piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3;
  192. piov[2].iov_base = &zero;
  193. param[0] = htonl(VLGETENTRYBYNAME);
  194. param[1] = htonl(piov[1].iov_len);
  195. piov[0].iov_len = sizeof(param);
  196. piov[0].iov_base = param;
  197. /* send the parameters to the server */
  198. ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS,
  199. 0, &sent);
  200. if (ret < 0)
  201. goto abort;
  202. /* wait for the reply to completely arrive */
  203. bp = rxrpc_call_alloc_scratch(call, 384);
  204. ret = rxrpc_call_read_data(call, bp, 384,
  205. RXRPC_CALL_READ_BLOCK |
  206. RXRPC_CALL_READ_ALL);
  207. if (ret < 0) {
  208. if (ret == -ECONNABORTED) {
  209. ret = call->app_errno;
  210. goto out_unwait;
  211. }
  212. goto abort;
  213. }
  214. /* unmarshall the reply */
  215. for (loop = 0; loop < 64; loop++)
  216. entry->name[loop] = ntohl(*bp++);
  217. bp++; /* final NUL */
  218. bp++; /* type */
  219. entry->nservers = ntohl(*bp++);
  220. for (loop = 0; loop < 8; loop++)
  221. entry->servers[loop].s_addr = *bp++;
  222. bp += 8; /* partition IDs */
  223. for (loop = 0; loop < 8; loop++) {
  224. tmp = ntohl(*bp++);
  225. if (tmp & AFS_VLSF_RWVOL)
  226. entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
  227. if (tmp & AFS_VLSF_ROVOL)
  228. entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
  229. if (tmp & AFS_VLSF_BACKVOL)
  230. entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
  231. }
  232. entry->vid[0] = ntohl(*bp++);
  233. entry->vid[1] = ntohl(*bp++);
  234. entry->vid[2] = ntohl(*bp++);
  235. bp++; /* clone ID */
  236. tmp = ntohl(*bp++); /* flags */
  237. if (tmp & AFS_VLF_RWEXISTS)
  238. entry->vidmask |= AFS_VOL_VTM_RW;
  239. if (tmp & AFS_VLF_ROEXISTS)
  240. entry->vidmask |= AFS_VOL_VTM_RO;
  241. if (tmp & AFS_VLF_BACKEXISTS)
  242. entry->vidmask |= AFS_VOL_VTM_BAK;
  243. ret = -ENOMEDIUM;
  244. if (!entry->vidmask)
  245. goto abort;
  246. /* success */
  247. entry->rtime = get_seconds();
  248. ret = 0;
  249. out_unwait:
  250. set_current_state(TASK_RUNNING);
  251. remove_wait_queue(&call->waitq, &myself);
  252. rxrpc_put_call(call);
  253. out_put_conn:
  254. rxrpc_put_connection(conn);
  255. out:
  256. _leave(" = %d", ret);
  257. return ret;
  258. abort:
  259. set_current_state(TASK_UNINTERRUPTIBLE);
  260. rxrpc_call_abort(call, ret);
  261. schedule();
  262. goto out_unwait;
  263. } /* end afs_rxvl_get_entry_by_name() */
  264. /*****************************************************************************/
  265. /*
  266. * look up a volume location database entry by ID
  267. */
  268. int afs_rxvl_get_entry_by_id(struct afs_server *server,
  269. afs_volid_t volid,
  270. afs_voltype_t voltype,
  271. struct afs_cache_vlocation *entry)
  272. {
  273. DECLARE_WAITQUEUE(myself, current);
  274. struct rxrpc_connection *conn;
  275. struct rxrpc_call *call;
  276. struct kvec piov[1];
  277. unsigned tmp;
  278. size_t sent;
  279. int ret, loop;
  280. __be32 *bp, param[3];
  281. _enter(",%x,%d,", volid, voltype);
  282. memset(entry, 0, sizeof(*entry));
  283. /* get hold of the vlserver connection */
  284. ret = afs_server_get_vlconn(server, &conn);
  285. if (ret < 0)
  286. goto out;
  287. /* create a call through that connection */
  288. ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call);
  289. if (ret < 0) {
  290. printk("kAFS: Unable to create call: %d\n", ret);
  291. goto out_put_conn;
  292. }
  293. call->app_opcode = VLGETENTRYBYID;
  294. /* we want to get event notifications from the call */
  295. add_wait_queue(&call->waitq, &myself);
  296. /* marshall the parameters */
  297. param[0] = htonl(VLGETENTRYBYID);
  298. param[1] = htonl(volid);
  299. param[2] = htonl(voltype);
  300. piov[0].iov_len = sizeof(param);
  301. piov[0].iov_base = param;
  302. /* send the parameters to the server */
  303. ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
  304. 0, &sent);
  305. if (ret < 0)
  306. goto abort;
  307. /* wait for the reply to completely arrive */
  308. bp = rxrpc_call_alloc_scratch(call, 384);
  309. ret = rxrpc_call_read_data(call, bp, 384,
  310. RXRPC_CALL_READ_BLOCK |
  311. RXRPC_CALL_READ_ALL);
  312. if (ret < 0) {
  313. if (ret == -ECONNABORTED) {
  314. ret = call->app_errno;
  315. goto out_unwait;
  316. }
  317. goto abort;
  318. }
  319. /* unmarshall the reply */
  320. for (loop = 0; loop < 64; loop++)
  321. entry->name[loop] = ntohl(*bp++);
  322. bp++; /* final NUL */
  323. bp++; /* type */
  324. entry->nservers = ntohl(*bp++);
  325. for (loop = 0; loop < 8; loop++)
  326. entry->servers[loop].s_addr = *bp++;
  327. bp += 8; /* partition IDs */
  328. for (loop = 0; loop < 8; loop++) {
  329. tmp = ntohl(*bp++);
  330. if (tmp & AFS_VLSF_RWVOL)
  331. entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
  332. if (tmp & AFS_VLSF_ROVOL)
  333. entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
  334. if (tmp & AFS_VLSF_BACKVOL)
  335. entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
  336. }
  337. entry->vid[0] = ntohl(*bp++);
  338. entry->vid[1] = ntohl(*bp++);
  339. entry->vid[2] = ntohl(*bp++);
  340. bp++; /* clone ID */
  341. tmp = ntohl(*bp++); /* flags */
  342. if (tmp & AFS_VLF_RWEXISTS)
  343. entry->vidmask |= AFS_VOL_VTM_RW;
  344. if (tmp & AFS_VLF_ROEXISTS)
  345. entry->vidmask |= AFS_VOL_VTM_RO;
  346. if (tmp & AFS_VLF_BACKEXISTS)
  347. entry->vidmask |= AFS_VOL_VTM_BAK;
  348. ret = -ENOMEDIUM;
  349. if (!entry->vidmask)
  350. goto abort;
  351. #if 0 /* TODO: remove */
  352. entry->nservers = 3;
  353. entry->servers[0].s_addr = htonl(0xac101249);
  354. entry->servers[1].s_addr = htonl(0xac101243);
  355. entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/);
  356. entry->srvtmask[0] = AFS_VOL_VTM_RO;
  357. entry->srvtmask[1] = AFS_VOL_VTM_RO;
  358. entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW;
  359. #endif
  360. /* success */
  361. entry->rtime = get_seconds();
  362. ret = 0;
  363. out_unwait:
  364. set_current_state(TASK_RUNNING);
  365. remove_wait_queue(&call->waitq, &myself);
  366. rxrpc_put_call(call);
  367. out_put_conn:
  368. rxrpc_put_connection(conn);
  369. out:
  370. _leave(" = %d", ret);
  371. return ret;
  372. abort:
  373. set_current_state(TASK_UNINTERRUPTIBLE);
  374. rxrpc_call_abort(call, ret);
  375. schedule();
  376. goto out_unwait;
  377. } /* end afs_rxvl_get_entry_by_id() */
  378. /*****************************************************************************/
  379. /*
  380. * look up a volume location database entry by ID asynchronously
  381. */
  382. int afs_rxvl_get_entry_by_id_async(struct afs_async_op *op,
  383. afs_volid_t volid,
  384. afs_voltype_t voltype)
  385. {
  386. struct rxrpc_connection *conn;
  387. struct rxrpc_call *call;
  388. struct kvec piov[1];
  389. size_t sent;
  390. int ret;
  391. __be32 param[3];
  392. _enter(",%x,%d,", volid, voltype);
  393. /* get hold of the vlserver connection */
  394. ret = afs_server_get_vlconn(op->server, &conn);
  395. if (ret < 0) {
  396. _leave(" = %d", ret);
  397. return ret;
  398. }
  399. /* create a call through that connection */
  400. ret = rxrpc_create_call(conn,
  401. afs_rxvl_get_entry_by_id_attn,
  402. afs_rxvl_get_entry_by_id_error,
  403. afs_rxvl_aemap,
  404. &op->call);
  405. rxrpc_put_connection(conn);
  406. if (ret < 0) {
  407. printk("kAFS: Unable to create call: %d\n", ret);
  408. _leave(" = %d", ret);
  409. return ret;
  410. }
  411. op->call->app_opcode = VLGETENTRYBYID;
  412. op->call->app_user = op;
  413. call = op->call;
  414. rxrpc_get_call(call);
  415. /* send event notifications from the call to kafsasyncd */
  416. afs_kafsasyncd_begin_op(op);
  417. /* marshall the parameters */
  418. param[0] = htonl(VLGETENTRYBYID);
  419. param[1] = htonl(volid);
  420. param[2] = htonl(voltype);
  421. piov[0].iov_len = sizeof(param);
  422. piov[0].iov_base = param;
  423. /* allocate result read buffer in scratch space */
  424. call->app_scr_ptr = rxrpc_call_alloc_scratch(op->call, 384);
  425. /* send the parameters to the server */
  426. ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
  427. 0, &sent);
  428. if (ret < 0) {
  429. rxrpc_call_abort(call, ret); /* handle from kafsasyncd */
  430. ret = 0;
  431. goto out;
  432. }
  433. /* wait for the reply to completely arrive */
  434. ret = rxrpc_call_read_data(call, call->app_scr_ptr, 384, 0);
  435. switch (ret) {
  436. case 0:
  437. case -EAGAIN:
  438. case -ECONNABORTED:
  439. ret = 0;
  440. break; /* all handled by kafsasyncd */
  441. default:
  442. rxrpc_call_abort(call, ret); /* make kafsasyncd handle it */
  443. ret = 0;
  444. break;
  445. }
  446. out:
  447. rxrpc_put_call(call);
  448. _leave(" = %d", ret);
  449. return ret;
  450. } /* end afs_rxvl_get_entry_by_id_async() */
  451. /*****************************************************************************/
  452. /*
  453. * attend to the asynchronous get VLDB entry by ID
  454. */
  455. int afs_rxvl_get_entry_by_id_async2(struct afs_async_op *op,
  456. struct afs_cache_vlocation *entry)
  457. {
  458. __be32 *bp;
  459. __u32 tmp;
  460. int loop, ret;
  461. _enter("{op=%p cst=%u}", op, op->call->app_call_state);
  462. memset(entry, 0, sizeof(*entry));
  463. if (op->call->app_call_state == RXRPC_CSTATE_COMPLETE) {
  464. /* operation finished */
  465. afs_kafsasyncd_terminate_op(op);
  466. bp = op->call->app_scr_ptr;
  467. /* unmarshall the reply */
  468. for (loop = 0; loop < 64; loop++)
  469. entry->name[loop] = ntohl(*bp++);
  470. bp++; /* final NUL */
  471. bp++; /* type */
  472. entry->nservers = ntohl(*bp++);
  473. for (loop = 0; loop < 8; loop++)
  474. entry->servers[loop].s_addr = *bp++;
  475. bp += 8; /* partition IDs */
  476. for (loop = 0; loop < 8; loop++) {
  477. tmp = ntohl(*bp++);
  478. if (tmp & AFS_VLSF_RWVOL)
  479. entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
  480. if (tmp & AFS_VLSF_ROVOL)
  481. entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
  482. if (tmp & AFS_VLSF_BACKVOL)
  483. entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
  484. }
  485. entry->vid[0] = ntohl(*bp++);
  486. entry->vid[1] = ntohl(*bp++);
  487. entry->vid[2] = ntohl(*bp++);
  488. bp++; /* clone ID */
  489. tmp = ntohl(*bp++); /* flags */
  490. if (tmp & AFS_VLF_RWEXISTS)
  491. entry->vidmask |= AFS_VOL_VTM_RW;
  492. if (tmp & AFS_VLF_ROEXISTS)
  493. entry->vidmask |= AFS_VOL_VTM_RO;
  494. if (tmp & AFS_VLF_BACKEXISTS)
  495. entry->vidmask |= AFS_VOL_VTM_BAK;
  496. ret = -ENOMEDIUM;
  497. if (!entry->vidmask) {
  498. rxrpc_call_abort(op->call, ret);
  499. goto done;
  500. }
  501. #if 0 /* TODO: remove */
  502. entry->nservers = 3;
  503. entry->servers[0].s_addr = htonl(0xac101249);
  504. entry->servers[1].s_addr = htonl(0xac101243);
  505. entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/);
  506. entry->srvtmask[0] = AFS_VOL_VTM_RO;
  507. entry->srvtmask[1] = AFS_VOL_VTM_RO;
  508. entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW;
  509. #endif
  510. /* success */
  511. entry->rtime = get_seconds();
  512. ret = 0;
  513. goto done;
  514. }
  515. if (op->call->app_call_state == RXRPC_CSTATE_ERROR) {
  516. /* operation error */
  517. ret = op->call->app_errno;
  518. goto done;
  519. }
  520. _leave(" = -EAGAIN");
  521. return -EAGAIN;
  522. done:
  523. rxrpc_put_call(op->call);
  524. op->call = NULL;
  525. _leave(" = %d", ret);
  526. return ret;
  527. } /* end afs_rxvl_get_entry_by_id_async2() */
  528. /*****************************************************************************/
  529. /*
  530. * handle attention events on an async get-entry-by-ID op
  531. * - called from krxiod
  532. */
  533. static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call)
  534. {
  535. struct afs_async_op *op = call->app_user;
  536. _enter("{op=%p cst=%u}", op, call->app_call_state);
  537. switch (call->app_call_state) {
  538. case RXRPC_CSTATE_COMPLETE:
  539. afs_kafsasyncd_attend_op(op);
  540. break;
  541. case RXRPC_CSTATE_CLNT_RCV_REPLY:
  542. if (call->app_async_read)
  543. break;
  544. case RXRPC_CSTATE_CLNT_GOT_REPLY:
  545. if (call->app_read_count == 0)
  546. break;
  547. printk("kAFS: Reply bigger than expected"
  548. " {cst=%u asyn=%d mark=%Zu rdy=%Zu pr=%u%s}",
  549. call->app_call_state,
  550. call->app_async_read,
  551. call->app_mark,
  552. call->app_ready_qty,
  553. call->pkt_rcv_count,
  554. call->app_last_rcv ? " last" : "");
  555. rxrpc_call_abort(call, -EBADMSG);
  556. break;
  557. default:
  558. BUG();
  559. }
  560. _leave("");
  561. } /* end afs_rxvl_get_entry_by_id_attn() */
  562. /*****************************************************************************/
  563. /*
  564. * handle error events on an async get-entry-by-ID op
  565. * - called from krxiod
  566. */
  567. static void afs_rxvl_get_entry_by_id_error(struct rxrpc_call *call)
  568. {
  569. struct afs_async_op *op = call->app_user;
  570. _enter("{op=%p cst=%u}", op, call->app_call_state);
  571. afs_kafsasyncd_attend_op(op);
  572. _leave("");
  573. } /* end afs_rxvl_get_entry_by_id_error() */