dafs-20060317
[openafs.git] / src / vol / vnode.h
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 /*
11         System:         VICE-TWO
12         Module:         vnode.h
13         Institution:    The Information Technology Center, Carnegie-Mellon University
14
15  */
16
17 #define Date afs_uint32
18
19 struct Volume;                  /* Potentially forward definition. */
20
21 typedef struct ViceLock {
22     int lockCount;
23     int lockTime;
24 } ViceLock;
25
26 #define ViceLockCheckLocked(vptr) ((vptr)->lockTime == 0)
27 #define ViceLockClear(vptr) ((vptr)->lockCount = (vptr)->lockTime = 0)
28
29 #define ROOTVNODE 1
30
31 /*typedef enum {vNull=0, vFile=1, vDirectory=2, vSymlink=3} VnodeType;*/
32 typedef unsigned int VnodeType;
33 #define vNull 0
34 #define vFile 1
35 #define vDirectory 2
36 #define vSymlink 3
37
38 /*typedef enum {vLarge=0,vSmall=1} VnodeClass;*/
39 #define vLarge  0
40 #define vSmall  1
41 typedef int VnodeClass;
42 #define VNODECLASSWIDTH 1
43 #define VNODECLASSMASK  ((1<<VNODECLASSWIDTH)-1)
44 #define nVNODECLASSES   (VNODECLASSMASK+1)
45
46 struct VnodeClassInfo {
47     struct Vnode *lruHead;      /* Head of list of vnodes of this class */
48     int diskSize;               /* size of vnode disk object, power of 2 */
49     int logSize;                /* log 2 diskSize */
50     int residentSize;           /* resident size of vnode */
51     int cacheSize;              /* Vnode cache size */
52     bit32 magic;                /* Magic number for this type of vnode,
53                                  * for as long as we're using vnode magic
54                                  * numbers */
55     int allocs;                 /* Total number of successful allocation
56                                  * requests; this is the same as the number
57                                  * of sanity checks on the vnode index */
58     int gets, reads;            /* Number of VGetVnodes and corresponding
59                                  * reads */
60     int writes;                 /* Number of vnode writes */
61 };
62
63 extern struct VnodeClassInfo VnodeClassInfo[nVNODECLASSES];
64
65 #define vnodeTypeToClass(type)  ((type) == vDirectory? vLarge: vSmall)
66 #define vnodeIdToClass(vnodeId) ((vnodeId-1)&VNODECLASSMASK)
67 #define vnodeIdToBitNumber(v) (((v)-1)>>VNODECLASSWIDTH)
68 /* The following calculation allows for a header record at the beginning
69    of the index.  The header record is the same size as a vnode */
70 #define vnodeIndexOffset(vcp,vnodeNumber) \
71     ((vnodeIdToBitNumber(vnodeNumber)+1)<<(vcp)->logSize)
72 #define bitNumberToVnodeNumber(b,class) ((VnodeId)(((b)<<VNODECLASSWIDTH)+(class)+1))
73 #define vnodeIsDirectory(vnodeNumber) (vnodeIdToClass(vnodeNumber) == vLarge)
74
75 typedef struct VnodeDiskObject {
76     unsigned int type:3;        /* Vnode is file, directory, symbolic link
77                                  * or not allocated */
78     unsigned int cloned:1;      /* This vnode was cloned--therefore the inode
79                                  * is copy-on-write; only set for directories */
80     unsigned int modeBits:12;   /* Unix mode bits */
81     signed int linkCount:16;    /* Number of directory references to vnode
82                                  * (from single directory only!) */
83     bit32 length;               /* Number of bytes in this file */
84     Unique uniquifier;          /* Uniquifier for the vnode; assigned
85                                  * from the volume uniquifier (actually
86                                  * from nextVnodeUnique in the Volume
87                                  * structure) */
88     FileVersion dataVersion;    /* version number of the data */
89     afs_int32 vn_ino_lo;        /* inode number of the data attached to
90                                  * this vnode - entire ino for standard */
91     Date unixModifyTime;        /* set by user */
92     UserId author;              /* Userid of the last user storing the file */
93     UserId owner;               /* Userid of the user who created the file */
94     VnodeId parent;             /* Parent directory vnode */
95     bit32 vnodeMagic;           /* Magic number--mainly for file server
96                                  * paranoia checks */
97 #   define        SMALLVNODEMAGIC       0xda8c041F
98 #   define        LARGEVNODEMAGIC       0xad8765fe
99     /* Vnode magic can be removed, someday, if we run need the room.  Simply
100      * have to be sure that the thing we replace can be VNODEMAGIC, rather
101      * than 0 (in an old file system).  Or go through and zero the fields,
102      * when we notice a version change (the index version number) */
103     ViceLock lock;              /* Advisory lock */
104     Date serverModifyTime;      /* Used only by the server; for incremental
105                                  * backup purposes */
106     afs_int32 group;            /* unix group */
107     afs_int32 vn_ino_hi;        /* high part of 64 bit inode. */
108     bit32 reserved6;
109     /* Missing:
110      * archiving/migration
111      * encryption key
112      */
113 } VnodeDiskObject;
114
115 #define SIZEOF_SMALLDISKVNODE   64
116 #define CHECKSIZE_SMALLVNODE\
117         (sizeof(VnodeDiskObject) == SIZEOF_SMALLDISKVNODE)
118 #define SIZEOF_LARGEDISKVNODE   256
119
120 typedef struct Vnode {
121     struct rx_queue vid_hash;   /* for vnode by volume id hash */
122     struct Vnode *hashNext;     /* Next vnode on hash conflict chain */
123     struct Vnode *lruNext;      /* Less recently used vnode than this one */
124     struct Vnode *lruPrev;      /* More recently used vnode than this one */
125     /* The lruNext, lruPrev fields are not
126      * meaningful if the vnode is in use */
127     bit16 hashIndex;            /* Hash table index */
128 #ifdef  AFS_AIX_ENV
129     unsigned changed_newTime:1; /* 1 if vnode changed, write time */
130     unsigned changed_oldTime:1; /* 1 changed, don't update time. */
131     unsigned delete:1;          /* 1 if the vnode should be deleted; in
132                                  * this case, changed must also be 1 */
133 #else
134     byte changed_newTime:1;     /* 1 if vnode changed, write time */
135     byte changed_oldTime:1;     /* 1 changed, don't update time. */
136     byte delete:1;              /* 1 if the vnode should be deleted; in
137                                  * this case, changed must also be 1 */
138 #endif
139     VnodeId vnodeNumber;
140     struct Volume
141      *volumePtr;                /* Pointer to the volume containing this file */
142     bit32 nUsers;               /* Number of lwp's who have done a VGetVnode */
143     bit32 cacheCheck;           /* Must equal the value in the volume Header
144                                  * for the cache entry to be valid */
145     struct Lock lock;           /* Internal lock */
146 #ifdef AFS_PTHREAD_ENV
147     pthread_t writer;           /* thread holding write lock */
148 #else                           /* AFS_PTHREAD_ENV */
149     PROCESS writer;             /* Process id having write lock */
150 #endif                          /* AFS_PTHREAD_ENV */
151     IHandle_t *handle;
152     VnodeDiskObject disk;       /* The actual disk data for the vnode */
153 } Vnode;
154
155 #define SIZEOF_LARGEVNODE \
156         (sizeof(struct Vnode) - sizeof(VnodeDiskObject) + SIZEOF_LARGEDISKVNODE)
157 #define SIZEOF_SMALLVNODE       (sizeof (struct Vnode))
158
159 #ifdef AFS_LARGEFILE_ENV
160 #define VN_GET_LEN(N, V) FillInt64(N, (V)->disk.reserved6, (V)->disk.length)
161 #define VNDISK_GET_LEN(N, V) FillInt64(N, (V)->reserved6, (V)->length)
162 #define VN_SET_LEN(V, N) SplitInt64(N, (V)->disk.reserved6, (V)->disk.length)
163 #define VNDISK_SET_LEN(V, N) SplitInt64(N, (V)->reserved6, (V)->length)
164 #else /* !AFS_LARGEFILE_ENV */
165 #define VN_GET_LEN(N, V) (N) = (V)->disk.length;
166 #define VNDISK_GET_LEN(N, V) (N) = (V)->length;
167 #define VN_SET_LEN(V, N) (V)->disk.length = (N);
168 #define VNDISK_SET_LEN(V, N) (V)->length = (N);
169 #endif /* !AFS_LARGEFILE_ENV */
170
171 #ifdef AFS_64BIT_IOPS_ENV
172 #define VN_GET_INO(V) ((Inode)((V)->disk.vn_ino_lo | \
173                                ((V)->disk.vn_ino_hi ? \
174                                 (((Inode)(V)->disk.vn_ino_hi)<<32) : 0)))
175
176 #define VN_SET_INO(V, I) ((V)->disk.vn_ino_lo = (int)((I)&0xffffffff), \
177                            ((V)->disk.vn_ino_hi = (I) ? \
178                             (int)(((I)>>32)&0xffffffff) : 0))
179
180 #define VNDISK_GET_INO(V) ((Inode)((V)->vn_ino_lo | \
181                                    ((V)->vn_ino_hi ? \
182                                     (((Inode)(V)->vn_ino_hi)<<32) : 0)))
183
184 #define VNDISK_SET_INO(V, I) ((V)->vn_ino_lo = (int)(I&0xffffffff), \
185                               ((V)->vn_ino_hi = (I) ? \
186                                (int)(((I)>>32)&0xffffffff) : 0))
187 #else
188 #define VN_GET_INO(V) ((V)->disk.vn_ino_lo)
189 #define VN_SET_INO(V, I) ((V)->disk.vn_ino_lo = (I))
190 #define VNDISK_GET_INO(V) ((V)->vn_ino_lo)
191 #define VNDISK_SET_INO(V, I) ((V)->vn_ino_lo = (I))
192 #endif
193
194 #define VVnodeDiskACL(v)     /* Only call this with large (dir) vnode!! */ \
195         ((AL_AccessList *) (((byte *)(v))+SIZEOF_SMALLDISKVNODE))
196 #define  VVnodeACL(vnp) (VVnodeDiskACL(&(vnp)->disk))
197 /* VAclSize is defined this way to allow information in the vnode header
198    to grow, in a POSSIBLY upward compatible manner.  SIZEOF_SMALLDISKVNODE
199    is the maximum size of the basic vnode.  The vnode header of either type
200    can actually grow to this size without conflicting with the ACL on larger
201    vnodes */
202 #define VAclSize(vnp)           (SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE)
203 #define VAclDiskSize(v)         (SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE)
204 /*extern int VolumeHashOffset(); */
205 extern int VolumeHashOffset_r(void);
206 extern int VInitVnodes(VnodeClass class, int nVnodes);
207 /*extern VInitVnodes_r();*/
208 extern Vnode *VGetVnode(Error * ec, struct Volume *vp, VnodeId vnodeNumber,
209                         int locktype);
210 extern Vnode *VGetVnode_r(Error * ec, struct Volume *vp, VnodeId vnodeNumber,
211                           int locktype);
212 extern void VPutVnode(Error * ec, register Vnode * vnp);
213 extern void VPutVnode_r(Error * ec, register Vnode * vnp);
214 extern int VVnodeWriteToRead(Error * ec, register Vnode * vnp);
215 extern int VVnodeWriteToRead_r(Error * ec, register Vnode * vnp);
216 extern Vnode *VAllocVnode(Error * ec, struct Volume *vp, VnodeType type);
217 extern Vnode *VAllocVnode_r(Error * ec, struct Volume *vp, VnodeType type);
218 /*extern VFreeVnode();*/
219 extern Vnode *VGetFreeVnode_r(struct VnodeClassInfo *vcp);
220 extern void VInitVnHashByVolume(void);