windows-byte-range-locks-20050816
[openafs.git] / src / WINNT / afsd / cm_scache.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 #ifndef __CM_SCACHE_H_ENV__
11 #define __CM_SCACHE_H_ENV__ 1
12
13 #ifdef DJGPP
14 #include "largeint95.h"
15 #endif /* DJGPP */
16
17 #define MOUNTPOINTLEN   1024
18
19 typedef struct cm_fid {
20         unsigned long cell;
21         unsigned long volume;
22         unsigned long vnode;
23         unsigned long unique;
24 } cm_fid_t;
25
26 #if 0
27 typedef struct cm_accessCache {
28         osi_queue_t q;                  /* queue header */
29         struct cm_user *userp;          /* user having access rights */
30         unsigned long rights;           /* rights */
31 } cm_accessCache_t;
32 #endif
33
34 /* Key used for byte range locking.  Each unique key identifies a
35    unique client per cm_scache_t for the purpose of locking. */
36 typedef afs_uint64 cm_key_t;
37
38 typedef struct cm_range {
39     afs_int64 offset;
40     afs_int64 length;
41 } cm_range_t;
42
43 /* forward dcls */
44 struct cm_scache;
45 typedef struct cm_scache cm_scache_t;
46
47 typedef struct cm_file_lock {
48     osi_queue_t q;              /* list of all locks [protected by
49                                    cm_scacheLock] */
50     osi_queue_t fileq;          /* per-file list of locks [protected
51                                    by scp->mx]*/
52     
53     cm_user_t *userp;           /* The user to which this lock belongs
54                                    to [immutable; held] */
55     cm_scache_t *scp;           /* The scache to which this lock
56                                    applies to [immutable; held] */
57 #ifdef DEBUG
58     cm_fid_t   fid;
59 #endif
60
61     cm_range_t range;           /* Range for the lock [immutable] */
62     cm_key_t key;               /* Key for the lock [immutable] */
63     unsigned char lockType;     /* LockRead or LockWrite [immutable] */
64     unsigned char flags;        /* combination of CM_FILELOCK_FLAG__*
65                                  * [protected by cm_scacheLock] */
66     time_t lastUpdate;          /* time of last assertion with
67                                  * server. [protected by
68                                  * cm_scacheLock] */
69 } cm_file_lock_t;
70
71 #define CM_FILELOCK_FLAG_DELETED         0x01
72 #define CM_FILELOCK_FLAG_LOST            0x02
73
74 /* the following are mutually exclusive */
75 #define CM_FILELOCK_FLAG_WAITLOCK        0x04
76 #define CM_FILELOCK_FLAG_WAITUNLOCK      0x0C
77
78 #define CM_FILELOCK_FLAG_CLIENTONLY      0x100
79
80 typedef struct cm_prefetch {            /* last region scanned for prefetching */
81         osi_hyper_t base;               /* start of region */
82         osi_hyper_t end;                /* first char past region */
83 } cm_prefetch_t;
84
85 #define CM_SCACHE_MAGIC ('S' | 'C'<<8 | 'A'<<16 | 'C'<<24)
86
87 typedef struct cm_scache {
88     osi_queue_t q;              /* lru queue; cm_scacheLock */
89         afs_uint32      magic;
90         struct cm_scache *nextp;        /* next in hash; cm_scacheLock */
91         cm_fid_t fid;
92         afs_uint32 flags;               /* flags; locked by mx */
93
94         /* synchronization stuff */
95         osi_mutex_t mx;                 /* mutex for this structure */
96         osi_rwlock_t bufCreateLock;     /* read-locked during buffer creation;
97                                          * write-locked to prevent buffers from
98                                          * being created during a truncate op, etc.
99                                          */
100         afs_uint32 refCount;            /* reference count; cm_scacheLock */
101         osi_queueData_t *bufReadsp;     /* queue of buffers being read */
102         osi_queueData_t *bufWritesp;    /* queue of buffers being written */
103
104         /* parent info for ACLs */
105         afs_uint32 parentVnode;         /* parent vnode for ACL callbacks */
106         afs_uint32 parentUnique;        /* for ACL callbacks */
107
108         /* local modification stat */
109         afs_uint32 mask;                /* for clientModTime, length and
110                                          * truncPos */
111
112         /* file status */
113         afs_uint32 fileType;            /* file type */
114         time_t clientModTime;           /* mtime */
115         time_t serverModTime;           /* at server, for concurrent call
116                                          * comparisons */
117         osi_hyper_t length;             /* file length */
118         cm_prefetch_t prefetch;         /* prefetch info structure */
119         afs_uint32 unixModeBits;        /* unix protection mode bits */
120         afs_uint32 linkCount;           /* link count */
121         afs_uint32 dataVersion;         /* data version */
122         afs_uint32 owner;               /* file owner */
123         afs_uint32 group;               /* file owning group */
124
125         /* pseudo file status */
126         osi_hyper_t serverLength;       /* length known to server */
127
128         /* aux file status */
129         osi_hyper_t truncPos;           /* file size to truncate to before
130                                          * storing data */
131
132         /* symlink and mount point info */
133         char mountPointStringp[MOUNTPOINTLEN];  /* the string stored in a mount point;
134                                          * first char is type, then vol name.
135                                          * If this is a normal symlink, we store
136                                          * the link contents here.
137                                          */
138         cm_fid_t  mountRootFid;         /* mounted on root */
139         time_t    mountRootGen;         /* time to update mountRootFidp? */
140         cm_fid_t  dotdotFid;            /* parent of volume root */
141
142         /* callback info */
143         struct cm_server *cbServerp;    /* server granting callback */
144         time_t cbExpires;               /* time callback expires */
145
146         /* access cache */
147         long anyAccess;                 /* anonymous user's access */
148         struct cm_aclent *randomACLp;   /* access cache entries */
149
150     /* file locks */
151     afs_int32    serverLock;    /* current lock we have acquired on
152                                  * this file.  One of (-1), LockRead
153                                  * or LockWrite. [protected by
154                                  * scp->mx]
155                                  */
156     unsigned long lastRefreshCycle; /* protected with cm_scacheLock
157                                      * for all scaches. */
158     osi_queue_t *fileLocksH;    /* queue of locks (head) */
159     osi_queue_t *fileLocksT;    /* queue of locks (tail) */
160     afs_uint32   sharedLocks;   /* number of shared locks on
161                                  * ::fileLocks */
162     afs_uint32   exclusiveLocks; /* number of exclusive locks on
163                                   * ::fileLocks
164                                   */
165         
166         /* volume info */
167         struct cm_volume *volp;         /* volume info; held reference */
168   
169         /* bulk stat progress */
170         osi_hyper_t bulkStatProgress;   /* track bulk stats of large dirs */
171
172         /* open state */
173         afs_uint16 openReads;           /* open for reading */
174         afs_uint16 openWrites;          /* open for writing */
175         afs_uint16 openShares;          /* open for read excl */
176         afs_uint16 openExcls;           /* open for exclusives */
177
178         /* syncop state */
179         afs_uint32 waitCount;           /* number of threads waiting */
180         afs_uint32 waitRequests;        /* num of thread wait requests */
181 } cm_scache_t;
182
183 /* mask field - tell what has been modified */
184 #define CM_SCACHEMASK_CLIENTMODTIME     1       /* client mod time */
185 #define CM_SCACHEMASK_LENGTH            2       /* length */
186 #define CM_SCACHEMASK_TRUNCPOS          4       /* truncation position */
187
188 /* fileType values */
189 #define CM_SCACHETYPE_FILE              1       /* a file */
190 #define CM_SCACHETYPE_DIRECTORY         2       /* a dir */
191 #define CM_SCACHETYPE_SYMLINK           3       /* a symbolic link */
192 #define CM_SCACHETYPE_MOUNTPOINT        4       /* a mount point */
193 #define CM_SCACHETYPE_DFSLINK           5       /* a Microsoft Dfs link */
194 #define CM_SCACHETYPE_INVALID           99      /* an invalid link */
195
196 /* flag bits */
197 #define CM_SCACHEFLAG_STATD             0x01    /* status info is valid */
198 #define CM_SCACHEFLAG_DELETED           0x02    /* file has been deleted */
199 #define CM_SCACHEFLAG_CALLBACK          0x04    /* have a valid callback */
200 #define CM_SCACHEFLAG_STORING           0x08    /* status being stored back */
201 #define CM_SCACHEFLAG_FETCHING          0x10    /* status being fetched */
202 #define CM_SCACHEFLAG_SIZESTORING       0x20    /* status being stored that
203                                                  * changes the data; typically,
204                                                  * this is a truncate op. */
205 #define CM_SCACHEFLAG_INHASH            0x40    /* in the hash table */
206 #define CM_SCACHEFLAG_BULKSTATTING      0x80    /* doing a bulk stat */
207 #define CM_SCACHEFLAG_WAITING           0x200   /* waiting for fetch/store
208                                                  * state to change */
209 #define CM_SCACHEFLAG_PURERO            0x400   /* read-only (not even backup);
210                                                  * for mount point eval */
211 #define CM_SCACHEFLAG_RO                0x800   /* read-only
212                                                  * (can't do write ops) */
213 #define CM_SCACHEFLAG_GETCALLBACK       0x1000  /* we're getting a callback */
214 #define CM_SCACHEFLAG_DATASTORING       0x2000  /* data being stored */
215 #define CM_SCACHEFLAG_PREFETCHING       0x4000  /* somebody is prefetching */
216 #define CM_SCACHEFLAG_OVERQUOTA         0x8000  /* over quota */
217 #define CM_SCACHEFLAG_OUTOFSPACE        0x10000 /* out of space */
218 #define CM_SCACHEFLAG_ASYNCSTORING      0x20000 /* scheduled to store back */
219 #define CM_SCACHEFLAG_LOCKING           0x40000 /* setting/clearing file lock */
220 #define CM_SCACHEFLAG_WATCHED           0x80000 /* directory being watched */
221 #define CM_SCACHEFLAG_WATCHEDSUBTREE    0x100000 /* dir subtree being watched */
222 #define CM_SCACHEFLAG_ANYWATCH \
223                         (CM_SCACHEFLAG_WATCHED | CM_SCACHEFLAG_WATCHEDSUBTREE)
224
225 /* sync flags for calls to the server.  The CM_SCACHEFLAG_FETCHING,
226  * CM_SCACHEFLAG_STORING and CM_SCACHEFLAG_SIZESTORING flags correspond to the
227  * below, except for FETCHDATA and STOREDATA, which correspond to non-null
228  * buffers in bufReadsp and bufWritesp.
229  * These flags correspond to individual RPCs that we may be making, and at most
230  * one can be set in any one call to SyncOp.
231  */
232 #define CM_SCACHESYNC_FETCHSTATUS           0x01        /* fetching status info */
233 #define CM_SCACHESYNC_STORESTATUS           0x02        /* storing status info */
234 #define CM_SCACHESYNC_FETCHDATA             0x04        /* fetch data */
235 #define CM_SCACHESYNC_STOREDATA             0x08        /* store data */
236 #define CM_SCACHESYNC_STORESIZE         0x10    /* store new file size */
237 #define CM_SCACHESYNC_GETCALLBACK       0x20    /* fetching a callback */
238 #define CM_SCACHESYNC_STOREDATA_EXCL    0x40    /* store data */
239 #define CM_SCACHESYNC_ASYNCSTORE        0x80    /* schedule data store */
240 #define CM_SCACHESYNC_LOCK              0x100   /* set/clear file lock */
241
242 /* sync flags for calls within the client; there are no corresponding flags
243  * in the scache entry, because we hold the scache entry locked during the
244  * operations below.
245  */
246 #define CM_SCACHESYNC_GETSTATUS         0x1000  /* read the status */
247 #define CM_SCACHESYNC_SETSTATUS         0x2000  /* e.g. utimes */
248 #define CM_SCACHESYNC_READ              0x4000  /* read data from a chunk */
249 #define CM_SCACHESYNC_WRITE             0x8000  /* write data to a chunk */
250 #define CM_SCACHESYNC_SETSIZE           0x10000 /* shrink the size of a file,
251                                                  * e.g. truncate */
252 #define CM_SCACHESYNC_NEEDCALLBACK      0x20000 /* need a callback on the file */
253 #define CM_SCACHESYNC_CHECKRIGHTS       0x40000 /* check that user has desired
254                                                  * access rights */
255 #define CM_SCACHESYNC_BUFLOCKED         0x80000 /* the buffer is locked */
256 #define CM_SCACHESYNC_NOWAIT            0x100000/* don't wait for the state,
257                                                  * just fail */
258
259 /* flags for cm_MergeStatus */
260 #define CM_MERGEFLAG_FORCE              1       /* check mtime before merging;
261                                                  * used to see if we're merging
262                                                  * in old info.
263                                                  */
264
265 /* hash define.  Must not include the cell, since the callback revocation code
266  * doesn't necessarily know the cell in the case of a multihomed server
267  * contacting us from a mystery address.
268  */
269 #define CM_SCACHE_HASH(fidp)    (((unsigned long)       \
270                                    ((fidp)->volume +    \
271                                     (fidp)->vnode +     \
272                                     (fidp)->unique))    \
273                                         % cm_data.hashTableSize)
274
275 #include "cm_conn.h"
276 #include "cm_buf.h"
277
278 extern void cm_InitSCache(int, long);
279
280 extern long cm_GetSCache(cm_fid_t *, cm_scache_t **, struct cm_user *,
281         struct cm_req *);
282
283 extern void cm_PutSCache(cm_scache_t *);
284
285 extern cm_scache_t *cm_GetNewSCache(void);
286
287 extern int cm_FidCmp(cm_fid_t *, cm_fid_t *);
288
289 extern long cm_SyncOp(cm_scache_t *, struct cm_buf *, struct cm_user *,
290         struct cm_req *, long, long);
291
292 extern void cm_SyncOpDone(cm_scache_t *, struct cm_buf *, long);
293
294 extern void cm_MergeStatus(cm_scache_t *, struct AFSFetchStatus *, struct AFSVolSync *,
295         struct cm_user *, int flags);
296
297 extern void cm_AFSFidFromFid(struct AFSFid *, cm_fid_t *);
298
299 extern void cm_HoldSCacheNoLock(cm_scache_t *);
300
301 extern void cm_HoldSCache(cm_scache_t *);
302
303 extern void cm_ReleaseSCacheNoLock(cm_scache_t *);
304
305 extern void cm_ReleaseSCache(cm_scache_t *);
306
307 extern cm_scache_t *cm_FindSCache(cm_fid_t *fidp);
308
309 extern osi_rwlock_t cm_scacheLock;
310
311 extern osi_queue_t *cm_allFileLocks;
312
313 extern osi_queue_t *cm_freeFileLocks;
314
315 extern unsigned long cm_lockRefreshCycle;
316
317 extern void cm_DiscardSCache(cm_scache_t *scp);
318
319 extern int cm_FindFileType(cm_fid_t *fidp);
320
321 extern long cm_ValidateSCache(void);
322
323 extern long cm_ShutdownSCache(void);
324
325 #endif /*  __CM_SCACHE_H_ENV__ */