PageRenderTime 43ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/fs/afs/vlocation.c

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