"Fossies" - the Fresh Open Source Software Archive

Member "coda-6.9.5/coda-src/venus/fso.h" (13 Feb 2009, 26180 Bytes) of package /linux/misc/old/coda-6.9.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "fso.h" see the Fossies "Dox" file reference documentation.

    1 /* BLURB gpl
    2 
    3                            Coda File System
    4                               Release 6
    5 
    6           Copyright (c) 1987-2008 Carnegie Mellon University
    7                   Additional copyrights listed below
    8 
    9 This  code  is  distributed "AS IS" without warranty of any kind under
   10 the terms of the GNU General Public Licence Version 2, as shown in the
   11 file  LICENSE.  The  technical and financial  contributors to Coda are
   12 listed in the file CREDITS.
   13 
   14                         Additional copyrights
   15               Copyright (c) 2002-2003 Intel Corporation
   16 
   17 #*/
   18 
   19 /*
   20  *
   21  *    Specification of the Venus File-System Object (fso) abstraction.
   22  *
   23  *    ToDo:
   24  *
   25  */
   26 
   27 
   28 #ifndef _VENUS_FSO_H_
   29 #define _VENUS_FSO_H_ 1
   30 
   31 
   32 /* Forward declarations. */
   33 class fsdb;
   34 class fsobj;
   35 class fso_iterator;
   36 
   37 class cmlent;       /* we have compiler troubles if volume.h is included! */
   38 
   39 #ifdef __cplusplus
   40 extern "C" {
   41 #endif
   42 
   43 #include <stdio.h>
   44 #include <sys/types.h>
   45 #include <sys/stat.h>
   46 
   47 #include <sys/uio.h>
   48 
   49 #include <rpc2/rpc2.h>
   50 
   51 #include <codadir.h>
   52 
   53 extern int global_kernfd;
   54 #ifdef __cplusplus
   55 }
   56 #endif
   57 
   58 /* interfaces */
   59 #include <user.h>
   60 #include <vice.h>
   61 
   62 /* from util */
   63 #include <bstree.h>
   64 #include <rec_bstree.h>
   65 #include <dlist.h>
   66 #include <rec_dlist.h>
   67 #include <ohash.h>
   68 #include <rec_ohash.h>
   69 #include <olist.h>
   70 #include <rec_olist.h>
   71 
   72 /* from lka */
   73 #include <lka.h>
   74 
   75 /* from venus */
   76 #include "binding.h"
   77 #include "comm.h"
   78 #include "hdb.h"
   79 #include "mariner.h"
   80 #include "venusrecov.h"
   81 #include "vproc.h"
   82 #include "venus.private.h"
   83 
   84 /* from coda include again, must appear AFTER venus.private.h */
   85 
   86 
   87 /*  *****  Constants  ***** */
   88 
   89 #define FSDB    (rvg->recov_FSDB)
   90 const int FSDB_MagicNumber = 3620289;
   91 const int FSDB_NBUCKETS = 2048;
   92 const int FSO_MagicNumber = 2687694;
   93 
   94 const int MAX_PIGGY_VALIDATIONS = 50;
   95 
   96 /* Priorities. */
   97 const int FSO_MAX_SPRI = H_MAX_PRI;
   98 const int FSO_MAX_MPRI = H_MAX_PRI;
   99 const int DFLT_SWT = 25;
  100 const int UNSET_SWT = -1;
  101 const int DFLT_MWT = 75;
  102 const int UNSET_MWT = -1;
  103 const int DFLT_SSF = 4;
  104 const int UNSET_SSF = -1;
  105 
  106 const int CPSIZE = 8;
  107 
  108 /*  *****  Types  ***** */
  109 /* Cache stuff was removed here to move to venus.private.h  5/14/92 */
  110 
  111 void FSODaemon(void); /* used to be member of class fsdb (Satya 3/31/95) */
  112 
  113 #define SERVER_SERVER   1
  114 #define LOCAL_GLOBAL    2
  115 #define MIXED_CONFLICT  3
  116 
  117 #define FILE_CONFLICT       1
  118 #define DIRECTORY_CONFLICT  2
  119 
  120 /* The (cached) file-system database. */
  121 class fsdb {
  122   friend void FSOInit();
  123   friend void FSOD_Init();
  124   friend void FSODaemon();
  125   friend class fsobj;
  126   friend class fso_iterator;
  127   friend class hdb;
  128   friend class vproc;
  129   friend void RecovInit();
  130   friend class volent;
  131   friend class repvol;
  132 
  133     int MagicNumber;
  134     int DataVersion;
  135     int damnitagain;
  136 
  137     /* Size parameters. */
  138     int MaxFiles;
  139     /* "files" is kept as count member of htab */
  140     int FreeFileMargin;
  141     /*T*/int MaxBlocks;
  142     /*T*/int blocks;
  143     /*T*/int FreeBlockMargin;
  144 
  145     /* Priority parameters. */
  146     int swt;            /* short-term component weight */
  147     int mwt;            /* medium-term component weight */
  148     int ssf;            /* short-term scaling factor */
  149     int maxpri;         /* maximum priority */
  150     int stdpri;         /* standard priority (for VFS operations) */
  151     int marginpri;      /* margin priority (for GetDown) */
  152 
  153     /* The hash table. */
  154     rec_ohashtab htab;
  155 
  156     /* The free list. */
  157     rec_olist freelist;
  158 
  159     /* The priority queue. */
  160     /*T*/bstree *prioq;
  161     long *LastRef;
  162     /*T*/long RefCounter;        /* used to compute short-term priority */
  163 
  164     /* The delete queue.  Objects are sent here to be garbage collected. */
  165     /*T*/dlist *delq;
  166 
  167     /* Queue of files open for write. */
  168     /*T*/olist *owriteq;
  169 
  170     /* Statistics. */
  171     /*T*/CacheStats DirAttrStats;
  172     /*T*/CacheStats DirDataStats;
  173     /*T*/CacheStats FileAttrStats;
  174     /*T*/CacheStats FileDataStats;
  175     int VolumeLevelMiss;              /* Counter to pass to data collection; Stored in RVM */
  176     /*T*/int Recomputes;                /* total priority recomputations */
  177     /*T*/int Reorders;                  /* number of resulting prioq reorders */
  178 
  179     /* Synchronization stuff for matriculating objects. */
  180     /*T*/char matriculation_sync;
  181     /*T*/int matriculation_count;
  182 
  183     /* Constructors, destructors. */
  184     void *operator new(size_t);
  185     void operator delete(void *);
  186 
  187     fsdb();
  188     void ResetTransient();
  189     ~fsdb() { abort(); }
  190 
  191     /* Allocation/Deallocation routines. */
  192     fsobj *Create(VenusFid *, int, const char *comp, VenusFid *parent);
  193     int FreeFsoCount();
  194     int AllocFso(int, fsobj **);
  195     int GrabFreeFso(int, fsobj **);
  196     void ReclaimFsos(int, int);
  197     void FreeFso(fsobj *);
  198     int FreeBlockCount();
  199     int DirtyBlockCount();
  200     int AllocBlocks(int, int);
  201     int GrabFreeBlocks(int, int);
  202     void ReclaimBlocks(int, int);
  203     void FreeBlocks(int);
  204     void ChangeDiskUsage(int);
  205 
  206     /* Daemon. */
  207     void RecomputePriorities(int =0);
  208     void GarbageCollect();
  209     void GetDown();
  210     void FlushRefVec();
  211 
  212   public:
  213     fsobj *Find(const VenusFid *);
  214     /* rcode arg added for local repair */
  215     int Get(fsobj **fso, VenusFid *fid, uid_t uid, int rights,
  216         const char *comp=NULL, VenusFid *parent=NULL, int *rcode=NULL,
  217         int GetInconsistent=0);
  218     void Put(fsobj **);
  219     void Flush();
  220     void Flush(Volid *);
  221     int TranslateFid(VenusFid *, VenusFid *);
  222     int CallBackBreak(const VenusFid *);
  223     void ResetUser(uid_t);
  224     void ClearPriorities();
  225     void InvalidateMtPts();
  226     int MakePri(int spri, int mpri)
  227       { return(swt * spri + mwt * mpri); }
  228     int MaxPri()
  229       { return(maxpri); }
  230     int StdPri()
  231       { return(stdpri); }
  232     int MarginPri()
  233       { return(marginpri); }
  234 
  235     void GetStats(int *fa, int *fo, int *ba, int *bo) 
  236       { *fa = MaxFiles; *fo = htab.count(); *ba = MaxBlocks; *bo = blocks; }
  237 
  238 
  239     void print() { print(stdout); }
  240     void print(FILE *fp) { fflush(fp); print(fileno(fp)); }
  241     void print(int, int =0);
  242 };
  243 
  244 enum FsoState { FsoRunt,
  245         FsoNormal,
  246         FsoDying
  247 };
  248 
  249 /* Representation of UFS file in cache directory. */
  250 /* Currently, CacheFiles and fsobjs are statically bound to each
  251    other, one-to-one, by embedding */
  252 /* a single CacheFile in each fsobj.  An fsobj may use its CacheFile
  253    in several ways (or not at all). */
  254 /* We guarantee that these uses are mutually exclusive (in time,
  255    per-fsobj), hence the static allocation */
  256 /* policy works.  In the future we may choose not to make the uses
  257    mutually exclusive, and will then */
  258 /* have to implement some sort of dynamic allocation/binding
  259    scheme. */
  260 /* The different uses of CacheFile are: */
  261 /*    1. Copy of plain file */
  262 /*    2. Unix-format copy of directory */
  263 
  264 #define CACHEFILENAMELEN 12
  265 
  266 class CacheFile {
  267     long length;
  268     long validdata; /* amount of successfully fetched data */
  269     int  refcnt;
  270     char name[CACHEFILENAMELEN];        /* "xx/xx/xx/xx" */
  271     int numopens;
  272 
  273     int ValidContainer();
  274 
  275   public:
  276     CacheFile(int);
  277     CacheFile();
  278     ~CacheFile();
  279 
  280     /* for safely obtaining access to container files, USE THESE!!! */
  281     void Create(int newlength = 0);
  282     int Open(int flags);
  283     int Close(int fd);
  284 
  285     void Validate();
  286     void Reset();
  287     int  Copy(CacheFile *destination);
  288     int  Copy(char *destname, int recovering = 0);
  289 
  290     void IncRef() { refcnt++; } /* creation already does an implicit incref */
  291     int  DecRef();             /* returns refcnt, unlinks if refcnt becomes 0 */
  292 
  293     void Stat(struct stat *);
  294     void Utimes(const struct timeval times[2]);
  295     void Truncate(long);
  296     void SetLength(long);
  297     void SetValidData(long);
  298 
  299     char *Name()         { return(name); }
  300     long Length()        { return(length); }
  301     long ValidData(void) { return(validdata); }
  302     int  IsPartial(void) { return(length != validdata); }
  303 
  304     void print() { print (stdout); }
  305     void print(FILE *fp) { fflush(fp); print(fileno(fp)); }
  306     void print(int);
  307 };
  308 
  309 /* Condensed version of ViceStatus. */
  310 struct VenusStat {
  311     ViceDataType VnodeType;
  312     unsigned char LinkCount;
  313     unsigned long Length;
  314     unsigned long DataVersion;
  315     ViceVersionVector VV;
  316     Date_t Date;
  317     uid_t Author;
  318     uid_t Owner;
  319     unsigned short Mode;
  320 };
  321 
  322 /* Condensed version of VenusStat. */
  323 /* needed to restore objects after store cancellation */
  324 struct MiniVenusStat {
  325     unsigned long Length;
  326     Date_t Date;
  327 };
  328 
  329 /* Access Control Rights */
  330 struct AcRights {
  331     uid_t uid;
  332     unsigned char rights;
  333     unsigned inuse : 1;
  334     /*T*/unsigned valid : 1;
  335 };
  336 
  337 struct FsoFlags {
  338     /*T*/unsigned random : 16;          /* help balance binary-search trees */
  339     unsigned fake : 1;              /* is this object fake? (c.f. repair) */
  340     unsigned owrite : 1;            /* file open for write? */
  341     unsigned dirty : 1;             /* is this object dirty? */
  342     unsigned local: 1;              /* local fake fid */
  343     /*T*/unsigned ckmtpt : 1;           /* mount point needs checked? */
  344     /*T*/unsigned fetching : 1;         /* fetch in progress? */
  345     unsigned expanded : 1;          /* are we an expanded object */
  346     unsigned modified : 1;          /* modified for expansion? */
  347     unsigned padding : 8;
  348 };
  349 
  350 enum MountStatus {  NORMAL,
  351             MOUNTPOINT,
  352             ROOT
  353 };
  354 
  355 
  356 struct VenusDirData {
  357     /* Vice format directory in VM/RVM. */
  358     struct DirHandle dh;
  359     /* Unix format directory in UFS. */
  360     /*T*/unsigned udcfvalid : 1;
  361     /*T*/CacheFile *udcf;
  362     /*T*/int padding;
  363 };
  364 
  365 union VenusData {
  366     int havedata;   /* generic test for null pointer (pretty gross, eh) */
  367     CacheFile *file;    /* VnodeType == File */
  368     VenusDirData *dir;  /* VnodeType == Directory */
  369     char *symlink;  /* VnodeType == SymbolicLink */
  370 };
  371 
  372 
  373 /* local-repair modification */
  374 typedef enum {FROMHEAP, FROMFREELIST} fso_alloc_t; /* placement argument to operator new() */
  375 
  376 typedef enum { HF_Fetch, HF_DontFetch } HoardFetchState;
  377 typedef enum { HA_Ask, HA_DontAsk } HoardAskState;
  378 
  379 class ClientModifyLog;
  380 class fsobj {
  381   friend void FSOInit();
  382   friend int FSO_PriorityFN(bsnode *, bsnode *);
  383   friend class fsdb;
  384   friend class fso_iterator;
  385   friend long VENUS_CallBackFetch(RPC2_Handle, ViceFid *, SE_Descriptor *);
  386   friend class vproc;
  387   friend class namectxt;
  388   friend class volent;
  389   friend class repvol;
  390   friend class ClientModifyLog;
  391   friend class cmlent;
  392   friend class cml_iterator;
  393   friend class resent;
  394   friend class mgrpent;
  395   friend class hdb;
  396   friend class Realm; /* ~Realm */
  397   friend void RecoverPathName(char *, VenusFid *, ClientModifyLog *, cmlent *);
  398 
  399     int MagicNumber;
  400 
  401     /* Keys. */
  402     VenusFid fid;               /* unique id for object */
  403     char *comp;                 /* most recently used component */
  404     /*T*/volent *vol;               /* pointer to object's volume */
  405 
  406     /* Links for various lists. */
  407     rec_olink primary_handle;           /* link for {fstab, free-list} */
  408     /*T*/struct dllist_head vol_handle;         /* link for volent fso_list */
  409     /*T*/bsnode prio_handle;            /* link for priority queue */
  410     /*T*/dlink del_handle;          /* link for delete queue */
  411     /*T*/olink owrite_handle;           /* link for owrite queue */
  412 
  413     /* General status. */
  414     enum FsoState state;            /* {FsoRunt, FsoNormal, FsoDying} */
  415     VenusStat stat;
  416     /*T*/long GotThisData;          /* used during fetch to keep
  417                            track of where we are */
  418     /*T*/int RcRights;              /* replica control rights */
  419     AcRights AnyUser;               /* access control rights: any user */
  420     AcRights SpecificUser[CPSIZE];      /* access control rights: specific users */
  421     FsoFlags flags;             /* some of these are transient */
  422     unsigned char VenusSHA[SHA_DIGEST_LENGTH];  /* if non-zero, the saved SHA of the file; used by lookaside code; */
  423 
  424     /* Mount state. */
  425     MountStatus mvstat;             /* { NORMAL, MOUNTPOINT, ROOT } */
  426     /*T*/union {
  427                         /* mvstat == NORMAL */
  428     fsobj *root;                /* mvstat == MOUNTPOINT */
  429     fsobj *mtpoint;             /* mvstat == ROOT */
  430     } u;
  431 
  432     /* Child/Parent linkage. */
  433     VenusFid pfid;
  434     /*T*/fsobj *pfso;               /* back pointer from child to parent */
  435     /*T*/dlist *children;           /* for directories; list of cached children */
  436     /*T*/dlink child_link;          /* link used for that list */
  437 
  438     /* Priority state. */
  439     /*T*/int priority;              /* f(spri, mpri) */
  440     /*T*/int HoardPri;              /* max of priorities of binders */
  441     /*T*/uid_t HoardVuid;           /* uid of that entry */
  442     /*T*/dlist *hdb_bindings;           /* list of (bindings to) hdbents referencing this object */
  443     /*T*/VnodeId  LocalFid_Vnode;       /* Values of the vnode and */
  444     /*T*/Unique_t LocalFid_Unique;      /* uniquifier when this object
  445                            had a local fid */
  446 
  447     /* MLE linkage. */
  448     /* T */dlist *mle_bindings;         /* list of (bindings to) mlents referencing this object */
  449     MiniVenusStat CleanStat;            /* last status before becoming dirty */
  450     /* T */ViceStoreId tSid;            /* temporary for serializing MLEs */
  451     /*T*/CacheFile *shadow;                     /* shadow copy, temporary during reintegration */
  452 
  453     /* Data contents. */
  454     VenusData data;
  455 
  456     /* Statically allocated cache-file stuff. */
  457     /* Eventually we might make cache-file allocation dynamic, in which case there would be */
  458     /* various of these pointed to by the VenusData descriptors! */
  459     int ix;
  460     CacheFile cf;
  461 
  462     /* Local synchronization state. */
  463     /*T*/char fso_sync;             /* for waiting/signalling */
  464     /*T*/short readers;             /* entry readers, not object readers */
  465     /*T*/short writers;             /* entry writers, not object writers */
  466     /*T*/short openers;             /* object openers */
  467     /*T*/short Writers;             /* object writers */
  468     /*T*/short Execers;             /* object execers (we don't know this under VFS!) */
  469     /*T*/short refcnt;              /* readers + writers + openers + temporary_refs */   
  470 
  471     // for asr invocation
  472     /*T*/long lastresolved;         // time when object was last resolved
  473 
  474     /* Constructors, destructors. */
  475     void *operator new(size_t, fso_alloc_t, int); /* for allocation from freelist */
  476     void *operator new(size_t, fso_alloc_t); /* for allocation from heap */
  477     void *operator new(size_t); /* dummy to pacify g++ */
  478     void operator delete(void *);
  479     fsobj(int);
  480     fsobj(VenusFid *, const char *);
  481     void ResetPersistent();
  482     void ResetTransient();
  483     fsobj(fsobj&) { abort(); }                          /* not supported! */
  484     int operator=(fsobj&) { abort(); return(0); }           /* not supported! */
  485     ~fsobj();
  486     void Recover();
  487 
  488     /* General status. */
  489     void Matriculate();
  490     void Demote(void);
  491     void Kill(int =1);
  492     void GC();
  493     int Flush();
  494     void UpdateStatus(ViceStatus *, ViceVersionVector *, uid_t);
  495     int StatusEq(ViceStatus *);
  496     void ReplaceStatus(ViceStatus *, ViceVersionVector *);
  497     int CheckRcRights(int);
  498     void SetRcRights(int);
  499     void ClearRcRights();
  500     int IsValid(int);
  501     void SetAcRights(uid_t uid, long my_rights, long any_rights);
  502     void DemoteAcRights(uid_t);
  503     void PromoteAcRights(uid_t);
  504     void ClearAcRights(uid_t);
  505     void SetParent(VnodeId, Unique_t);
  506     void MakeDirty();
  507     void MakeClean();
  508 
  509     /* Mount state. */
  510     int TryToCover(VenusFid *, uid_t);
  511     void CoverMtPt(fsobj *);
  512     void UncoverMtPt();
  513     void MountRoot(fsobj *);
  514     void UnmountRoot();
  515 
  516     /* Child/Parent linkage. */
  517     void AttachChild(fsobj *);
  518     void DetachChild(fsobj *);
  519 
  520     /* Priority state. */
  521     void Reference();
  522     void ComputePriority(int Force=0);
  523     void EnableReplacement();
  524     void DisableReplacement();
  525     binding *AttachHdbBinding(namectxt *);
  526     void DemoteHdbBindings();
  527     void DemoteHdbBinding(binding *);
  528     void DetachHdbBindings();
  529     void DetachHdbBinding(binding *, int =0);
  530 
  531     /* MLE Linkage. */
  532     void AttachMleBinding(binding *);
  533     void DetachMleBinding(binding *);
  534 
  535     /* Data contents. */
  536     void DiscardData();
  537 
  538     /* Fake object management. */
  539     int Fakeify();
  540     int IsFake() { return(flags.fake); }
  541     int IsFakeDir() { return(flags.fake && IsDir() && !IsMtPt()); }
  542     int IsFakeMtPt() { return(flags.fake && IsMtPt()); }
  543     int IsFakeMTLink() { return(flags.fake && IsMTLink()); }
  544 
  545     /* expansion related functions */
  546     int ExpandObject(void);
  547     int CollapseObject(void);
  548     int IsExpandedObj(void) { return(flags.expanded); }
  549     int IsExpandedDir(void) { return(flags.expanded && IsDir()); }
  550     int IsExpandedMTLink(void) { return(flags.expanded && IsMTLink()); }
  551     int IsModifiedObj(void) { return(flags.modified); }
  552     void SetMtLinkContents(VenusFid *fid);
  553 
  554     /* cmlent expansion related functions */
  555     void ExpandCMLEntries(void);
  556     void CollapseCMLEntries(void);
  557     int HasExpandedCMLEntries(void);
  558 
  559 #define LOCALCACHE "_localcache"    /* implies we have a locally cached copy */
  560 #define LOCALCACHE_HIDDEN ".localcache" /* implies we don't */
  561 
  562     /* Local synchronization. */
  563     void Lock(LockLevel);
  564     void PromoteLock();
  565     void DemoteLock();
  566     void UnLock(LockLevel);
  567 
  568     /* Local-global conflict detection */
  569     int IsToBeRepaired(void);
  570     uid_t WhoIsLastAuthor(void);
  571     int LaunchASR(int, int);
  572 
  573     /* Interface to the dir package. */
  574     void dir_Create(const char *, VenusFid *);
  575     int dir_Length();
  576     void dir_Delete(const char *);
  577     void dir_MakeDir();
  578     int dir_LookupByFid(char *, VenusFid *);
  579     void dir_Rebuild();
  580     int dir_IsEmpty();
  581     int dir_IsParent(VenusFid *);
  582     void dir_Zap();
  583     void dir_Flush();
  584     void dir_TranslateFid(VenusFid *, VenusFid *);
  585     void dir_Print();
  586 
  587     /* Private portions of the CFS interface. */
  588     void LocalStore(Date_t, unsigned long);
  589     int DisconnectedStore(Date_t, uid_t, unsigned long, int prepend=0);
  590     void LocalSetAttr(Date_t, unsigned long, Date_t,
  591                uid_t, unsigned short);
  592     int DisconnectedSetAttr(Date_t, uid_t, unsigned long, Date_t,
  593                  uid_t, unsigned short, int prepend=0);
  594     void LocalCreate(Date_t, fsobj *, char *,
  595               uid_t, unsigned short);
  596     int DisconnectedCreate(Date_t, uid_t, fsobj **,
  597                 char *, unsigned short, int, int prepend=0);
  598     void LocalRemove(Date_t, char *, fsobj *);
  599     int DisconnectedRemove(Date_t, uid_t, char *, fsobj *, int prepend=0);
  600     void LocalLink(Date_t, char *, fsobj *);
  601     int DisconnectedLink(Date_t, uid_t, char *, fsobj *, int prepend=0);
  602     void LocalRename(Date_t, fsobj *, char *,
  603               fsobj *, char *, fsobj *);
  604     int DisconnectedRename(Date_t, uid_t, fsobj *,
  605                 char *, fsobj *, char *, fsobj *, int prepend=0);
  606     void LocalMkdir(Date_t, fsobj *, char *, uid_t, unsigned short);
  607     int DisconnectedMkdir(Date_t, uid_t, fsobj **,
  608                char *, unsigned short, int, int prepend=0);
  609     void LocalRmdir(Date_t, char *, fsobj *);
  610     int DisconnectedRmdir(Date_t, uid_t, char *, fsobj *, int prepend=0);
  611     void LocalSymlink(Date_t, fsobj *, char *,
  612                char *, uid_t, unsigned short);
  613     int DisconnectedSymlink(Date_t, uid_t, fsobj **, char *,
  614                  char *, unsigned short, int, int prepend=0);
  615     int GetContainerFD(void);
  616     int LookAside(void);
  617 
  618   public:
  619     /* The public CFS interface (Vice portion). */
  620     int Fetch(uid_t);
  621     int GetAttr(uid_t, RPC2_BoundedBS * =0);
  622     int GetACL(RPC2_BoundedBS *, uid_t);
  623     int Store(unsigned long, Date_t, uid_t);
  624     int SetAttr(struct coda_vattr *, uid_t);
  625     int SetACL(RPC2_CountedBS *, uid_t);
  626     int Create(char *, fsobj **, uid_t, unsigned short, int);
  627     int Remove(char *, fsobj *, uid_t);
  628     int Link(char *, fsobj *, uid_t);
  629     int Rename(fsobj *, char *, fsobj *, char *, fsobj *, uid_t);
  630     int Mkdir(char *, fsobj **, uid_t, unsigned short, int);
  631     int Rmdir(char *, fsobj *, uid_t);
  632     int Symlink(char *, char *, uid_t, unsigned short, int);
  633     int SetVV(ViceVersionVector *, uid_t);
  634 
  635     /* The public CFS interface (non-Vice portion). */
  636     int Open(int writep, int truncp, venus_cnode *cp, uid_t uid);
  637     int Sync(uid_t uid);
  638     void Release(int writep);
  639     int Close(int writep, uid_t uid);
  640     int Access(int rights, int modes, uid_t);
  641     int Lookup(fsobj **, VenusFid *, const char *, uid_t, int flags, int GetInconsistent=0);
  642 // These are defined in coda-src/kerndep/coda.h
  643 // #define CLU_CASE_SENSITIVE   0x01
  644 // #define CLU_CASE_INSENSITIVE 0x02
  645 #define CLU_CASE_MASK       0x03
  646 #define CLU_TRAVERSE_MTPT   0x04
  647     int Readdir(char *, int, int, int *, uid_t);
  648     int Readlink(char *, unsigned long, int *, uid_t);
  649 
  650     /* Miscellaneous utility routines. */
  651     int dir_Lookup(const char *, VenusFid *, int);
  652     int CheckAcRights(uid_t uid, long rights, int connected);
  653     void GetVattr(struct coda_vattr *);     /* translate attributes to VFS format */
  654     void GetFid(VenusFid *f) { *f = fid; }
  655     void ReturnEarly();
  656 
  657 #define PATH_VOLUME 0
  658 #define PATH_FULL   1
  659 #define PATH_REALM  2
  660     void GetPath(char *, int scope=PATH_VOLUME);
  661 
  662     ViceVersionVector *VV() { return(&stat.VV); }
  663     int IsFile() { return(stat.VnodeType == (int)File); }
  664     int IsDir() { return(stat.VnodeType == (int)Directory); }
  665     int IsSymLink() { return(stat.VnodeType == (int)SymbolicLink); }
  666     int IsNormal() { return(mvstat == NORMAL); }
  667     int IsRoot() { return(mvstat == ROOT); }
  668     int IsVenusRoot() { return(FID_EQ(&fid, &rootfid)); }
  669     int IsMtPt() { return(mvstat == MOUNTPOINT); }      /* covered mount point */
  670     int IsMTLink() { return(IsSymLink() && stat.Mode == 0644 && IsNormal()); }
  671                                                         /* uncovered mount point */
  672     int IsVirgin();        /* file which has been created, but not yet stored */
  673     int IsBackFetching();  /* fso involved in an ongoing reintegration */
  674     int SetLastResolved(long t) { lastresolved = t; return(0); }
  675     int  MakeShadow();
  676     void RemoveShadow();
  677     void CacheReport(int, int);
  678 
  679     void print() { print(stdout); }
  680     void print(FILE *fp) { fflush(fp); print(fileno(fp)); }
  681     void print(int);
  682 
  683     void ListCache(FILE *, int long_format=0, unsigned int valid=3);
  684     void ListCacheShort(FILE *);
  685     void ListCacheLong(FILE *);
  686 
  687     /* local-repair additions */
  688     cmlent *FinalCmlent(int);                                   /*N*/
  689     void SetComp(const char *);                                 /*U*/
  690     const char *GetComp(void);
  691     void SetLocalObj();                     /*T*/
  692     void UnsetLocalObj();                   /*T*/
  693     int IsLocalObj() { return flags.local; }            /*N*/
  694     int IsAncestor(VenusFid *);                 /*N*/
  695 
  696     void DeLocalRootParent(fsobj *, VenusFid *, fsobj *);   /*U*/
  697     void RecoverRootParent(VenusFid *, char *);         /*U*/
  698 
  699     int SetLocalVV(ViceVersionVector *);
  700 
  701     int RepairStore();
  702     int RepairSetAttr(unsigned long, Date_t, uid_t, unsigned short, RPC2_CountedBS *);
  703     int RepairCreate(fsobj **, char *, unsigned short, int);
  704     int RepairRemove(char *, fsobj *);
  705     int RepairLink(char *, fsobj *);
  706     int RepairRename(fsobj *, char *, fsobj *, char *, fsobj *);
  707     int RepairMkdir(fsobj **, char *, unsigned short, int);
  708     int RepairRmdir(char *, fsobj *);
  709     int RepairSymlink(fsobj **, char *, char *, unsigned short, int);
  710 
  711     void FetchProgressIndicator(unsigned long offset);
  712 
  713     size_t Size(void) { return stat.Length; }
  714 };
  715 
  716 class fso_iterator : public rec_ohashtab_iterator {
  717     LockLevel clevel;       /* locking level */
  718     volent *cvol;       /* 0 --> all volumes */
  719 
  720   public:
  721     fso_iterator(LockLevel, const VenusFid * =(VenusFid *)-1);
  722     fsobj *operator()();
  723 };
  724 
  725 /*  *****  Variables  ***** */
  726 
  727 extern int CacheFiles;
  728 extern int FSO_SWT;
  729 extern int FSO_MWT;
  730 extern int FSO_SSF;
  731 
  732 
  733 /*  *****  Functions/Procedures  *****  */
  734 
  735 /* fso0.c */
  736 extern void FSOInit();
  737 extern int FSO_PriorityFN(bsnode *, bsnode *);
  738 extern void UpdateCacheStats(CacheStats *c, enum CacheEvent event, unsigned long blocks);
  739 extern void PrintCacheStats(const char* description, CacheStats *, int);
  740 extern void VenusToViceStatus(VenusStat *, ViceStatus *);
  741 
  742 /* fso_daemon.c */
  743 void FSOD_Init(void);
  744 void FSOD_ReclaimFSOs(void);
  745 
  746 /* More locking macros. */
  747 #define FSO_HOLD(f)     { (f)->refcnt++; }
  748 #define FSO_RELE(f)     { (f)->refcnt--; }
  749 
  750 /* Some useful state predicates. */
  751 #define UNREACHABLE(f)  ((f)->vol->IsUnreachable())
  752 #define REACHABLE(f)    ((f)->vol->IsReachable())
  753 #define RESOLVING(f)    ((f)->vol->IsResolving())
  754 #define DIRTY(f)    ((f)->flags.dirty)
  755 #define HAVESTATUS(f)   ((f)->state != FsoRunt)
  756 #define STATUSVALID(f)  ((f)->IsValid(RC_STATUS))
  757 #define HAVEDATA(f) ((f)->data.havedata != 0)
  758 #define PARTIALDATA(f)  ((f)->IsFile() && (f)->cf.IsPartial())
  759 #define HAVEALLDATA(f)  (HAVEDATA(f) && !PARTIALDATA(f))
  760 #define DATAVALID(f)    ((f)->IsValid(RC_DATA))
  761 #define EXECUTABLE(f)   (HAVESTATUS(f) &&\
  762              (f)->IsFile() &&\
  763              ((f)->stat.Mode & 0111))
  764 #define DYING(f)    ((f)->state == FsoDying)
  765 #define READING(f)  (((f)->openers - (f)->Writers) > 0)
  766 #define WRITING(f)  ((f)->Writers > 0)
  767 #define EXECUTING(f)    (EXECUTABLE(f) && READING(f) && !k_Purge(&(f)->fid))
  768 #define ACTIVE(f)   (WRITING(f) || READING(f)) // was EXECUTING(f)
  769 #define BUSY(f)     ((f)->refcnt > 0 || EXECUTING(f))
  770 #define HOARDABLE(f)    ((f)->HoardPri > 0)
  771 #define FETCHABLE(f)    (!DYING(f) && REACHABLE(f) && !DIRTY(f) && \
  772              (!HAVESTATUS(f) || !ACTIVE(f)) && !f->IsLocalObj())
  773 /* we are replaceable whenever we are linked into FSDB->prioq */
  774 #define REPLACEABLE(f)  ((f)->prio_handle.tree() != 0)
  775 #define GCABLE(f)   (DYING(f) && !DIRTY(f) && !BUSY(f))
  776 #define FLUSHABLE(f)    ((DYING(f) || REPLACEABLE(f)) && \
  777                          !DIRTY(f) && !BUSY(f))
  778 #define BLOCKS(f)   (NBLOCKS((f)->stat.Length))
  779 
  780 
  781 #define FSO_ASSERT(f, ex)\
  782 {\
  783     if (!(ex)) {\
  784     (f)->print(logFile);\
  785     CHOKE("Assertion failed: file \"%s\", line %d\n", __FILE__, __LINE__);\
  786     }\
  787 }
  788 
  789 #define CFSOP_PRELUDE(str, comp, fid)\
  790 {\
  791     char buf[CODA_MAXNAMLEN+1];\
  792     if (comp && comp[0] != '\0')\
  793      strcpy(buf, comp);\
  794     else sprintf(buf, "%s", FID_(&fid));\
  795     MarinerLog((str), buf);\
  796 }
  797 #define CFSOP_POSTLUDE(str)\
  798     MarinerLog((str));
  799 
  800 #define PrintFsoState(state)\
  801     (state == FsoRunt ? "Runt" :\
  802      state == FsoNormal ? "Normal":\
  803      state == FsoDying ? "Dying" :\
  804      "???")
  805 #define PrintVnodeType(vnodetype)\
  806     (vnodetype == (int)File ? "File" :\
  807      vnodetype == (int)Directory ? "Directory" :\
  808      vnodetype == (int)SymbolicLink ? "Symlink" :\
  809      "???")
  810 #define PrintMvStat(mvstat)\
  811     (mvstat == NORMAL ? "Normal" :\
  812      mvstat == MOUNTPOINT ? "MountPoint" :\
  813      mvstat == ROOT ? "Root" :\
  814      "???")
  815 
  816 #endif  /* _VENUS_FSO_H_ */