1 /* 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
);
32 static void __afs_put_vlocation(struct afs_vlocation
*vlocation
);
34 static void __afs_vlocation_timeout(struct afs_timer
*timer
)
36 struct afs_vlocation
*vlocation
=
37 list_entry(timer
, struct afs_vlocation
, timeout
);
39 _debug("VL TIMEOUT [%s{u=%d}]",
40 vlocation
->vldb
.name
, atomic_read(&vlocation
->usage
));
42 afs_vlocation_do_timeout(vlocation
);
45 static const struct afs_timer_ops afs_vlocation_timer_ops
= {
46 .timed_out
= __afs_vlocation_timeout
,
49 static const struct afs_timer_ops afs_vlocation_update_timer_ops
= {
50 .timed_out
= afs_vlocation_update_timer
,
53 static const struct afs_async_op_ops afs_vlocation_update_op_ops
= {
54 .attend
= afs_vlocation_update_attend
,
55 .discard
= afs_vlocation_update_discard
,
58 static LIST_HEAD(afs_vlocation_update_pendq
); /* queue of VLs awaiting update */
59 static struct afs_vlocation
*afs_vlocation_update
; /* VL currently being updated */
60 static DEFINE_SPINLOCK(afs_vlocation_update_lock
); /* lock guarding update queue */
62 #ifdef AFS_CACHING_SUPPORT
63 static cachefs_match_val_t
afs_vlocation_cache_match(void *target
,
65 static void afs_vlocation_cache_update(void *source
, void *entry
);
67 struct cachefs_index_def afs_vlocation_cache_index_def
= {
69 .data_size
= sizeof(struct afs_cache_vlocation
),
70 .keys
[0] = { CACHEFS_INDEX_KEYS_ASCIIZ
, 64 },
71 .match
= afs_vlocation_cache_match
,
72 .update
= afs_vlocation_cache_update
,
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
);
154 * iterate through the VL servers in a cell until one of them admits knowing
155 * about the volume in question
156 * - caller must have cell->vl_sem write-locked
158 static int afs_vlocation_access_vl_by_id(struct afs_vlocation
*vlocation
,
160 afs_voltype_t voltype
,
161 struct afs_cache_vlocation
*vldb
)
163 struct afs_server
*server
= NULL
;
164 struct afs_cell
*cell
= vlocation
->cell
;
167 _enter("%s,%x,%d,", cell
->name
, volid
, voltype
);
170 for (count
= cell
->vl_naddrs
; count
> 0; count
--) {
171 _debug("CellServ[%hu]: %08x",
173 cell
->vl_addrs
[cell
->vl_curr_svix
].s_addr
);
175 /* try and create a server */
176 ret
= afs_server_lookup(cell
,
177 &cell
->vl_addrs
[cell
->vl_curr_svix
],
189 /* attempt to access the VL server */
190 ret
= afs_rxvl_get_entry_by_id(server
, volid
, voltype
, vldb
);
193 afs_put_server(server
);
200 down_write(&server
->sem
);
201 if (server
->vlserver
) {
202 rxrpc_put_connection(server
->vlserver
);
203 server
->vlserver
= NULL
;
205 up_write(&server
->sem
);
206 afs_put_server(server
);
207 if (ret
== -ENOMEM
|| ret
== -ENONET
)
211 afs_put_server(server
);
214 afs_put_server(server
);
219 /* rotate the server records upon lookup failure */
221 cell
->vl_curr_svix
++;
222 cell
->vl_curr_svix
%= cell
->vl_naddrs
;
226 _leave(" = %d", ret
);
231 * lookup volume location
232 * - caller must have cell->vol_sem write-locked
233 * - iterate through the VL servers in a cell until one of them admits knowing
234 * about the volume in question
235 * - lookup in the local cache if not able to find on the VL server
236 * - insert/update in the local cache if did get a VL response
238 int afs_vlocation_lookup(struct afs_cell
*cell
,
241 struct afs_vlocation
**_vlocation
)
243 struct afs_cache_vlocation vldb
;
244 struct afs_vlocation
*vlocation
;
245 afs_voltype_t voltype
;
249 _enter("{%s},%*.*s,%u,", cell
->name
, namesz
, namesz
, name
, namesz
);
251 if (namesz
> sizeof(vlocation
->vldb
.name
)) {
252 _leave(" = -ENAMETOOLONG");
253 return -ENAMETOOLONG
;
256 /* search the cell's active list first */
257 list_for_each_entry(vlocation
, &cell
->vl_list
, link
) {
258 if (namesz
< sizeof(vlocation
->vldb
.name
) &&
259 vlocation
->vldb
.name
[namesz
] != '\0')
262 if (memcmp(vlocation
->vldb
.name
, name
, namesz
) == 0)
263 goto found_in_memory
;
266 /* search the cell's graveyard list second */
267 spin_lock(&cell
->vl_gylock
);
268 list_for_each_entry(vlocation
, &cell
->vl_graveyard
, link
) {
269 if (namesz
< sizeof(vlocation
->vldb
.name
) &&
270 vlocation
->vldb
.name
[namesz
] != '\0')
273 if (memcmp(vlocation
->vldb
.name
, name
, namesz
) == 0)
274 goto found_in_graveyard
;
276 spin_unlock(&cell
->vl_gylock
);
278 /* not in the cell's in-memory lists - create a new record */
279 vlocation
= kzalloc(sizeof(struct afs_vlocation
), GFP_KERNEL
);
283 atomic_set(&vlocation
->usage
, 1);
284 INIT_LIST_HEAD(&vlocation
->link
);
285 rwlock_init(&vlocation
->lock
);
286 memcpy(vlocation
->vldb
.name
, name
, namesz
);
288 afs_timer_init(&vlocation
->timeout
, &afs_vlocation_timer_ops
);
289 afs_timer_init(&vlocation
->upd_timer
, &afs_vlocation_update_timer_ops
);
290 afs_async_op_init(&vlocation
->upd_op
, &afs_vlocation_update_op_ops
);
293 vlocation
->cell
= cell
;
295 list_add_tail(&vlocation
->link
, &cell
->vl_list
);
297 #ifdef AFS_CACHING_SUPPORT
298 /* we want to store it in the cache, plus it might already be
300 cachefs_acquire_cookie(cell
->cache
,
301 &afs_volume_cache_index_def
,
305 if (vlocation
->valid
)
309 /* try to look up an unknown volume in the cell VL databases by name */
310 ret
= afs_vlocation_access_vl_by_name(vlocation
, name
, namesz
, &vldb
);
312 printk("kAFS: failed to locate '%*.*s' in cell '%s'\n",
313 namesz
, namesz
, name
, cell
->name
);
317 goto found_on_vlserver
;
320 /* found in the graveyard - resurrect */
321 _debug("found in graveyard");
322 atomic_inc(&vlocation
->usage
);
323 list_move_tail(&vlocation
->link
, &cell
->vl_list
);
324 spin_unlock(&cell
->vl_gylock
);
326 afs_kafstimod_del_timer(&vlocation
->timeout
);
330 /* found in memory - check to see if it's active */
331 _debug("found in memory");
332 atomic_inc(&vlocation
->usage
);
337 #ifdef AFS_CACHING_SUPPORT
340 /* try to look up a cached volume in the cell VL databases by ID */
341 _debug("found in cache");
343 _debug("Locally Cached: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
344 vlocation
->vldb
.name
,
345 vlocation
->vldb
.vidmask
,
346 ntohl(vlocation
->vldb
.servers
[0].s_addr
),
347 vlocation
->vldb
.srvtmask
[0],
348 ntohl(vlocation
->vldb
.servers
[1].s_addr
),
349 vlocation
->vldb
.srvtmask
[1],
350 ntohl(vlocation
->vldb
.servers
[2].s_addr
),
351 vlocation
->vldb
.srvtmask
[2]
354 _debug("Vids: %08x %08x %08x",
355 vlocation
->vldb
.vid
[0],
356 vlocation
->vldb
.vid
[1],
357 vlocation
->vldb
.vid
[2]);
359 if (vlocation
->vldb
.vidmask
& AFS_VOL_VTM_RW
) {
360 vid
= vlocation
->vldb
.vid
[0];
361 voltype
= AFSVL_RWVOL
;
362 } else if (vlocation
->vldb
.vidmask
& AFS_VOL_VTM_RO
) {
363 vid
= vlocation
->vldb
.vid
[1];
364 voltype
= AFSVL_ROVOL
;
365 } else if (vlocation
->vldb
.vidmask
& AFS_VOL_VTM_BAK
) {
366 vid
= vlocation
->vldb
.vid
[2];
367 voltype
= AFSVL_BACKVOL
;
374 ret
= afs_vlocation_access_vl_by_id(vlocation
, vid
, voltype
, &vldb
);
378 printk("kAFS: failed to volume '%*.*s' (%x) up in '%s': %d\n",
379 namesz
, namesz
, name
, vid
, cell
->name
, ret
);
382 /* pulled from local cache into memory */
384 goto found_on_vlserver
;
386 /* uh oh... looks like the volume got deleted */
388 printk("kAFS: volume '%*.*s' (%x) does not exist '%s'\n",
389 namesz
, namesz
, name
, vid
, cell
->name
);
391 /* TODO: make existing record unavailable */
396 _debug("Done VL Lookup: %*.*s %02x { %08x(%x) %08x(%x) %08x(%x) }",
397 namesz
, namesz
, name
,
399 ntohl(vldb
.servers
[0].s_addr
), vldb
.srvtmask
[0],
400 ntohl(vldb
.servers
[1].s_addr
), vldb
.srvtmask
[1],
401 ntohl(vldb
.servers
[2].s_addr
), vldb
.srvtmask
[2]
404 _debug("Vids: %08x %08x %08x", vldb
.vid
[0], vldb
.vid
[1], vldb
.vid
[2]);
406 if ((namesz
< sizeof(vlocation
->vldb
.name
) &&
407 vlocation
->vldb
.name
[namesz
] != '\0') ||
408 memcmp(vldb
.name
, name
, namesz
) != 0)
409 printk("kAFS: name of volume '%*.*s' changed to '%s' on server\n",
410 namesz
, namesz
, name
, vldb
.name
);
412 memcpy(&vlocation
->vldb
, &vldb
, sizeof(vlocation
->vldb
));
414 afs_kafstimod_add_timer(&vlocation
->upd_timer
, 10 * HZ
);
416 #ifdef AFS_CACHING_SUPPORT
417 /* update volume entry in local cache */
418 cachefs_update_cookie(vlocation
->cache
);
421 *_vlocation
= vlocation
;
422 _leave(" = 0 (%p)",vlocation
);
428 __afs_put_vlocation(vlocation
);
430 list_del(&vlocation
->link
);
431 #ifdef AFS_CACHING_SUPPORT
432 cachefs_relinquish_cookie(vlocation
->cache
, 0);
434 afs_put_cell(vlocation
->cell
);
439 _leave(" = %d", ret
);
444 * finish using a volume location record
445 * - caller must have cell->vol_sem write-locked
447 static void __afs_put_vlocation(struct afs_vlocation
*vlocation
)
449 struct afs_cell
*cell
;
454 _enter("%s", vlocation
->vldb
.name
);
456 cell
= vlocation
->cell
;
459 BUG_ON(atomic_read(&vlocation
->usage
) <= 0);
461 spin_lock(&cell
->vl_gylock
);
462 if (likely(!atomic_dec_and_test(&vlocation
->usage
))) {
463 spin_unlock(&cell
->vl_gylock
);
468 /* move to graveyard queue */
469 list_move_tail(&vlocation
->link
,&cell
->vl_graveyard
);
471 /* remove from pending timeout queue (refcounted if actually being
473 list_del_init(&vlocation
->upd_op
.link
);
475 /* time out in 10 secs */
476 afs_kafstimod_del_timer(&vlocation
->upd_timer
);
477 afs_kafstimod_add_timer(&vlocation
->timeout
, 10 * HZ
);
479 spin_unlock(&cell
->vl_gylock
);
485 * finish using a volume location record
487 void afs_put_vlocation(struct afs_vlocation
*vlocation
)
490 struct afs_cell
*cell
= vlocation
->cell
;
492 down_write(&cell
->vl_sem
);
493 __afs_put_vlocation(vlocation
);
494 up_write(&cell
->vl_sem
);
499 * timeout vlocation record
500 * - removes from the cell's graveyard if the usage count is zero
502 void afs_vlocation_do_timeout(struct afs_vlocation
*vlocation
)
504 struct afs_cell
*cell
;
506 _enter("%s", vlocation
->vldb
.name
);
508 cell
= vlocation
->cell
;
510 BUG_ON(atomic_read(&vlocation
->usage
) < 0);
512 /* remove from graveyard if still dead */
513 spin_lock(&cell
->vl_gylock
);
514 if (atomic_read(&vlocation
->usage
) == 0)
515 list_del_init(&vlocation
->link
);
518 spin_unlock(&cell
->vl_gylock
);
522 return; /* resurrected */
525 /* we can now destroy it properly */
526 #ifdef AFS_CACHING_SUPPORT
527 cachefs_relinquish_cookie(vlocation
->cache
, 0);
533 _leave(" [destroyed]");
537 * send an update operation to the currently selected server
539 static int afs_vlocation_update_begin(struct afs_vlocation
*vlocation
)
541 afs_voltype_t voltype
;
545 _enter("%s{ufs=%u ucs=%u}",
546 vlocation
->vldb
.name
,
547 vlocation
->upd_first_svix
,
548 vlocation
->upd_curr_svix
);
550 /* try to look up a cached volume in the cell VL databases by ID */
551 if (vlocation
->vldb
.vidmask
& AFS_VOL_VTM_RW
) {
552 vid
= vlocation
->vldb
.vid
[0];
553 voltype
= AFSVL_RWVOL
;
554 } else if (vlocation
->vldb
.vidmask
& AFS_VOL_VTM_RO
) {
555 vid
= vlocation
->vldb
.vid
[1];
556 voltype
= AFSVL_ROVOL
;
557 } else if (vlocation
->vldb
.vidmask
& AFS_VOL_VTM_BAK
) {
558 vid
= vlocation
->vldb
.vid
[2];
559 voltype
= AFSVL_BACKVOL
;
566 /* contact the chosen server */
567 ret
= afs_server_lookup(
569 &vlocation
->cell
->vl_addrs
[vlocation
->upd_curr_svix
],
570 &vlocation
->upd_op
.server
);
578 _leave(" = %d", ret
);
582 /* initiate the update operation */
583 ret
= afs_rxvl_get_entry_by_id_async(&vlocation
->upd_op
, vid
, voltype
);
585 _leave(" = %d", ret
);
589 _leave(" = %d", ret
);
594 * abandon updating a VL record
595 * - does not restart the update timer
597 static void afs_vlocation_update_abandon(struct afs_vlocation
*vlocation
,
598 afs_vlocation_upd_t state
,
601 _enter("%s,%u", vlocation
->vldb
.name
, state
);
604 printk("kAFS: Abandoning VL update '%s': %d\n",
605 vlocation
->vldb
.name
, ret
);
607 /* discard the server record */
608 afs_put_server(vlocation
->upd_op
.server
);
609 vlocation
->upd_op
.server
= NULL
;
611 spin_lock(&afs_vlocation_update_lock
);
612 afs_vlocation_update
= NULL
;
613 vlocation
->upd_state
= state
;
615 /* TODO: start updating next VL record on pending list */
617 spin_unlock(&afs_vlocation_update_lock
);
623 * handle periodic update timeouts and busy retry timeouts
624 * - called from kafstimod
626 static void afs_vlocation_update_timer(struct afs_timer
*timer
)
628 struct afs_vlocation
*vlocation
=
629 list_entry(timer
, struct afs_vlocation
, upd_timer
);
632 _enter("%s", vlocation
->vldb
.name
);
634 /* only update if not in the graveyard (defend against putting too) */
635 spin_lock(&vlocation
->cell
->vl_gylock
);
637 if (!atomic_read(&vlocation
->usage
))
640 spin_lock(&afs_vlocation_update_lock
);
642 /* if we were woken up due to EBUSY sleep then restart immediately if
643 * possible or else jump to front of pending queue */
644 if (vlocation
->upd_state
== AFS_VLUPD_BUSYSLEEP
) {
645 if (afs_vlocation_update
) {
646 list_add(&vlocation
->upd_op
.link
,
647 &afs_vlocation_update_pendq
);
649 afs_get_vlocation(vlocation
);
650 afs_vlocation_update
= vlocation
;
651 vlocation
->upd_state
= AFS_VLUPD_INPROGRESS
;
656 /* put on pending queue if there's already another update in progress */
657 if (afs_vlocation_update
) {
658 vlocation
->upd_state
= AFS_VLUPD_PENDING
;
659 list_add_tail(&vlocation
->upd_op
.link
,
660 &afs_vlocation_update_pendq
);
664 /* hold a ref on it while actually updating */
665 afs_get_vlocation(vlocation
);
666 afs_vlocation_update
= vlocation
;
667 vlocation
->upd_state
= AFS_VLUPD_INPROGRESS
;
669 spin_unlock(&afs_vlocation_update_lock
);
670 spin_unlock(&vlocation
->cell
->vl_gylock
);
672 /* okay... we can start the update */
673 _debug("BEGIN VL UPDATE [%s]", vlocation
->vldb
.name
);
674 vlocation
->upd_first_svix
= vlocation
->cell
->vl_curr_svix
;
675 vlocation
->upd_curr_svix
= vlocation
->upd_first_svix
;
676 vlocation
->upd_rej_cnt
= 0;
677 vlocation
->upd_busy_cnt
= 0;
679 ret
= afs_vlocation_update_begin(vlocation
);
681 afs_vlocation_update_abandon(vlocation
, AFS_VLUPD_SLEEP
, ret
);
682 afs_kafstimod_add_timer(&vlocation
->upd_timer
,
684 afs_put_vlocation(vlocation
);
691 spin_unlock(&afs_vlocation_update_lock
);
693 spin_unlock(&vlocation
->cell
->vl_gylock
);
698 * attend to an update operation upon which an event happened
699 * - called in kafsasyncd context
701 static void afs_vlocation_update_attend(struct afs_async_op
*op
)
703 struct afs_cache_vlocation vldb
;
704 struct afs_vlocation
*vlocation
=
705 list_entry(op
, struct afs_vlocation
, upd_op
);
709 _enter("%s", vlocation
->vldb
.name
);
711 ret
= afs_rxvl_get_entry_by_id_async2(op
, &vldb
);
714 _leave(" [unfinished]");
718 _debug("END VL UPDATE: %d\n", ret
);
719 vlocation
->valid
= 1;
721 _debug("Done VL Lookup: %02x { %08x(%x) %08x(%x) %08x(%x) }",
723 ntohl(vldb
.servers
[0].s_addr
), vldb
.srvtmask
[0],
724 ntohl(vldb
.servers
[1].s_addr
), vldb
.srvtmask
[1],
725 ntohl(vldb
.servers
[2].s_addr
), vldb
.srvtmask
[2]
728 _debug("Vids: %08x %08x %08x",
729 vldb
.vid
[0], vldb
.vid
[1], vldb
.vid
[2]);
731 afs_vlocation_update_abandon(vlocation
, AFS_VLUPD_SLEEP
, 0);
733 down_write(&vlocation
->cell
->vl_sem
);
735 /* actually update the cache */
736 if (strncmp(vldb
.name
, vlocation
->vldb
.name
,
737 sizeof(vlocation
->vldb
.name
)) != 0)
738 printk("kAFS: name of volume '%s'"
739 " changed to '%s' on server\n",
740 vlocation
->vldb
.name
, vldb
.name
);
742 memcpy(&vlocation
->vldb
, &vldb
, sizeof(vlocation
->vldb
));
745 /* TODO update volume entry in local cache */
748 up_write(&vlocation
->cell
->vl_sem
);
751 printk("kAFS: failed to update local cache: %d\n", ret
);
753 afs_kafstimod_add_timer(&vlocation
->upd_timer
,
755 afs_put_vlocation(vlocation
);
760 vlocation
->upd_rej_cnt
++;
763 /* the server is locked - retry in a very short while */
765 vlocation
->upd_busy_cnt
++;
766 if (vlocation
->upd_busy_cnt
> 3)
767 goto try_next
; /* too many retries */
769 afs_vlocation_update_abandon(vlocation
,
770 AFS_VLUPD_BUSYSLEEP
, 0);
771 afs_kafstimod_add_timer(&vlocation
->upd_timer
, HZ
/ 2);
772 afs_put_vlocation(vlocation
);
780 /* record bad vlserver info in the cell too
781 * - TODO: use down_write_trylock() if available
783 if (vlocation
->upd_curr_svix
== vlocation
->cell
->vl_curr_svix
)
784 vlocation
->cell
->vl_curr_svix
=
785 vlocation
->cell
->vl_curr_svix
%
786 vlocation
->cell
->vl_naddrs
;
798 /* try contacting the next server */
800 vlocation
->upd_busy_cnt
= 0;
802 /* discard the server record */
803 afs_put_server(vlocation
->upd_op
.server
);
804 vlocation
->upd_op
.server
= NULL
;
806 tmp
= vlocation
->cell
->vl_naddrs
;
810 vlocation
->upd_curr_svix
++;
811 if (vlocation
->upd_curr_svix
>= tmp
)
812 vlocation
->upd_curr_svix
= 0;
813 if (vlocation
->upd_first_svix
>= tmp
)
814 vlocation
->upd_first_svix
= tmp
- 1;
816 /* move to the next server */
817 if (vlocation
->upd_curr_svix
!= vlocation
->upd_first_svix
) {
818 afs_vlocation_update_begin(vlocation
);
823 /* run out of servers to try - was the volume rejected? */
824 if (vlocation
->upd_rej_cnt
> 0) {
825 printk("kAFS: Active volume no longer valid '%s'\n",
826 vlocation
->vldb
.name
);
827 vlocation
->valid
= 0;
828 afs_vlocation_update_abandon(vlocation
, AFS_VLUPD_SLEEP
, 0);
829 afs_kafstimod_add_timer(&vlocation
->upd_timer
,
831 afs_put_vlocation(vlocation
);
832 _leave(" [invalidated]");
836 /* abandon the update */
838 afs_vlocation_update_abandon(vlocation
, AFS_VLUPD_SLEEP
, ret
);
839 afs_kafstimod_add_timer(&vlocation
->upd_timer
, HZ
* 10);
840 afs_put_vlocation(vlocation
);
841 _leave(" [abandoned]");
845 * deal with an update operation being discarded
846 * - called in kafsasyncd context when it's dying due to rmmod
847 * - the call has already been aborted and put()'d
849 static void afs_vlocation_update_discard(struct afs_async_op
*op
)
851 struct afs_vlocation
*vlocation
=
852 list_entry(op
, struct afs_vlocation
, upd_op
);
854 _enter("%s", vlocation
->vldb
.name
);
856 afs_put_server(op
->server
);
859 afs_put_vlocation(vlocation
);
865 * match a VLDB record stored in the cache
866 * - may also load target from entry
868 #ifdef AFS_CACHING_SUPPORT
869 static cachefs_match_val_t
afs_vlocation_cache_match(void *target
,
872 const struct afs_cache_vlocation
*vldb
= entry
;
873 struct afs_vlocation
*vlocation
= target
;
875 _enter("{%s},{%s}", vlocation
->vldb
.name
, vldb
->name
);
877 if (strncmp(vlocation
->vldb
.name
, vldb
->name
, sizeof(vldb
->name
)) == 0
879 if (!vlocation
->valid
||
880 vlocation
->vldb
.rtime
== vldb
->rtime
882 vlocation
->vldb
= *vldb
;
883 vlocation
->valid
= 1;
884 _leave(" = SUCCESS [c->m]");
885 return CACHEFS_MATCH_SUCCESS
;
886 } else if (memcmp(&vlocation
->vldb
, vldb
, sizeof(*vldb
)) != 0) {
887 /* delete if VIDs for this name differ */
888 if (memcmp(&vlocation
->vldb
.vid
,
890 sizeof(vldb
->vid
)) != 0) {
892 return CACHEFS_MATCH_SUCCESS_DELETE
;
896 return CACHEFS_MATCH_SUCCESS_UPDATE
;
898 _leave(" = SUCCESS");
899 return CACHEFS_MATCH_SUCCESS
;
904 return CACHEFS_MATCH_FAILED
;
909 * update a VLDB record stored in the cache
911 #ifdef AFS_CACHING_SUPPORT
912 static void afs_vlocation_cache_update(void *source
, void *entry
)
914 struct afs_cache_vlocation
*vldb
= entry
;
915 struct afs_vlocation
*vlocation
= source
;
919 *vldb
= vlocation
->vldb
;