vlocation.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. /* volume location management
  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/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/init.h>
  14. #include <linux/slab.h>
  15. #include <linux/fs.h>
  16. #include <linux/pagemap.h>
  17. #include "volume.h"
  18. #include "cell.h"
  19. #include "cmservice.h"
  20. #include "fsclient.h"
  21. #include "vlclient.h"
  22. #include "kafstimod.h"
  23. #include <rxrpc/connection.h>
  24. #include "internal.h"
  25. #define AFS_VLDB_TIMEOUT HZ*1000
  26. static void afs_vlocation_update_timer(struct afs_timer *timer);
  27. static void afs_vlocation_update_attend(struct afs_async_op *op);
  28. static void afs_vlocation_update_discard(struct afs_async_op *op);
  29. static void __afs_put_vlocation(struct afs_vlocation *vlocation);
  30. static void __afs_vlocation_timeout(struct afs_timer *timer)
  31. {
  32. struct afs_vlocation *vlocation =
  33. list_entry(timer, struct afs_vlocation, timeout);
  34. _debug("VL TIMEOUT [%s{u=%d}]",
  35. vlocation->vldb.name, atomic_read(&vlocation->usage));
  36. afs_vlocation_do_timeout(vlocation);
  37. }
  38. static const struct afs_timer_ops afs_vlocation_timer_ops = {
  39. .timed_out = __afs_vlocation_timeout,
  40. };
  41. static const struct afs_timer_ops afs_vlocation_update_timer_ops = {
  42. .timed_out = afs_vlocation_update_timer,
  43. };
  44. static const struct afs_async_op_ops afs_vlocation_update_op_ops = {
  45. .attend = afs_vlocation_update_attend,
  46. .discard = afs_vlocation_update_discard,
  47. };
  48. static LIST_HEAD(afs_vlocation_update_pendq); /* queue of VLs awaiting update */
  49. static struct afs_vlocation *afs_vlocation_update; /* VL currently being updated */
  50. static DEFINE_SPINLOCK(afs_vlocation_update_lock); /* lock guarding update queue */
  51. #ifdef AFS_CACHING_SUPPORT
  52. static cachefs_match_val_t afs_vlocation_cache_match(void *target,
  53. const void *entry);
  54. static void afs_vlocation_cache_update(void *source, void *entry);
  55. struct cachefs_index_def afs_vlocation_cache_index_def = {
  56. .name = "vldb",
  57. .data_size = sizeof(struct afs_cache_vlocation),
  58. .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
  59. .match = afs_vlocation_cache_match,
  60. .update = afs_vlocation_cache_update,
  61. };
  62. #endif
  63. /*
  64. * iterate through the VL servers in a cell until one of them admits knowing
  65. * about the volume in question
  66. * - caller must have cell->vl_sem write-locked
  67. */
  68. static int afs_vlocation_access_vl_by_name(struct afs_vlocation *vlocation,
  69. const char *name,
  70. unsigned namesz,
  71. struct afs_cache_vlocation *vldb)
  72. {
  73. struct afs_server *server = NULL;
  74. struct afs_cell *cell = vlocation->cell;
  75. int count, ret;
  76. _enter("%s,%*.*s,%u", cell->name, namesz, namesz, name, namesz);
  77. ret = -ENOMEDIUM;
  78. for (count = cell->vl_naddrs; count > 0; count--) {
  79. _debug("CellServ[%hu]: %08x",
  80. cell->vl_curr_svix,
  81. cell->vl_addrs[cell->vl_curr_svix].s_addr);
  82. /* try and create a server */
  83. ret = afs_server_lookup(cell,
  84. &cell->vl_addrs[cell->vl_curr_svix],
  85. &server);
  86. switch (ret) {
  87. case 0:
  88. break;
  89. case -ENOMEM:
  90. case -ENONET:
  91. goto out;
  92. default:
  93. goto rotate;
  94. }
  95. /* attempt to access the VL server */
  96. ret = afs_rxvl_get_entry_by_name(server, name, namesz, vldb);
  97. switch (ret) {
  98. case 0:
  99. afs_put_server(server);
  100. goto out;
  101. case -ENOMEM:
  102. case -ENONET:
  103. case -ENETUNREACH:
  104. case -EHOSTUNREACH:
  105. case -ECONNREFUSED:
  106. down_write(&server->sem);
  107. if (server->vlserver) {
  108. rxrpc_put_connection(server->vlserver);
  109. server->vlserver = NULL;
  110. }
  111. up_write(&server->sem);
  112. afs_put_server(server);
  113. if (ret == -ENOMEM || ret == -ENONET)
  114. goto out;
  115. goto rotate;
  116. case -ENOMEDIUM:
  117. afs_put_server(server);
  118. goto out;
  119. default:
  120. afs_put_server(server);
  121. ret = -ENOMEDIUM;
  122. goto rotate;
  123. }
  124. /* rotate the server records upon lookup failure */
  125. rotate:
  126. cell->vl_curr_svix++;
  127. cell->vl_curr_svix %= cell->vl_naddrs;
  128. }
  129. out:
  130. _leave(" = %d", ret);
  131. return ret;
  132. }
  133. /*
  134. * iterate through the VL servers in a cell until one of them admits knowing
  135. * about the volume in question
  136. * - caller must have cell->vl_sem write-locked
  137. */
  138. static int afs_vlocation_access_vl_by_id(struct afs_vlocation *vlocation,
  139. afs_volid_t volid,
  140. afs_voltype_t voltype,
  141. struct afs_cache_vlocation *vldb)
  142. {
  143. struct afs_server *server = NULL;
  144. struct afs_cell *cell = vlocation->cell;
  145. int count, ret;
  146. _enter("%s,%x,%d,", cell->name, volid, voltype);
  147. ret = -ENOMEDIUM;
  148. for (count = cell->vl_naddrs; count > 0; count--) {
  149. _debug("CellServ[%hu]: %08x",
  150. cell->vl_curr_svix,
  151. cell->vl_addrs[cell->vl_curr_svix].s_addr);
  152. /* try and create a server */
  153. ret = afs_server_lookup(cell,
  154. &cell->vl_addrs[cell->vl_curr_svix],
  155. &server);
  156. switch (ret) {
  157. case 0:
  158. break;
  159. case -ENOMEM:
  160. case -ENONET:
  161. goto out;
  162. default:
  163. goto rotate;
  164. }
  165. /* attempt to access the VL server */
  166. ret = afs_rxvl_get_entry_by_id(server, volid, voltype, vldb);
  167. switch (ret) {
  168. case 0:
  169. afs_put_server(server);
  170. goto out;
  171. case -ENOMEM:
  172. case -ENONET:
  173. case -ENETUNREACH:
  174. case -EHOSTUNREACH:
  175. case -ECONNREFUSED:
  176. down_write(&server->sem);
  177. if (server->vlserver) {
  178. rxrpc_put_connection(server->vlserver);
  179. server->vlserver = NULL;
  180. }
  181. up_write(&server->sem);
  182. afs_put_server(server);
  183. if (ret == -ENOMEM || ret == -ENONET)
  184. goto out;
  185. goto rotate;
  186. case -ENOMEDIUM:
  187. afs_put_server(server);
  188. goto out;
  189. default:
  190. afs_put_server(server);
  191. ret = -ENOMEDIUM;
  192. goto rotate;
  193. }
  194. /* rotate the server records upon lookup failure */
  195. rotate:
  196. cell->vl_curr_svix++;
  197. cell->vl_curr_svix %= cell->vl_naddrs;
  198. }
  199. out:
  200. _leave(" = %d", ret);
  201. return ret;
  202. }
  203. /*
  204. * lookup volume location
  205. * - caller must have cell->vol_sem write-locked
  206. * - iterate through the VL servers in a cell until one of them admits knowing
  207. * about the volume in question
  208. * - lookup in the local cache if not able to find on the VL server
  209. * - insert/update in the local cache if did get a VL response
  210. */
  211. int afs_vlocation_lookup(struct afs_cell *cell,
  212. const char *name,
  213. unsigned namesz,
  214. struct afs_vlocation **_vlocation)
  215. {
  216. struct afs_cache_vlocation vldb;
  217. struct afs_vlocation *vlocation;
  218. afs_voltype_t voltype;
  219. afs_volid_t vid;
  220. int active = 0, ret;
  221. _enter("{%s},%*.*s,%u,", cell->name, namesz, namesz, name, namesz);
  222. if (namesz > sizeof(vlocation->vldb.name)) {
  223. _leave(" = -ENAMETOOLONG");
  224. return -ENAMETOOLONG;
  225. }
  226. /* search the cell's active list first */
  227. list_for_each_entry(vlocation, &cell->vl_list, link) {
  228. if (namesz < sizeof(vlocation->vldb.name) &&
  229. vlocation->vldb.name[namesz] != '\0')
  230. continue;
  231. if (memcmp(vlocation->vldb.name, name, namesz) == 0)
  232. goto found_in_memory;
  233. }
  234. /* search the cell's graveyard list second */
  235. spin_lock(&cell->vl_gylock);
  236. list_for_each_entry(vlocation, &cell->vl_graveyard, link) {
  237. if (namesz < sizeof(vlocation->vldb.name) &&
  238. vlocation->vldb.name[namesz] != '\0')
  239. continue;
  240. if (memcmp(vlocation->vldb.name, name, namesz) == 0)
  241. goto found_in_graveyard;
  242. }
  243. spin_unlock(&cell->vl_gylock);
  244. /* not in the cell's in-memory lists - create a new record */
  245. vlocation = kzalloc(sizeof(struct afs_vlocation), GFP_KERNEL);
  246. if (!vlocation)
  247. return -ENOMEM;
  248. atomic_set(&vlocation->usage, 1);
  249. INIT_LIST_HEAD(&vlocation->link);
  250. rwlock_init(&vlocation->lock);
  251. memcpy(vlocation->vldb.name, name, namesz);
  252. afs_timer_init(&vlocation->timeout, &afs_vlocation_timer_ops);
  253. afs_timer_init(&vlocation->upd_timer, &afs_vlocation_update_timer_ops);
  254. afs_async_op_init(&vlocation->upd_op, &afs_vlocation_update_op_ops);
  255. afs_get_cell(cell);
  256. vlocation->cell = cell;
  257. list_add_tail(&vlocation->link, &cell->vl_list);
  258. #ifdef AFS_CACHING_SUPPORT
  259. /* we want to store it in the cache, plus it might already be
  260. * encached */
  261. cachefs_acquire_cookie(cell->cache,
  262. &afs_volume_cache_index_def,
  263. vlocation,
  264. &vlocation->cache);
  265. if (vlocation->valid)
  266. goto found_in_cache;
  267. #endif
  268. /* try to look up an unknown volume in the cell VL databases by name */
  269. ret = afs_vlocation_access_vl_by_name(vlocation, name, namesz, &vldb);
  270. if (ret < 0) {
  271. printk("kAFS: failed to locate '%*.*s' in cell '%s'\n",
  272. namesz, namesz, name, cell->name);
  273. goto error;
  274. }
  275. goto found_on_vlserver;
  276. found_in_graveyard:
  277. /* found in the graveyard - resurrect */
  278. _debug("found in graveyard");
  279. atomic_inc(&vlocation->usage);
  280. list_move_tail(&vlocation->link, &cell->vl_list);
  281. spin_unlock(&cell->vl_gylock);
  282. afs_kafstimod_del_timer(&vlocation->timeout);
  283. goto active;
  284. found_in_memory:
  285. /* found in memory - check to see if it's active */
  286. _debug("found in memory");
  287. atomic_inc(&vlocation->usage);
  288. active:
  289. active = 1;
  290. #ifdef AFS_CACHING_SUPPORT
  291. found_in_cache:
  292. #endif
  293. /* try to look up a cached volume in the cell VL databases by ID */
  294. _debug("found in cache");
  295. _debug("Locally Cached: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
  296. vlocation->vldb.name,
  297. vlocation->vldb.vidmask,
  298. ntohl(vlocation->vldb.servers[0].s_addr),
  299. vlocation->vldb.srvtmask[0],
  300. ntohl(vlocation->vldb.servers[1].s_addr),
  301. vlocation->vldb.srvtmask[1],
  302. ntohl(vlocation->vldb.servers[2].s_addr),
  303. vlocation->vldb.srvtmask[2]
  304. );
  305. _debug("Vids: %08x %08x %08x",
  306. vlocation->vldb.vid[0],
  307. vlocation->vldb.vid[1],
  308. vlocation->vldb.vid[2]);
  309. if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) {
  310. vid = vlocation->vldb.vid[0];
  311. voltype = AFSVL_RWVOL;
  312. } else if (vlocation->vldb.vidmask & AFS_VOL_VTM_RO) {
  313. vid = vlocation->vldb.vid[1];
  314. voltype = AFSVL_ROVOL;
  315. } else if (vlocation->vldb.vidmask & AFS_VOL_VTM_BAK) {
  316. vid = vlocation->vldb.vid[2];
  317. voltype = AFSVL_BACKVOL;
  318. } else {
  319. BUG();
  320. vid = 0;
  321. voltype = 0;
  322. }
  323. ret = afs_vlocation_access_vl_by_id(vlocation, vid, voltype, &vldb);
  324. switch (ret) {
  325. /* net error */
  326. default:
  327. printk("kAFS: failed to volume '%*.*s' (%x) up in '%s': %d\n",
  328. namesz, namesz, name, vid, cell->name, ret);
  329. goto error;
  330. /* pulled from local cache into memory */
  331. case 0:
  332. goto found_on_vlserver;
  333. /* uh oh... looks like the volume got deleted */
  334. case -ENOMEDIUM:
  335. printk("kAFS: volume '%*.*s' (%x) does not exist '%s'\n",
  336. namesz, namesz, name, vid, cell->name);
  337. /* TODO: make existing record unavailable */
  338. goto error;
  339. }
  340. found_on_vlserver:
  341. _debug("Done VL Lookup: %*.*s %02x { %08x(%x) %08x(%x) %08x(%x) }",
  342. namesz, namesz, name,
  343. vldb.vidmask,
  344. ntohl(vldb.servers[0].s_addr), vldb.srvtmask[0],
  345. ntohl(vldb.servers[1].s_addr), vldb.srvtmask[1],
  346. ntohl(vldb.servers[2].s_addr), vldb.srvtmask[2]
  347. );
  348. _debug("Vids: %08x %08x %08x", vldb.vid[0], vldb.vid[1], vldb.vid[2]);
  349. if ((namesz < sizeof(vlocation->vldb.name) &&
  350. vlocation->vldb.name[namesz] != '\0') ||
  351. memcmp(vldb.name, name, namesz) != 0)
  352. printk("kAFS: name of volume '%*.*s' changed to '%s' on server\n",
  353. namesz, namesz, name, vldb.name);
  354. memcpy(&vlocation->vldb, &vldb, sizeof(vlocation->vldb));
  355. afs_kafstimod_add_timer(&vlocation->upd_timer, 10 * HZ);
  356. #ifdef AFS_CACHING_SUPPORT
  357. /* update volume entry in local cache */
  358. cachefs_update_cookie(vlocation->cache);
  359. #endif
  360. *_vlocation = vlocation;
  361. _leave(" = 0 (%p)",vlocation);
  362. return 0;
  363. error:
  364. if (vlocation) {
  365. if (active) {
  366. __afs_put_vlocation(vlocation);
  367. } else {
  368. list_del(&vlocation->link);
  369. #ifdef AFS_CACHING_SUPPORT
  370. cachefs_relinquish_cookie(vlocation->cache, 0);
  371. #endif
  372. afs_put_cell(vlocation->cell);
  373. kfree(vlocation);
  374. }
  375. }
  376. _leave(" = %d", ret);
  377. return ret;
  378. }
  379. /*
  380. * finish using a volume location record
  381. * - caller must have cell->vol_sem write-locked
  382. */
  383. static void __afs_put_vlocation(struct afs_vlocation *vlocation)
  384. {
  385. struct afs_cell *cell;
  386. if (!vlocation)
  387. return;
  388. _enter("%s", vlocation->vldb.name);
  389. cell = vlocation->cell;
  390. /* sanity check */
  391. BUG_ON(atomic_read(&vlocation->usage) <= 0);
  392. spin_lock(&cell->vl_gylock);
  393. if (likely(!atomic_dec_and_test(&vlocation->usage))) {
  394. spin_unlock(&cell->vl_gylock);
  395. _leave("");
  396. return;
  397. }
  398. /* move to graveyard queue */
  399. list_move_tail(&vlocation->link,&cell->vl_graveyard);
  400. /* remove from pending timeout queue (refcounted if actually being
  401. * updated) */
  402. list_del_init(&vlocation->upd_op.link);
  403. /* time out in 10 secs */
  404. afs_kafstimod_del_timer(&vlocation->upd_timer);
  405. afs_kafstimod_add_timer(&vlocation->timeout, 10 * HZ);
  406. spin_unlock(&cell->vl_gylock);
  407. _leave(" [killed]");
  408. }
  409. /*
  410. * finish using a volume location record
  411. */
  412. void afs_put_vlocation(struct afs_vlocation *vlocation)
  413. {
  414. if (vlocation) {
  415. struct afs_cell *cell = vlocation->cell;
  416. down_write(&cell->vl_sem);
  417. __afs_put_vlocation(vlocation);
  418. up_write(&cell->vl_sem);
  419. }
  420. }
  421. /*
  422. * timeout vlocation record
  423. * - removes from the cell's graveyard if the usage count is zero
  424. */
  425. void afs_vlocation_do_timeout(struct afs_vlocation *vlocation)
  426. {
  427. struct afs_cell *cell;
  428. _enter("%s", vlocation->vldb.name);
  429. cell = vlocation->cell;
  430. BUG_ON(atomic_read(&vlocation->usage) < 0);
  431. /* remove from graveyard if still dead */
  432. spin_lock(&cell->vl_gylock);
  433. if (atomic_read(&vlocation->usage) == 0)
  434. list_del_init(&vlocation->link);
  435. else
  436. vlocation = NULL;
  437. spin_unlock(&cell->vl_gylock);
  438. if (!vlocation) {
  439. _leave("");
  440. return; /* resurrected */
  441. }
  442. /* we can now destroy it properly */
  443. #ifdef AFS_CACHING_SUPPORT
  444. cachefs_relinquish_cookie(vlocation->cache, 0);
  445. #endif
  446. afs_put_cell(cell);
  447. kfree(vlocation);
  448. _leave(" [destroyed]");
  449. }
  450. /*
  451. * send an update operation to the currently selected server
  452. */
  453. static int afs_vlocation_update_begin(struct afs_vlocation *vlocation)
  454. {
  455. afs_voltype_t voltype;
  456. afs_volid_t vid;
  457. int ret;
  458. _enter("%s{ufs=%u ucs=%u}",
  459. vlocation->vldb.name,
  460. vlocation->upd_first_svix,
  461. vlocation->upd_curr_svix);
  462. /* try to look up a cached volume in the cell VL databases by ID */
  463. if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) {
  464. vid = vlocation->vldb.vid[0];
  465. voltype = AFSVL_RWVOL;
  466. } else if (vlocation->vldb.vidmask & AFS_VOL_VTM_RO) {
  467. vid = vlocation->vldb.vid[1];
  468. voltype = AFSVL_ROVOL;
  469. } else if (vlocation->vldb.vidmask & AFS_VOL_VTM_BAK) {
  470. vid = vlocation->vldb.vid[2];
  471. voltype = AFSVL_BACKVOL;
  472. } else {
  473. BUG();
  474. vid = 0;
  475. voltype = 0;
  476. }
  477. /* contact the chosen server */
  478. ret = afs_server_lookup(
  479. vlocation->cell,
  480. &vlocation->cell->vl_addrs[vlocation->upd_curr_svix],
  481. &vlocation->upd_op.server);
  482. switch (ret) {
  483. case 0:
  484. break;
  485. case -ENOMEM:
  486. case -ENONET:
  487. default:
  488. _leave(" = %d", ret);
  489. return ret;
  490. }
  491. /* initiate the update operation */
  492. ret = afs_rxvl_get_entry_by_id_async(&vlocation->upd_op, vid, voltype);
  493. if (ret < 0) {
  494. _leave(" = %d", ret);
  495. return ret;
  496. }
  497. _leave(" = %d", ret);
  498. return ret;
  499. }
  500. /*
  501. * abandon updating a VL record
  502. * - does not restart the update timer
  503. */
  504. static void afs_vlocation_update_abandon(struct afs_vlocation *vlocation,
  505. afs_vlocation_upd_t state,
  506. int ret)
  507. {
  508. _enter("%s,%u", vlocation->vldb.name, state);
  509. if (ret < 0)
  510. printk("kAFS: Abandoning VL update '%s': %d\n",
  511. vlocation->vldb.name, ret);
  512. /* discard the server record */
  513. afs_put_server(vlocation->upd_op.server);
  514. vlocation->upd_op.server = NULL;
  515. spin_lock(&afs_vlocation_update_lock);
  516. afs_vlocation_update = NULL;
  517. vlocation->upd_state = state;
  518. /* TODO: start updating next VL record on pending list */
  519. spin_unlock(&afs_vlocation_update_lock);
  520. _leave("");
  521. }
  522. /*
  523. * handle periodic update timeouts and busy retry timeouts
  524. * - called from kafstimod
  525. */
  526. static void afs_vlocation_update_timer(struct afs_timer *timer)
  527. {
  528. struct afs_vlocation *vlocation =
  529. list_entry(timer, struct afs_vlocation, upd_timer);
  530. int ret;
  531. _enter("%s", vlocation->vldb.name);
  532. /* only update if not in the graveyard (defend against putting too) */
  533. spin_lock(&vlocation->cell->vl_gylock);
  534. if (!atomic_read(&vlocation->usage))
  535. goto out_unlock1;
  536. spin_lock(&afs_vlocation_update_lock);
  537. /* if we were woken up due to EBUSY sleep then restart immediately if
  538. * possible or else jump to front of pending queue */
  539. if (vlocation->upd_state == AFS_VLUPD_BUSYSLEEP) {
  540. if (afs_vlocation_update) {
  541. list_add(&vlocation->upd_op.link,
  542. &afs_vlocation_update_pendq);
  543. } else {
  544. afs_get_vlocation(vlocation);
  545. afs_vlocation_update = vlocation;
  546. vlocation->upd_state = AFS_VLUPD_INPROGRESS;
  547. }
  548. goto out_unlock2;
  549. }
  550. /* put on pending queue if there's already another update in progress */
  551. if (afs_vlocation_update) {
  552. vlocation->upd_state = AFS_VLUPD_PENDING;
  553. list_add_tail(&vlocation->upd_op.link,
  554. &afs_vlocation_update_pendq);
  555. goto out_unlock2;
  556. }
  557. /* hold a ref on it while actually updating */
  558. afs_get_vlocation(vlocation);
  559. afs_vlocation_update = vlocation;
  560. vlocation->upd_state = AFS_VLUPD_INPROGRESS;
  561. spin_unlock(&afs_vlocation_update_lock);
  562. spin_unlock(&vlocation->cell->vl_gylock);
  563. /* okay... we can start the update */
  564. _debug("BEGIN VL UPDATE [%s]", vlocation->vldb.name);
  565. vlocation->upd_first_svix = vlocation->cell->vl_curr_svix;
  566. vlocation->upd_curr_svix = vlocation->upd_first_svix;
  567. vlocation->upd_rej_cnt = 0;
  568. vlocation->upd_busy_cnt = 0;
  569. ret = afs_vlocation_update_begin(vlocation);
  570. if (ret < 0) {
  571. afs_vlocation_update_abandon(vlocation, AFS_VLUPD_SLEEP, ret);
  572. afs_kafstimod_add_timer(&vlocation->upd_timer,
  573. AFS_VLDB_TIMEOUT);
  574. afs_put_vlocation(vlocation);
  575. }
  576. _leave("");
  577. return;
  578. out_unlock2:
  579. spin_unlock(&afs_vlocation_update_lock);
  580. out_unlock1:
  581. spin_unlock(&vlocation->cell->vl_gylock);
  582. _leave("");
  583. }
  584. /*
  585. * attend to an update operation upon which an event happened
  586. * - called in kafsasyncd context
  587. */
  588. static void afs_vlocation_update_attend(struct afs_async_op *op)
  589. {
  590. struct afs_cache_vlocation vldb;
  591. struct afs_vlocation *vlocation =
  592. list_entry(op, struct afs_vlocation, upd_op);
  593. unsigned tmp;
  594. int ret;
  595. _enter("%s", vlocation->vldb.name);
  596. ret = afs_rxvl_get_entry_by_id_async2(op, &vldb);
  597. switch (ret) {
  598. case -EAGAIN:
  599. _leave(" [unfinished]");
  600. return;
  601. case 0:
  602. _debug("END VL UPDATE: %d\n", ret);
  603. vlocation->valid = 1;
  604. _debug("Done VL Lookup: %02x { %08x(%x) %08x(%x) %08x(%x) }",
  605. vldb.vidmask,
  606. ntohl(vldb.servers[0].s_addr), vldb.srvtmask[0],
  607. ntohl(vldb.servers[1].s_addr), vldb.srvtmask[1],
  608. ntohl(vldb.servers[2].s_addr), vldb.srvtmask[2]
  609. );
  610. _debug("Vids: %08x %08x %08x",
  611. vldb.vid[0], vldb.vid[1], vldb.vid[2]);
  612. afs_vlocation_update_abandon(vlocation, AFS_VLUPD_SLEEP, 0);
  613. down_write(&vlocation->cell->vl_sem);
  614. /* actually update the cache */
  615. if (strncmp(vldb.name, vlocation->vldb.name,
  616. sizeof(vlocation->vldb.name)) != 0)
  617. printk("kAFS: name of volume '%s'"
  618. " changed to '%s' on server\n",
  619. vlocation->vldb.name, vldb.name);
  620. memcpy(&vlocation->vldb, &vldb, sizeof(vlocation->vldb));
  621. #if 0
  622. /* TODO update volume entry in local cache */
  623. #endif
  624. up_write(&vlocation->cell->vl_sem);
  625. if (ret < 0)
  626. printk("kAFS: failed to update local cache: %d\n", ret);
  627. afs_kafstimod_add_timer(&vlocation->upd_timer,
  628. AFS_VLDB_TIMEOUT);
  629. afs_put_vlocation(vlocation);
  630. _leave(" [found]");
  631. return;
  632. case -ENOMEDIUM:
  633. vlocation->upd_rej_cnt++;
  634. goto try_next;
  635. /* the server is locked - retry in a very short while */
  636. case -EBUSY:
  637. vlocation->upd_busy_cnt++;
  638. if (vlocation->upd_busy_cnt > 3)
  639. goto try_next; /* too many retries */
  640. afs_vlocation_update_abandon(vlocation,
  641. AFS_VLUPD_BUSYSLEEP, 0);
  642. afs_kafstimod_add_timer(&vlocation->upd_timer, HZ / 2);
  643. afs_put_vlocation(vlocation);
  644. _leave(" [busy]");
  645. return;
  646. case -ENETUNREACH:
  647. case -EHOSTUNREACH:
  648. case -ECONNREFUSED:
  649. case -EREMOTEIO:
  650. /* record bad vlserver info in the cell too
  651. * - TODO: use down_write_trylock() if available
  652. */
  653. if (vlocation->upd_curr_svix == vlocation->cell->vl_curr_svix)
  654. vlocation->cell->vl_curr_svix =
  655. vlocation->cell->vl_curr_svix %
  656. vlocation->cell->vl_naddrs;
  657. case -EBADRQC:
  658. case -EINVAL:
  659. case -EACCES:
  660. case -EBADMSG:
  661. goto try_next;
  662. default:
  663. goto abandon;
  664. }
  665. /* try contacting the next server */
  666. try_next:
  667. vlocation->upd_busy_cnt = 0;
  668. /* discard the server record */
  669. afs_put_server(vlocation->upd_op.server);
  670. vlocation->upd_op.server = NULL;
  671. tmp = vlocation->cell->vl_naddrs;
  672. if (tmp == 0)
  673. goto abandon;
  674. vlocation->upd_curr_svix++;
  675. if (vlocation->upd_curr_svix >= tmp)
  676. vlocation->upd_curr_svix = 0;
  677. if (vlocation->upd_first_svix >= tmp)
  678. vlocation->upd_first_svix = tmp - 1;
  679. /* move to the next server */
  680. if (vlocation->upd_curr_svix != vlocation->upd_first_svix) {
  681. afs_vlocation_update_begin(vlocation);
  682. _leave(" [next]");
  683. return;
  684. }
  685. /* run out of servers to try - was the volume rejected? */
  686. if (vlocation->upd_rej_cnt > 0) {
  687. printk("kAFS: Active volume no longer valid '%s'\n",
  688. vlocation->vldb.name);
  689. vlocation->valid = 0;
  690. afs_vlocation_update_abandon(vlocation, AFS_VLUPD_SLEEP, 0);
  691. afs_kafstimod_add_timer(&vlocation->upd_timer,
  692. AFS_VLDB_TIMEOUT);
  693. afs_put_vlocation(vlocation);
  694. _leave(" [invalidated]");
  695. return;
  696. }
  697. /* abandon the update */
  698. abandon:
  699. afs_vlocation_update_abandon(vlocation, AFS_VLUPD_SLEEP, ret);
  700. afs_kafstimod_add_timer(&vlocation->upd_timer, HZ * 10);
  701. afs_put_vlocation(vlocation);
  702. _leave(" [abandoned]");
  703. }
  704. /*
  705. * deal with an update operation being discarded
  706. * - called in kafsasyncd context when it's dying due to rmmod
  707. * - the call has already been aborted and put()'d
  708. */
  709. static void afs_vlocation_update_discard(struct afs_async_op *op)
  710. {
  711. struct afs_vlocation *vlocation =
  712. list_entry(op, struct afs_vlocation, upd_op);
  713. _enter("%s", vlocation->vldb.name);
  714. afs_put_server(op->server);
  715. op->server = NULL;
  716. afs_put_vlocation(vlocation);
  717. _leave("");
  718. }
  719. /*
  720. * match a VLDB record stored in the cache
  721. * - may also load target from entry
  722. */
  723. #ifdef AFS_CACHING_SUPPORT
  724. static cachefs_match_val_t afs_vlocation_cache_match(void *target,
  725. const void *entry)
  726. {
  727. const struct afs_cache_vlocation *vldb = entry;
  728. struct afs_vlocation *vlocation = target;
  729. _enter("{%s},{%s}", vlocation->vldb.name, vldb->name);
  730. if (strncmp(vlocation->vldb.name, vldb->name, sizeof(vldb->name)) == 0
  731. ) {
  732. if (!vlocation->valid ||
  733. vlocation->vldb.rtime == vldb->rtime
  734. ) {
  735. vlocation->vldb = *vldb;
  736. vlocation->valid = 1;
  737. _leave(" = SUCCESS [c->m]");
  738. return CACHEFS_MATCH_SUCCESS;
  739. } else if (memcmp(&vlocation->vldb, vldb, sizeof(*vldb)) != 0) {
  740. /* delete if VIDs for this name differ */
  741. if (memcmp(&vlocation->vldb.vid,
  742. &vldb->vid,
  743. sizeof(vldb->vid)) != 0) {
  744. _leave(" = DELETE");
  745. return CACHEFS_MATCH_SUCCESS_DELETE;
  746. }
  747. _leave(" = UPDATE");
  748. return CACHEFS_MATCH_SUCCESS_UPDATE;
  749. } else {
  750. _leave(" = SUCCESS");
  751. return CACHEFS_MATCH_SUCCESS;
  752. }
  753. }
  754. _leave(" = FAILED");
  755. return CACHEFS_MATCH_FAILED;
  756. }
  757. #endif
  758. /*
  759. * update a VLDB record stored in the cache
  760. */
  761. #ifdef AFS_CACHING_SUPPORT
  762. static void afs_vlocation_cache_update(void *source, void *entry)
  763. {
  764. struct afs_cache_vlocation *vldb = entry;
  765. struct afs_vlocation *vlocation = source;
  766. _enter("");
  767. *vldb = vlocation->vldb;
  768. }
  769. #endif