vlocation.c 17 KB

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