1 /* vlocation.c: volume location management
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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.
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/slab.h>
17 #include <linux/pagemap.h>
20 #include "cmservice.h"
23 #include "kafstimod.h"
24 #include <rxrpc/connection.h>
27 #define AFS_VLDB_TIMEOUT HZ*1000
29 static void afs_vlocation_update_timer(struct afs_timer *timer);
30 static void afs_vlocation_update_attend(struct afs_async_op *op);
31 static void afs_vlocation_update_discard(struct afs_async_op *op);
33 static void __afs_vlocation_timeout(struct afs_timer *timer)
35 struct afs_vlocation *vlocation =
36 list_entry(timer, struct afs_vlocation, timeout);
38 _debug("VL TIMEOUT [%s{u=%d}]",
39 vlocation->vldb.name, atomic_read(&vlocation->usage));
41 afs_vlocation_do_timeout(vlocation);
44 static const struct afs_timer_ops afs_vlocation_timer_ops = {
45 .timed_out = __afs_vlocation_timeout,
48 static const struct afs_timer_ops afs_vlocation_update_timer_ops = {
49 .timed_out = afs_vlocation_update_timer,
52 static const struct afs_async_op_ops afs_vlocation_update_op_ops = {
53 .attend = afs_vlocation_update_attend,
54 .discard = afs_vlocation_update_discard,
57 static LIST_HEAD(afs_vlocation_update_pendq); /* queue of VLs awaiting update */
58 static struct afs_vlocation *afs_vlocation_update; /* VL currently being updated */
59 static spinlock_t afs_vlocation_update_lock = SPIN_LOCK_UNLOCKED; /* lock guarding update queue */
61 #ifdef AFS_CACHING_SUPPORT
62 static cachefs_match_val_t afs_vlocation_cache_match(void *target,
64 static void afs_vlocation_cache_update(void *source, void *entry);
66 struct cachefs_index_def afs_vlocation_cache_index_def = {
68 .data_size = sizeof(struct afs_cache_vlocation),
69 .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
70 .match = afs_vlocation_cache_match,
71 .update = afs_vlocation_cache_update,
75 /*****************************************************************************/
77 * iterate through the VL servers in a cell until one of them admits knowing
78 * about the volume in question
79 * - caller must have cell->vl_sem write-locked
81 static int afs_vlocation_access_vl_by_name(struct afs_vlocation *vlocation,
84 struct afs_cache_vlocation *vldb)
86 struct afs_server *server = NULL;
87 struct afs_cell *cell = vlocation->cell;
90 _enter("%s,%*.*s,%u", cell->name, namesz, namesz, name, namesz);
93 for (count = cell->vl_naddrs; count > 0; count--) {
94 _debug("CellServ[%hu]: %08x",
96 cell->vl_addrs[cell->vl_curr_svix].s_addr);
98 /* try and create a server */
99 ret = afs_server_lookup(cell,
100 &cell->vl_addrs[cell->vl_curr_svix],
112 /* attempt to access the VL server */
113 ret = afs_rxvl_get_entry_by_name(server, name, namesz, vldb);
116 afs_put_server(server);
123 down_write(&server->sem);
124 if (server->vlserver) {
125 rxrpc_put_connection(server->vlserver);
126 server->vlserver = NULL;
128 up_write(&server->sem);
129 afs_put_server(server);
130 if (ret == -ENOMEM || ret == -ENONET)
134 afs_put_server(server);
137 afs_put_server(server);
142 /* rotate the server records upon lookup failure */
144 cell->vl_curr_svix++;
145 cell->vl_curr_svix %= cell->vl_naddrs;
149 _leave(" = %d", ret);
152 } /* end afs_vlocation_access_vl_by_name() */
154 /*****************************************************************************/
156 * iterate through the VL servers in a cell until one of them admits knowing
157 * about the volume in question
158 * - caller must have cell->vl_sem write-locked
160 static int afs_vlocation_access_vl_by_id(struct afs_vlocation *vlocation,
162 afs_voltype_t voltype,
163 struct afs_cache_vlocation *vldb)
165 struct afs_server *server = NULL;
166 struct afs_cell *cell = vlocation->cell;
169 _enter("%s,%x,%d,", cell->name, volid, voltype);
172 for (count = cell->vl_naddrs; count > 0; count--) {
173 _debug("CellServ[%hu]: %08x",
175 cell->vl_addrs[cell->vl_curr_svix].s_addr);
177 /* try and create a server */
178 ret = afs_server_lookup(cell,
179 &cell->vl_addrs[cell->vl_curr_svix],
191 /* attempt to access the VL server */
192 ret = afs_rxvl_get_entry_by_id(server, volid, voltype, vldb);
195 afs_put_server(server);
202 down_write(&server->sem);
203 if (server->vlserver) {
204 rxrpc_put_connection(server->vlserver);
205 server->vlserver = NULL;
207 up_write(&server->sem);
208 afs_put_server(server);
209 if (ret == -ENOMEM || ret == -ENONET)
213 afs_put_server(server);
216 afs_put_server(server);
221 /* rotate the server records upon lookup failure */
223 cell->vl_curr_svix++;
224 cell->vl_curr_svix %= cell->vl_naddrs;
228 _leave(" = %d", ret);
231 } /* end afs_vlocation_access_vl_by_id() */
233 /*****************************************************************************/
235 * lookup volume location
236 * - caller must have cell->vol_sem write-locked
237 * - iterate through the VL servers in a cell until one of them admits knowing
238 * about the volume in question
239 * - lookup in the local cache if not able to find on the VL server
240 * - insert/update in the local cache if did get a VL response
242 int afs_vlocation_lookup(struct afs_cell *cell,
245 struct afs_vlocation **_vlocation)
247 struct afs_cache_vlocation vldb;
248 struct afs_vlocation *vlocation;
249 afs_voltype_t voltype;
253 _enter("{%s},%*.*s,%u,", cell->name, namesz, namesz, name, namesz);
255 if (namesz > sizeof(vlocation->vldb.name)) {
256 _leave(" = -ENAMETOOLONG");
257 return -ENAMETOOLONG;
260 /* search the cell's active list first */
261 list_for_each_entry(vlocation, &cell->vl_list, link) {
262 if (namesz < sizeof(vlocation->vldb.name) &&
263 vlocation->vldb.name[namesz] != '\0')
266 if (memcmp(vlocation->vldb.name, name, namesz) == 0)
267 goto found_in_memory;
270 /* search the cell's graveyard list second */
271 spin_lock(&cell->vl_gylock);
272 list_for_each_entry(vlocation, &cell->vl_graveyard, link) {
273 if (namesz < sizeof(vlocation->vldb.name) &&
274 vlocation->vldb.name[namesz] != '\0')
277 if (memcmp(vlocation->vldb.name, name, namesz) == 0)
278 goto found_in_graveyard;
280 spin_unlock(&cell->vl_gylock);
282 /* not in the cell's in-memory lists - create a new record */
283 vlocation = kmalloc(sizeof(struct afs_vlocation), GFP_KERNEL);
287 memset(vlocation, 0, sizeof(struct afs_vlocation));
288 atomic_set(&vlocation->usage, 1);
289 INIT_LIST_HEAD(&vlocation->link);
290 rwlock_init(&vlocation->lock);
291 memcpy(vlocation->vldb.name, name, namesz);
293 afs_timer_init(&vlocation->timeout, &afs_vlocation_timer_ops);
294 afs_timer_init(&vlocation->upd_timer, &afs_vlocation_update_timer_ops);
295 afs_async_op_init(&vlocation->upd_op, &afs_vlocation_update_op_ops);
298 vlocation->cell = cell;
300 list_add_tail(&vlocation->link, &cell->vl_list);
302 #ifdef AFS_CACHING_SUPPORT
303 /* we want to store it in the cache, plus it might already be
305 cachefs_acquire_cookie(cell->cache,
306 &afs_volume_cache_index_def,
310 if (vlocation->valid)
314 /* try to look up an unknown volume in the cell VL databases by name */
315 ret = afs_vlocation_access_vl_by_name(vlocation, name, namesz, &vldb);
317 printk("kAFS: failed to locate '%*.*s' in cell '%s'\n",
318 namesz, namesz, name, cell->name);
322 goto found_on_vlserver;
325 /* found in the graveyard - resurrect */
326 _debug("found in graveyard");
327 atomic_inc(&vlocation->usage);
328 list_del(&vlocation->link);
329 list_add_tail(&vlocation->link, &cell->vl_list);
330 spin_unlock(&cell->vl_gylock);
332 afs_kafstimod_del_timer(&vlocation->timeout);
336 /* found in memory - check to see if it's active */
337 _debug("found in memory");
338 atomic_inc(&vlocation->usage);
343 #ifdef AFS_CACHING_SUPPORT
346 /* try to look up a cached volume in the cell VL databases by ID */
347 _debug("found in cache");
349 _debug("Locally Cached: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
350 vlocation->vldb.name,
351 vlocation->vldb.vidmask,
352 ntohl(vlocation->vldb.servers[0].s_addr),
353 vlocation->vldb.srvtmask[0],
354 ntohl(vlocation->vldb.servers[1].s_addr),
355 vlocation->vldb.srvtmask[1],
356 ntohl(vlocation->vldb.servers[2].s_addr),
357 vlocation->vldb.srvtmask[2]
360 _debug("Vids: %08x %08x %08x",
361 vlocation->vldb.vid[0],
362 vlocation->vldb.vid[1],
363 vlocation->vldb.vid[2]);
365 if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) {
366 vid = vlocation->vldb.vid[0];
367 voltype = AFSVL_RWVOL;
369 else if (vlocation->vldb.vidmask & AFS_VOL_VTM_RO) {
370 vid = vlocation->vldb.vid[1];
371 voltype = AFSVL_ROVOL;
373 else if (vlocation->vldb.vidmask & AFS_VOL_VTM_BAK) {
374 vid = vlocation->vldb.vid[2];
375 voltype = AFSVL_BACKVOL;
383 ret = afs_vlocation_access_vl_by_id(vlocation, vid, voltype, &vldb);
387 printk("kAFS: failed to volume '%*.*s' (%x) up in '%s': %d\n",
388 namesz, namesz, name, vid, cell->name, ret);
391 /* pulled from local cache into memory */
393 goto found_on_vlserver;
395 /* uh oh... looks like the volume got deleted */
397 printk("kAFS: volume '%*.*s' (%x) does not exist '%s'\n",
398 namesz, namesz, name, vid, cell->name);
400 /* TODO: make existing record unavailable */
405 _debug("Done VL Lookup: %*.*s %02x { %08x(%x) %08x(%x) %08x(%x) }",
406 namesz, namesz, name,
408 ntohl(vldb.servers[0].s_addr), vldb.srvtmask[0],
409 ntohl(vldb.servers[1].s_addr), vldb.srvtmask[1],
410 ntohl(vldb.servers[2].s_addr), vldb.srvtmask[2]
413 _debug("Vids: %08x %08x %08x", vldb.vid[0], vldb.vid[1], vldb.vid[2]);
415 if ((namesz < sizeof(vlocation->vldb.name) &&
416 vlocation->vldb.name[namesz] != '\0') ||
417 memcmp(vldb.name, name, namesz) != 0)
418 printk("kAFS: name of volume '%*.*s' changed to '%s' on server\n",
419 namesz, namesz, name, vldb.name);
421 memcpy(&vlocation->vldb, &vldb, sizeof(vlocation->vldb));
423 afs_kafstimod_add_timer(&vlocation->upd_timer, 10 * HZ);
425 #ifdef AFS_CACHING_SUPPORT
426 /* update volume entry in local cache */
427 cachefs_update_cookie(vlocation->cache);
430 *_vlocation = vlocation;
431 _leave(" = 0 (%p)",vlocation);
437 __afs_put_vlocation(vlocation);
440 list_del(&vlocation->link);
441 #ifdef AFS_CACHING_SUPPORT
442 cachefs_relinquish_cookie(vlocation->cache, 0);
444 afs_put_cell(vlocation->cell);
449 _leave(" = %d", ret);
451 } /* end afs_vlocation_lookup() */
453 /*****************************************************************************/
455 * finish using a volume location record
456 * - caller must have cell->vol_sem write-locked
458 void __afs_put_vlocation(struct afs_vlocation *vlocation)
460 struct afs_cell *cell;
465 _enter("%s", vlocation->vldb.name);
467 cell = vlocation->cell;
470 BUG_ON(atomic_read(&vlocation->usage) <= 0);
472 spin_lock(&cell->vl_gylock);
473 if (likely(!atomic_dec_and_test(&vlocation->usage))) {
474 spin_unlock(&cell->vl_gylock);
479 /* move to graveyard queue */
480 list_del(&vlocation->link);
481 list_add_tail(&vlocation->link,&cell->vl_graveyard);
483 /* remove from pending timeout queue (refcounted if actually being
485 list_del_init(&vlocation->upd_op.link);
487 /* time out in 10 secs */
488 afs_kafstimod_del_timer(&vlocation->upd_timer);
489 afs_kafstimod_add_timer(&vlocation->timeout, 10 * HZ);
491 spin_unlock(&cell->vl_gylock);
494 } /* end __afs_put_vlocation() */
496 /*****************************************************************************/
498 * finish using a volume location record
500 void afs_put_vlocation(struct afs_vlocation *vlocation)
503 struct afs_cell *cell = vlocation->cell;
505 down_write(&cell->vl_sem);
506 __afs_put_vlocation(vlocation);
507 up_write(&cell->vl_sem);
509 } /* end afs_put_vlocation() */
511 /*****************************************************************************/
513 * timeout vlocation record
514 * - removes from the cell's graveyard if the usage count is zero
516 void afs_vlocation_do_timeout(struct afs_vlocation *vlocation)
518 struct afs_cell *cell;
520 _enter("%s", vlocation->vldb.name);
522 cell = vlocation->cell;
524 BUG_ON(atomic_read(&vlocation->usage) < 0);
526 /* remove from graveyard if still dead */
527 spin_lock(&cell->vl_gylock);
528 if (atomic_read(&vlocation->usage) == 0)
529 list_del_init(&vlocation->link);
532 spin_unlock(&cell->vl_gylock);
536 return; /* resurrected */
539 /* we can now destroy it properly */
540 #ifdef AFS_CACHING_SUPPORT
541 cachefs_relinquish_cookie(vlocation->cache, 0);
547 _leave(" [destroyed]");
548 } /* end afs_vlocation_do_timeout() */
550 /*****************************************************************************/
552 * send an update operation to the currently selected server
554 static int afs_vlocation_update_begin(struct afs_vlocation *vlocation)
556 afs_voltype_t voltype;
560 _enter("%s{ufs=%u ucs=%u}",
561 vlocation->vldb.name,
562 vlocation->upd_first_svix,
563 vlocation->upd_curr_svix);
565 /* try to look up a cached volume in the cell VL databases by ID */
566 if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) {
567 vid = vlocation->vldb.vid[0];
568 voltype = AFSVL_RWVOL;
570 else if (vlocation->vldb.vidmask & AFS_VOL_VTM_RO) {
571 vid = vlocation->vldb.vid[1];
572 voltype = AFSVL_ROVOL;
574 else if (vlocation->vldb.vidmask & AFS_VOL_VTM_BAK) {
575 vid = vlocation->vldb.vid[2];
576 voltype = AFSVL_BACKVOL;
584 /* contact the chosen server */
585 ret = afs_server_lookup(
587 &vlocation->cell->vl_addrs[vlocation->upd_curr_svix],
588 &vlocation->upd_op.server);
596 _leave(" = %d", ret);
600 /* initiate the update operation */
601 ret = afs_rxvl_get_entry_by_id_async(&vlocation->upd_op, vid, voltype);
603 _leave(" = %d", ret);
607 _leave(" = %d", ret);
609 } /* end afs_vlocation_update_begin() */
611 /*****************************************************************************/
613 * abandon updating a VL record
614 * - does not restart the update timer
616 static void afs_vlocation_update_abandon(struct afs_vlocation *vlocation,
617 afs_vlocation_upd_t state,
620 _enter("%s,%u", vlocation->vldb.name, state);
623 printk("kAFS: Abandoning VL update '%s': %d\n",
624 vlocation->vldb.name, ret);
626 /* discard the server record */
627 afs_put_server(vlocation->upd_op.server);
628 vlocation->upd_op.server = NULL;
630 spin_lock(&afs_vlocation_update_lock);
631 afs_vlocation_update = NULL;
632 vlocation->upd_state = state;
634 /* TODO: start updating next VL record on pending list */
636 spin_unlock(&afs_vlocation_update_lock);
639 } /* end afs_vlocation_update_abandon() */
641 /*****************************************************************************/
643 * handle periodic update timeouts and busy retry timeouts
644 * - called from kafstimod
646 static void afs_vlocation_update_timer(struct afs_timer *timer)
648 struct afs_vlocation *vlocation =
649 list_entry(timer, struct afs_vlocation, upd_timer);
652 _enter("%s", vlocation->vldb.name);
654 /* only update if not in the graveyard (defend against putting too) */
655 spin_lock(&vlocation->cell->vl_gylock);
657 if (!atomic_read(&vlocation->usage))
660 spin_lock(&afs_vlocation_update_lock);
662 /* if we were woken up due to EBUSY sleep then restart immediately if
663 * possible or else jump to front of pending queue */
664 if (vlocation->upd_state == AFS_VLUPD_BUSYSLEEP) {
665 if (afs_vlocation_update) {
666 list_add(&vlocation->upd_op.link,
667 &afs_vlocation_update_pendq);
670 afs_get_vlocation(vlocation);
671 afs_vlocation_update = vlocation;
672 vlocation->upd_state = AFS_VLUPD_INPROGRESS;
677 /* put on pending queue if there's already another update in progress */
678 if (afs_vlocation_update) {
679 vlocation->upd_state = AFS_VLUPD_PENDING;
680 list_add_tail(&vlocation->upd_op.link,
681 &afs_vlocation_update_pendq);
685 /* hold a ref on it while actually updating */
686 afs_get_vlocation(vlocation);
687 afs_vlocation_update = vlocation;
688 vlocation->upd_state = AFS_VLUPD_INPROGRESS;
690 spin_unlock(&afs_vlocation_update_lock);
691 spin_unlock(&vlocation->cell->vl_gylock);
693 /* okay... we can start the update */
694 _debug("BEGIN VL UPDATE [%s]", vlocation->vldb.name);
695 vlocation->upd_first_svix = vlocation->cell->vl_curr_svix;
696 vlocation->upd_curr_svix = vlocation->upd_first_svix;
697 vlocation->upd_rej_cnt = 0;
698 vlocation->upd_busy_cnt = 0;
700 ret = afs_vlocation_update_begin(vlocation);
702 afs_vlocation_update_abandon(vlocation, AFS_VLUPD_SLEEP, ret);
703 afs_kafstimod_add_timer(&vlocation->upd_timer,
705 afs_put_vlocation(vlocation);
712 spin_unlock(&afs_vlocation_update_lock);
714 spin_unlock(&vlocation->cell->vl_gylock);
718 } /* end afs_vlocation_update_timer() */
720 /*****************************************************************************/
722 * attend to an update operation upon which an event happened
723 * - called in kafsasyncd context
725 static void afs_vlocation_update_attend(struct afs_async_op *op)
727 struct afs_cache_vlocation vldb;
728 struct afs_vlocation *vlocation =
729 list_entry(op, struct afs_vlocation, upd_op);
733 _enter("%s", vlocation->vldb.name);
735 ret = afs_rxvl_get_entry_by_id_async2(op, &vldb);
738 _leave(" [unfinished]");
742 _debug("END VL UPDATE: %d\n", ret);
743 vlocation->valid = 1;
745 _debug("Done VL Lookup: %02x { %08x(%x) %08x(%x) %08x(%x) }",
747 ntohl(vldb.servers[0].s_addr), vldb.srvtmask[0],
748 ntohl(vldb.servers[1].s_addr), vldb.srvtmask[1],
749 ntohl(vldb.servers[2].s_addr), vldb.srvtmask[2]
752 _debug("Vids: %08x %08x %08x",
753 vldb.vid[0], vldb.vid[1], vldb.vid[2]);
755 afs_vlocation_update_abandon(vlocation, AFS_VLUPD_SLEEP, 0);
757 down_write(&vlocation->cell->vl_sem);
759 /* actually update the cache */
760 if (strncmp(vldb.name, vlocation->vldb.name,
761 sizeof(vlocation->vldb.name)) != 0)
762 printk("kAFS: name of volume '%s'"
763 " changed to '%s' on server\n",
764 vlocation->vldb.name, vldb.name);
766 memcpy(&vlocation->vldb, &vldb, sizeof(vlocation->vldb));
769 /* TODO update volume entry in local cache */
772 up_write(&vlocation->cell->vl_sem);
775 printk("kAFS: failed to update local cache: %d\n", ret);
777 afs_kafstimod_add_timer(&vlocation->upd_timer,
779 afs_put_vlocation(vlocation);
784 vlocation->upd_rej_cnt++;
787 /* the server is locked - retry in a very short while */
789 vlocation->upd_busy_cnt++;
790 if (vlocation->upd_busy_cnt > 3)
791 goto try_next; /* too many retries */
793 afs_vlocation_update_abandon(vlocation,
794 AFS_VLUPD_BUSYSLEEP, 0);
795 afs_kafstimod_add_timer(&vlocation->upd_timer, HZ / 2);
796 afs_put_vlocation(vlocation);
804 /* record bad vlserver info in the cell too
805 * - TODO: use down_write_trylock() if available
807 if (vlocation->upd_curr_svix == vlocation->cell->vl_curr_svix)
808 vlocation->cell->vl_curr_svix =
809 vlocation->cell->vl_curr_svix %
810 vlocation->cell->vl_naddrs;
822 /* try contacting the next server */
824 vlocation->upd_busy_cnt = 0;
826 /* discard the server record */
827 afs_put_server(vlocation->upd_op.server);
828 vlocation->upd_op.server = NULL;
830 tmp = vlocation->cell->vl_naddrs;
834 vlocation->upd_curr_svix++;
835 if (vlocation->upd_curr_svix >= tmp)
836 vlocation->upd_curr_svix = 0;
837 if (vlocation->upd_first_svix >= tmp)
838 vlocation->upd_first_svix = tmp - 1;
840 /* move to the next server */
841 if (vlocation->upd_curr_svix != vlocation->upd_first_svix) {
842 afs_vlocation_update_begin(vlocation);
847 /* run out of servers to try - was the volume rejected? */
848 if (vlocation->upd_rej_cnt > 0) {
849 printk("kAFS: Active volume no longer valid '%s'\n",
850 vlocation->vldb.name);
851 vlocation->valid = 0;
852 afs_vlocation_update_abandon(vlocation, AFS_VLUPD_SLEEP, 0);
853 afs_kafstimod_add_timer(&vlocation->upd_timer,
855 afs_put_vlocation(vlocation);
856 _leave(" [invalidated]");
860 /* abandon the update */
862 afs_vlocation_update_abandon(vlocation, AFS_VLUPD_SLEEP, ret);
863 afs_kafstimod_add_timer(&vlocation->upd_timer, HZ * 10);
864 afs_put_vlocation(vlocation);
865 _leave(" [abandoned]");
867 } /* end afs_vlocation_update_attend() */
869 /*****************************************************************************/
871 * deal with an update operation being discarded
872 * - called in kafsasyncd context when it's dying due to rmmod
873 * - the call has already been aborted and put()'d
875 static void afs_vlocation_update_discard(struct afs_async_op *op)
877 struct afs_vlocation *vlocation =
878 list_entry(op, struct afs_vlocation, upd_op);
880 _enter("%s", vlocation->vldb.name);
882 afs_put_server(op->server);
885 afs_put_vlocation(vlocation);
888 } /* end afs_vlocation_update_discard() */
890 /*****************************************************************************/
892 * match a VLDB record stored in the cache
893 * - may also load target from entry
895 #ifdef AFS_CACHING_SUPPORT
896 static cachefs_match_val_t afs_vlocation_cache_match(void *target,
899 const struct afs_cache_vlocation *vldb = entry;
900 struct afs_vlocation *vlocation = target;
902 _enter("{%s},{%s}", vlocation->vldb.name, vldb->name);
904 if (strncmp(vlocation->vldb.name, vldb->name, sizeof(vldb->name)) == 0
906 if (!vlocation->valid ||
907 vlocation->vldb.rtime == vldb->rtime
909 vlocation->vldb = *vldb;
910 vlocation->valid = 1;
911 _leave(" = SUCCESS [c->m]");
912 return CACHEFS_MATCH_SUCCESS;
914 /* need to update cache if cached info differs */
915 else if (memcmp(&vlocation->vldb, vldb, sizeof(*vldb)) != 0) {
916 /* delete if VIDs for this name differ */
917 if (memcmp(&vlocation->vldb.vid,
919 sizeof(vldb->vid)) != 0) {
921 return CACHEFS_MATCH_SUCCESS_DELETE;
925 return CACHEFS_MATCH_SUCCESS_UPDATE;
928 _leave(" = SUCCESS");
929 return CACHEFS_MATCH_SUCCESS;
934 return CACHEFS_MATCH_FAILED;
935 } /* end afs_vlocation_cache_match() */
938 /*****************************************************************************/
940 * update a VLDB record stored in the cache
942 #ifdef AFS_CACHING_SUPPORT
943 static void afs_vlocation_cache_update(void *source, void *entry)
945 struct afs_cache_vlocation *vldb = entry;
946 struct afs_vlocation *vlocation = source;
950 *vldb = vlocation->vldb;
952 } /* end afs_vlocation_cache_update() */