2000-11-04 10:01:08 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2000, International Business Machines Corporation and others.
|
|
|
|
* All Rights Reserved.
|
|
|
|
*
|
|
|
|
* This software has been released under the terms of the IBM Public
|
|
|
|
* License. For details, see the LICENSE file in the top-level source
|
|
|
|
* directory or online at http://www.openafs.org/dl/license10.html
|
|
|
|
*/
|
2000-11-04 02:13:13 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
System: VICE-TWO
|
|
|
|
Module: vnode.h
|
|
|
|
Institution: The Information Technology Center, Carnegie-Mellon University
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define Date afs_uint32
|
|
|
|
|
2003-08-08 22:40:42 +01:00
|
|
|
struct Volume; /* Potentially forward definition. */
|
|
|
|
|
2003-07-16 01:28:24 +01:00
|
|
|
typedef struct ViceLock {
|
|
|
|
int lockCount;
|
|
|
|
int lockTime;
|
2000-11-04 02:13:13 +00:00
|
|
|
} ViceLock;
|
|
|
|
|
|
|
|
#define ViceLockCheckLocked(vptr) ((vptr)->lockTime == 0)
|
|
|
|
#define ViceLockClear(vptr) ((vptr)->lockCount = (vptr)->lockTime = 0)
|
|
|
|
|
|
|
|
#define ROOTVNODE 1
|
|
|
|
|
|
|
|
/*typedef enum {vNull=0, vFile=1, vDirectory=2, vSymlink=3} VnodeType;*/
|
2003-06-02 16:35:59 +01:00
|
|
|
typedef unsigned int VnodeType;
|
2000-11-04 02:13:13 +00:00
|
|
|
#define vNull 0
|
|
|
|
#define vFile 1
|
|
|
|
#define vDirectory 2
|
|
|
|
#define vSymlink 3
|
|
|
|
|
|
|
|
/*typedef enum {vLarge=0,vSmall=1} VnodeClass;*/
|
|
|
|
#define vLarge 0
|
|
|
|
#define vSmall 1
|
|
|
|
typedef int VnodeClass;
|
|
|
|
#define VNODECLASSWIDTH 1
|
|
|
|
#define VNODECLASSMASK ((1<<VNODECLASSWIDTH)-1)
|
|
|
|
#define nVNODECLASSES (VNODECLASSMASK+1)
|
|
|
|
|
|
|
|
struct VnodeClassInfo {
|
|
|
|
struct Vnode *lruHead; /* Head of list of vnodes of this class */
|
|
|
|
int diskSize; /* size of vnode disk object, power of 2 */
|
|
|
|
int logSize; /* log 2 diskSize */
|
|
|
|
int residentSize; /* resident size of vnode */
|
|
|
|
int cacheSize; /* Vnode cache size */
|
|
|
|
bit32 magic; /* Magic number for this type of vnode,
|
2003-07-16 01:28:24 +01:00
|
|
|
* for as long as we're using vnode magic
|
|
|
|
* numbers */
|
|
|
|
int allocs; /* Total number of successful allocation
|
|
|
|
* requests; this is the same as the number
|
|
|
|
* of sanity checks on the vnode index */
|
|
|
|
int gets, reads; /* Number of VGetVnodes and corresponding
|
|
|
|
* reads */
|
2000-11-04 02:13:13 +00:00
|
|
|
int writes; /* Number of vnode writes */
|
|
|
|
};
|
|
|
|
|
|
|
|
extern struct VnodeClassInfo VnodeClassInfo[nVNODECLASSES];
|
|
|
|
|
|
|
|
#define vnodeTypeToClass(type) ((type) == vDirectory? vLarge: vSmall)
|
|
|
|
#define vnodeIdToClass(vnodeId) ((vnodeId-1)&VNODECLASSMASK)
|
|
|
|
#define vnodeIdToBitNumber(v) (((v)-1)>>VNODECLASSWIDTH)
|
|
|
|
/* The following calculation allows for a header record at the beginning
|
|
|
|
of the index. The header record is the same size as a vnode */
|
|
|
|
#define vnodeIndexOffset(vcp,vnodeNumber) \
|
|
|
|
((vnodeIdToBitNumber(vnodeNumber)+1)<<(vcp)->logSize)
|
2003-06-02 16:35:59 +01:00
|
|
|
#define bitNumberToVnodeNumber(b,class) ((VnodeId)(((b)<<VNODECLASSWIDTH)+(class)+1))
|
2000-11-04 02:13:13 +00:00
|
|
|
#define vnodeIsDirectory(vnodeNumber) (vnodeIdToClass(vnodeNumber) == vLarge)
|
|
|
|
|
|
|
|
typedef struct VnodeDiskObject {
|
2003-07-16 01:28:24 +01:00
|
|
|
unsigned int type:3; /* Vnode is file, directory, symbolic link
|
|
|
|
* or not allocated */
|
|
|
|
unsigned int cloned:1; /* This vnode was cloned--therefore the inode
|
|
|
|
* is copy-on-write; only set for directories */
|
|
|
|
unsigned int modeBits:12; /* Unix mode bits */
|
|
|
|
signed int linkCount:16; /* Number of directory references to vnode
|
|
|
|
* (from single directory only!) */
|
|
|
|
bit32 length; /* Number of bytes in this file */
|
|
|
|
Unique uniquifier; /* Uniquifier for the vnode; assigned
|
|
|
|
* from the volume uniquifier (actually
|
|
|
|
* from nextVnodeUnique in the Volume
|
|
|
|
* structure) */
|
|
|
|
FileVersion dataVersion; /* version number of the data */
|
|
|
|
afs_int32 vn_ino_lo; /* inode number of the data attached to
|
|
|
|
* this vnode - entire ino for standard */
|
|
|
|
Date unixModifyTime; /* set by user */
|
|
|
|
UserId author; /* Userid of the last user storing the file */
|
|
|
|
UserId owner; /* Userid of the user who created the file */
|
|
|
|
VnodeId parent; /* Parent directory vnode */
|
|
|
|
bit32 vnodeMagic; /* Magic number--mainly for file server
|
|
|
|
* paranoia checks */
|
2000-11-04 02:13:13 +00:00
|
|
|
# define SMALLVNODEMAGIC 0xda8c041F
|
|
|
|
# define LARGEVNODEMAGIC 0xad8765fe
|
|
|
|
/* Vnode magic can be removed, someday, if we run need the room. Simply
|
2003-07-16 01:28:24 +01:00
|
|
|
* have to be sure that the thing we replace can be VNODEMAGIC, rather
|
|
|
|
* than 0 (in an old file system). Or go through and zero the fields,
|
|
|
|
* when we notice a version change (the index version number) */
|
|
|
|
ViceLock lock; /* Advisory lock */
|
|
|
|
Date serverModifyTime; /* Used only by the server; for incremental
|
|
|
|
* backup purposes */
|
|
|
|
afs_int32 group; /* unix group */
|
|
|
|
afs_int32 vn_ino_hi; /* high part of 64 bit inode. */
|
|
|
|
bit32 reserved6;
|
2000-11-04 02:13:13 +00:00
|
|
|
/* Missing:
|
2003-07-16 01:28:24 +01:00
|
|
|
* archiving/migration
|
|
|
|
* encryption key
|
2000-11-04 02:13:13 +00:00
|
|
|
*/
|
|
|
|
} VnodeDiskObject;
|
|
|
|
|
|
|
|
#define SIZEOF_SMALLDISKVNODE 64
|
|
|
|
#define CHECKSIZE_SMALLVNODE\
|
|
|
|
(sizeof(VnodeDiskObject) == SIZEOF_SMALLDISKVNODE)
|
|
|
|
#define SIZEOF_LARGEDISKVNODE 256
|
|
|
|
|
|
|
|
typedef struct Vnode {
|
2003-07-16 01:28:24 +01:00
|
|
|
struct Vnode *hashNext; /* Next vnode on hash conflict chain */
|
|
|
|
struct Vnode *lruNext; /* Less recently used vnode than this one */
|
|
|
|
struct Vnode *lruPrev; /* More recently used vnode than this one */
|
|
|
|
/* The lruNext, lruPrev fields are not
|
|
|
|
* meaningful if the vnode is in use */
|
|
|
|
bit16 hashIndex; /* Hash table index */
|
2000-11-04 02:13:13 +00:00
|
|
|
#ifdef AFS_AIX_ENV
|
2003-07-16 01:28:24 +01:00
|
|
|
unsigned changed_newTime:1; /* 1 if vnode changed, write time */
|
|
|
|
unsigned changed_oldTime:1; /* 1 changed, don't update time. */
|
|
|
|
unsigned delete:1; /* 1 if the vnode should be deleted; in
|
|
|
|
* this case, changed must also be 1 */
|
2000-11-04 02:13:13 +00:00
|
|
|
#else
|
2003-07-16 01:28:24 +01:00
|
|
|
byte changed_newTime:1; /* 1 if vnode changed, write time */
|
|
|
|
byte changed_oldTime:1; /* 1 changed, don't update time. */
|
|
|
|
byte delete:1; /* 1 if the vnode should be deleted; in
|
|
|
|
* this case, changed must also be 1 */
|
2000-11-04 02:13:13 +00:00
|
|
|
#endif
|
2003-07-16 01:28:24 +01:00
|
|
|
VnodeId vnodeNumber;
|
2000-11-04 02:13:13 +00:00
|
|
|
struct Volume
|
2003-07-16 01:28:24 +01:00
|
|
|
*volumePtr; /* Pointer to the volume containing this file */
|
|
|
|
byte nUsers; /* Number of lwp's who have done a VGetVnode */
|
|
|
|
bit32 cacheCheck; /* Must equal the value in the volume Header
|
|
|
|
* for the cache entry to be valid */
|
|
|
|
struct Lock lock; /* Internal lock */
|
2000-11-04 02:13:13 +00:00
|
|
|
#ifdef AFS_PTHREAD_ENV
|
2003-07-16 01:28:24 +01:00
|
|
|
pthread_t writer; /* thread holding write lock */
|
|
|
|
#else /* AFS_PTHREAD_ENV */
|
|
|
|
PROCESS writer; /* Process id having write lock */
|
|
|
|
#endif /* AFS_PTHREAD_ENV */
|
|
|
|
IHandle_t *handle;
|
2000-11-04 02:13:13 +00:00
|
|
|
VnodeDiskObject disk; /* The actual disk data for the vnode */
|
|
|
|
} Vnode;
|
|
|
|
|
|
|
|
#define SIZEOF_LARGEVNODE \
|
|
|
|
(sizeof(struct Vnode) - sizeof(VnodeDiskObject) + SIZEOF_LARGEDISKVNODE)
|
|
|
|
#define SIZEOF_SMALLVNODE (sizeof (struct Vnode))
|
|
|
|
|
2003-06-02 16:27:54 +01:00
|
|
|
#ifdef AFS_LARGEFILE_ENV
|
|
|
|
#define VN_GET_LEN(N, V) FillInt64(N, (V)->disk.reserved6, (V)->disk.length)
|
|
|
|
#define VNDISK_GET_LEN(N, V) FillInt64(N, (V)->reserved6, (V)->length)
|
|
|
|
#define VN_SET_LEN(V, N) SplitInt64(N, (V)->disk.reserved6, (V)->disk.length)
|
|
|
|
#define VNDISK_SET_LEN(V, N) SplitInt64(N, (V)->reserved6, (V)->length)
|
|
|
|
#else /* !AFS_LARGEFILE_ENV */
|
|
|
|
#define VN_GET_LEN(N, V) (N) = (V)->disk.length;
|
|
|
|
#define VNDISK_GET_LEN(N, V) (N) = (V)->length;
|
|
|
|
#define VN_SET_LEN(V, N) (V)->disk.length = (N);
|
|
|
|
#define VNDISK_SET_LEN(V, N) (V)->length = (N);
|
|
|
|
#endif /* !AFS_LARGEFILE_ENV */
|
|
|
|
|
2000-11-04 02:13:13 +00:00
|
|
|
#ifdef AFS_64BIT_IOPS_ENV
|
|
|
|
#define VN_GET_INO(V) ((Inode)((V)->disk.vn_ino_lo | \
|
|
|
|
((V)->disk.vn_ino_hi ? \
|
|
|
|
(((Inode)(V)->disk.vn_ino_hi)<<32) : 0)))
|
|
|
|
|
|
|
|
#define VN_SET_INO(V, I) ((V)->disk.vn_ino_lo = (int)((I)&0xffffffff), \
|
|
|
|
((V)->disk.vn_ino_hi = (I) ? \
|
|
|
|
(int)(((I)>>32)&0xffffffff) : 0))
|
|
|
|
|
|
|
|
#define VNDISK_GET_INO(V) ((Inode)((V)->vn_ino_lo | \
|
|
|
|
((V)->vn_ino_hi ? \
|
|
|
|
(((Inode)(V)->vn_ino_hi)<<32) : 0)))
|
|
|
|
|
|
|
|
#define VNDISK_SET_INO(V, I) ((V)->vn_ino_lo = (int)(I&0xffffffff), \
|
|
|
|
((V)->vn_ino_hi = (I) ? \
|
|
|
|
(int)(((I)>>32)&0xffffffff) : 0))
|
|
|
|
#else
|
|
|
|
#define VN_GET_INO(V) ((V)->disk.vn_ino_lo)
|
|
|
|
#define VN_SET_INO(V, I) ((V)->disk.vn_ino_lo = (I))
|
|
|
|
#define VNDISK_GET_INO(V) ((V)->vn_ino_lo)
|
|
|
|
#define VNDISK_SET_INO(V, I) ((V)->vn_ino_lo = (I))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define VVnodeDiskACL(v) /* Only call this with large (dir) vnode!! */ \
|
|
|
|
((AL_AccessList *) (((byte *)(v))+SIZEOF_SMALLDISKVNODE))
|
|
|
|
#define VVnodeACL(vnp) (VVnodeDiskACL(&(vnp)->disk))
|
|
|
|
/* VAclSize is defined this way to allow information in the vnode header
|
|
|
|
to grow, in a POSSIBLY upward compatible manner. SIZEOF_SMALLDISKVNODE
|
|
|
|
is the maximum size of the basic vnode. The vnode header of either type
|
|
|
|
can actually grow to this size without conflicting with the ACL on larger
|
|
|
|
vnodes */
|
|
|
|
#define VAclSize(vnp) (SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE)
|
|
|
|
#define VAclDiskSize(v) (SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE)
|
2003-08-08 22:40:42 +01:00
|
|
|
/*extern int VolumeHashOffset(); */
|
|
|
|
extern int VolumeHashOffset_r(void);
|
|
|
|
extern VInitVnodes(VnodeClass class, int nVnodes);
|
|
|
|
/*extern VInitVnodes_r();*/
|
|
|
|
extern Vnode *VGetVnode(Error * ec, struct Volume *vp, VnodeId vnodeNumber,
|
|
|
|
int locktype);
|
|
|
|
extern Vnode *VGetVnode_r(Error * ec, struct Volume *vp, VnodeId vnodeNumber,
|
|
|
|
int locktype);
|
|
|
|
extern void VPutVnode(Error * ec, register Vnode * vnp);
|
|
|
|
extern void VPutVnode_r(Error * ec, register Vnode * vnp);
|
|
|
|
extern VVnodeWriteToRead(Error * ec, register Vnode * vnp);
|
|
|
|
extern VVnodeWriteToRead_r(Error * ec, register Vnode * vnp);
|
|
|
|
extern Vnode *VAllocVnode(Error * ec, struct Volume *vp, VnodeType type);
|
|
|
|
extern Vnode *VAllocVnode_r(Error * ec, struct Volume *vp, VnodeType type);
|
|
|
|
/*extern VFreeVnode();*/
|
|
|
|
extern Vnode *VGetFreeVnode_r(struct VnodeClassInfo *vcp);
|