vlocation.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. /* AFS volume location management
  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/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/init.h>
  14. #include <linux/sched.h>
  15. #include "internal.h"
  16. static unsigned afs_vlocation_timeout = 10; /* volume location timeout in seconds */
  17. static unsigned afs_vlocation_update_timeout = 10 * 60;
  18. static void afs_vlocation_reaper(struct work_struct *);
  19. static void afs_vlocation_updater(struct work_struct *);
  20. static LIST_HEAD(afs_vlocation_updates);
  21. static LIST_HEAD(afs_vlocation_graveyard);
  22. static DEFINE_SPINLOCK(afs_vlocation_updates_lock);
  23. static DEFINE_SPINLOCK(afs_vlocation_graveyard_lock);
  24. static DECLARE_DELAYED_WORK(afs_vlocation_reap, afs_vlocation_reaper);
  25. static DECLARE_DELAYED_WORK(afs_vlocation_update, afs_vlocation_updater);
  26. static struct workqueue_struct *afs_vlocation_update_worker;
  27. /*
  28. * iterate through the VL servers in a cell until one of them admits knowing
  29. * about the volume in question
  30. */
  31. static int afs_vlocation_access_vl_by_name(struct afs_vlocation *vl,
  32. struct key *key,
  33. struct afs_cache_vlocation *vldb)
  34. {
  35. struct afs_cell *cell = vl->cell;
  36. struct in_addr addr;
  37. int count, ret;
  38. _enter("%s,%s", cell->name, vl->vldb.name);
  39. down_write(&vl->cell->vl_sem);
  40. ret = -ENOMEDIUM;
  41. for (count = cell->vl_naddrs; count > 0; count--) {
  42. addr = cell->vl_addrs[cell->vl_curr_svix];
  43. _debug("CellServ[%hu]: %08x", cell->vl_curr_svix, addr.s_addr);
  44. /* attempt to access the VL server */
  45. ret = afs_vl_get_entry_by_name(&addr, key, vl->vldb.name, vldb,
  46. &afs_sync_call);
  47. switch (ret) {
  48. case 0:
  49. goto out;
  50. case -ENOMEM:
  51. case -ENONET:
  52. case -ENETUNREACH:
  53. case -EHOSTUNREACH:
  54. case -ECONNREFUSED:
  55. if (ret == -ENOMEM || ret == -ENONET)
  56. goto out;
  57. goto rotate;
  58. case -ENOMEDIUM:
  59. goto out;
  60. default:
  61. ret = -EIO;
  62. goto rotate;
  63. }
  64. /* rotate the server records upon lookup failure */
  65. rotate:
  66. cell->vl_curr_svix++;
  67. cell->vl_curr_svix %= cell->vl_naddrs;
  68. }
  69. out:
  70. up_write(&vl->cell->vl_sem);
  71. _leave(" = %d", ret);
  72. return ret;
  73. }
  74. /*
  75. * iterate through the VL servers in a cell until one of them admits knowing
  76. * about the volume in question
  77. */
  78. static int afs_vlocation_access_vl_by_id(struct afs_vlocation *vl,
  79. struct key *key,
  80. afs_volid_t volid,
  81. afs_voltype_t voltype,
  82. struct afs_cache_vlocation *vldb)
  83. {
  84. struct afs_cell *cell = vl->cell;
  85. struct in_addr addr;
  86. int count, ret;
  87. _enter("%s,%x,%d,", cell->name, volid, voltype);
  88. down_write(&vl->cell->vl_sem);
  89. ret = -ENOMEDIUM;
  90. for (count = cell->vl_naddrs; count > 0; count--) {
  91. addr = cell->vl_addrs[cell->vl_curr_svix];
  92. _debug("CellServ[%hu]: %08x", cell->vl_curr_svix, addr.s_addr);
  93. /* attempt to access the VL server */
  94. ret = afs_vl_get_entry_by_id(&addr, key, volid, voltype, vldb,
  95. &afs_sync_call);
  96. switch (ret) {
  97. case 0:
  98. goto out;
  99. case -ENOMEM:
  100. case -ENONET:
  101. case -ENETUNREACH:
  102. case -EHOSTUNREACH:
  103. case -ECONNREFUSED:
  104. if (ret == -ENOMEM || ret == -ENONET)
  105. goto out;
  106. goto rotate;
  107. case -EBUSY:
  108. vl->upd_busy_cnt++;
  109. if (vl->upd_busy_cnt <= 3) {
  110. if (vl->upd_busy_cnt > 1) {
  111. /* second+ BUSY - sleep a little bit */
  112. set_current_state(TASK_UNINTERRUPTIBLE);
  113. schedule_timeout(1);
  114. __set_current_state(TASK_RUNNING);
  115. }
  116. continue;
  117. }
  118. break;
  119. case -ENOMEDIUM:
  120. vl->upd_rej_cnt++;
  121. goto rotate;
  122. default:
  123. ret = -EIO;
  124. goto rotate;
  125. }
  126. /* rotate the server records upon lookup failure */
  127. rotate:
  128. cell->vl_curr_svix++;
  129. cell->vl_curr_svix %= cell->vl_naddrs;
  130. vl->upd_busy_cnt = 0;
  131. }
  132. out:
  133. if (ret < 0 && vl->upd_rej_cnt > 0) {
  134. printk(KERN_NOTICE "kAFS:"
  135. " Active volume no longer valid '%s'\n",
  136. vl->vldb.name);
  137. vl->valid = 0;
  138. ret = -ENOMEDIUM;
  139. }
  140. up_write(&vl->cell->vl_sem);
  141. _leave(" = %d", ret);
  142. return ret;
  143. }
  144. /*
  145. * allocate a volume location record
  146. */
  147. static struct afs_vlocation *afs_vlocation_alloc(struct afs_cell *cell,
  148. const char *name,
  149. size_t namesz)
  150. {
  151. struct afs_vlocation *vl;
  152. vl = kzalloc(sizeof(struct afs_vlocation), GFP_KERNEL);
  153. if (vl) {
  154. vl->cell = cell;
  155. vl->state = AFS_VL_NEW;
  156. atomic_set(&vl->usage, 1);
  157. INIT_LIST_HEAD(&vl->link);
  158. INIT_LIST_HEAD(&vl->grave);
  159. INIT_LIST_HEAD(&vl->update);
  160. init_waitqueue_head(&vl->waitq);
  161. spin_lock_init(&vl->lock);
  162. memcpy(vl->vldb.name, name, namesz);
  163. }
  164. _leave(" = %p", vl);
  165. return vl;
  166. }
  167. /*
  168. * update record if we found it in the cache
  169. */
  170. static int afs_vlocation_update_record(struct afs_vlocation *vl,
  171. struct key *key,
  172. struct afs_cache_vlocation *vldb)
  173. {
  174. afs_voltype_t voltype;
  175. afs_volid_t vid;
  176. int ret;
  177. /* try to look up a cached volume in the cell VL databases by ID */
  178. _debug("Locally Cached: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
  179. vl->vldb.name,
  180. vl->vldb.vidmask,
  181. ntohl(vl->vldb.servers[0].s_addr),
  182. vl->vldb.srvtmask[0],
  183. ntohl(vl->vldb.servers[1].s_addr),
  184. vl->vldb.srvtmask[1],
  185. ntohl(vl->vldb.servers[2].s_addr),
  186. vl->vldb.srvtmask[2]);
  187. _debug("Vids: %08x %08x %08x",
  188. vl->vldb.vid[0],
  189. vl->vldb.vid[1],
  190. vl->vldb.vid[2]);
  191. if (vl->vldb.vidmask & AFS_VOL_VTM_RW) {
  192. vid = vl->vldb.vid[0];
  193. voltype = AFSVL_RWVOL;
  194. } else if (vl->vldb.vidmask & AFS_VOL_VTM_RO) {
  195. vid = vl->vldb.vid[1];
  196. voltype = AFSVL_ROVOL;
  197. } else if (vl->vldb.vidmask & AFS_VOL_VTM_BAK) {
  198. vid = vl->vldb.vid[2];
  199. voltype = AFSVL_BACKVOL;
  200. } else {
  201. BUG();
  202. vid = 0;
  203. voltype = 0;
  204. }
  205. /* contact the server to make sure the volume is still available
  206. * - TODO: need to handle disconnected operation here
  207. */
  208. ret = afs_vlocation_access_vl_by_id(vl, key, vid, voltype, vldb);
  209. switch (ret) {
  210. /* net error */
  211. default:
  212. printk(KERN_WARNING "kAFS:"
  213. " failed to update volume '%s' (%x) up in '%s': %d\n",
  214. vl->vldb.name, vid, vl->cell->name, ret);
  215. _leave(" = %d", ret);
  216. return ret;
  217. /* pulled from local cache into memory */
  218. case 0:
  219. _leave(" = 0");
  220. return 0;
  221. /* uh oh... looks like the volume got deleted */
  222. case -ENOMEDIUM:
  223. printk(KERN_ERR "kAFS:"
  224. " volume '%s' (%x) does not exist '%s'\n",
  225. vl->vldb.name, vid, vl->cell->name);
  226. /* TODO: make existing record unavailable */
  227. _leave(" = %d", ret);
  228. return ret;
  229. }
  230. }
  231. /*
  232. * apply the update to a VL record
  233. */
  234. static void afs_vlocation_apply_update(struct afs_vlocation *vl,
  235. struct afs_cache_vlocation *vldb)
  236. {
  237. _debug("Done VL Lookup: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
  238. vldb->name, vldb->vidmask,
  239. ntohl(vldb->servers[0].s_addr), vldb->srvtmask[0],
  240. ntohl(vldb->servers[1].s_addr), vldb->srvtmask[1],
  241. ntohl(vldb->servers[2].s_addr), vldb->srvtmask[2]);
  242. _debug("Vids: %08x %08x %08x",
  243. vldb->vid[0], vldb->vid[1], vldb->vid[2]);
  244. if (strcmp(vldb->name, vl->vldb.name) != 0)
  245. printk(KERN_NOTICE "kAFS:"
  246. " name of volume '%s' changed to '%s' on server\n",
  247. vl->vldb.name, vldb->name);
  248. vl->vldb = *vldb;
  249. #ifdef CONFIG_AFS_FSCACHE
  250. fscache_update_cookie(vl->cache);
  251. #endif
  252. }
  253. /*
  254. * fill in a volume location record, consulting the cache and the VL server
  255. * both
  256. */
  257. static int afs_vlocation_fill_in_record(struct afs_vlocation *vl,
  258. struct key *key)
  259. {
  260. struct afs_cache_vlocation vldb;
  261. int ret;
  262. _enter("");
  263. ASSERTCMP(vl->valid, ==, 0);
  264. memset(&vldb, 0, sizeof(vldb));
  265. /* see if we have an in-cache copy (will set vl->valid if there is) */
  266. #ifdef CONFIG_AFS_FSCACHE
  267. vl->cache = fscache_acquire_cookie(vl->cell->cache,
  268. &afs_vlocation_cache_index_def, vl);
  269. #endif
  270. if (vl->valid) {
  271. /* try to update a known volume in the cell VL databases by
  272. * ID as the name may have changed */
  273. _debug("found in cache");
  274. ret = afs_vlocation_update_record(vl, key, &vldb);
  275. } else {
  276. /* try to look up an unknown volume in the cell VL databases by
  277. * name */
  278. ret = afs_vlocation_access_vl_by_name(vl, key, &vldb);
  279. if (ret < 0) {
  280. printk("kAFS: failed to locate '%s' in cell '%s'\n",
  281. vl->vldb.name, vl->cell->name);
  282. return ret;
  283. }
  284. }
  285. afs_vlocation_apply_update(vl, &vldb);
  286. _leave(" = 0");
  287. return 0;
  288. }
  289. /*
  290. * queue a vlocation record for updates
  291. */
  292. static void afs_vlocation_queue_for_updates(struct afs_vlocation *vl)
  293. {
  294. struct afs_vlocation *xvl;
  295. /* wait at least 10 minutes before updating... */
  296. vl->update_at = get_seconds() + afs_vlocation_update_timeout;
  297. spin_lock(&afs_vlocation_updates_lock);
  298. if (!list_empty(&afs_vlocation_updates)) {
  299. /* ... but wait at least 1 second more than the newest record
  300. * already queued so that we don't spam the VL server suddenly
  301. * with lots of requests
  302. */
  303. xvl = list_entry(afs_vlocation_updates.prev,
  304. struct afs_vlocation, update);
  305. if (vl->update_at <= xvl->update_at)
  306. vl->update_at = xvl->update_at + 1;
  307. } else {
  308. queue_delayed_work(afs_vlocation_update_worker,
  309. &afs_vlocation_update,
  310. afs_vlocation_update_timeout * HZ);
  311. }
  312. list_add_tail(&vl->update, &afs_vlocation_updates);
  313. spin_unlock(&afs_vlocation_updates_lock);
  314. }
  315. /*
  316. * lookup volume location
  317. * - iterate through the VL servers in a cell until one of them admits knowing
  318. * about the volume in question
  319. * - lookup in the local cache if not able to find on the VL server
  320. * - insert/update in the local cache if did get a VL response
  321. */
  322. struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *cell,
  323. struct key *key,
  324. const char *name,
  325. size_t namesz)
  326. {
  327. struct afs_vlocation *vl;
  328. int ret;
  329. _enter("{%s},{%x},%*.*s,%zu",
  330. cell->name, key_serial(key),
  331. (int) namesz, (int) namesz, name, namesz);
  332. if (namesz >= sizeof(vl->vldb.name)) {
  333. _leave(" = -ENAMETOOLONG");
  334. return ERR_PTR(-ENAMETOOLONG);
  335. }
  336. /* see if we have an in-memory copy first */
  337. down_write(&cell->vl_sem);
  338. spin_lock(&cell->vl_lock);
  339. list_for_each_entry(vl, &cell->vl_list, link) {
  340. if (vl->vldb.name[namesz] != '\0')
  341. continue;
  342. if (memcmp(vl->vldb.name, name, namesz) == 0)
  343. goto found_in_memory;
  344. }
  345. spin_unlock(&cell->vl_lock);
  346. /* not in the cell's in-memory lists - create a new record */
  347. vl = afs_vlocation_alloc(cell, name, namesz);
  348. if (!vl) {
  349. up_write(&cell->vl_sem);
  350. return ERR_PTR(-ENOMEM);
  351. }
  352. afs_get_cell(cell);
  353. list_add_tail(&vl->link, &cell->vl_list);
  354. vl->state = AFS_VL_CREATING;
  355. up_write(&cell->vl_sem);
  356. fill_in_record:
  357. ret = afs_vlocation_fill_in_record(vl, key);
  358. if (ret < 0)
  359. goto error_abandon;
  360. spin_lock(&vl->lock);
  361. vl->state = AFS_VL_VALID;
  362. spin_unlock(&vl->lock);
  363. wake_up(&vl->waitq);
  364. /* update volume entry in local cache */
  365. #ifdef CONFIG_AFS_FSCACHE
  366. fscache_update_cookie(vl->cache);
  367. #endif
  368. /* schedule for regular updates */
  369. afs_vlocation_queue_for_updates(vl);
  370. goto success;
  371. found_in_memory:
  372. /* found in memory */
  373. _debug("found in memory");
  374. atomic_inc(&vl->usage);
  375. spin_unlock(&cell->vl_lock);
  376. if (!list_empty(&vl->grave)) {
  377. spin_lock(&afs_vlocation_graveyard_lock);
  378. list_del_init(&vl->grave);
  379. spin_unlock(&afs_vlocation_graveyard_lock);
  380. }
  381. up_write(&cell->vl_sem);
  382. /* see if it was an abandoned record that we might try filling in */
  383. spin_lock(&vl->lock);
  384. while (vl->state != AFS_VL_VALID) {
  385. afs_vlocation_state_t state = vl->state;
  386. _debug("invalid [state %d]", state);
  387. if (state == AFS_VL_NEW || state == AFS_VL_NO_VOLUME) {
  388. vl->state = AFS_VL_CREATING;
  389. spin_unlock(&vl->lock);
  390. goto fill_in_record;
  391. }
  392. /* must now wait for creation or update by someone else to
  393. * complete */
  394. _debug("wait");
  395. spin_unlock(&vl->lock);
  396. ret = wait_event_interruptible(vl->waitq,
  397. vl->state == AFS_VL_NEW ||
  398. vl->state == AFS_VL_VALID ||
  399. vl->state == AFS_VL_NO_VOLUME);
  400. if (ret < 0)
  401. goto error;
  402. spin_lock(&vl->lock);
  403. }
  404. spin_unlock(&vl->lock);
  405. success:
  406. _leave(" = %p", vl);
  407. return vl;
  408. error_abandon:
  409. spin_lock(&vl->lock);
  410. vl->state = AFS_VL_NEW;
  411. spin_unlock(&vl->lock);
  412. wake_up(&vl->waitq);
  413. error:
  414. ASSERT(vl != NULL);
  415. afs_put_vlocation(vl);
  416. _leave(" = %d", ret);
  417. return ERR_PTR(ret);
  418. }
  419. /*
  420. * finish using a volume location record
  421. */
  422. void afs_put_vlocation(struct afs_vlocation *vl)
  423. {
  424. if (!vl)
  425. return;
  426. _enter("%s", vl->vldb.name);
  427. ASSERTCMP(atomic_read(&vl->usage), >, 0);
  428. if (likely(!atomic_dec_and_test(&vl->usage))) {
  429. _leave("");
  430. return;
  431. }
  432. spin_lock(&afs_vlocation_graveyard_lock);
  433. if (atomic_read(&vl->usage) == 0) {
  434. _debug("buried");
  435. list_move_tail(&vl->grave, &afs_vlocation_graveyard);
  436. vl->time_of_death = get_seconds();
  437. schedule_delayed_work(&afs_vlocation_reap,
  438. afs_vlocation_timeout * HZ);
  439. /* suspend updates on this record */
  440. if (!list_empty(&vl->update)) {
  441. spin_lock(&afs_vlocation_updates_lock);
  442. list_del_init(&vl->update);
  443. spin_unlock(&afs_vlocation_updates_lock);
  444. }
  445. }
  446. spin_unlock(&afs_vlocation_graveyard_lock);
  447. _leave(" [killed?]");
  448. }
  449. /*
  450. * destroy a dead volume location record
  451. */
  452. static void afs_vlocation_destroy(struct afs_vlocation *vl)
  453. {
  454. _enter("%p", vl);
  455. #ifdef CONFIG_AFS_FSCACHE
  456. fscache_relinquish_cookie(vl->cache, 0);
  457. #endif
  458. afs_put_cell(vl->cell);
  459. kfree(vl);
  460. }
  461. /*
  462. * reap dead volume location records
  463. */
  464. static void afs_vlocation_reaper(struct work_struct *work)
  465. {
  466. LIST_HEAD(corpses);
  467. struct afs_vlocation *vl;
  468. unsigned long delay, expiry;
  469. time_t now;
  470. _enter("");
  471. now = get_seconds();
  472. spin_lock(&afs_vlocation_graveyard_lock);
  473. while (!list_empty(&afs_vlocation_graveyard)) {
  474. vl = list_entry(afs_vlocation_graveyard.next,
  475. struct afs_vlocation, grave);
  476. _debug("check %p", vl);
  477. /* the queue is ordered most dead first */
  478. expiry = vl->time_of_death + afs_vlocation_timeout;
  479. if (expiry > now) {
  480. delay = (expiry - now) * HZ;
  481. _debug("delay %lu", delay);
  482. if (!schedule_delayed_work(&afs_vlocation_reap,
  483. delay)) {
  484. cancel_delayed_work(&afs_vlocation_reap);
  485. schedule_delayed_work(&afs_vlocation_reap,
  486. delay);
  487. }
  488. break;
  489. }
  490. spin_lock(&vl->cell->vl_lock);
  491. if (atomic_read(&vl->usage) > 0) {
  492. _debug("no reap");
  493. list_del_init(&vl->grave);
  494. } else {
  495. _debug("reap");
  496. list_move_tail(&vl->grave, &corpses);
  497. list_del_init(&vl->link);
  498. }
  499. spin_unlock(&vl->cell->vl_lock);
  500. }
  501. spin_unlock(&afs_vlocation_graveyard_lock);
  502. /* now reap the corpses we've extracted */
  503. while (!list_empty(&corpses)) {
  504. vl = list_entry(corpses.next, struct afs_vlocation, grave);
  505. list_del(&vl->grave);
  506. afs_vlocation_destroy(vl);
  507. }
  508. _leave("");
  509. }
  510. /*
  511. * initialise the VL update process
  512. */
  513. int __init afs_vlocation_update_init(void)
  514. {
  515. afs_vlocation_update_worker =
  516. create_singlethread_workqueue("kafs_vlupdated");
  517. return afs_vlocation_update_worker ? 0 : -ENOMEM;
  518. }
  519. /*
  520. * discard all the volume location records for rmmod
  521. */
  522. void afs_vlocation_purge(void)
  523. {
  524. afs_vlocation_timeout = 0;
  525. spin_lock(&afs_vlocation_updates_lock);
  526. list_del_init(&afs_vlocation_updates);
  527. spin_unlock(&afs_vlocation_updates_lock);
  528. cancel_delayed_work(&afs_vlocation_update);
  529. queue_delayed_work(afs_vlocation_update_worker,
  530. &afs_vlocation_update, 0);
  531. destroy_workqueue(afs_vlocation_update_worker);
  532. cancel_delayed_work(&afs_vlocation_reap);
  533. schedule_delayed_work(&afs_vlocation_reap, 0);
  534. }
  535. /*
  536. * update a volume location
  537. */
  538. static void afs_vlocation_updater(struct work_struct *work)
  539. {
  540. struct afs_cache_vlocation vldb;
  541. struct afs_vlocation *vl, *xvl;
  542. time_t now;
  543. long timeout;
  544. int ret;
  545. _enter("");
  546. now = get_seconds();
  547. /* find a record to update */
  548. spin_lock(&afs_vlocation_updates_lock);
  549. for (;;) {
  550. if (list_empty(&afs_vlocation_updates)) {
  551. spin_unlock(&afs_vlocation_updates_lock);
  552. _leave(" [nothing]");
  553. return;
  554. }
  555. vl = list_entry(afs_vlocation_updates.next,
  556. struct afs_vlocation, update);
  557. if (atomic_read(&vl->usage) > 0)
  558. break;
  559. list_del_init(&vl->update);
  560. }
  561. timeout = vl->update_at - now;
  562. if (timeout > 0) {
  563. queue_delayed_work(afs_vlocation_update_worker,
  564. &afs_vlocation_update, timeout * HZ);
  565. spin_unlock(&afs_vlocation_updates_lock);
  566. _leave(" [nothing]");
  567. return;
  568. }
  569. list_del_init(&vl->update);
  570. atomic_inc(&vl->usage);
  571. spin_unlock(&afs_vlocation_updates_lock);
  572. /* we can now perform the update */
  573. _debug("update %s", vl->vldb.name);
  574. vl->state = AFS_VL_UPDATING;
  575. vl->upd_rej_cnt = 0;
  576. vl->upd_busy_cnt = 0;
  577. ret = afs_vlocation_update_record(vl, NULL, &vldb);
  578. spin_lock(&vl->lock);
  579. switch (ret) {
  580. case 0:
  581. afs_vlocation_apply_update(vl, &vldb);
  582. vl->state = AFS_VL_VALID;
  583. break;
  584. case -ENOMEDIUM:
  585. vl->state = AFS_VL_VOLUME_DELETED;
  586. break;
  587. default:
  588. vl->state = AFS_VL_UNCERTAIN;
  589. break;
  590. }
  591. spin_unlock(&vl->lock);
  592. wake_up(&vl->waitq);
  593. /* and then reschedule */
  594. _debug("reschedule");
  595. vl->update_at = get_seconds() + afs_vlocation_update_timeout;
  596. spin_lock(&afs_vlocation_updates_lock);
  597. if (!list_empty(&afs_vlocation_updates)) {
  598. /* next update in 10 minutes, but wait at least 1 second more
  599. * than the newest record already queued so that we don't spam
  600. * the VL server suddenly with lots of requests
  601. */
  602. xvl = list_entry(afs_vlocation_updates.prev,
  603. struct afs_vlocation, update);
  604. if (vl->update_at <= xvl->update_at)
  605. vl->update_at = xvl->update_at + 1;
  606. xvl = list_entry(afs_vlocation_updates.next,
  607. struct afs_vlocation, update);
  608. timeout = xvl->update_at - now;
  609. if (timeout < 0)
  610. timeout = 0;
  611. } else {
  612. timeout = afs_vlocation_update_timeout;
  613. }
  614. ASSERT(list_empty(&vl->update));
  615. list_add_tail(&vl->update, &afs_vlocation_updates);
  616. _debug("timeout %ld", timeout);
  617. queue_delayed_work(afs_vlocation_update_worker,
  618. &afs_vlocation_update, timeout * HZ);
  619. spin_unlock(&afs_vlocation_updates_lock);
  620. afs_put_vlocation(vl);
  621. }