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