windows-byte-range-locks-20050816
[openafs.git] / src / WINNT / afsd / cm_scache.h
index a162bb9..b99c633 100644 (file)
@@ -14,6 +14,8 @@
 #include "largeint95.h"
 #endif /* DJGPP */
 
+#define MOUNTPOINTLEN   1024
+
 typedef struct cm_fid {
        unsigned long cell;
         unsigned long volume;
@@ -21,36 +23,73 @@ typedef struct cm_fid {
         unsigned long unique;
 } cm_fid_t;
 
+#if 0
 typedef struct cm_accessCache {
        osi_queue_t q;                  /* queue header */
         struct cm_user *userp;         /* user having access rights */
         unsigned long rights;          /* rights */
 } cm_accessCache_t;
+#endif
+
+/* Key used for byte range locking.  Each unique key identifies a
+   unique client per cm_scache_t for the purpose of locking. */
+typedef afs_uint64 cm_key_t;
+
+typedef struct cm_range {
+    afs_int64 offset;
+    afs_int64 length;
+} cm_range_t;
+
+/* forward dcls */
+struct cm_scache;
+typedef struct cm_scache cm_scache_t;
 
 typedef struct cm_file_lock {
-       osi_queue_t q;                  /* list of all locks */
-       osi_queue_t fileq;              /* per-file list of locks */
-       cm_user_t *userp;
-       LARGE_INTEGER LOffset;
-       LARGE_INTEGER LLength;
-       cm_fid_t fid;
-       unsigned char LockType;
-       unsigned char flags;
+    osi_queue_t q;              /* list of all locks [protected by
+                                   cm_scacheLock] */
+    osi_queue_t fileq;         /* per-file list of locks [protected
+                                   by scp->mx]*/
+    
+    cm_user_t *userp;           /* The user to which this lock belongs
+                                   to [immutable; held] */
+    cm_scache_t *scp;           /* The scache to which this lock
+                                   applies to [immutable; held] */
+#ifdef DEBUG
+    cm_fid_t   fid;
+#endif
+
+    cm_range_t range;           /* Range for the lock [immutable] */
+    cm_key_t key;               /* Key for the lock [immutable] */
+    unsigned char lockType;     /* LockRead or LockWrite [immutable] */
+    unsigned char flags;        /* combination of CM_FILELOCK_FLAG__*
+                                 * [protected by cm_scacheLock] */
+    time_t lastUpdate;          /* time of last assertion with
+                                 * server. [protected by
+                                 * cm_scacheLock] */
 } cm_file_lock_t;
 
-#define CM_FILELOCK_FLAG_INVALID       0x1
-#define CM_FILELOCK_FLAG_WAITING       0x2
+#define CM_FILELOCK_FLAG_DELETED         0x01
+#define CM_FILELOCK_FLAG_LOST            0x02
+
+/* the following are mutually exclusive */
+#define CM_FILELOCK_FLAG_WAITLOCK        0x04
+#define CM_FILELOCK_FLAG_WAITUNLOCK      0x0C
+
+#define CM_FILELOCK_FLAG_CLIENTONLY      0x100
 
 typedef struct cm_prefetch {           /* last region scanned for prefetching */
        osi_hyper_t base;               /* start of region */
         osi_hyper_t end;               /* first char past region */
 } cm_prefetch_t;
 
+#define CM_SCACHE_MAGIC ('S' | 'C'<<8 | 'A'<<16 | 'C'<<24)
+
 typedef struct cm_scache {
-       osi_queue_t q;                  /* lru queue; cm_scacheLock */
-       struct cm_scache *nextp;        /* next in hash; cm_scacheLock */
+    osi_queue_t q;              /* lru queue; cm_scacheLock */
+        afs_uint32      magic;
+        struct cm_scache *nextp;       /* next in hash; cm_scacheLock */
        cm_fid_t fid;
-        unsigned long flags;           /* flags; locked by mx */
+        afs_uint32 flags;              /* flags; locked by mx */
 
        /* synchronization stuff */
         osi_mutex_t mx;                        /* mutex for this structure */
@@ -58,30 +97,30 @@ typedef struct cm_scache {
                                         * write-locked to prevent buffers from
                                          * being created during a truncate op, etc.
                                          */
-        long refCount;                 /* reference count; cm_scacheLock */
+        afs_uint32 refCount;           /* reference count; cm_scacheLock */
         osi_queueData_t *bufReadsp;    /* queue of buffers being read */
         osi_queueData_t *bufWritesp;   /* queue of buffers being written */
 
        /* parent info for ACLs */
-        long parentVnode;              /* parent vnode for ACL callbacks */
-        long parentUnique;             /* for ACL callbacks */
+        afs_uint32 parentVnode;                /* parent vnode for ACL callbacks */
+        afs_uint32 parentUnique;       /* for ACL callbacks */
 
        /* local modification stat */
-        unsigned long mask;            /* for clientModTime, length and
+        afs_uint32 mask;               /* for clientModTime, length and
                                         * truncPos */
 
        /* file status */
-       unsigned int fileType;                  /* file type */
-       time_t clientModTime;   /* mtime */
-        time_t serverModTime;  /* at server, for concurrent call
+       afs_uint32 fileType;            /* file type */
+       time_t clientModTime;           /* mtime */
+        time_t serverModTime;          /* at server, for concurrent call
                                         * comparisons */
         osi_hyper_t length;            /* file length */
        cm_prefetch_t prefetch;         /* prefetch info structure */
-        unsigned int unixModeBits;     /* unix protection mode bits */
-        int linkCount;                 /* link count */
-        long dataVersion;              /* data version */
-        long owner;                    /* file owner */
-        long group;                    /* file owning group */
+        afs_uint32 unixModeBits;       /* unix protection mode bits */
+        afs_uint32 linkCount;          /* link count */
+        afs_uint32 dataVersion;                /* data version */
+        afs_uint32 owner;              /* file owner */
+        afs_uint32 group;              /* file owning group */
 
        /* pseudo file status */
        osi_hyper_t serverLength;       /* length known to server */
@@ -91,14 +130,14 @@ typedef struct cm_scache {
                                         * storing data */
 
        /* symlink and mount point info */
-        char *mountPointStringp;       /* the string stored in a mount point;
+        char mountPointStringp[MOUNTPOINTLEN]; /* the string stored in a mount point;
                                         * first char is type, then vol name.
                                          * If this is a normal symlink, we store
                                         * the link contents here.
                                          */
-       cm_fid_t *mountRootFidp;        /* mounted on root */
+       cm_fid_t  mountRootFid;         /* mounted on root */
        time_t    mountRootGen;         /* time to update mountRootFidp? */
-       cm_fid_t *dotdotFidp;           /* parent of volume root */
+       cm_fid_t  dotdotFid;            /* parent of volume root */
 
        /* callback info */
         struct cm_server *cbServerp;   /* server granting callback */
@@ -108,8 +147,21 @@ typedef struct cm_scache {
         long anyAccess;                        /* anonymous user's access */
         struct cm_aclent *randomACLp;  /* access cache entries */
 
-       /* file locks */
-       osi_queue_t *fileLocks;
+    /* file locks */
+    afs_int32    serverLock;    /* current lock we have acquired on
+                                 * this file.  One of (-1), LockRead
+                                 * or LockWrite. [protected by
+                                 * scp->mx]
+                                 */
+    unsigned long lastRefreshCycle; /* protected with cm_scacheLock
+                                     * for all scaches. */
+    osi_queue_t *fileLocksH;    /* queue of locks (head) */
+    osi_queue_t *fileLocksT;    /* queue of locks (tail) */
+    afs_uint32   sharedLocks;   /* number of shared locks on
+                                 * ::fileLocks */
+    afs_uint32   exclusiveLocks; /* number of exclusive locks on
+                                  * ::fileLocks
+                                  */
        
        /* volume info */
         struct cm_volume *volp;                /* volume info; held reference */
@@ -118,10 +170,14 @@ typedef struct cm_scache {
         osi_hyper_t bulkStatProgress;  /* track bulk stats of large dirs */
 
         /* open state */
-        short openReads;               /* open for reading */
-        short openWrites;              /* open for writing */
-        short openShares;              /* open for read excl */
-        short openExcls;               /* open for exclusives */
+        afs_uint16 openReads;          /* open for reading */
+        afs_uint16 openWrites;         /* open for writing */
+        afs_uint16 openShares;         /* open for read excl */
+        afs_uint16 openExcls;          /* open for exclusives */
+
+        /* syncop state */
+        afs_uint32 waitCount;           /* number of threads waiting */
+        afs_uint32 waitRequests;        /* num of thread wait requests */
 } cm_scache_t;
 
 /* mask field - tell what has been modified */
@@ -134,9 +190,11 @@ typedef struct cm_scache {
 #define CM_SCACHETYPE_DIRECTORY                2       /* a dir */
 #define CM_SCACHETYPE_SYMLINK          3       /* a symbolic link */
 #define CM_SCACHETYPE_MOUNTPOINT       4       /* a mount point */
+#define CM_SCACHETYPE_DFSLINK           5       /* a Microsoft Dfs link */
+#define CM_SCACHETYPE_INVALID           99      /* an invalid link */
 
 /* flag bits */
-#define CM_SCACHEFLAG_STATD                 0x01        /* status info is valid */
+#define CM_SCACHEFLAG_STATD             0x01    /* status info is valid */
 #define CM_SCACHEFLAG_DELETED           0x02    /* file has been deleted */
 #define CM_SCACHEFLAG_CALLBACK          0x04    /* have a valid callback */
 #define CM_SCACHEFLAG_STORING           0x08    /* status being stored back */
@@ -212,14 +270,12 @@ typedef struct cm_scache {
                                   ((fidp)->volume +    \
                                    (fidp)->vnode +     \
                                    (fidp)->unique))    \
-                                       % cm_hashTableSize)
+                                       % cm_data.hashTableSize)
 
 #include "cm_conn.h"
 #include "cm_buf.h"
 
-extern cm_scache_t cm_fakeSCache;
-
-extern void cm_InitSCache(long);
+extern void cm_InitSCache(int, long);
 
 extern long cm_GetSCache(cm_fid_t *, cm_scache_t **, struct cm_user *,
        struct cm_req *);
@@ -250,16 +306,20 @@ extern void cm_ReleaseSCache(cm_scache_t *);
 
 extern cm_scache_t *cm_FindSCache(cm_fid_t *fidp);
 
-extern long cm_hashTableSize;
-
 extern osi_rwlock_t cm_scacheLock;
 
 extern osi_queue_t *cm_allFileLocks;
 
-extern cm_scache_t **cm_hashTablep;
+extern osi_queue_t *cm_freeFileLocks;
+
+extern unsigned long cm_lockRefreshCycle;
 
 extern void cm_DiscardSCache(cm_scache_t *scp);
 
 extern int cm_FindFileType(cm_fid_t *fidp);
 
+extern long cm_ValidateSCache(void);
+
+extern long cm_ShutdownSCache(void);
+
 #endif /*  __CM_SCACHE_H_ENV__ */