|
|
1.1 ! root 1: /* ! 2: * Written by Paul Popelka ([email protected]) ! 3: * ! 4: * You can do anything you want with this software, ! 5: * just don't say you wrote it, ! 6: * and don't remove this notice. ! 7: * ! 8: * This software is provided "as is". ! 9: * ! 10: * The author supplies this software to be publicly ! 11: * redistributed on the understanding that the author ! 12: * is not responsible for the correct functioning of ! 13: * this software in any circumstances and is not liable ! 14: * for any damages caused by this software. ! 15: * ! 16: * October 1992 ! 17: * ! 18: * denode.h,v 1.2 1993/05/20 03:34:05 cgd Exp ! 19: */ ! 20: ! 21: /* ! 22: * This is the pc filesystem specific portion of the ! 23: * vnode structure. ! 24: * To describe a file uniquely the de_dirclust, de_diroffset, ! 25: * and de_de.deStartCluster fields are used. de_dirclust ! 26: * contains the cluster number of the directory cluster containing ! 27: * the entry for a file or directory. de_diroffset is the ! 28: * index into the cluster for the entry describing a file ! 29: * or directory. de_de.deStartCluster is the number of the ! 30: * first cluster of the file or directory. Now to describe the ! 31: * quirks of the pc filesystem. ! 32: * - Clusters 0 and 1 are reserved. ! 33: * - The first allocatable cluster is 2. ! 34: * - The root directory is of fixed size and all blocks that ! 35: * make it up are contiguous. ! 36: * - Cluster 0 refers to the root directory when it is found ! 37: * in the startcluster field of a directory entry that points ! 38: * to another directory. ! 39: * - Cluster 0 implies a 0 length file when found in the start ! 40: * cluster field of a directory entry that points to a file. ! 41: * - You can't use the cluster number 0 to derive ! 42: * the address of the root directory. ! 43: * - Multiple directory entries can point to a directory. ! 44: * The entry in the parent directory points to a child ! 45: * directory. Any directories in the child directory contain ! 46: * a ".." entry that points back to the child. The child ! 47: * directory itself contains a "." entry that points to ! 48: * itself. ! 49: * - The root directory does not contain a "." or ".." entry. ! 50: * - Directory entries for directories are never changed once ! 51: * they are created (except when removed). The size stays ! 52: * 0, and the last modification time is never changed. This ! 53: * is because so many directory entries can point to the physical ! 54: * clusters that make up a directory. It would lead to an update ! 55: * nightmare. ! 56: * - The length field in a directory entry pointing to a directory ! 57: * contains 0 (always). The only way to find the end of a directory ! 58: * is to follow the cluster chain until the "last cluster" ! 59: * marker is found. ! 60: * My extensions to make this house of cards work. These apply ! 61: * only to the in memory copy of the directory entry. ! 62: * - A reference count for each denode will be kept since dos doesn't ! 63: * keep such things. ! 64: */ ! 65: ! 66: /* Internal pseudo-offset for (nonexistent) directory entry for the root dir ! 67: * in the root dir */ ! 68: #define PCFSROOT_OFS 0x1fffffff ! 69: ! 70: /* ! 71: * The fat cache structure. ! 72: * fc_fsrcn is the filesystem relative cluster number ! 73: * that corresponds to the file relative cluster number ! 74: * in this structure (fc_frcn). ! 75: */ ! 76: struct fatcache { ! 77: u_short fc_frcn; /* file relative cluster number */ ! 78: u_short fc_fsrcn; /* filesystem relative cluster number */ ! 79: }; ! 80: ! 81: /* ! 82: * The fat entry cache as it stands helps make extending ! 83: * files a "quick" operation by avoiding having to scan ! 84: * the fat to discover the last cluster of the file. ! 85: * The cache also helps sequential reads by remembering ! 86: * the last cluster read from the file. This also prevents ! 87: * us from having to rescan the fat to find the next cluster ! 88: * to read. This cache is probably pretty worthless if a ! 89: * file is opened by multiple processes. ! 90: */ ! 91: #define FC_SIZE 2 /* number of entries in the cache */ ! 92: #define FC_LASTMAP 0 /* entry the last call to pcbmap() resolved to */ ! 93: #define FC_LASTFC 1 /* entry for the last cluster in the file */ ! 94: ! 95: #define FCE_EMPTY 0xffff /* doesn't represent an actual cluster # */ ! 96: ! 97: /* ! 98: * Set a slot in the fat cache. ! 99: */ ! 100: #define fc_setcache(dep, slot, frcn, fsrcn) \ ! 101: (dep)->de_fc[slot].fc_frcn = frcn; \ ! 102: (dep)->de_fc[slot].fc_fsrcn = fsrcn; ! 103: ! 104: /* ! 105: * This is the in memory variant of a dos directory ! 106: * entry. It is usually contained within a vnode. ! 107: */ ! 108: struct denode { ! 109: struct denode *de_chain[2]; /* hash chain ptrs */ ! 110: struct vnode *de_vnode; /* addr of vnode we are part of */ ! 111: struct vnode *de_devvp; /* vnode of blk dev we live on */ ! 112: u_long de_flag; /* flag bits */ ! 113: dev_t de_dev; /* device where direntry lives */ ! 114: u_long de_dirclust; /* cluster of the directory file ! 115: * containing this entry */ ! 116: u_long de_diroffset; /* ordinal of this entry in the ! 117: * directory */ ! 118: long de_refcnt; /* reference count */ ! 119: struct pcfsmount *de_pmp; /* addr of our mount struct */ ! 120: struct lockf *de_lockf; /* byte level lock list */ ! 121: long de_spare0; /* current lock holder */ ! 122: long de_spare1; /* lock wanter */ ! 123: struct direntry de_de; /* the actual directory entry */ ! 124: struct fatcache de_fc[FC_SIZE]; /* fat cache */ ! 125: }; ! 126: ! 127: /* ! 128: * Values for the de_flag field of the denode. ! 129: */ ! 130: #define DELOCKED 0x0001 /* directory entry is locked */ ! 131: #define DEWANT 0x0002 /* someone wants this de */ ! 132: #define DERENAME 0x0004 /* de is being renamed */ ! 133: #define DEUPD 0x0008 /* file has been modified */ ! 134: #define DESHLOCK 0x0010 /* file has shared lock */ ! 135: #define DEEXLOCK 0x0020 /* file has exclusive lock */ ! 136: #define DELWAIT 0x0040 /* someone waiting on file lock */ ! 137: #define DEMOD 0x0080 /* denode wants to be written back ! 138: * to disk */ ! 139: ! 140: /* ! 141: * Shorthand macros used to reference fields in the direntry ! 142: * contained in the denode structure. ! 143: */ ! 144: #define de_Name de_de.deName ! 145: #define de_Extension de_de.deExtension ! 146: #define de_Attributes de_de.deAttributes ! 147: #define de_Reserved de_de.deReserved ! 148: #define de_Time de_de.deTime ! 149: #define de_Date de_de.deDate ! 150: #define de_StartCluster de_de.deStartCluster ! 151: #define de_FileSize de_de.deFileSize ! 152: #define de_forw de_chain[0] ! 153: #define de_back de_chain[1] ! 154: ! 155: #if defined(KERNEL) ! 156: ! 157: #define VTODE(vp) ((struct denode *)(vp)->v_data) ! 158: #define DETOV(de) ((de)->de_vnode) ! 159: ! 160: #define DELOCK(de) delock(de) ! 161: #define DEUNLOCK(de) deunlock(de) ! 162: ! 163: #define DEUPDAT(dep, t, waitfor) \ ! 164: if (dep->de_flag & DEUPD) \ ! 165: (void) deupdat(dep, t, waitfor); ! 166: ! 167: #define DETIMES(dep, t) \ ! 168: if (dep->de_flag & DEUPD) { \ ! 169: (dep)->de_flag |= DEMOD; \ ! 170: unix2dostime(t, (union dosdate *)&dep->de_Date, \ ! 171: (union dostime *)&dep->de_Time); \ ! 172: (dep)->de_flag &= ~DEUPD; \ ! 173: } ! 174: ! 175: /* ! 176: * This overlays the fid sturcture (see mount.h) ! 177: */ ! 178: struct defid { ! 179: u_short defid_len; /* length of structure */ ! 180: u_short defid_pad; /* force long alignment */ ! 181: ! 182: u_long defid_dirclust; /* cluster this dir entry came from */ ! 183: u_long defid_dirofs; /* index of entry within the cluster */ ! 184: ! 185: /* u_long defid_gen; /* generation number */ ! 186: }; ! 187: ! 188: /* ! 189: * Prototypes for PCFS vnode operations ! 190: */ ! 191: int pcfs_lookup __P((struct vnode *vp, struct nameidata *ndp, struct proc *p)); ! 192: int pcfs_create __P((struct nameidata *ndp, struct vattr *vap, struct proc *p)); ! 193: int pcfs_mknod __P((struct nameidata *ndp, struct vattr *vap, struct ucred *cred, ! 194: struct proc *p)); ! 195: int pcfs_open __P((struct vnode *vp, int mode, struct ucred *cred, ! 196: struct proc *p)); ! 197: int pcfs_close __P((struct vnode *vp, int fflag, struct ucred *cred, ! 198: struct proc *p)); ! 199: int pcfs_access __P((struct vnode *vp, int mode, struct ucred *cred, ! 200: struct proc *p)); ! 201: int pcfs_getattr __P((struct vnode *vp, struct vattr *vap, struct ucred *cred, ! 202: struct proc *p)); ! 203: int pcfs_setattr __P((struct vnode *vp, struct vattr *vap, struct ucred *cred, ! 204: struct proc *p)); ! 205: int pcfs_read __P((struct vnode *vp, struct uio *uio, int ioflag, ! 206: struct ucred *cred)); ! 207: int pcfs_write __P((struct vnode *vp, struct uio *uio, int ioflag, ! 208: struct ucred *cred)); ! 209: int pcfs_ioctl __P((struct vnode *vp, int command, caddr_t data, int fflag, ! 210: struct ucred *cred, struct proc *p)); ! 211: int pcfs_select __P((struct vnode *vp, int which, int fflags, struct ucred *cred, ! 212: struct proc *p)); ! 213: int pcfs_mmap __P((struct vnode *vp, int fflags, struct ucred *cred, ! 214: struct proc *p)); ! 215: int pcfs_fsync __P((struct vnode *vp, int fflags, struct ucred *cred, ! 216: int waitfor, struct proc *p)); ! 217: int pcfs_seek __P((struct vnode *vp, off_t oldoff, off_t newoff, ! 218: struct ucred *cred)); ! 219: int pcfs_remove __P((struct nameidata *ndp, struct proc *p)); ! 220: int pcfs_link __P((struct vnode *vp, struct nameidata *ndp, struct proc *p)); ! 221: int pcfs_rename __P((struct nameidata *fndp, struct nameidata *tdnp, ! 222: struct proc *p)); ! 223: int pcfs_mkdir __P((struct nameidata *ndp, struct vattr *vap, struct proc *p)); ! 224: int pcfs_rmdir __P((struct nameidata *ndp, struct proc *p)); ! 225: int pcfs_symlink __P((struct nameidata *ndp, struct vattr *vap, char *target, ! 226: struct proc *p)); ! 227: int pcfs_readdir __P((struct vnode *vp, struct uio *uio, struct ucred *cred, ! 228: int *eofflagp)); ! 229: int pcfs_readlink __P((struct vnode *vp, struct uio *uio, struct ucred *cred)); ! 230: int pcfs_abortop __P((struct nameidata *ndp)); ! 231: int pcfs_inactive __P((struct vnode *vp, struct proc *p)); ! 232: int pcfs_reclaim __P((struct vnode *vp)); ! 233: int pcfs_lock __P((struct vnode *vp)); ! 234: int pcfs_unlock __P((struct vnode *vp)); ! 235: int pcfs_bmap __P((struct vnode *vp, daddr_t bn, struct vnode **vpp, ! 236: daddr_t *bnp)); ! 237: int pcfs_strategy __P((struct buf *bp)); ! 238: int pcfs_print __P((struct vnode *vp)); ! 239: int pcfs_islocked __P((struct vnode *vp)); ! 240: int pcfs_advlock __P((struct vnode *vp, caddr_t id, int op, struct flock *fl, ! 241: int flags)); ! 242: ! 243: /* ! 244: * Internal service routine prototypes. ! 245: */ ! 246: int deget __P((struct pcfsmount *pmp, u_long dirclust, u_long diroffset, ! 247: struct direntry *direntptr, struct denode **depp)); ! 248: #endif /* defined(KERNEL) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.