*/
#ifdef KDUMP_KERNEL
#include <afs/afs_args.h>
+#include <afs/afs_consts.h>
#else
#include "afs/afs_args.h"
+#include "afs/afs_consts.h"
#endif
+/*
+ * afs_fsfragsize cannot be less than 1023, or some cache-tracking
+ * calculations will be incorrect (since we track cache usage in kb).
+ * Some filesystems have fundamental blocksizes less than 1k, and
+ * normally we would tune afs_fsfragsize to be fragsize-1, but we must
+ * make sure to check that afs_fsfragsize does not go below this value.
+ */
+#define AFS_MIN_FRAGSIZE 1023
/* Upper bound on number of iovecs out uio routines will deal with. */
#define AFS_MAXIOVCNT 16
#if defined(AFS_HPUX102_ENV)
#define AFS_FLOCK k_flock
#else
-#if defined(AFS_SUN56_ENV) || (defined(AFS_LINUX24_ENV) && !defined(AFS_PPC64_LINUX26_ENV) && !defined(AFS_AMD64_LINUX26_ENV) && !defined(AFS_IA64_LINUX26_ENV) && !defined(AFS_S390X_LINUX26_ENV) && !defined(AFS_ALPHA_LINUX26_ENV))
+#if defined(AFS_SUN56_ENV) || (defined(AFS_LINUX24_ENV) && !(defined(AFS_LINUX26_ENV) && defined(AFS_LINUX_64BIT_KERNEL)))
#define AFS_FLOCK flock64
#else
#define AFS_FLOCK flock
/* The basic defines for the Andrew file system
better keep things powers of two so "& (foo-1)" hack works for masking bits */
-#define MAXHOSTS 13 /* max hosts per single volume */
-#define OMAXHOSTS 8 /* backwards compatibility */
-#define MAXCELLHOSTS 8 /* max vldb servers per cell */
#define NBRS 15 /* max number of queued daemon requests */
#define NUSERS 16 /* hash table size for unixuser table */
#define NSERVERS 16 /* hash table size for server table */
#define AFS_NRXPACKETS 80
#define AFS_RXDEADTIME 50
#define AFS_HARDDEADTIME 120
+#define AFS_IDLEDEADTIME 50
+#define AFS_BLKBITS 12
+#define AFS_BLKSIZE (1 << AFS_BLKBITS)
extern afs_int32 afs_rx_deadtime;
extern afs_int32 afs_rx_harddead;
+extern afs_int32 afs_rx_idledead;
struct sysname_info {
char *name;
#define BOP_STORE 2 /* parm1 is chunk to store */
#define BOP_PATH 3 /* parm1 is path, parm2 is chunk to fetch */
+#if defined(AFS_CACHE_BYPASS)
+#define BOP_FETCH_NOCACHE 4 /* parms are: vnode ptr, offset, segment ptr, addr, cred ptr */
+#endif
+
#define B_DONTWAIT 1 /* On failure return; don't wait */
/* protocol is: refCount is incremented by user to take block out of free pool.
#define BUWAIT 4 /* someone is waiting for BUVALID */
struct brequest {
struct vcache *vc; /* vnode to use, with vrefcount bumped */
- struct AFS_UCRED *cred; /* credentials to use for operation */
+ afs_ucred_t *cred; /* credentials to use for operation */
afs_size_t size_parm[BPARMS]; /* random parameters */
void *ptr_parm[BPARMS]; /* pointer parameters */
afs_int32 code; /* return code */
/* The actual number of bytes in the SmallFid, not the sizeof struct. */
#define SIZEOF_SMALLFID 10
+/* Queues
+ * ------
+ *
+ * Circular queues, implemented with pointers. Structures may contain as many
+ * queues as required, which may be located at any point within the structure,
+ * providing the QEntry macro is used to translate between a queue pointer, and
+ * the address of its containing structure
+ */
-/*
- * Queues implemented with both pointers and short offsets into a disk file.
- */
struct afs_q {
struct afs_q *next;
struct afs_q *prev;
};
+#define QZero(e) ((e)->prev = (e)->next = NULL)
+#define QInit(q) ((q)->prev = (q)->next = (q))
+#define QAdd(q,e) ((e)->next = (q)->next, (e)->prev = (q), \
+ (q)->next->prev = (e), (q)->next = (e))
+#define QRemove(e) ((e)->next->prev = (e)->prev, (e)->prev->next = (e)->next, (e)->prev = NULL, (e)->next = NULL)
+#define QNext(e) ((e)->next)
+#define QPrev(e) ((e)->prev)
+#define QEmpty(q) ((q)->prev == (q))
+/* this one takes q1 and sticks it on the end of q2 - that is, the other end, not the end
+ * that things are added onto. q1 shouldn't be empty, it's silly */
+#define QCat(q1,q2) ((q2)->prev->next = (q1)->next, (q1)->next->prev=(q2)->prev, (q1)->prev->next=(q2), (q2)->prev=(q1)->prev, (q1)->prev=(q1)->next=(q1))
+
+/* Given a pointer to an afs_q within a structure, go back to the address of
+ * the parent structure
+ */
+
+#define QEntry(queue, structure, member) \
+ ((structure *)((char *)(queue)-(char *)(&((structure *)NULL)->member)))
+
+/* And implement operations for individual lists in terms of the above macro */
+
+#define QTOV(e) QEntry(e, struct vcache, vlruq)
+#define QTOC(e) QEntry(e, struct cell, lruq)
+#define QTOVH(e) QEntry(e, struct vcache, vhashq)
+
+/*!
+ * List of free slot numbers
+ */
+struct afs_slotlist {
+ afs_uint32 slot;
+ struct afs_slotlist *next;
+};
+
struct vrequest {
afs_int32 uid; /* user id making the request */
afs_int32 busyCount; /* how many busies we've seen so far */
afs_int32 flags; /* things like O_SYNC, O_NONBLOCK go here */
- char initd; /* if non-zero, non-uid fields meaningful */
+ char initd; /* if non-zero, Error fields meaningful */
char accessError; /* flags for overriding error return code */
char volumeError; /* encountered a missing or busy volume */
char networkError; /* encountered network problems */
char permWriteError; /* fileserver returns permenent error. */
+ char tokenError; /* a token error other than expired. */
+ char idleError; /* the server idled too long */
+ char skipserver[AFS_MAXHOSTS];
};
#define VOLMISSING 1
#define VOLBUSY 2
char *cellName; /* char string name of cell */
afs_int32 cellIndex; /* sequence number */
afs_int32 cellNum; /* semi-permanent cell number */
- struct server *cellHosts[MAXCELLHOSTS]; /* volume *location* hosts */
+ struct server *cellHosts[AFS_MAXCELLHOSTS]; /* volume *location* hosts */
struct cell *lcellp; /* Associated linked cell */
u_short fsport; /* file server port */
u_short vlport; /* volume server port */
time_t timeout; /* data expire time, if non-zero */
struct cell_name *cnamep; /* pointer to our cell_name */
afs_rwlock_t lock; /* protects cell data */
+ unsigned char cellHandle[16]; /* deterministic handle for this cell */
};
struct cell_name {
#define UPrimary 4 /* on iff primary identity */
#define UNeedsReset 8 /* needs afs_ResetAccessCache call done */
#define UPAGCounted 16 /* entry seen during PAG search (for stats) */
+#define UNFSGetCreds 32 /* getting creds for NFS client */
/* A flag used by afs_GCPAGs to keep track of
* which entries in afs_users need to be deleted.
* The lifetime of its presence in the table is the
extern afs_int32 afs_gcpags;
extern afs_int32 afs_gcpags_procsize;
extern afs_int32 afs_bkvolpref;
+extern char afs_cachebasedir[1024];
+extern afs_int32 afs_numcachefiles;
+extern afs_int32 afs_numfilesperdir;
struct unixuser {
struct unixuser *next; /* next hash pointer */
char *stp; /* pointer to ticket itself */
struct ClearToken ct;
struct afs_exporter *exporter; /* more info about the exporter for the remote user */
+ void *cellinfo; /* pointer to cell info (PAG manager only) */
};
-struct conn {
+struct afs_conn {
/* Per-connection block. */
- struct conn *next; /* Next dude same server. */
+ struct afs_conn *next; /* Next dude same server. */
struct unixuser *user; /* user validated with respect to. */
struct rx_connection *id; /* RPC connid. */
struct srvAddr *srvr; /* server associated with this conn */
|| (a)->Fid.Volume != (b)->Fid.Volume \
|| (a)->Cell != (b)->Cell)
-#define FidMatches(afid,tvc) ((tvc)->fid.Fid.Vnode == (afid)->Fid.Vnode && \
- (tvc)->fid.Fid.Volume == (afid)->Fid.Volume && \
- (tvc)->fid.Cell == (afid)->Cell && \
- ( (tvc)->fid.Fid.Unique == (afid)->Fid.Unique || \
- (!(afid)->Fid.Unique && ((tvc)->states & CUnique))))
+#define FidMatches(afid,tvc) ((tvc)->f.fid.Fid.Vnode == (afid)->Fid.Vnode && \
+ (tvc)->f.fid.Fid.Volume == (afid)->Fid.Volume && \
+ (tvc)->f.fid.Cell == (afid)->Cell && \
+ ( (tvc)->f.fid.Fid.Unique == (afid)->Fid.Unique || \
+ (!(afid)->Fid.Unique && ((tvc)->f.states & CUnique))))
-/*
- * Operations on circular queues implemented with pointers. Note: these queue
- * objects are always located at the beginning of the structures they are linking.
- */
-#define QInit(q) ((q)->prev = (q)->next = (q))
-#define QAdd(q,e) ((e)->next = (q)->next, (e)->prev = (q), \
- (q)->next->prev = (e), (q)->next = (e))
-#define QRemove(e) ((e)->next->prev = (e)->prev, (e)->prev->next = (e)->next)
-#define QNext(e) ((e)->next)
-#define QPrev(e) ((e)->prev)
-#define QEmpty(q) ((q)->prev == (q))
-/* this one takes q1 and sticks it on the end of q2 - that is, the other end, not the end
- * that things are added onto. q1 shouldn't be empty, it's silly */
-#define QCat(q1,q2) ((q2)->prev->next = (q1)->next, (q1)->next->prev=(q2)->prev, (q1)->prev->next=(q2), (q2)->prev=(q1)->prev, (q1)->prev=(q1)->next=(q1))
-/*
- * Do lots of address arithmetic to go from vlruq to the base of the vcache
- * structure. Don't move struct vnode, since we think of a struct vcache as
- * a specialization of a struct vnode
- */
-#define QTOV(e) ((struct vcache *)(((char *) (e)) - (((char *)(&(((struct vcache *)(e))->vlruq))) - ((char *)(e)))))
-#define QTOC(e) ((struct cell *)((char *) (e)))
-
#define SRVADDR_MH 1
#define SRVADDR_ISDOWN 0x20 /* same as SRVR_ISDOWN */
#define SRVADDR_NOUSE 0x40 /* Don't use this srvAddr */
struct srvAddr *next_bkt; /* next item in hash bucket */
struct srvAddr *next_sa; /* another interface on same host */
struct server *server; /* back to parent */
- struct conn *conns; /* All user connections to this server */
+ struct afs_conn *conns; /* All user connections to this server */
afs_int32 sa_ip; /* Host addr in network byte order */
u_short sa_iprank; /* indiv ip address priority */
u_short sa_portal; /* port addr in network byte order */
afs_rwlock_t lock; /* the lock for this structure */
afs_int32 volume; /* This volume's ID number. */
char *name; /* This volume's name, or 0 if unknown */
- struct server *serverHost[MAXHOSTS]; /* servers serving this volume */
- enum repstate status[MAXHOSTS]; /* busy, offline, etc */
+ struct server *serverHost[AFS_MAXHOSTS]; /* servers serving this volume */
+ enum repstate status[AFS_MAXHOSTS]; /* busy, offline, etc */
struct VenusFid dotdot; /* dir to access as .. */
struct VenusFid mtpoint; /* The mount point for this volume. */
afs_int32 rootVnode, rootUnique; /* Volume's root fid */
#define CNSHARE 0x00000100 /* support O_NSHARE semantics */
#define CLied 0x00000200
#define CTruth 0x00000400
-#ifdef AFS_OSF_ENV
-#define CWired 0x00000800 /* OSF hack only */
-#else
-#ifdef AFS_DARWIN_ENV
+
+#if defined(AFS_DARWIN80_ENV)
+#define CDeadVnode 0x00000800
+#elif defined(AFS_DARWIN_ENV)
#define CUBCinit 0x00000800
#else
#define CWRITE_IGN 0x00000800 /* Next OS hack only */
#endif
-#endif
+
#define CUnique 0x00001000 /* vc's uniquifier - latest unifiquier for fid */
#define CForeign 0x00002000 /* this is a non-afs vcache */
+#define CReadDir 0x00004000 /* readdir in progress */
#define CUnlinked 0x00010000
#define CBulkStat 0x00020000 /* loaded by a bulk stat, and not ref'd since */
#define CUnlinkedDel 0x00040000
#define CVFlushed 0x00080000
-#define CCore1 0x00100000 /* osf1 core file; not same as CCore above */
+#ifdef AFS_LINUX22_ENV
+#define CPageWrite 0x00200000 /* to detect vm deadlock - linux */
+#else
#define CWritingUFS 0x00200000 /* to detect vm deadlock - used by sgi */
+#endif
#define CCreating 0x00400000 /* avoid needless store after open truncate */
#define CPageHog 0x00800000 /* AIX - dumping large cores is a page hog. */
#define CDCLock 0x02000000 /* Vnode lock held over call to GetDownD */
#define CBulkFetching 0x04000000 /* stats are being fetched by bulk stat */
#define CExtendedFile 0x08000000 /* extended file via ftruncate call. */
+#define CVInit 0x10000000 /* being initialized */
+#define CMetaDirty 0x20000000 /* vnode meta-data needs to be flushed */
/* vcache vstate bits */
#define VRevokeWait 0x1
#define VPageCleaning 0x2 /* Solaris - Cache Trunc Daemon sez keep out */
+#if defined(AFS_DISCON_ENV)
+
+/* Dirty disconnected vcache flags. */
+#define VDisconSetTime 0x00000001 /* set time. */
+#define VDisconSetMode 0x00000002 /* set mode. */
+/* XXX: to be continued ? */
+#define VDisconTrunc 0x00000020 /* truncate file. */
+#define VDisconSetAttrMask 0x0000003F /* Masks for setattr ops. */
+#define VDisconWriteClose 0x00000400 /* Write op on file close. */
+#define VDisconWriteFlush 0x00000800 /* Write op on normal fsync/flush. */
+#define VDisconWriteOsiFlush 0x00001000 /* Write op on osi flush. */
+
+#define VDisconRemove 0x00002000 /* Remove vnop. */
+#define VDisconCreate 0x00004000 /* Create vnop. */
+#define VDisconCreated 0x00008000 /* A file that was created during
+ this resync operation */
+#define VDisconRename 0x00010000 /* Rename vnop. */
+#define VDisconRenameSameDir 0x00020000 /* Rename in same dir. */
+
+/*... to be continued ... */
+#endif
+
+#if defined(AFS_CACHE_BYPASS)
+/* vcache (file) cachingStates bits */
+#define FCSDesireBypass 0x1 /* This file should bypass the cache */
+#define FCSBypass 0x2 /* This file is currently NOT being cached */
+#define FCSManuallySet 0x4 /* The bypass flags were set, or reset, manually (via pioctl)
+ and should not be overridden by the file's name */
+
+/* Flag values used by the Transition routines */
+#define TRANSChangeDesiredBit 0x1 /* The Transition routine should set or
+ * reset the FCSDesireBypass bit */
+#define TRANSVcacheIsLocked 0x2 /* The Transition routine does not need to
+ * lock vcache (it's already locked) */
+#define TRANSSetManualBit 0x4 /* The Transition routine should set FCSManuallySet so that
+ * filename checking does not override pioctl requests */
+#endif /* AFS_CACHE_BYPASS */
+
#define CPSIZE 2
#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
#define vrefCount v->v_usecount
#define vrefCount v.v_count
#endif /* AFS_XBSD_ENV */
-#if defined(AFS_LINUX24_ENV)
-#define VREFCOUNT(v) atomic_read(&((vnode_t *) v)->v_count)
-#define VREFCOUNT_SET(v, c) atomic_set(&((vnode_t *) v)->v_count, c)
-#define VREFCOUNT_DEC(v) atomic_dec(&((vnode_t *) v)->v_count)
-#define VREFCOUNT_INC(v) atomic_inc(&((vnode_t *) v)->v_count)
+#if defined(AFS_DARWIN80_ENV)
+#define VREFCOUNT_GT(v, y) vnode_isinuse(AFSTOV(v), (y))
+#elif defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
+#define VREFCOUNT(v) ((v)->vrefCount)
+#define VREFCOUNT_GT(v, y) (AFSTOV(v)->v_usecount > (y))
+#elif defined(AFS_LINUX24_ENV)
+#define VREFCOUNT(v) atomic_read(&(AFSTOV(v)->v_count))
+#define VREFCOUNT_GT(v, y) (VREFCOUNT(v)>y)
+#define VREFCOUNT_SET(v, c) atomic_set(&(AFSTOV(v)->v_count), c)
+#define VREFCOUNT_DEC(v) atomic_dec(&(AFSTOV(v)->v_count))
+#define VREFCOUNT_INC(v) atomic_inc(&(AFSTOV(v)->v_count))
#else
#define VREFCOUNT(v) ((v)->vrefCount)
+#define VREFCOUNT_GT(v,y) ((v)->vrefCount > (y))
#define VREFCOUNT_SET(v, c) (v)->vrefCount = c;
#define VREFCOUNT_DEC(v) (v)->vrefCount--;
#define VREFCOUNT_INC(v) (v)->vrefCount++;
extern afs_int32 vmPageHog; /* counter for # of vnodes which are page hogs. */
-/*
- * Fast map from vcache to dcache
- */
-struct vtodc {
- struct dcache *dc;
- afs_uint32 stamp;
- struct osi_file *f;
- afs_offs_t minLoc; /* smallest offset into dc. */
- afs_offs_t len; /* largest offset into dc. */
-};
-
-extern afs_uint32 afs_stampValue; /* stamp for pair's usage */
-#define MakeStamp() (++afs_stampValue)
-
-#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
+#if defined(AFS_DARWIN80_ENV)
+#define VTOAFS(v) ((struct vcache *)vnode_fsnode((v)))
+#define AFSTOV(vc) ((vc)->v)
+#elif defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_HAS_ALLOC_INODE))
#define VTOAFS(v) ((struct vcache *)(v)->v_data)
#define AFSTOV(vc) ((vc)->v)
#else
#define AFSTOV(V) (&(V)->v)
#endif
-#ifdef AFS_LINUX22_ENV
-#define ITOAFS(V) ((struct vcache*)(V))
-#define AFSTOI(V) (struct inode *)(&(V)->v)
+struct afs_vnuniq {
+ afs_uint32 vnode;
+ afs_uint32 unique;
+};
+
+/* VCache elements which are kept on disk, and in the kernel */
+struct fvcache {
+ struct VenusFid fid;
+ struct mstat {
+ afs_size_t Length;
+ afs_hyper_t DataVersion;
+ afs_uint32 Date;
+ afs_uint32 Owner;
+ afs_uint32 Group;
+ afs_uint16 Mode; /* XXXX Should be afs_int32 XXXX */
+ afs_uint16 LinkCount;
+#ifdef AFS_DARWIN80_ENV
+ afs_uint16 Type;
+#else
+ /* vnode type is in v.v_type */
#endif
+ } m;
+ struct afs_vnuniq parent;
+
+ /*! Truncate file to this position at the next store */
+ afs_size_t truncPos;
+
+ /*! System:AnyUser's access to this. */
+ afs_int32 anyAccess;
+
+ /*! state bits */
+ afs_uint32 states;
+#if defined(AFS_DISCON_ENV)
+ /*! Disconnected flags for this vcache element. */
+ afs_uint32 ddirty_flags;
+ /*! Shadow vnode + unique keep the shadow dir location. */
+ struct afs_vnuniq shadow;
+ /*! The old parent FID for renamed vnodes */
+ struct afs_vnuniq oldParent;
+#endif
+};
+
/* INVARIANTs: (vlruq.next != NULL) == (vlruq.prev != NULL)
* nextfree => !vlruq.next && ! vlruq.prev
* !(avc->nextfree) && !avc->vlruq.next => (FreeVCList == avc->nextfree)
*/
struct vcache {
-#if defined(AFS_XBSD_ENV)||defined(AFS_DARWIN_ENV)
+#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_HAS_ALLOC_INODE))
struct vnode *v;
#else
struct vnode v; /* Has reference count in v.v_count */
#endif
struct afs_q vlruq; /* lru q next and prev */
+#if !defined(AFS_LINUX22_ENV)
struct vcache *nextfree; /* next on free list (if free) */
+#endif
struct vcache *hnext; /* Hash next */
- struct VenusFid fid;
- struct mstat {
- afs_size_t Length;
- afs_hyper_t DataVersion;
- afs_uint32 Date;
- afs_uint32 Owner;
- afs_uint32 Group;
- afs_uint16 Mode; /* XXXX Should be afs_int32 XXXX */
- afs_uint16 LinkCount;
- /* vnode type is in v.v_type */
- } m;
+ struct afs_q vhashq; /* Hashed per-volume list */
+#if defined(AFS_DISCON_ENV)
+ /*! Queue of dirty vcaches. Lock with afs_disconDirtyLock */
+ struct afs_q dirtyq;
+ /*! Queue of vcaches with shadow entries. Lock with afs_disconDirtyLock */
+ struct afs_q shadowq;
+ /*! Queue of vcaches with dirty metadata. Locked by afs_xvcdirty */
+ struct afs_q metadirty;
+ /*! Vcaches slot number in the disk backup. Protected by tvc->lock */
+ afs_uint32 diskSlot;
+#endif
+ struct fvcache f;
afs_rwlock_t lock; /* The lock on the vcache contents. */
#if defined(AFS_SUN5_ENV)
/* Lock used to protect the activeV, multipage, and vstates fields.
#ifdef AFS_AIX_ENV
int ownslock; /* pid of owner of excl lock, else 0 - defect 3083 */
#endif
-#ifdef AFS_DARWIN_ENV
+#ifdef AFS_DARWIN80_ENV
+ lck_mtx_t *rwlock;
+#elif defined(AFS_DARWIN_ENV)
struct lock__bsd__ rwlock;
#endif
#ifdef AFS_XBSD_ENV
+#if !defined(AFS_DFBSD_ENV)
struct lock rwlock;
#endif
- afs_int32 parentVnode; /* Parent dir, if a file. */
- afs_int32 parentUnique;
+#endif
+
struct VenusFid *mvid; /* Either parent dir (if root) or root (if mt pt) */
char *linkData; /* Link data if a symlink. */
afs_hyper_t flushDV; /* data version last flushed from text */
afs_hyper_t mapDV; /* data version last flushed from map */
- afs_size_t truncPos; /* truncate file to this position at next store */
struct server *callback; /* The callback host, if any */
afs_uint32 cbExpires; /* time the callback expires */
struct afs_q callsort; /* queue in expiry order, sort of */
struct axscache *Access; /* a list of cached access bits */
- afs_int32 anyAccess; /* System:AnyUser's access to this. */
afs_int32 last_looker; /* pag/uid from last lookup here */
#if defined(AFS_SUN5_ENV)
afs_int32 activeV;
* this file. */
short flockCount; /* count of flock readers, or -1 if writer */
char mvstat; /* 0->normal, 1->mt pt, 2->root. */
- afs_uint32 states; /* state bits */
+
+#if defined(AFS_CACHE_BYPASS)
+ char cachingStates; /* Caching policies for this file */
+ afs_uint32 cachingTransitions; /* # of times file has flopped between caching and not */
+#if defined(AFS_LINUX24_ENV)
+ off_t next_seq_offset; /* Next sequential offset (used by prefetch/readahead) */
+#else
+ off_t next_seq_blk_offset; /* accounted in blocks for Solaris & IRIX */
+#endif
+#endif
+
#if defined(AFS_SUN5_ENV)
afs_uint32 vstates; /* vstate bits */
#endif /* defined(AFS_SUN5_ENV) */
- struct vtodc quick;
- afs_uint32 symhintstamp;
- union {
- struct vcache *symhint;
- struct dcache *dchint;
- } h1;
+ struct dcache *dchint;
+ struct dcache *dcreaddir; /* dcache for in-progress readdir */
+ unsigned int readdir_pid; /* pid of the thread in readdir */
#ifdef AFS_LINUX22_ENV
u_short mapcnt; /* Number of mappings of this file. */
#endif
struct bhv_desc vc_bhv_desc; /* vnode's behavior data. */
#endif
#endif /* AFS_SGI_ENV */
+#if defined(AFS_LINUX26_ENV)
+ cred_t *cred; /* last writer's cred */
+#endif
afs_int32 vc_error; /* stash write error for this vnode. */
int xlatordv; /* Used by nfs xlator */
- struct AFS_UCRED *uncred;
+ afs_ucred_t *uncred;
int asynchrony; /* num kbytes to store behind */
#ifdef AFS_SUN5_ENV
short multiPage; /* count of multi-page getpages in progress */
#endif
};
-#define afs_symhint_inval(avc)
-
-
#define DONT_CHECK_MODE_BITS 0
#define CHECK_MODE_BITS 1
#define CMB_ALLOW_EXEC_AS_READ 2 /* For the NFS xlator */
afs_uint32 states;
};
+struct vcxstat2 {
+ afs_int32 callerAccess;
+ afs_int32 cbExpires;
+ afs_int32 anyAccess;
+ char mvstat;
+};
+
struct sbstruct {
int sb_thisfile;
int sb_default;
#define NULLIDX (-1) /* null index definition */
/* struct dcache states bits */
+#define DRO 1
+#define DBackup 2
+#define DRW 4
#define DWriting 8 /* file being written (used for cache validation) */
/* dcache data flags */
#define IFAnyPages 32
#define IFDiscarded 64 /* index entry in discardDCList */
+#ifdef AFS_DARWIN100_ENV
+typedef user_addr_t iparmtype; /* 64 bit */
+typedef user_addr_t uparmtype; /* 64 bit */
+#else
+typedef char * uparmtype;
+#ifdef AFS_SGI65_ENV
+typedef afs_uint32 iparmtype;
+#else
+typedef long iparmtype;
+#endif
+#endif
+
struct afs_ioctl {
- char *in; /* input buffer */
- char *out; /* output buffer */
+ uparmtype in; /* input buffer */
+ uparmtype out; /* output buffer */
short in_size; /* Size of input buffer <= 2K */
short out_size; /* Maximum size of output buffer, <= 2K */
};
afs_int32 otherCSize;
};
-#if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_64BIT_ENV)
+#if defined(AFS_CACHE_VNODE_PATH)
+typedef char *afs_ufs_dcache_id_t;
+#elif defined(UKERNEL)
+typedef afs_int32 afs_ufs_dcache_id_t;
+#elif defined(AFS_SGI61_ENV) || defined(AFS_SUN57_64BIT_ENV)
/* Using ino64_t here so that user level debugging programs compile
* the size correctly.
*/
-#define afs_inode_t ino64_t
-#else
-#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_S390X_LINUX24_ENV)
-#define afs_inode_t long
+typedef ino64_t afs_ufs_dcache_id_t;
+#elif defined(LINUX_USE_FH)
+#define MAX_FH_LEN 10
+typedef union {
+ struct fid fh;
+ __u32 raw[MAX_FH_LEN];
+} afs_ufs_dcache_id_t;
+extern int cache_fh_type;
+extern int cache_fh_len;
+#elif defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_S390X_LINUX24_ENV)
+typedef long afs_ufs_dcache_id_t;
+#elif defined(AFS_AIX51_ENV) || defined(AFS_HPUX1123_ENV)
+typedef ino_t afs_ufs_dcache_id_t;
#else
-#if defined(AFS_AIX51_ENV) || defined(AFS_HPUX1123_ENV)
-#define afs_inode_t ino_t
-#else
-#define afs_inode_t afs_int32
-#endif
-#endif
+typedef afs_int32 afs_ufs_dcache_id_t;
#endif
+typedef afs_int32 afs_mem_dcache_id_t;
+
+typedef union {
+ afs_ufs_dcache_id_t ufs;
+ afs_mem_dcache_id_t mem;
+} afs_dcache_id_t;
+
+/* it does not compile outside kernel */
struct buffer {
afs_int32 fid; /* is adc->index, the cache file number */
- afs_inode_t inode; /* is adc->f.inode, the inode number of the cac\
+ afs_dcache_id_t inode; /* is adc->f.inode, the inode number of the cac\
he file */
afs_int32 page;
afs_int32 accesstime;
char lockers;
char dirty;
char hashIndex;
-#if AFS_USEBUFFERS
- struct buf *bufp;
-#endif
afs_rwlock_t lock; /* the lock for this structure */
};
afs_int32 modTime; /* last time this entry was modified */
afs_hyper_t versionNo; /* Associated data version number */
afs_int32 chunk; /* Relative chunk number */
- afs_inode_t inode; /* Unix inode for this chunk */
+ afs_dcache_id_t inode; /* Unix inode for this chunk */
afs_int32 chunkBytes; /* Num bytes in this chunk */
char states; /* Has this chunk been modified? */
};
char dflags; /* Data flags */
char mflags; /* Meta flags */
struct fcache f; /* disk image */
- afs_int32 stamp; /* used with vtodc struct for hints */
-
+ afs_int32 bucket; /* which bucket these dcache entries are in */
/*
* Locking rules:
*
* Note that dcache.lock(W) gives you the right to update mflags,
* as dcache.mflock(W) can only be held with dcache.lock(R).
*
- * dcache.stamp is protected by the associated vcache lock, because
- * it's only purpose is to establish correspondence between vcache
- * and dcache entries.
- *
* dcache.index, dcache.f.fid, dcache.f.chunk and dcache.f.inode are
* write-protected by afs_xdcache and read-protected by refCount.
* Once an entry is referenced, these values cannot change, and if
* ensuring noone else has a refCount on it).
*/
};
-/* this is obsolete and should be removed */
-#define ihint stamp
/* afs_memcache.c */
struct memCacheEntry {
char *data; /* bytes */
};
+struct afs_FetchOutput {
+ struct AFSVolSync tsync;
+ struct AFSFetchStatus OutStatus;
+ struct AFSCallBack CallBack;
+};
+
/* macro to mark a dcache entry as bad */
#define ZapDCE(x) \
do { \
#define afs_FakeClose(avc, acred) \
{ if (avc->execsOrWriters == 1) { \
/* we're the last writer, just use CCore flag */ \
- avc->states |= CCore; /* causes close to be called later */ \
+ avc->f.states |= CCore; /* causes close to be called later */ \
\
/* The cred and vnode holds will be released in afs_FlushActiveVcaches */ \
VN_HOLD(AFSTOV(avc)); /* So it won't disappear */ \
#define AFS_ZEROS 64 /* zero buffer */
-/*#define afs_DirtyPages(avc) (((avc)->states & CDirty) || osi_VMDirty_p((avc)))*/
-#define afs_DirtyPages(avc) ((avc)->states & CDirty)
+/*#define afs_DirtyPages(avc) (((avc)->f.states & CDirty) || osi_VMDirty_p((avc)))*/
+#define afs_DirtyPages(avc) ((avc)->f.states & CDirty)
+
+#define afs_InReadDir(avc) (((avc)->f.states & CReadDir) && (avc)->readdir_pid == MyPidxx2Pid(MyPidxx))
/* The PFlush algorithm makes use of the fact that Fid.Unique is not used in
below hash algorithms. Change it if need be so that flushing algorithm
/* don't hash on the cell, our callback-breaking code sometimes fails to compute
the cell correctly, and only scans one hash bucket */
#define VCHash(fid) (((fid)->Fid.Volume + (fid)->Fid.Vnode) & (VCSIZE-1))
+/* Hash only on volume to speed up volume callbacks. */
+#define VCHashV(fid) ((fid)->Fid.Volume & (VCSIZE-1))
extern struct dcache **afs_indexTable; /*Pointers to in-memory dcache entries */
extern afs_int32 *afs_indexUnique; /*dcache entry Fid.Unique */
extern afs_int32 afs_cacheBlocks; /*1K blocks in cache */
extern afs_int32 afs_cacheStats; /*Stat entries in cache */
extern struct vcache *afs_vhashT[VCSIZE]; /*Stat cache hash table */
+extern struct afs_q afs_vhashTV[VCSIZE]; /* cache hash table on volume */
extern afs_int32 afs_initState; /*Initialization state */
extern afs_int32 afs_termState; /* Termination state */
extern struct VenusFid afs_rootFid; /*Root for whole file system */
* GetVCache incantation, and could eliminate even this code from afs_UFSRead
* by making intentionally invalidating quick.stamp in the various callbacks
* expiration/breaking code */
-#ifdef AFS_LINUX20_ENV
-#define afs_VerifyVCache(avc, areq) \
- (((avc)->states & CStatd) ? (vcache2inode(avc), 0) : \
- afs_VerifyVCache2((avc),areq))
-#else
#ifdef AFS_DARWIN_ENV
#define afs_VerifyVCache(avc, areq) \
- (((avc)->states & CStatd) ? (osi_VM_Setup(avc, 0), 0) : \
+ (((avc)->f.states & CStatd) ? (osi_VM_Setup(avc, 0), 0) : \
afs_VerifyVCache2((avc),areq))
#else
#define afs_VerifyVCache(avc, areq) \
- (((avc)->states & CStatd) ? 0 : afs_VerifyVCache2((avc),areq))
-#endif
+ (((avc)->f.states & CStatd) ? 0 : afs_VerifyVCache2((avc),areq))
#endif
#define DO_STATS 1 /* bits used by FindVCache */
#define DO_VLRU 2
+#define IS_SLOCK 4
+#define IS_WLOCK 8
/* values for flag param of afs_CheckVolumeNames */
#define AFS_VOLCHECK_EXPIRED 0x1 /* volumes whose callbacks have expired */
#define CM_CACHESIZEDRAINEDPCT 95 /* wakeup processes when down to here. */
#define CM_WAITFORDRAINPCT 98 /* sleep if cache is this full. */
+/* when afs_cacheBlocks is large, settle for slightly decreased precision */
+#define PERCENT(p, v) \
+ ((afs_cacheBlocks & 0xffe00000) ? ((v) / 100 * (p)) : ((p) * (v) / 100))
+
#define afs_CacheIsTooFull() \
(afs_blocksUsed - afs_blocksDiscarded > \
- (CM_DCACHECOUNTFREEPCT*afs_cacheBlocks)/100 || \
+ PERCENT(CM_DCACHECOUNTFREEPCT, afs_cacheBlocks) || \
afs_freeDCCount - afs_discardDCCount < \
- ((100-CM_DCACHECOUNTFREEPCT)*afs_cacheFiles)/100)
+ PERCENT(100 - CM_DCACHECOUNTFREEPCT, afs_cacheFiles))
/* Handy max length of a numeric string. */
#define CVBS 12 /* max afs_int32 is 2^32 ~ 4*10^9, +1 for NULL, +luck */
#if defined(AFS_SGI62_ENV) || defined(AFS_HAVE_VXFS) || defined(AFS_DARWIN_ENV)
#define afs_vnodeToInumber(V) VnodeToIno(V)
#else
-#ifdef AFS_DECOSF_ENV
-#define afs_vnodeToInumber(V) osi_vnodeToInumber(V)
-#else
#define afs_vnodeToInumber(V) (VTOI(V)->i_number)
-#endif /* AFS_DECOSF_ENV */
#endif /* AFS_SGI62_ENV */
#endif
#ifndef afs_vnodeToDev
#if defined(AFS_SGI62_ENV) || defined(AFS_HAVE_VXFS) || defined(AFS_DARWIN_ENV)
#define afs_vnodeToDev(V) VnodeToDev(V)
-#elif defined(AFS_DECOSF_ENV)
-#define afs_vnodeToDev(V) osi_vnodeToDev(V)
#else
#define afs_vnodeToDev(V) (VTOI(V)->i_dev)
#endif
#endif
-
-/* Note: this should agree with the definition in kdump.c */
-#if defined(AFS_OSF_ENV)
-#if !defined(UKERNEL)
-#define AFS_USEBUFFERS 1
-#endif
-#endif
-
-#if !defined(UKERNEL) && !defined(HAVE_STRUCT_BUF)
/* declare something so that prototypes don't flip out */
/* appears struct buf stuff is only actually passed around as a pointer,
except with libuafs, in which case it is actually defined */
struct buf;
-#endif
+
+struct rxfs_storeVariables {
+ struct rx_call *call;
+ struct vcache *vcache;
+ char *tbuffer;
+ struct iovec *tiov;
+ afs_int32 tnio;
+ afs_int32 hasNo64bit;
+ struct AFSStoreStatus InStatus;
+};
+
+struct storeOps {
+ int (*prepare)(void *rock, afs_uint32 size, afs_uint32 *bytestoxfer);
+ int (*read)(void *rock, struct osi_file *tfile, afs_uint32 offset,
+ afs_uint32 tlen, afs_uint32 *bytesread);
+ int (*write)(void *rock, afs_uint32 tlen, afs_uint32 *byteswritten);
+ int (*status)(void *rock);
+ int (*padd)(void *rock, afs_uint32 tlen);
+ int (*close)(void *rock, struct AFSFetchStatus *OutStatus,
+ afs_int32 *doProcessFS);
+ int (*destroy)(void **rock, afs_int32 error);
+ int (*storeproc)(struct storeOps *, void *, struct dcache *, int *,
+ afs_size_t *);
+};
+
+struct fetchOps {
+ int (*more)(void *rock, afs_int32 *length, afs_uint32 *moredata);
+ int (*read)(void *rock, afs_uint32 tlen, afs_uint32 *bytesread);
+ int (*write)(void *rock, struct osi_file *fp, afs_uint32 offset,
+ afs_uint32 tlen, afs_uint32 *byteswritten);
+ int (*close)(void *rock, struct vcache *avc, struct dcache *adc,
+ struct afs_FetchOutput *Outputs);
+ int (*destroy)(void **rock, afs_int32 error);
+};
/* fakestat support: opaque storage for afs_EvalFakeStat to remember
* what vcache should be released.
extern int afs_fakestat_enable;
-/* First 32 bits of capabilities */
-#define CAPABILITY_ERRORTRANS (1<<0)
-
-#define CAPABILITY_BITS 1
+#ifdef AFS_MAXVCOUNT_ENV
+extern int afsd_dynamic_vcaches;
+#else
+#define afsd_dynamic_vcaches 0
+#endif
+/*
+ * Wrappers for access to credentials structure members
+ * Linux uses the kernel cred structure if available, with the
+ * wrappers defined in LINUX/osi_machdep.h
+ */
+#if !(defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_HAS_CRED))
+#define afs_cr_uid(cred) ((cred)->cr_uid)
+#define afs_cr_gid(cred) ((cred)->cr_gid)
+#define afs_cr_ruid(cred) ((cred)->cr_ruid)
+#define afs_cr_rgid(cred) ((cred)->cr_rgid)
+
+static_inline void
+afs_set_cr_uid(afs_ucred_t *cred, uid_t uid) {
+ cred->cr_uid = uid;
+}
+static_inline void
+afs_set_cr_gid(afs_ucred_t *cred, gid_t gid) {
+ cred->cr_gid = gid;
+}
+static_inline void
+afs_set_cr_ruid(afs_ucred_t *cred, uid_t uid) {
+ cred->cr_ruid = uid;
+}
+static_inline void
+afs_set_cr_rgid(afs_ucred_t *cred, gid_t gid) {
+ cred->cr_rgid = gid;
+}
+#endif
#endif /* _AFS_H_ */