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
);
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
,
76 /*****************************************************************************/
78 * iterate through the VL servers in a cell until one of them admits knowing
79 * about the volume in question
80 * - caller must have cell->vl_sem write-locked
82 static int afs_vlocation_access_vl_by_name(struct afs_vlocation
*vlocation
,
85 struct afs_cache_vlocation
*vldb
)
87 struct afs_server
*server
= NULL
;
88 struct afs_cell
*cell
= vlocation
->cell
;
91 _enter("%s,%*.*s,%u", cell
->name
, namesz
, namesz
, name
, namesz
);
94 for (count
= cell
->vl_naddrs
; count
> 0; count
--) {
95 _debug("CellServ[%hu]: %08x",
97 cell
->vl_addrs
[cell
->vl_curr_svix
].s_addr
);
99 /* try and create a server */
100 ret
= afs_server_lookup(cell
,
101 &cell
->vl_addrs
[cell
->vl_curr_svix
],
113 /* attempt to access the VL server */
114 ret
= afs_rxvl_get_entry_by_name(server
, name
, namesz
, vldb
);
117 afs_put_server(server
);
124 down_write(&server
->sem
);
125 if (server
->vlserver
) {
126 rxrpc_put_connection(server
->vlserver
);
127 server
->vlserver
= NULL
;
129 up_write(&server
->sem
);
130 afs_put_server(server
);
131 if (ret
== -ENOMEM
|| ret
== -ENONET
)
135 afs_put_server(server
);
138 afs_put_server(server
);
143 /* rotate the server records upon lookup failure */
145 cell
->vl_curr_svix
++;
146 cell
->vl_curr_svix
%= cell
->vl_naddrs
;
150 _leave(" = %d", ret
);
153 } /* end afs_vlocation_access_vl_by_name() */
155 /*****************************************************************************/
157 * iterate through the VL servers in a cell until one of them admits knowing
158 * about the volume in question
159 * - caller must have cell->vl_sem write-locked
161 static int afs_vlocation_access_vl_by_id(struct afs_vlocation
*vlocation
,
163 afs_voltype_t voltype
,
164 struct afs_cache_vlocation
*vldb
)
166 struct afs_server
*server
= NULL
;
167 struct afs_cell
*cell
= vlocation
->cell
;
170 _enter("%s,%x,%d,", cell
->name
, volid
, voltype
);
173 for (count
= cell
->vl_naddrs
; count
> 0; count
--) {
174 _debug("CellServ[%hu]: %08x",
176 cell
->vl_addrs
[cell
->vl_curr_svix
].s_addr
);
178 /* try and create a server */
179 ret
= afs_server_lookup(cell
,
180 &cell
->vl_addrs
[cell
->vl_curr_svix
],
192 /* attempt to access the VL server */
193 ret
= afs_rxvl_get_entry_by_id(server
, volid
, voltype
, vldb
);
196 afs_put_server(server
);
203 down_write(&server
->sem
);
204 if (server
->vlserver
) {
205 rxrpc_put_connection(server
->vlserver
);
206 server
->vlserver
= NULL
;
208 up_write(&server
->sem
);
209 afs_put_server(server
);
210 if (ret
== -ENOMEM
|| ret
== -ENONET
)
214 afs_put_server(server
);
217 afs_put_server(server
);
222 /* rotate the server records upon lookup failure */
224 cell
->vl_curr_svix
++;
225 cell
->vl_curr_svix
%= cell
->vl_naddrs
;
229 _leave(" = %d", ret
);
232 } /* end afs_vlocation_access_vl_by_id() */
234 /*****************************************************************************/
236 * lookup volume location
237 * - caller must have cell->vol_sem write-locked
238 * - iterate through the VL servers in a cell until one of them admits knowing
239 * about the volume in question
240 * - lookup in the local cache if not able to find on the VL server
241 * - insert/update in the local cache if did get a VL response
243 int afs_vlocation_lookup(struct afs_cell
*cell
,
246 struct afs_vlocation
**_vlocation
)
248 struct afs_cache_vlocation vldb
;
249 struct afs_vlocation
*vlocation
;
250 afs_voltype_t voltype
;
254 _enter("{%s},%*.*s,%u,", cell
->name
, namesz
, namesz
, name
, namesz
);
256 if (namesz
> sizeof(vlocation
->vldb
.name
)) {
257 _leave(" = -ENAMETOOLONG");
258 return -ENAMETOOLONG
;
261 /* search the cell's active list first */
262 list_for_each_entry(vlocation
, &cell
->vl_list
, link
) {
263 if (namesz
< sizeof(vlocation
->vldb
.name
) &&
264 vlocation
->vldb
.name
[namesz
] != '\0')
267 if (memcmp(vlocation
->vldb
.name
, name
, namesz
) == 0)
268 goto found_in_memory
;
271 /* search the cell's graveyard list second */
272 spin_lock(&cell
->vl_gylock
);
273 list_for_each_entry(vlocation
, &cell
->vl_graveyard
, link
) {
274 if (namesz
< sizeof(vlocation
->vldb
.name
) &&
275 vlocation
->vldb
.name
[namesz
] != '\0')
278 if (memcmp(vlocation
->vldb
.name
, name
, namesz
) == 0)
279 goto found_in_graveyard
;
281 spin_unlock(&cell
->vl_gylock
);
283 /* not in the cell's in-memory lists - create a new record */
284 vlocation
= kmalloc(sizeof(struct afs_vlocation
), GFP_KERNEL
);
288 memset(vlocation
, 0, sizeof(struct afs_vlocation
));
289 atomic_set(&vlocation
->usage
, 1);
290 INIT_LIST_HEAD(&vlocation
->link
);
291 rwlock_init(&vlocation
->lock
);
292 memcpy(vlocation
->vldb
.name
, name
, namesz
);
294 afs_timer_init(&vlocation
->timeout
, &afs_vlocation_timer_ops
);
295 afs_timer_init(&vlocation
->upd_timer
, &afs_vlocation_update_timer_ops
);
296 afs_async_op_init(&vlocation
->upd_op
, &afs_vlocation_update_op_ops
);
299 vlocation
->cell
= cell
;
301 list_add_tail(&vlocation
->link
, &cell
->vl_list
);
303 #ifdef AFS_CACHING_SUPPORT
304 /* we want to store it in the cache, plus it might already be
306 cachefs_acquire_cookie(cell
->cache
,
307 &afs_volume_cache_index_def
,
311 if (vlocation
->valid
)
315 /* try to look up an unknown volume in the cell VL databases by name */
316 ret
= afs_vlocation_access_vl_by_name(vlocation
, name
, namesz
, &vldb
);
318 printk("kAFS: failed to locate '%*.*s' in cell '%s'\n",
319 namesz
, namesz
, name
, cell
->name
);
323 goto found_on_vlserver
;
326 /* found in the graveyard - resurrect */
327 _debug("found in graveyard");
328 atomic_inc(&vlocation
->usage
);
329 list_del(&vlocation
->link
);
330 list_add_tail(&vlocation
->link
, &cell
->vl_list
);
331 spin_unlock(&cell
->vl_gylock
);
333 afs_kafstimod_del_timer(&vlocation
->timeout
);
337 /* found in memory - check to see if it's active */
338 _debug("found in memory");
339 atomic_inc(&vlocation
->usage
);
344 #ifdef AFS_CACHING_SUPPORT
347 /* try to look up a cached volume in the cell VL databases by ID */
348 _debug("found in cache");
350 _debug("Locally Cached: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
351 vlocation
->vldb
.name
,
352 vlocation
->vldb
.vidmask
,
353 ntohl(vlocation
->vldb
.servers
[0].s_addr
),
354 vlocation
->vldb
.srvtmask
[0],
355 ntohl(vlocation
->vldb
.servers
[1].s_addr
),
356 vlocation
->vldb
.srvtmask
[1],
357 ntohl(vlocation
->vldb
.servers
[2].s_addr
),
358 vlocation
->vldb
.srvtmask
[2]
361 _debug("Vids: %08x %08x %08x",
362 vlocation
->vldb
.vid
[0],
363 vlocation
->vldb
.vid
[1],
364 vlocation
->vldb
.vid
[2]);
366 if (vlocation
->vldb
.vidmask
& AFS_VOL_VTM_RW
) {
367 vid
= vlocation
->vldb
.vid
[0];
368 voltype
= AFSVL_RWVOL
;
370 else if (vlocation
->vldb
.vidmask
& AFS_VOL_VTM_RO
) {
371 vid
= vlocation
->vldb
.vid
[1];
372 voltype
= AFSVL_ROVOL
;
374 else if (vlocation
->vldb
.vidmask
& AFS_VOL_VTM_BAK
) {
375 vid
= vlocation
->vldb
.vid
[2];
376 voltype
= AFSVL_BACKVOL
;
384 ret
= afs_vlocation_access_vl_by_id(vlocation
, vid
, voltype
, &vldb
);
388 printk("kAFS: failed to volume '%*.*s' (%x) up in '%s': %d\n",
389 namesz
, namesz
, name
, vid
, cell
->name
, ret
);
392 /* pulled from local cache into memory */
394 goto found_on_vlserver
;
396 /* uh oh... looks like the volume got deleted */
398 printk("kAFS: volume '%*.*s' (%x) does not exist '%s'\n",
399 namesz
, namesz
, name
, vid
, cell
->name
);
401 /* TODO: make existing record unavailable */
406 _debug("Done VL Lookup: %*.*s %02x { %08x(%x) %08x(%x) %08x(%x) }",
407 namesz
, namesz
, name
,
409 ntohl(vldb
.servers
[0].s_addr
), vldb
.srvtmask
[0],
410 ntohl(vldb
.servers
[1].s_addr
), vldb
.srvtmask
[1],
411 ntohl(vldb
.servers
[2].s_addr
), vldb
.srvtmask
[2]
414 _debug("Vids: %08x %08x %08x", vldb
.vid
[0], vldb
.vid
[1], vldb
.vid
[2]);
416 if ((namesz
< sizeof(vlocation
->vldb
.name
) &&
417 vlocation
->vldb
.name
[namesz
] != '\0') ||
418 memcmp(vldb
.name
, name
, namesz
) != 0)
419 printk("kAFS: name of volume '%*.*s' changed to '%s' on server\n",
420 namesz
, namesz
, name
, vldb
.name
);
422 memcpy(&vlocation
->vldb
, &vldb
, sizeof(vlocation
->vldb
));
424 afs_kafstimod_add_timer(&vlocation
->upd_timer
, 10 * HZ
);
426 #ifdef AFS_CACHING_SUPPORT
427 /* update volume entry in local cache */
428 cachefs_update_cookie(vlocation
->cache
);
431 *_vlocation
= vlocation
;
432 _leave(" = 0 (%p)",vlocation
);
438 __afs_put_vlocation(vlocation
);
441 list_del(&vlocation
->link
);
442 #ifdef AFS_CACHING_SUPPORT
443 cachefs_relinquish_cookie(vlocation
->cache
, 0);
445 afs_put_cell(vlocation
->cell
);
450 _leave(" = %d", ret
);
452 } /* end afs_vlocation_lookup() */
454 /*****************************************************************************/
456 * finish using a volume location record
457 * - caller must have cell->vol_sem write-locked
459 static void __afs_put_vlocation(struct afs_vlocation
*vlocation
)
461 struct afs_cell
*cell
;
466 _enter("%s", vlocation
->vldb
.name
);
468 cell
= vlocation
->cell
;
471 BUG_ON(atomic_read(&vlocation
->usage
) <= 0);
473 spin_lock(&cell
->vl_gylock
);
474 if (likely(!atomic_dec_and_test(&vlocation
->usage
))) {
475 spin_unlock(&cell
->vl_gylock
);
480 /* move to graveyard queue */
481 list_del(&vlocation
->link
);
482 list_add_tail(&vlocation
->link
,&cell
->vl_graveyard
);
484 /* remove from pending timeout queue (refcounted if actually being
486 list_del_init(&vlocation
->upd_op
.link
);
488 /* time out in 10 secs */
489 afs_kafstimod_del_timer(&vlocation
->upd_timer
);
490 afs_kafstimod_add_timer(&vlocation
->timeout
, 10 * HZ
);
492 spin_unlock(&cell
->vl_gylock
);
495 } /* end __afs_put_vlocation() */
497 /*****************************************************************************/
499 * finish using a volume location record
501 void afs_put_vlocation(struct afs_vlocation
*vlocation
)
504 struct afs_cell
*cell
= vlocation
->cell
;
506 down_write(&cell
->vl_sem
);
507 __afs_put_vlocation(vlocation
);
508 up_write(&cell
->vl_sem
);
510 } /* end afs_put_vlocation() */
512 /*****************************************************************************/
514 * timeout vlocation record
515 * - removes from the cell's graveyard if the usage count is zero
517 void afs_vlocation_do_timeout(struct afs_vlocation
*vlocation
)
519 struct afs_cell
*cell
;
521 _enter("%s", vlocation
->vldb
.name
);
523 cell
= vlocation
->cell
;
525 BUG_ON(atomic_read(&vlocation
->usage
) < 0);
527 /* remove from graveyard if still dead */
528 spin_lock(&cell
->vl_gylock
);
529 if (atomic_read(&vlocation
->usage
) == 0)
530 list_del_init(&vlocation
->link
);
533 spin_unlock(&cell
->vl_gylock
);
537 return; /* resurrected */
540 /* we can now destroy it properly */
541 #ifdef AFS_CACHING_SUPPORT
542 cachefs_relinquish_cookie(vlocation
->cache
, 0);
548 _leave(" [destroyed]");
549 } /* end afs_vlocation_do_timeout() */
551 /*****************************************************************************/
553 * send an update operation to the currently selected server
555 static int afs_vlocation_update_begin(struct afs_vlocation
*vlocation
)
557 afs_voltype_t voltype
;
561 _enter("%s{ufs=%u ucs=%u}",
562 vlocation
->vldb
.name
,
563 vlocation
->upd_first_svix
,
564 vlocation
->upd_curr_svix
);
566 /* try to look up a cached volume in the cell VL databases by ID */
567 if (vlocation
->vldb
.vidmask
& AFS_VOL_VTM_RW
) {
568 vid
= vlocation
->vldb
.vid
[0];
569 voltype
= AFSVL_RWVOL
;
571 else if (vlocation
->vldb
.vidmask
& AFS_VOL_VTM_RO
) {
572 vid
= vlocation
->vldb
.vid
[1];
573 voltype
= AFSVL_ROVOL
;
575 else if (vlocation
->vldb
.vidmask
& AFS_VOL_VTM_BAK
) {
576 vid
= vlocation
->vldb
.vid
[2];
577 voltype
= AFSVL_BACKVOL
;
585 /* contact the chosen server */
586 ret
= afs_server_lookup(
588 &vlocation
->cell
->vl_addrs
[vlocation
->upd_curr_svix
],
589 &vlocation
->upd_op
.server
);
597 _leave(" = %d", ret
);
601 /* initiate the update operation */
602 ret
= afs_rxvl_get_entry_by_id_async(&vlocation
->upd_op
, vid
, voltype
);
604 _leave(" = %d", ret
);
608 _leave(" = %d", ret
);
610 } /* end afs_vlocation_update_begin() */
612 /*****************************************************************************/
614 * abandon updating a VL record
615 * - does not restart the update timer
617 static void afs_vlocation_update_abandon(struct afs_vlocation
*vlocation
,
618 afs_vlocation_upd_t state
,
621 _enter("%s,%u", vlocation
->vldb
.name
, state
);
624 printk("kAFS: Abandoning VL update '%s': %d\n",
625 vlocation
->vldb
.name
, ret
);
627 /* discard the server record */
628 afs_put_server(vlocation
->upd_op
.server
);
629 vlocation
->upd_op
.server
= NULL
;
631 spin_lock(&afs_vlocation_update_lock
);
632 afs_vlocation_update
= NULL
;
633 vlocation
->upd_state
= state
;
635 /* TODO: start updating next VL record on pending list */
637 spin_unlock(&afs_vlocation_update_lock
);
640 } /* end afs_vlocation_update_abandon() */
642 /*****************************************************************************/
644 * handle periodic update timeouts and busy retry timeouts
645 * - called from kafstimod
647 static void afs_vlocation_update_timer(struct afs_timer
*timer
)
649 struct afs_vlocation
*vlocation
=
650 list_entry(timer
, struct afs_vlocation
, upd_timer
);
653 _enter("%s", vlocation
->vldb
.name
);
655 /* only update if not in the graveyard (defend against putting too) */
656 spin_lock(&vlocation
->cell
->vl_gylock
);
658 if (!atomic_read(&vlocation
->usage
))
661 spin_lock(&afs_vlocation_update_lock
);
663 /* if we were woken up due to EBUSY sleep then restart immediately if
664 * possible or else jump to front of pending queue */
665 if (vlocation
->upd_state
== AFS_VLUPD_BUSYSLEEP
) {
666 if (afs_vlocation_update
) {
667 list_add(&vlocation
->upd_op
.link
,
668 &afs_vlocation_update_pendq
);
671 afs_get_vlocation(vlocation
);
672 afs_vlocation_update
= vlocation
;
673 vlocation
->upd_state
= AFS_VLUPD_INPROGRESS
;
678 /* put on pending queue if there's already another update in progress */
679 if (afs_vlocation_update
) {
680 vlocation
->upd_state
= AFS_VLUPD_PENDING
;
681 list_add_tail(&vlocation
->upd_op
.link
,
682 &afs_vlocation_update_pendq
);
686 /* hold a ref on it while actually updating */
687 afs_get_vlocation(vlocation
);
688 afs_vlocation_update
= vlocation
;
689 vlocation
->upd_state
= AFS_VLUPD_INPROGRESS
;
691 spin_unlock(&afs_vlocation_update_lock
);
692 spin_unlock(&vlocation
->cell
->vl_gylock
);
694 /* okay... we can start the update */
695 _debug("BEGIN VL UPDATE [%s]", vlocation
->vldb
.name
);
696 vlocation
->upd_first_svix
= vlocation
->cell
->vl_curr_svix
;
697 vlocation
->upd_curr_svix
= vlocation
->upd_first_svix
;
698 vlocation
->upd_rej_cnt
= 0;
699 vlocation
->upd_busy_cnt
= 0;
701 ret
= afs_vlocation_update_begin(vlocation
);
703 afs_vlocation_update_abandon(vlocation
, AFS_VLUPD_SLEEP
, ret
);
704 afs_kafstimod_add_timer(&vlocation
->upd_timer
,
706 afs_put_vlocation(vlocation
);
713 spin_unlock(&afs_vlocation_update_lock
);
715 spin_unlock(&vlocation
->cell
->vl_gylock
);
719 } /* end afs_vlocation_update_timer() */
721 /*****************************************************************************/
723 * attend to an update operation upon which an event happened
724 * - called in kafsasyncd context
726 static void afs_vlocation_update_attend(struct afs_async_op
*op
)
728 struct afs_cache_vlocation vldb
;
729 struct afs_vlocation
*vlocation
=
730 list_entry(op
, struct afs_vlocation
, upd_op
);
734 _enter("%s", vlocation
->vldb
.name
);
736 ret
= afs_rxvl_get_entry_by_id_async2(op
, &vldb
);
739 _leave(" [unfinished]");
743 _debug("END VL UPDATE: %d\n", ret
);
744 vlocation
->valid
= 1;
746 _debug("Done VL Lookup: %02x { %08x(%x) %08x(%x) %08x(%x) }",
748 ntohl(vldb
.servers
[0].s_addr
), vldb
.srvtmask
[0],
749 ntohl(vldb
.servers
[1].s_addr
), vldb
.srvtmask
[1],
750 ntohl(vldb
.servers
[2].s_addr
), vldb
.srvtmask
[2]
753 _debug("Vids: %08x %08x %08x",
754 vldb
.vid
[0], vldb
.vid
[1], vldb
.vid
[2]);
756 afs_vlocation_update_abandon(vlocation
, AFS_VLUPD_SLEEP
, 0);
758 down_write(&vlocation
->cell
->vl_sem
);
760 /* actually update the cache */
761 if (strncmp(vldb
.name
, vlocation
->vldb
.name
,
762 sizeof(vlocation
->vldb
.name
)) != 0)
763 printk("kAFS: name of volume '%s'"
764 " changed to '%s' on server\n",
765 vlocation
->vldb
.name
, vldb
.name
);
767 memcpy(&vlocation
->vldb
, &vldb
, sizeof(vlocation
->vldb
));
770 /* TODO update volume entry in local cache */
773 up_write(&vlocation
->cell
->vl_sem
);
776 printk("kAFS: failed to update local cache: %d\n", ret
);
778 afs_kafstimod_add_timer(&vlocation
->upd_timer
,
780 afs_put_vlocation(vlocation
);
785 vlocation
->upd_rej_cnt
++;
788 /* the server is locked - retry in a very short while */
790 vlocation
->upd_busy_cnt
++;
791 if (vlocation
->upd_busy_cnt
> 3)
792 goto try_next
; /* too many retries */
794 afs_vlocation_update_abandon(vlocation
,
795 AFS_VLUPD_BUSYSLEEP
, 0);
796 afs_kafstimod_add_timer(&vlocation
->upd_timer
, HZ
/ 2);
797 afs_put_vlocation(vlocation
);
805 /* record bad vlserver info in the cell too
806 * - TODO: use down_write_trylock() if available
808 if (vlocation
->upd_curr_svix
== vlocation
->cell
->vl_curr_svix
)
809 vlocation
->cell
->vl_curr_svix
=
810 vlocation
->cell
->vl_curr_svix
%
811 vlocation
->cell
->vl_naddrs
;
823 /* try contacting the next server */
825 vlocation
->upd_busy_cnt
= 0;
827 /* discard the server record */
828 afs_put_server(vlocation
->upd_op
.server
);
829 vlocation
->upd_op
.server
= NULL
;
831 tmp
= vlocation
->cell
->vl_naddrs
;
835 vlocation
->upd_curr_svix
++;
836 if (vlocation
->upd_curr_svix
>= tmp
)
837 vlocation
->upd_curr_svix
= 0;
838 if (vlocation
->upd_first_svix
>= tmp
)
839 vlocation
->upd_first_svix
= tmp
- 1;
841 /* move to the next server */
842 if (vlocation
->upd_curr_svix
!= vlocation
->upd_first_svix
) {
843 afs_vlocation_update_begin(vlocation
);
848 /* run out of servers to try - was the volume rejected? */
849 if (vlocation
->upd_rej_cnt
> 0) {
850 printk("kAFS: Active volume no longer valid '%s'\n",
851 vlocation
->vldb
.name
);
852 vlocation
->valid
= 0;
853 afs_vlocation_update_abandon(vlocation
, AFS_VLUPD_SLEEP
, 0);
854 afs_kafstimod_add_timer(&vlocation
->upd_timer
,
856 afs_put_vlocation(vlocation
);
857 _leave(" [invalidated]");
861 /* abandon the update */
863 afs_vlocation_update_abandon(vlocation
, AFS_VLUPD_SLEEP
, ret
);
864 afs_kafstimod_add_timer(&vlocation
->upd_timer
, HZ
* 10);
865 afs_put_vlocation(vlocation
);
866 _leave(" [abandoned]");
868 } /* end afs_vlocation_update_attend() */
870 /*****************************************************************************/
872 * deal with an update operation being discarded
873 * - called in kafsasyncd context when it's dying due to rmmod
874 * - the call has already been aborted and put()'d
876 static void afs_vlocation_update_discard(struct afs_async_op
*op
)
878 struct afs_vlocation
*vlocation
=
879 list_entry(op
, struct afs_vlocation
, upd_op
);
881 _enter("%s", vlocation
->vldb
.name
);
883 afs_put_server(op
->server
);
886 afs_put_vlocation(vlocation
);
889 } /* end afs_vlocation_update_discard() */
891 /*****************************************************************************/
893 * match a VLDB record stored in the cache
894 * - may also load target from entry
896 #ifdef AFS_CACHING_SUPPORT
897 static cachefs_match_val_t
afs_vlocation_cache_match(void *target
,
900 const struct afs_cache_vlocation
*vldb
= entry
;
901 struct afs_vlocation
*vlocation
= target
;
903 _enter("{%s},{%s}", vlocation
->vldb
.name
, vldb
->name
);
905 if (strncmp(vlocation
->vldb
.name
, vldb
->name
, sizeof(vldb
->name
)) == 0
907 if (!vlocation
->valid
||
908 vlocation
->vldb
.rtime
== vldb
->rtime
910 vlocation
->vldb
= *vldb
;
911 vlocation
->valid
= 1;
912 _leave(" = SUCCESS [c->m]");
913 return CACHEFS_MATCH_SUCCESS
;
915 /* need to update cache if cached info differs */
916 else if (memcmp(&vlocation
->vldb
, vldb
, sizeof(*vldb
)) != 0) {
917 /* delete if VIDs for this name differ */
918 if (memcmp(&vlocation
->vldb
.vid
,
920 sizeof(vldb
->vid
)) != 0) {
922 return CACHEFS_MATCH_SUCCESS_DELETE
;
926 return CACHEFS_MATCH_SUCCESS_UPDATE
;
929 _leave(" = SUCCESS");
930 return CACHEFS_MATCH_SUCCESS
;
935 return CACHEFS_MATCH_FAILED
;
936 } /* end afs_vlocation_cache_match() */
939 /*****************************************************************************/
941 * update a VLDB record stored in the cache
943 #ifdef AFS_CACHING_SUPPORT
944 static void afs_vlocation_cache_update(void *source
, void *entry
)
946 struct afs_cache_vlocation
*vldb
= entry
;
947 struct afs_vlocation
*vlocation
= source
;
951 *vldb
= vlocation
->vldb
;
953 } /* end afs_vlocation_cache_update() */