OpenAFS
OpenAFS distributed network file system
/cygdrive/c/src/openafs/openafs.git/repo/src/WINNT/afsd/cm_scache.h
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 */
 All Data Structures Files Functions Variables