vnode-disk-object-name-hi-length-field-20090611
[openafs.git] / src / vol / vnode.h
index d0863db..718a0c2 100644 (file)
@@ -1,25 +1,31 @@
-
-#if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
-#endif
-
 /*
- * (C) COPYRIGHT IBM CORPORATION 1987
- * LICENSED MATERIALS - PROPERTY OF IBM
+ * 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
+ *
+ * Portions Copyright (c) 2007-2008 Sine Nomine Associates
  */
-/*
 
+/*
        System:         VICE-TWO
        Module:         vnode.h
        Institution:    The Information Technology Center, Carnegie-Mellon University
 
  */
 
+#ifndef _AFS_VOL_VNODE_H
+#define _AFS_VOL_VNODE_H 1
+
 #define Date afs_uint32
 
-typedef struct ViceLock
-{
-    int                lockCount;
-    int                lockTime;
+struct Volume;                 /* Potentially forward definition. */
+
+typedef struct ViceLock {
+    int lockCount;
+    int lockTime;
 } ViceLock;
 
 #define ViceLockCheckLocked(vptr) ((vptr)->lockTime == 0)
@@ -28,7 +34,7 @@ typedef struct ViceLock
 #define ROOTVNODE 1
 
 /*typedef enum {vNull=0, vFile=1, vDirectory=2, vSymlink=3} VnodeType;*/
-typedef int VnodeType;
+typedef unsigned int VnodeType;
 #define vNull 0
 #define vFile 1
 #define vDirectory 2
@@ -49,13 +55,13 @@ struct VnodeClassInfo {
     int residentSize;          /* resident size of vnode */
     int cacheSize;             /* Vnode cache size */
     bit32 magic;               /* Magic number for this type of vnode,
-                                  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 */
+                                * 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 */
     int writes;                        /* Number of vnode writes */
 };
 
@@ -68,46 +74,46 @@ extern struct VnodeClassInfo VnodeClassInfo[nVNODECLASSES];
    of the index.  The header record is the same size as a vnode */
 #define vnodeIndexOffset(vcp,vnodeNumber) \
     ((vnodeIdToBitNumber(vnodeNumber)+1)<<(vcp)->logSize)
-#define bitNumberToVnodeNumber(b,class) (((b)<<VNODECLASSWIDTH)+(class)+1)
+#define bitNumberToVnodeNumber(b,class) ((VnodeId)(((b)<<VNODECLASSWIDTH)+(class)+1))
 #define vnodeIsDirectory(vnodeNumber) (vnodeIdToClass(vnodeNumber) == vLarge)
 
 typedef struct VnodeDiskObject {
-    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 */
+    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 */
 #   define       SMALLVNODEMAGIC       0xda8c041F
 #   define       LARGEVNODEMAGIC       0xad8765fe
     /* Vnode magic can be removed, someday, if we run need the room.  Simply
-       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;
+     * 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 vn_length_hi;         /* high part of 64 bit length */
     /* Missing:
-       archiving/migration
-       encryption key
+     * archiving/migration
+     * encryption key
      */
 } VnodeDiskObject;
 
@@ -116,37 +122,83 @@ typedef struct VnodeDiskObject {
        (sizeof(VnodeDiskObject) == SIZEOF_SMALLDISKVNODE)
 #define SIZEOF_LARGEDISKVNODE  256
 
+
+
+#ifdef AFS_DEMAND_ATTACH_FS
+/**
+ * demand attach vnode state enumeration.
+ *
+ * @note values must be contiguous for VnIsValidState() to work
+ */
+typedef enum {
+    VN_STATE_INVALID            = 0,    /**< vnode does not contain valid cache data */
+    VN_STATE_RELEASING          = 1,    /**< vnode is busy releasing its ihandle ref */
+    VN_STATE_CLOSING            = 2,    /**< vnode is busy closing its ihandle ref */
+    VN_STATE_ALLOC              = 3,    /**< vnode is busy allocating disk entry */
+    VN_STATE_ONLINE             = 4,    /**< vnode is ready for use */
+    VN_STATE_LOAD               = 5,    /**< vnode is busy being loaded from disk */
+    VN_STATE_EXCLUSIVE          = 6,    /**< something external to the vnode package
+                                        *   is operating exclusively on this vnode */
+    VN_STATE_STORE              = 7,    /**< vnode is busy being stored to disk */
+    VN_STATE_READ               = 8,    /**< a non-zero number of threads are executing
+                                        *   code external to the vnode package which
+                                        *   requires shared access */
+    VN_STATE_ERROR              = 10,   /**< vnode hard error state */
+    VN_STATE_COUNT
+} VnState;
+#endif /* AFS_DEMAND_ATTACH_FS */
+
+/**
+ * DAFS vnode state flags.
+ */
+enum VnFlags {
+    VN_ON_HASH            = 0x1,        /**< vnode is on hash table */
+    VN_ON_LRU             = 0x2,        /**< vnode is on lru list */
+    VN_ON_VVN             = 0x4,        /**< vnode is on volume vnode list */
+    VN_FLAGS_END
+};
+
+
 typedef struct Vnode {
-    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 */
+    struct rx_queue vid_hash;   /* for vnode by volume id hash */
+    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 */
 #ifdef AFS_AIX_ENV
-    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 */
+    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 */
 #else
-    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 */
+    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 */
 #endif
-    VnodeId    vnodeNumber;
+    VnodeId vnodeNumber;
     struct Volume
-               *volumePtr;     /* Pointer to the volume containing this file*/
-    byte       nUsers;         /* Number of lwp's who have done a VGetVnode */
-    bit16      cacheCheck;     /* Must equal the value in the volume Header
-                                  for the cache entry to be valid */
-    struct     Lock lock;      /* Internal lock */
+     *volumePtr;               /* Pointer to the volume containing this file */
+    bit32 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 */
+    bit32 vn_state_flags;       /**< vnode state flags */
+#ifdef AFS_DEMAND_ATTACH_FS
+    bit32 nReaders;             /**< number of read locks held */
+    VnState vn_state;           /**< vnode state */
+    pthread_cond_t vn_state_cv; /**< state change notification cv */
+#else /* !AFS_DEMAND_ATTACH_FS */
+    struct Lock lock;          /* Internal lock */
+#endif /* !AFS_DEMAND_ATTACH_FS */
 #ifdef AFS_PTHREAD_ENV
-    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;
+    pthread_t writer;          /* thread holding write lock */
+#else                          /* AFS_PTHREAD_ENV */
+    PROCESS writer;            /* Process id having write lock */
+#endif                         /* AFS_PTHREAD_ENV */
+    struct VnodeClassInfo * vcp; /**< our vnode class */
+    IHandle_t *handle;
     VnodeDiskObject disk;      /* The actual disk data for the vnode */
 } Vnode;
 
@@ -154,6 +206,33 @@ typedef struct Vnode {
        (sizeof(struct Vnode) - sizeof(VnodeDiskObject) + SIZEOF_LARGEDISKVNODE)
 #define SIZEOF_SMALLVNODE      (sizeof (struct Vnode))
 
+
+/*
+ * struct Vnode accessor abstraction
+ */
+#define Vn_refcount(vnp)      ((vnp)->nUsers)
+#define Vn_state(vnp)         ((vnp)->vn_state)
+#define Vn_stateFlags(vnp)    ((vnp)->vn_state_flags)
+#define Vn_stateCV(vnp)       ((vnp)->vn_state_cv)
+#define Vn_volume(vnp)        ((vnp)->volumePtr)
+#define Vn_cacheCheck(vnp)    ((vnp)->cacheCheck)
+#define Vn_class(vnp)         ((vnp)->vcp)
+#define Vn_readers(vnp)       ((vnp)->nReaders)
+#define Vn_id(vnp)            ((vnp)->vnodeNumber)
+
+
+#ifdef AFS_LARGEFILE_ENV
+#define VN_GET_LEN(N, V) FillInt64(N, (V)->disk.vn_length_hi, (V)->disk.length)
+#define VNDISK_GET_LEN(N, V) FillInt64(N, (V)->vn_length_hi, (V)->length)
+#define VN_SET_LEN(V, N) SplitInt64(N, (V)->disk.vn_length_hi, (V)->disk.length)
+#define VNDISK_SET_LEN(V, N) SplitInt64(N, (V)->vn_length_hi, (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 */
+
 #ifdef AFS_64BIT_IOPS_ENV
 #define VN_GET_INO(V) ((Inode)((V)->disk.vn_ino_lo | \
                               ((V)->disk.vn_ino_hi ? \
@@ -187,17 +266,29 @@ typedef struct Vnode {
    vnodes */
 #define VAclSize(vnp)          (SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE)
 #define VAclDiskSize(v)                (SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE)
-extern int VolumeHashOffset();
-extern int VolumeHashOffset_r();
-extern VInitVnodes();
-extern VInitVnodes_r();
-extern Vnode *VGetVnode();
-extern Vnode *VGetVnode_r();
-extern VputVnode();
-extern VputVnode_r();
-extern VVnodeWriteToRead();
-extern VVnodeWriteToRead_r();
-extern Vnode *VAllocVnode();
-extern Vnode *VAllocVnode_r();
-extern VFreeVnode();
-extern VFreeVnode_r();
+/*extern int VolumeHashOffset(); */
+extern int VolumeHashOffset_r(void);
+extern int 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 int VVnodeWriteToRead(Error * ec, register Vnode * vnp);
+extern int 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);
+extern Vnode *VLookupVnode(struct Volume * vp, VnodeId vnodeId);
+
+extern void AddToVVnList(struct Volume * vp, Vnode * vnp);
+extern void DeleteFromVVnList(register Vnode * vnp);
+extern void AddToVnLRU(struct VnodeClassInfo * vcp, Vnode * vnp);
+extern void DeleteFromVnLRU(struct VnodeClassInfo * vcp, Vnode * vnp);
+extern void AddToVnHash(Vnode * vnp);
+extern void DeleteFromVnHash(Vnode * vnp);
+
+#endif /* _AFS_VOL_VNODE_H */