2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
9 * Portions Copyright (c) 2007-2008 Sine Nomine Associates
15 Institution: The Information Technology Center, Carnegie-Mellon University
19 #ifndef _AFS_VOL_VNODE_H
20 #define _AFS_VOL_VNODE_H 1
22 #define Date afs_uint32
24 struct Volume
; /* Potentially forward definition. */
26 typedef struct ViceLock
{
31 #define ViceLockCheckLocked(vptr) ((vptr)->lockTime == 0)
32 #define ViceLockClear(vptr) ((vptr)->lockCount = (vptr)->lockTime = 0)
36 /*typedef enum {vNull=0, vFile=1, vDirectory=2, vSymlink=3} VnodeType;*/
37 typedef unsigned int VnodeType
;
43 /*typedef enum {vLarge=0,vSmall=1} VnodeClass;*/
46 typedef int VnodeClass
;
47 #define VNODECLASSWIDTH 1
48 #define VNODECLASSMASK ((1<<VNODECLASSWIDTH)-1)
49 #define nVNODECLASSES (VNODECLASSMASK+1)
51 struct VnodeClassInfo
{
52 struct Vnode
*lruHead
; /* Head of list of vnodes of this class */
53 int diskSize
; /* size of vnode disk object, power of 2 */
54 int logSize
; /* log 2 diskSize */
55 int residentSize
; /* resident size of vnode */
56 int cacheSize
; /* Vnode cache size */
57 bit32 magic
; /* Magic number for this type of vnode,
58 * for as long as we're using vnode magic
60 int allocs
; /* Total number of successful allocation
61 * requests; this is the same as the number
62 * of sanity checks on the vnode index */
63 int gets
, reads
; /* Number of VGetVnodes and corresponding
65 int writes
; /* Number of vnode writes */
68 extern struct VnodeClassInfo VnodeClassInfo
[nVNODECLASSES
];
70 #define vnodeTypeToClass(type) ((type) == vDirectory? vLarge: vSmall)
71 #define vnodeIdToClass(vnodeId) ((vnodeId-1)&VNODECLASSMASK)
72 #define vnodeIdToBitNumber(v) (((v)-1)>>VNODECLASSWIDTH)
73 /* The following calculation allows for a header record at the beginning
74 of the index. The header record is the same size as a vnode */
75 #define vnodeIndexOffset(vcp,vnodeNumber) \
76 ((vnodeIdToBitNumber(vnodeNumber)+1)<<(vcp)->logSize)
77 #define bitNumberToVnodeNumber(b,class) ((VnodeId)(((b)<<VNODECLASSWIDTH)+(class)+1))
78 #define vnodeIsDirectory(vnodeNumber) (vnodeIdToClass(vnodeNumber) == vLarge)
80 typedef struct VnodeDiskObject
{
81 unsigned int type
:3; /* Vnode is file, directory, symbolic link
83 unsigned int cloned
:1; /* This vnode was cloned--therefore the inode
84 * is copy-on-write; only set for directories */
85 unsigned int modeBits
:12; /* Unix mode bits */
86 signed int linkCount
:16; /* Number of directory references to vnode
87 * (from single directory only!) */
88 bit32 length
; /* Number of bytes in this file */
89 Unique uniquifier
; /* Uniquifier for the vnode; assigned
90 * from the volume uniquifier (actually
91 * from nextVnodeUnique in the Volume
93 FileVersion dataVersion
; /* version number of the data */
94 afs_int32 vn_ino_lo
; /* inode number of the data attached to
95 * this vnode - entire ino for standard */
96 Date unixModifyTime
; /* set by user */
97 UserId author
; /* Userid of the last user storing the file */
98 UserId owner
; /* Userid of the user who created the file */
99 VnodeId parent
; /* Parent directory vnode */
100 bit32 vnodeMagic
; /* Magic number--mainly for file server
102 # define SMALLVNODEMAGIC 0xda8c041F
103 # define LARGEVNODEMAGIC 0xad8765fe
104 /* Vnode magic can be removed, someday, if we run need the room. Simply
105 * have to be sure that the thing we replace can be VNODEMAGIC, rather
106 * than 0 (in an old file system). Or go through and zero the fields,
107 * when we notice a version change (the index version number) */
108 ViceLock lock
; /* Advisory lock */
109 Date serverModifyTime
; /* Used only by the server; for incremental
111 afs_int32 group
; /* unix group */
112 afs_int32 vn_ino_hi
; /* high part of 64 bit inode. */
113 bit32 vn_length_hi
; /* high part of 64 bit length */
115 * archiving/migration
120 #define SIZEOF_SMALLDISKVNODE 64
121 #define CHECKSIZE_SMALLVNODE\
122 (sizeof(VnodeDiskObject) == SIZEOF_SMALLDISKVNODE)
123 #define SIZEOF_LARGEDISKVNODE 256
127 #ifdef AFS_DEMAND_ATTACH_FS
129 * demand attach vnode state enumeration.
131 * @note values must be contiguous for VnIsValidState() to work
134 VN_STATE_INVALID
= 0, /**< vnode does not contain valid cache data */
135 VN_STATE_RELEASING
= 1, /**< vnode is busy releasing its ihandle ref */
136 VN_STATE_CLOSING
= 2, /**< vnode is busy closing its ihandle ref */
137 VN_STATE_ALLOC
= 3, /**< vnode is busy allocating disk entry */
138 VN_STATE_ONLINE
= 4, /**< vnode is ready for use */
139 VN_STATE_LOAD
= 5, /**< vnode is busy being loaded from disk */
140 VN_STATE_EXCLUSIVE
= 6, /**< something external to the vnode package
141 * is operating exclusively on this vnode */
142 VN_STATE_STORE
= 7, /**< vnode is busy being stored to disk */
143 VN_STATE_READ
= 8, /**< a non-zero number of threads are executing
144 * code external to the vnode package which
145 * requires shared access */
146 VN_STATE_ERROR
= 10, /**< vnode hard error state */
149 #endif /* AFS_DEMAND_ATTACH_FS */
152 * DAFS vnode state flags.
155 VN_ON_HASH
= 0x1, /**< vnode is on hash table */
156 VN_ON_LRU
= 0x2, /**< vnode is on lru list */
157 VN_ON_VVN
= 0x4, /**< vnode is on volume vnode list */
162 typedef struct Vnode
{
163 struct rx_queue vid_hash
; /* for vnode by volume id hash */
164 struct Vnode
*hashNext
; /* Next vnode on hash conflict chain */
165 struct Vnode
*lruNext
; /* Less recently used vnode than this one */
166 struct Vnode
*lruPrev
; /* More recently used vnode than this one */
167 /* The lruNext, lruPrev fields are not
168 * meaningful if the vnode is in use */
169 bit16 hashIndex
; /* Hash table index */
171 unsigned changed_newTime
:1; /* 1 if vnode changed, write time */
172 unsigned changed_oldTime
:1; /* 1 changed, don't update time. */
173 unsigned delete:1; /* 1 if the vnode should be deleted; in
174 * this case, changed must also be 1 */
176 byte changed_newTime
:1; /* 1 if vnode changed, write time */
177 byte changed_oldTime
:1; /* 1 changed, don't update time. */
178 byte
delete:1; /* 1 if the vnode should be deleted; in
179 * this case, changed must also be 1 */
183 *volumePtr
; /* Pointer to the volume containing this file */
184 bit32 nUsers
; /* Number of lwp's who have done a VGetVnode */
185 bit32 cacheCheck
; /* Must equal the value in the volume Header
186 * for the cache entry to be valid */
187 bit32 vn_state_flags
; /**< vnode state flags */
188 #ifdef AFS_DEMAND_ATTACH_FS
189 bit32 nReaders
; /**< number of read locks held */
190 VnState vn_state
; /**< vnode state */
191 pthread_cond_t vn_state_cv
; /**< state change notification cv */
192 #else /* !AFS_DEMAND_ATTACH_FS */
193 struct Lock lock
; /* Internal lock */
194 #endif /* !AFS_DEMAND_ATTACH_FS */
195 #ifdef AFS_PTHREAD_ENV
196 pthread_t writer
; /* thread holding write lock */
197 #else /* AFS_PTHREAD_ENV */
198 PROCESS writer
; /* Process id having write lock */
199 #endif /* AFS_PTHREAD_ENV */
200 struct VnodeClassInfo
* vcp
; /**< our vnode class */
202 VnodeDiskObject disk
; /* The actual disk data for the vnode */
205 #define SIZEOF_LARGEVNODE \
206 (sizeof(struct Vnode) - sizeof(VnodeDiskObject) + SIZEOF_LARGEDISKVNODE)
207 #define SIZEOF_SMALLVNODE (sizeof (struct Vnode))
211 * struct Vnode accessor abstraction
213 #define Vn_refcount(vnp) ((vnp)->nUsers)
214 #define Vn_state(vnp) ((vnp)->vn_state)
215 #define Vn_stateFlags(vnp) ((vnp)->vn_state_flags)
216 #define Vn_stateCV(vnp) ((vnp)->vn_state_cv)
217 #define Vn_volume(vnp) ((vnp)->volumePtr)
218 #define Vn_cacheCheck(vnp) ((vnp)->cacheCheck)
219 #define Vn_class(vnp) ((vnp)->vcp)
220 #define Vn_readers(vnp) ((vnp)->nReaders)
221 #define Vn_id(vnp) ((vnp)->vnodeNumber)
224 #define VN_GET_LEN(N, V) FillInt64(N, (V)->disk.vn_length_hi, (V)->disk.length)
225 #define VNDISK_GET_LEN(N, V) FillInt64(N, (V)->vn_length_hi, (V)->length)
226 #define VN_SET_LEN(V, N) SplitInt64(N, (V)->disk.vn_length_hi, (V)->disk.length)
227 #define VNDISK_SET_LEN(V, N) SplitInt64(N, (V)->vn_length_hi, (V)->length)
229 #ifdef AFS_64BIT_IOPS_ENV
230 #define VN_GET_INO(V) ((Inode)((V)->disk.vn_ino_lo | \
231 ((V)->disk.vn_ino_hi ? \
232 (((Inode)(V)->disk.vn_ino_hi)<<32) : 0)))
234 #define VN_SET_INO(V, I) ((V)->disk.vn_ino_lo = (int)((I)&0xffffffff), \
235 ((V)->disk.vn_ino_hi = (I) ? \
236 (int)(((I)>>32)&0xffffffff) : 0))
238 #define VNDISK_GET_INO(V) ((Inode)((V)->vn_ino_lo | \
240 (((Inode)(V)->vn_ino_hi)<<32) : 0)))
242 #define VNDISK_SET_INO(V, I) ((V)->vn_ino_lo = (int)(I&0xffffffff), \
243 ((V)->vn_ino_hi = (I) ? \
244 (int)(((I)>>32)&0xffffffff) : 0))
246 #define VN_GET_INO(V) ((V)->disk.vn_ino_lo)
247 #define VN_SET_INO(V, I) ((V)->disk.vn_ino_lo = (I))
248 #define VNDISK_GET_INO(V) ((V)->vn_ino_lo)
249 #define VNDISK_SET_INO(V, I) ((V)->vn_ino_lo = (I))
252 #define VVnodeDiskACL(v) /* Only call this with large (dir) vnode!! */ \
253 ((AL_AccessList *) (((byte *)(v))+SIZEOF_SMALLDISKVNODE))
254 #define VVnodeACL(vnp) (VVnodeDiskACL(&(vnp)->disk))
255 /* VAclSize is defined this way to allow information in the vnode header
256 to grow, in a POSSIBLY upward compatible manner. SIZEOF_SMALLDISKVNODE
257 is the maximum size of the basic vnode. The vnode header of either type
258 can actually grow to this size without conflicting with the ACL on larger
260 #define VAclSize(vnp) (SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE)
261 #define VAclDiskSize(v) (SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE)
262 /*extern int VolumeHashOffset(); */
263 extern int VolumeHashOffset_r(void);
264 extern int VInitVnodes(VnodeClass
class, int nVnodes
);
265 /*extern VInitVnodes_r();*/
266 extern Vnode
*VGetVnode(Error
* ec
, struct Volume
*vp
, VnodeId vnodeNumber
,
268 extern Vnode
*VGetVnode_r(Error
* ec
, struct Volume
*vp
, VnodeId vnodeNumber
,
270 extern void VPutVnode(Error
* ec
, Vnode
* vnp
);
271 extern void VPutVnode_r(Error
* ec
, Vnode
* vnp
);
272 extern int VVnodeWriteToRead(Error
* ec
, Vnode
* vnp
);
273 extern int VVnodeWriteToRead_r(Error
* ec
, Vnode
* vnp
);
274 extern Vnode
*VAllocVnode(Error
* ec
, struct Volume
*vp
, VnodeType type
);
275 extern Vnode
*VAllocVnode_r(Error
* ec
, struct Volume
*vp
, VnodeType type
);
276 /*extern VFreeVnode();*/
277 extern Vnode
*VGetFreeVnode_r(struct VnodeClassInfo
*vcp
, struct Volume
*vp
,
278 VnodeId vnodeNumber
);
279 extern Vnode
*VLookupVnode(struct Volume
* vp
, VnodeId vnodeId
);
281 extern void AddToVVnList(struct Volume
* vp
, Vnode
* vnp
);
282 extern void DeleteFromVVnList(Vnode
* vnp
);
283 extern void AddToVnLRU(struct VnodeClassInfo
* vcp
, Vnode
* vnp
);
284 extern void DeleteFromVnLRU(struct VnodeClassInfo
* vcp
, Vnode
* vnp
);
285 extern void AddToVnHash(Vnode
* vnp
);
286 extern void DeleteFromVnHash(Vnode
* vnp
);
288 #endif /* _AFS_VOL_VNODE_H */