summaryrefslogtreecommitdiffstats
path: root/fs/afs/volume.h
blob: bfdcf19ba3f387080523c6e78027197058808c58 (plain)
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* volume.h: 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 _LINUX_AFS_VOLUME_H
#define _LINUX_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 *cell,
				const char *name,
				unsigned namesz,
				struct afs_vlocation **_vlocation);

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

extern void afs_put_vlocation(struct afs_vlocation *vlocation);
extern void afs_vlocation_do_timeout(struct afs_vlocation *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 *name,
			     struct afs_cell *cell,
			     int rwpath,
			     struct afs_volume **_volume);

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

extern void afs_put_volume(struct afs_volume *volume);

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

extern int afs_volume_release_fileserver(struct afs_volume *volume,
					 struct afs_server *server,
					 int result);

#endif /* _LINUX_AFS_VOLUME_H */