OpenAFS
OpenAFS distributed network file system
|
00001 /* 00002 * Copyright 2000, International Business Machines Corporation and others. 00003 * All Rights Reserved. 00004 * 00005 * This software has been released under the terms of the IBM Public 00006 * License. For details, see the LICENSE file in the top-level source 00007 * directory or online at http://www.openafs.org/dl/license10.html 00008 */ 00009 00010 #ifndef OPENAFS_WINNT_AFSD_CM_SCACHE_H 00011 #define OPENAFS_WINNT_AFSD_CM_SCACHE_H 1 00012 00013 #include <opr/jhash.h> 00014 00015 #define MOUNTPOINTLEN 1024 /* max path length for symlink; same as AFSPATHMAX */ 00016 00017 typedef struct cm_fid { 00018 afs_uint32 cell; 00019 afs_uint32 volume; 00020 afs_uint32 vnode; 00021 afs_uint32 unique; 00022 afs_uint32 hash; 00023 } cm_fid_t; 00024 00025 00026 /* Key used for byte range locking. Each unique key identifies a 00027 unique client per cm_scache_t for the purpose of locking. */ 00028 typedef struct cm_key { 00029 afs_offs_t process_id; /* process IDs can be 64bit on 64bit environments */ 00030 afs_uint16 session_id; 00031 afs_uint64 file_id; /* afs redir uses File Object pointers as file id */ 00032 } cm_key_t; 00033 00034 typedef struct cm_range { 00035 afs_int64 offset; 00036 afs_int64 length; 00037 } cm_range_t; 00038 00039 /* forward dcls */ 00040 struct cm_scache; 00041 typedef struct cm_scache cm_scache_t; 00042 00043 typedef struct cm_file_lock { 00044 osi_queue_t q; /* list of all locks [protected by 00045 cm_scacheLock] */ 00046 osi_queue_t fileq; /* per-file list of locks [protected 00047 by scp->rw]*/ 00048 00049 cm_user_t *userp; /* The user to which this lock belongs 00050 to [immutable; held] */ 00051 cm_scache_t *scp; /* The scache to which this lock 00052 applies to [immutable; held] */ 00053 #ifdef DEBUG 00054 cm_fid_t fid; 00055 #endif 00056 00057 cm_range_t range; /* Range for the lock [immutable] */ 00058 cm_key_t key; /* Key for the lock [immutable] */ 00059 unsigned char lockType; /* LockRead or LockWrite [immutable] */ 00060 unsigned char flags; /* combination of CM_FILELOCK_FLAG__* 00061 * [protected by cm_scacheLock] */ 00062 time_t lastUpdate; /* time of last assertion with 00063 * server. [protected by 00064 * cm_scacheLock] */ 00065 } cm_file_lock_t; 00066 00067 #define fileq_to_cm_file_lock_t(q) ((cm_file_lock_t *)((char *) (q) - offsetof(cm_file_lock_t, fileq))) 00068 00069 #define CM_FILELOCK_FLAG_DELETED 0x01 00070 #define CM_FILELOCK_FLAG_LOST 0x02 00071 00072 /* the following are mutually exclusive */ 00073 #define CM_FILELOCK_FLAG_WAITLOCK 0x04 00074 #define CM_FILELOCK_FLAG_WAITUNLOCK 0x0C 00075 00076 /* the following is used to indicate that there are no server side 00077 locks associated with this lock. This is true for locks obtained 00078 against files in RO volumes as well as files residing on servers 00079 that disable client side byte range locking. */ 00080 #define CM_FILELOCK_FLAG_CLIENTONLY 0x10 00081 00082 #define CM_FLSHARE_OFFSET_HIGH 0x01000000 00083 #define CM_FLSHARE_OFFSET_LOW 0x00000000 00084 #define CM_FLSHARE_LENGTH_HIGH 0x00000000 00085 #define CM_FLSHARE_LENGTH_LOW 0x00000001 00086 00087 typedef struct cm_prefetch { /* last region scanned for prefetching */ 00088 osi_hyper_t base; /* start of region */ 00089 osi_hyper_t end; /* first char past region */ 00090 } cm_prefetch_t; 00091 00092 #define CM_SCACHE_MAGIC ('S' | 'C'<<8 | 'A'<<16 | 'C'<<24) 00093 00094 typedef struct cm_scache { 00095 osi_queue_t q; /* lru queue; cm_scacheLock */ 00096 afs_uint32 magic; 00097 struct cm_scache *nextp; /* next in hash; cm_scacheLock */ 00098 struct cm_scache *allNextp; /* next in all scache list; cm_scacheLock */ 00099 cm_fid_t fid; 00100 afs_uint32 flags; /* flags; locked by rw */ 00101 00102 /* synchronization stuff */ 00103 osi_rwlock_t rw; /* rwlock for this structure */ 00104 osi_rwlock_t bufCreateLock; /* read-locked during buffer creation; 00105 * write-locked to prevent buffers from 00106 * being created during a truncate op, etc. 00107 */ 00108 afs_int32 refCount; /* reference count; cm_scacheLock */ 00109 osi_queueData_t *bufReadsp; /* queue of buffers being read */ 00110 osi_queueData_t *bufWritesp; /* queue of buffers being written */ 00111 00112 /* parent info for ACLs */ 00113 afs_uint32 parentVnode; /* parent vnode for ACL callbacks */ 00114 afs_uint32 parentUnique; /* for ACL callbacks */ 00115 00116 /* local modification stat */ 00117 afs_uint32 mask; /* for clientModTime, length and 00118 * truncPos */ 00119 00120 /* file status */ 00121 afs_uint32 fileType; /* file type */ 00122 time_t clientModTime; /* mtime */ 00123 time_t serverModTime; /* at server, for concurrent call 00124 * comparisons */ 00125 osi_hyper_t length; /* file length */ 00126 cm_prefetch_t prefetch; /* prefetch info structure */ 00127 afs_uint32 unixModeBits; /* unix protection mode bits */ 00128 afs_uint32 linkCount; /* link count */ 00129 afs_uint64 dataVersion; /* data version */ 00130 afs_uint64 bufDataVersionLow; /* range of valid cm_buf_t dataVersions; 00131 does not apply to directory buffers */ 00132 afs_uint32 owner; /* file owner */ 00133 afs_uint32 group; /* file owning group */ 00134 cm_user_t *creator; /* user, if new file */ 00135 00136 /* volume status */ 00137 time_t volumeCreationDate; /* volume creation date from AFSVolSync */ 00138 00139 /* pseudo file status */ 00140 osi_hyper_t serverLength; /* length known to server */ 00141 00142 /* aux file status */ 00143 osi_hyper_t truncPos; /* file size to truncate to before 00144 * storing data */ 00145 00146 /* symlink and mount point info */ 00147 afs_uint64 mpDataVersion; /* data version represented by mountPointStringp */ 00148 char mountPointStringp[MOUNTPOINTLEN]; /* the string stored in a mount point; 00149 * first char is type, then vol name. 00150 * If this is a normal symlink, we store 00151 * the link contents here. 00152 */ 00153 cm_fid_t mountRootFid; /* mounted on root */ 00154 time_t mountRootGen; /* time to update mountRootFid? */ 00155 cm_fid_t dotdotFid; /* parent of volume root */ 00156 00157 /* callback info */ 00158 struct cm_server *cbServerp; /* server granting callback */ 00159 time_t cbExpires; /* time callback expires */ 00160 time_t cbIssued; /* time callback was issued */ 00161 00162 /* access cache */ 00163 long anyAccess; /* anonymous user's access */ 00164 struct cm_aclent *randomACLp; /* access cache entries */ 00165 00166 /* file locks */ 00167 afs_int32 serverLock; /* current lock we have acquired on 00168 * this file. One of (-1), LockRead 00169 * or LockWrite. [protected by 00170 * scp->rw]. In the future, this 00171 * should be replaced by a queue of 00172 * cm_server_lock_t objects which keep 00173 * track of lock type, the user for 00174 * whom the lock was obtained, the 00175 * dataVersion at the time the lock 00176 * was asserted last, lastRefreshCycle 00177 * and lateUpdateTime. 00178 */ 00179 unsigned long lastRefreshCycle; /* protected with cm_scacheLock 00180 * for all scaches. */ 00181 afs_uint64 lockDataVersion; /* dataVersion of the scp at the time 00182 the server lock for the scp was 00183 asserted for this lock the last 00184 time. */ 00185 osi_queue_t *fileLocksH; /* queue of locks (head) */ 00186 osi_queue_t *fileLocksT; /* queue of locks (tail) */ 00187 00188 afs_uint32 sharedLocks; /* number of shared locks on 00189 * ::fileLocks. This count does not 00190 * include locks which have 00191 * CM_FILELOCK_FLAG_CLIENTONLY set. */ 00192 00193 afs_uint32 exclusiveLocks; /* number of exclusive locks on 00194 * ::fileLocks. This count does not 00195 * include locks which have 00196 * CM_FILELOCK_FLAG_CLIENTONLY set. 00197 */ 00198 00199 afs_uint32 clientLocks; /* number of locks on ::fileLocks that 00200 have CM_FILELOCK_FLAG_CLIENTONLY 00201 set. */ 00202 00203 afs_int32 fsLockCount; /* number of locks held as reported 00204 * by the file server in the most 00205 * recent fetch status. Updated by 00206 * the locks known to have been acquired 00207 * or released by this client. 00208 */ 00209 00210 /* bulk stat progress */ 00211 osi_hyper_t bulkStatProgress; /* track bulk stats of large dirs */ 00212 00213 #ifdef USE_BPLUS 00214 /* directory B+ tree */ /* only allocated if is directory */ 00215 osi_rwlock_t dirlock; /* controls access to dirBplus */ 00216 afs_uint64 dirDataVersion; /* data version represented by dirBplus */ 00217 struct tree *dirBplus; /* dirBplus */ 00218 #endif 00219 00220 /* open state */ 00221 afs_uint16 openReads; /* open for reading */ 00222 afs_uint16 openWrites; /* open for writing */ 00223 afs_uint16 openShares; /* open for read excl */ 00224 afs_uint16 openExcls; /* open for exclusives */ 00225 00226 /* syncop state */ 00227 afs_uint32 waitCount; /* number of threads waiting */ 00228 afs_uint32 waitRequests; /* num of thread wait requests */ 00229 osi_queue_t * waitQueueH; /* Queue of waiting threads. 00230 Holds queue of 00231 cm_scache_waiter_t 00232 objects. Protected by 00233 cm_scacheLock. */ 00234 osi_queue_t * waitQueueT; /* locked by cm_scacheLock */ 00235 00236 /* redirector state - protected by scp->redirMx */ 00237 osi_queue_t * redirQueueH; /* LRU queue of buffers for this 00238 file that are assigned to the 00239 afsredir kernel module. */ 00240 osi_queue_t * redirQueueT; 00241 afs_uint32 redirBufCount; /* Number of buffers held by the redirector */ 00242 time_t redirLastAccess; /* last time redir accessed the vnode */ 00243 osi_mutex_t redirMx; 00244 00245 afs_uint32 activeRPCs; /* atomic */ 00246 } cm_scache_t; 00247 00248 /* dataVersion */ 00249 #define CM_SCACHE_VERSION_BAD 0xFFFFFFFFFFFFFFFF 00250 00251 /* mask field - tell what has been modified */ 00252 #define CM_SCACHEMASK_CLIENTMODTIME 1 /* client mod time */ 00253 #define CM_SCACHEMASK_LENGTH 2 /* length */ 00254 #define CM_SCACHEMASK_TRUNCPOS 4 /* truncation position */ 00255 00256 /* fileType values */ 00257 #define CM_SCACHETYPE_UNKNOWN 0 /* unknown */ 00258 #define CM_SCACHETYPE_FILE 1 /* a file */ 00259 #define CM_SCACHETYPE_DIRECTORY 2 /* a dir */ 00260 #define CM_SCACHETYPE_SYMLINK 3 /* a symbolic link */ 00261 #define CM_SCACHETYPE_MOUNTPOINT 4 /* a mount point */ 00262 #define CM_SCACHETYPE_DFSLINK 5 /* a Microsoft Dfs link */ 00263 #define CM_SCACHETYPE_INVALID 99 /* an invalid link */ 00264 00265 /* flag bits */ 00266 #define CM_SCACHEFLAG_DELETED 0x02 /* file has been deleted */ 00267 #define CM_SCACHEFLAG_STORING 0x08 /* status being stored back */ 00268 #define CM_SCACHEFLAG_FETCHING 0x10 /* status being fetched */ 00269 #define CM_SCACHEFLAG_SIZESTORING 0x20 /* status being stored that 00270 * changes the data; typically, 00271 * this is a truncate op. */ 00272 #define CM_SCACHEFLAG_INHASH 0x40 /* in the hash table */ 00273 #define CM_SCACHEFLAG_BULKSTATTING 0x80 /* doing a bulk stat */ 00274 #define CM_SCACHEFLAG_SIZESETTING 0x100 /* Stabilized; Truncate */ 00275 #define CM_SCACHEFLAG_WAITING 0x200 /* waiting for fetch/store 00276 * state to change */ 00277 #define CM_SCACHEFLAG_PURERO 0x400 /* read-only (not even backup); 00278 * for mount point eval */ 00279 #define CM_SCACHEFLAG_RO 0x800 /* read-only 00280 * (can't do write ops) */ 00281 #define CM_SCACHEFLAG_GETCALLBACK 0x1000 /* we're getting a callback */ 00282 #define CM_SCACHEFLAG_DATASTORING 0x2000 /* data being stored */ 00283 #define CM_SCACHEFLAG_PREFETCHING 0x4000 /* somebody is prefetching */ 00284 #define CM_SCACHEFLAG_OVERQUOTA 0x8000 /* over quota */ 00285 #define CM_SCACHEFLAG_OUTOFSPACE 0x10000 /* out of space */ 00286 #define CM_SCACHEFLAG_ASYNCSTORING 0x20000 /* scheduled to store back */ 00287 #define CM_SCACHEFLAG_LOCKING 0x40000 /* setting/clearing file lock */ 00288 #define CM_SCACHEFLAG_WATCHED 0x80000 /* directory being watched */ 00289 #define CM_SCACHEFLAG_WATCHEDSUBTREE 0x100000 /* dir subtree being watched */ 00290 #define CM_SCACHEFLAG_ANYWATCH \ 00291 (CM_SCACHEFLAG_WATCHED | CM_SCACHEFLAG_WATCHEDSUBTREE) 00292 00293 #define CM_SCACHEFLAG_SMB_FID 0x400000 00294 #define CM_SCACHEFLAG_LOCAL 0x800000 /* Locally modified */ 00295 #define CM_SCACHEFLAG_BULKREADING 0x1000000/* Bulk read in progress */ 00296 #define CM_SCACHEFLAG_RDR_IN_USE 0x2000000/* in use by Redirector; advisory */ 00297 00298 /* sync flags for calls to the server. The CM_SCACHEFLAG_FETCHING, 00299 * CM_SCACHEFLAG_STORING and CM_SCACHEFLAG_SIZESTORING flags correspond to the 00300 * below, except for FETCHDATA and STOREDATA, which correspond to non-null 00301 * buffers in bufReadsp and bufWritesp. 00302 * These flags correspond to individual RPCs that we may be making, and at most 00303 * one can be set in any one call to SyncOp. 00304 */ 00305 #define CM_SCACHESYNC_FETCHSTATUS 0x01 /* fetching status info */ 00306 #define CM_SCACHESYNC_STORESTATUS 0x02 /* storing status info */ 00307 #define CM_SCACHESYNC_FETCHDATA 0x04 /* fetch data */ 00308 #define CM_SCACHESYNC_STOREDATA 0x08 /* store data */ 00309 #define CM_SCACHESYNC_STORESIZE 0x10 /* store new file size */ 00310 #define CM_SCACHESYNC_GETCALLBACK 0x20 /* fetching a callback */ 00311 #define CM_SCACHESYNC_STOREDATA_EXCL 0x40 /* store data */ 00312 #define CM_SCACHESYNC_ASYNCSTORE 0x80 /* schedule data store */ 00313 #define CM_SCACHESYNC_LOCK 0x100 /* set/clear file lock */ 00314 00315 /* sync flags for calls within the client; there are no corresponding flags 00316 * in the scache entry, because we hold the scache entry locked during the 00317 * operations below. 00318 */ 00319 #define CM_SCACHESYNC_GETSTATUS 0x1000 /* read the status */ 00320 #define CM_SCACHESYNC_SETSTATUS 0x2000 /* e.g. utimes */ 00321 #define CM_SCACHESYNC_READ 0x4000 /* read data from a chunk */ 00322 #define CM_SCACHESYNC_WRITE 0x8000 /* write data to a chunk */ 00323 #define CM_SCACHESYNC_SETSIZE 0x10000 /* shrink the size of a file, 00324 * e.g. truncate */ 00325 #define CM_SCACHESYNC_NEEDCALLBACK 0x20000 /* need a callback on the file */ 00326 #define CM_SCACHESYNC_CHECKRIGHTS 0x40000 /* check that user has desired 00327 * access rights */ 00328 #define CM_SCACHESYNC_BUFLOCKED 0x80000 /* the buffer is locked */ 00329 #define CM_SCACHESYNC_NOWAIT 0x100000/* don't wait for the state, 00330 * just fail */ 00331 #define CM_SCACHESYNC_FORCECB 0x200000/* when calling cm_GetCallback() 00332 * set the force flag */ 00333 00334 #define CM_SCACHESYNC_BULKREAD 0x400000/* reading many buffers */ 00335 00336 /* flags for cm_RecycleSCache */ 00337 #define CM_SCACHE_RECYCLEFLAG_DESTROY_BUFFERS 0x1 00338 00339 /* flags for cm_MergeStatus */ 00340 #define CM_MERGEFLAG_FORCE 1 /* check mtime before merging; 00341 * used to see if we're merging 00342 * in old info. 00343 */ 00344 #define CM_MERGEFLAG_STOREDATA 2 /* Merge due to storedata op */ 00345 #define CM_MERGEFLAG_DIROP 4 /* Merge due to directory op */ 00346 #define CM_MERGEFLAG_FETCHDATA 8 /* Merge due to fetchdata op */ 00347 #define CM_MERGEFLAG_BULKSTAT 0x10 /* Merge due to bulkstat op */ 00348 00349 /* hash define. Must not include the cell, since the callback revocation code 00350 * doesn't necessarily know the cell in the case of a multihomed server 00351 * contacting us from a mystery address. 00352 */ 00353 00354 #define CM_FID_GEN_HASH(fidp) do { \ 00355 (fidp)->hash = opr_jhash(&(fidp)->volume, 3, 0); \ 00356 } while(0) 00357 00358 #define CM_SCACHE_HASH(fidp) ((fidp)->hash & (cm_data.scacheHashTableSize - 1)) 00359 00360 #include "cm_conn.h" 00361 #include "cm_buf.h" 00362 00363 typedef struct cm_scache_waiter { 00364 osi_queue_t q; 00365 afs_int32 threadId; 00366 00367 cm_scache_t *scp; 00368 afs_int32 flags; 00369 cm_buf_t *bufp; 00370 } cm_scache_waiter_t; 00371 00372 extern void cm_InitSCache(int, long); 00373 00374 #ifdef DEBUG_REFCOUNT 00375 extern long cm_GetSCacheDbg(cm_fid_t *, cm_fid_t *, cm_scache_t **, struct cm_user *, 00376 struct cm_req *, char *, long); 00377 00378 #define cm_GetSCache(a,b,c,d,e) cm_GetSCacheDbg(a,b,c,d,e,__FILE__,__LINE__) 00379 #else 00380 extern long cm_GetSCache(cm_fid_t *, cm_fid_t *, cm_scache_t **, struct cm_user *, 00381 struct cm_req *); 00382 #endif 00383 00384 extern cm_scache_t *cm_GetNewSCache(afs_uint32 locked); 00385 00386 extern __inline int cm_FidCmp(cm_fid_t *, cm_fid_t *); 00387 00388 extern void cm_SetFid(cm_fid_t *, afs_uint32 cell, afs_uint32 volume, afs_uint32 vnode, afs_uint32 unique); 00389 00390 extern long cm_SyncOp(cm_scache_t *, struct cm_buf *, struct cm_user *, 00391 struct cm_req *, afs_uint32, afs_uint32); 00392 00393 extern void cm_SyncOpDone(cm_scache_t *, struct cm_buf *, afs_uint32); 00394 00395 extern void cm_MergeStatus(cm_scache_t * dscp, cm_scache_t * scp, 00396 struct AFSFetchStatus * statusp, 00397 struct AFSVolSync * volsyncp, 00398 struct cm_user *userp, 00399 cm_req_t *reqp, 00400 afs_uint32 flags); 00401 00402 extern void cm_AFSFidFromFid(struct AFSFid *, cm_fid_t *); 00403 00404 #ifdef DEBUG_REFCOUNT 00405 extern void cm_HoldSCacheNoLockDbg(cm_scache_t *, char *, long); 00406 00407 extern void cm_HoldSCacheDbg(cm_scache_t *, char *, long); 00408 00409 extern void cm_ReleaseSCacheNoLockDbg(cm_scache_t *, char *, long); 00410 00411 extern void cm_ReleaseSCacheDbg(cm_scache_t *, char *, long); 00412 00413 #define cm_HoldSCacheNoLock(scp) cm_HoldSCacheNoLockDbg(scp, __FILE__, __LINE__) 00414 #define cm_HoldSCache(scp) cm_HoldSCacheDbg(scp, __FILE__, __LINE__) 00415 #define cm_ReleaseSCacheNoLock(scp) cm_ReleaseSCacheNoLockDbg(scp, __FILE__, __LINE__) 00416 #define cm_ReleaseSCache(scp) cm_ReleaseSCacheDbg(scp, __FILE__, __LINE__) 00417 #else 00418 extern void cm_HoldSCacheNoLock(cm_scache_t *); 00419 00420 extern void cm_HoldSCache(cm_scache_t *); 00421 00422 extern void cm_ReleaseSCacheNoLock(cm_scache_t *); 00423 00424 extern void cm_ReleaseSCache(cm_scache_t *); 00425 #endif 00426 extern cm_scache_t *cm_FindSCache(cm_fid_t *fidp); 00427 00428 extern cm_scache_t *cm_FindSCacheParent(cm_scache_t *); 00429 00430 extern osi_rwlock_t cm_scacheLock; 00431 00432 extern osi_queue_t *cm_allFileLocks; 00433 00434 extern osi_queue_t *cm_freeFileLocks; 00435 00436 extern unsigned long cm_lockRefreshCycle; 00437 00438 extern void cm_DiscardSCache(cm_scache_t *scp); 00439 00440 extern int cm_FindFileType(cm_fid_t *fidp); 00441 00442 extern long cm_ValidateSCache(void); 00443 00444 extern long cm_ShutdownSCache(void); 00445 00446 extern void cm_SuspendSCache(void); 00447 00448 extern long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags); 00449 00450 extern void cm_RemoveSCacheFromHashTable(cm_scache_t *scp); 00451 00452 extern void cm_AdjustScacheLRU(cm_scache_t *scp); 00453 00454 extern int cm_DumpSCache(FILE *outputFile, char *cookie, int lock); 00455 00456 extern void cm_ResetSCacheDirectory(cm_scache_t *scp, afs_int32 locked); 00457 00458 extern cm_scache_t * cm_RootSCachep(cm_user_t *userp, cm_req_t *reqp); 00459 #endif /* OPENAFS_WINNT_AFSD_CM_SCACHE_H */