summaryrefslogtreecommitdiff
path: root/fs/afs/volume.h
blob: a605bea2e3a0ef69b70ce2d03c3b02a177214978 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* AFS volume management
 *
 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#ifndef AFS_VOLUME_H
#define AFS_VOLUME_H

#include "types.h"
#include "fsclient.h"
#include "kafstimod.h"
#include "kafsasyncd.h"
#include "cache.h"

typedef enum {
	AFS_VLUPD_SLEEP,		/* sleeping waiting for update timer to fire */
	AFS_VLUPD_PENDING,		/* on pending queue */
	AFS_VLUPD_INPROGRESS,		/* op in progress */
	AFS_VLUPD_BUSYSLEEP,		/* sleeping because server returned EBUSY */
} __attribute__((packed)) afs_vlocation_upd_t;

/*
 * entry in the cached volume location catalogue
 */
struct afs_cache_vlocation {
	uint8_t			name[64];	/* volume name (lowercase, padded with NULs) */
	uint8_t			nservers;	/* number of entries used in servers[] */
	uint8_t			vidmask;	/* voltype mask for vid[] */
	uint8_t			srvtmask[8];	/* voltype masks for servers[] */
#define AFS_VOL_VTM_RW	0x01 /* R/W version of the volume is available (on this server) */
#define AFS_VOL_VTM_RO	0x02 /* R/O version of the volume is available (on this server) */
#define AFS_VOL_VTM_BAK	0x04 /* backup version of the volume is available (on this server) */

	afs_volid_t		vid[3];		/* volume IDs for R/W, R/O and Bak volumes */
	struct in_addr		servers[8];	/* fileserver addresses */
	time_t			rtime;		/* last retrieval time */
};

#ifdef AFS_CACHING_SUPPORT
extern struct cachefs_index_def afs_vlocation_cache_index_def;
#endif

/*
 * volume -> vnode hash table entry
 */
struct afs_cache_vhash {
	afs_voltype_t		vtype;		/* which volume variation */
	uint8_t			hash_bucket;	/* which hash bucket this represents */
} __attribute__((packed));

#ifdef AFS_CACHING_SUPPORT
extern struct cachefs_index_def afs_volume_cache_index_def;
#endif

/*
 * AFS volume location record
 */
struct afs_vlocation {
	atomic_t		usage;
	struct list_head	link;		/* link in cell volume location list */
	struct afs_timer	timeout;	/* decaching timer */
	struct afs_cell		*cell;		/* cell to which volume belongs */
#ifdef AFS_CACHING_SUPPORT
	struct cachefs_cookie	*cache;		/* caching cookie */
#endif
	struct afs_cache_vlocation vldb;	/* volume information DB record */
	struct afs_volume	*vols[3];	/* volume access record pointer (index by type) */
	rwlock_t		lock;		/* access lock */
	unsigned long		read_jif;	/* time at which last read from vlserver */
	struct afs_timer	upd_timer;	/* update timer */
	struct afs_async_op	upd_op;		/* update operation */
	afs_vlocation_upd_t	upd_state;	/* update state */
	unsigned short		upd_first_svix;	/* first server index during update */
	unsigned short		upd_curr_svix;	/* current server index during update */
	unsigned short		upd_rej_cnt;	/* ENOMEDIUM count during update */
	unsigned short		upd_busy_cnt;	/* EBUSY count during update */
	unsigned short		valid;		/* T if valid */
};

extern int afs_vlocation_lookup(struct afs_cell *, const char *, unsigned,
				struct afs_vlocation **);

#define afs_get_vlocation(V) do { atomic_inc(&(V)->usage); } while(0)

extern void afs_put_vlocation(struct afs_vlocation *);
extern void afs_vlocation_do_timeout(struct afs_vlocation *);

/*
 * AFS volume access record
 */
struct afs_volume {
	atomic_t		usage;
	struct afs_cell		*cell;		/* cell to which belongs (unrefd ptr) */
	struct afs_vlocation	*vlocation;	/* volume location */
#ifdef AFS_CACHING_SUPPORT
	struct cachefs_cookie	*cache;		/* caching cookie */
#endif
	afs_volid_t		vid;		/* volume ID */
	afs_voltype_t		type;		/* type of volume */
	char			type_force;	/* force volume type (suppress R/O -> R/W) */
	unsigned short		nservers;	/* number of server slots filled */
	unsigned short		rjservers;	/* number of servers discarded due to -ENOMEDIUM */
	struct afs_server	*servers[8];	/* servers on which volume resides (ordered) */
	struct rw_semaphore	server_sem;	/* lock for accessing current server */
};

extern int afs_volume_lookup(const char *, struct afs_cell *, int,
			     struct afs_volume **);

#define afs_get_volume(V) do { atomic_inc(&(V)->usage); } while(0)

extern void afs_put_volume(struct afs_volume *);

extern int afs_volume_pick_fileserver(struct afs_volume *,
				      struct afs_server **);

extern int afs_volume_release_fileserver(struct afs_volume *,
					 struct afs_server *, int);

#endif /* AFS_VOLUME_H */