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