NetBSD/sys/msdosfs/denode.h

215 lines
9.5 KiB
C
Raw Normal View History

brought in fixed/renamed/matching MS-DOS FS code, from Jeff Polk <polk@bsdi.com>. His notes are as follows: ------------------------------------------------------------------------------ July 22, 1993 - Changed name of entire package from PCFS to MSDOSFS - Fixed bugs: root directory size in clusters instead of bytes growing directory didn't update in-core size link, symlink, mknod didn't free locked parent (deadlock) lookup returned real error on create and rename instead of EJUSTRETURN rename changed `.' entry in child instead of name entry in parent rename removed `.' entry in child instead of removing entry in parent when moving a directory from one dir to another createde() left new node locked when write of parent failed (deadlock) removede() decremented refcount even on error (rmdir's which failed due to write errors left in-core cache entries inconsistent) changed validation for filesystem to not check for the boot signature since some disks (e.g., mtools) aren't bootable directories are always show current time as modify time (needed for NFS export since DOS never updates dir mod times -- ctime is true create time). - Added support for cookies changes to the readdir() vnode interface (#ifdef __bsdi__) - Punted on the whole problem of inode generation numbers. This means that there's a chance of using a stale file handle to access a new file, but it doesn't appear to be the common case, and I don't see how to generate reasonable generation numbers without changing something on the disk (which is the way the SVR4 filesystem survival kit guys did it). I don't think it would be very safe to change the on-disk format. Jeff Polk (polk@BSDI.COM) ------------------------------------------------------------------------------
1993-08-13 15:35:13 +04:00
/*
* Written by Paul Popelka (paulp@uts.amdahl.com)
*
* You can do anything you want with this software, just don't say you wrote
* it, and don't remove this notice.
*
* This software is provided "as is".
*
* The author supplies this software to be publicly redistributed on the
* understanding that the author is not responsible for the correct
* functioning of this software in any circumstances and is not liable for
* any damages caused by this software.
*
* October 1992
*
* $Id: denode.h,v 1.2 1993/09/07 15:41:31 ws Exp $
brought in fixed/renamed/matching MS-DOS FS code, from Jeff Polk <polk@bsdi.com>. His notes are as follows: ------------------------------------------------------------------------------ July 22, 1993 - Changed name of entire package from PCFS to MSDOSFS - Fixed bugs: root directory size in clusters instead of bytes growing directory didn't update in-core size link, symlink, mknod didn't free locked parent (deadlock) lookup returned real error on create and rename instead of EJUSTRETURN rename changed `.' entry in child instead of name entry in parent rename removed `.' entry in child instead of removing entry in parent when moving a directory from one dir to another createde() left new node locked when write of parent failed (deadlock) removede() decremented refcount even on error (rmdir's which failed due to write errors left in-core cache entries inconsistent) changed validation for filesystem to not check for the boot signature since some disks (e.g., mtools) aren't bootable directories are always show current time as modify time (needed for NFS export since DOS never updates dir mod times -- ctime is true create time). - Added support for cookies changes to the readdir() vnode interface (#ifdef __bsdi__) - Punted on the whole problem of inode generation numbers. This means that there's a chance of using a stale file handle to access a new file, but it doesn't appear to be the common case, and I don't see how to generate reasonable generation numbers without changing something on the disk (which is the way the SVR4 filesystem survival kit guys did it). I don't think it would be very safe to change the on-disk format. Jeff Polk (polk@BSDI.COM) ------------------------------------------------------------------------------
1993-08-13 15:35:13 +04:00
*/
/*
* This is the pc filesystem specific portion of the vnode structure. To
* describe a file uniquely the de_dirclust, de_diroffset, and
* de_de.deStartCluster fields are used. de_dirclust contains the cluster
* number of the directory cluster containing the entry for a file or
* directory. de_diroffset is the index into the cluster for the entry
* describing a file or directory. de_de.deStartCluster is the number of
* the first cluster of the file or directory. Now to describe the quirks
* of the pc filesystem. - Clusters 0 and 1 are reserved. - The first
* allocatable cluster is 2. - The root directory is of fixed size and all
* blocks that make it up are contiguous. - Cluster 0 refers to the root
* directory when it is found in the startcluster field of a directory
* entry that points to another directory. - Cluster 0 implies a 0 length
* file when found in the start cluster field of a directory entry that
* points to a file. - You can't use the cluster number 0 to derive the
* address of the root directory. - Multiple directory entries can point to
* a directory. The entry in the parent directory points to a child
* directory. Any directories in the child directory contain a ".." entry
* that points back to the child. The child directory itself contains a
* "." entry that points to itself. - The root directory does not contain a
* "." or ".." entry. - Directory entries for directories are never changed
* once they are created (except when removed). The size stays 0, and the
* last modification time is never changed. This is because so many
* directory entries can point to the physical clusters that make up a
* directory. It would lead to an update nightmare. - The length field in
* a directory entry pointing to a directory contains 0 (always). The only
* way to find the end of a directory is to follow the cluster chain until
* the "last cluster" marker is found. My extensions to make this house of
* cards work. These apply only to the in memory copy of the directory
* entry. - A reference count for each denode will be kept since dos
* doesn't keep such things.
*/
/*
* Internal pseudo-offset for (nonexistent) directory entry for the root
* dir in the root dir
*/
#define MSDOSFSROOT_OFS 0x1fffffff
/*
* The fat cache structure. fc_fsrcn is the filesystem relative cluster
* number that corresponds to the file relative cluster number in this
* structure (fc_frcn).
*/
struct fatcache {
u_short fc_frcn; /* file relative cluster number */
u_short fc_fsrcn; /* filesystem relative cluster number */
};
/*
* The fat entry cache as it stands helps make extending files a "quick"
* operation by avoiding having to scan the fat to discover the last
* cluster of the file. The cache also helps sequential reads by
* remembering the last cluster read from the file. This also prevents us
* from having to rescan the fat to find the next cluster to read. This
* cache is probably pretty worthless if a file is opened by multiple
* processes.
*/
#define FC_SIZE 2 /* number of entries in the cache */
#define FC_LASTMAP 0 /* entry the last call to pcbmap() resolved
* to */
#define FC_LASTFC 1 /* entry for the last cluster in the file */
#define FCE_EMPTY 0xffff /* doesn't represent an actual cluster # */
/*
* Set a slot in the fat cache.
*/
#define fc_setcache(dep, slot, frcn, fsrcn) \
(dep)->de_fc[slot].fc_frcn = frcn; \
(dep)->de_fc[slot].fc_fsrcn = fsrcn;
/*
* This is the in memory variant of a dos directory entry. It is usually
* contained within a vnode.
*/
struct denode {
struct denode *de_chain[2]; /* hash chain ptrs */
struct vnode *de_vnode; /* addr of vnode we are part of */
struct vnode *de_devvp; /* vnode of blk dev we live on */
u_long de_flag; /* flag bits */
dev_t de_dev; /* device where direntry lives */
u_long de_dirclust; /* cluster of the directory file containing this entry */
u_long de_diroffset; /* ordinal of this entry in the directory */
long de_refcnt; /* reference count */
struct msdosfsmount *de_pmp; /* addr of our mount struct */
struct lockf *de_lockf; /* byte level lock list */
long de_spare0; /* current lock holder */
long de_spare1; /* lock wanter */
struct direntry de_de; /* the actual directory entry */
struct fatcache de_fc[FC_SIZE]; /* fat cache */
};
/*
* Values for the de_flag field of the denode.
*/
#define DELOCKED 0x0001 /* directory entry is locked */
#define DEWANT 0x0002 /* someone wants this de */
#define DERENAME 0x0004 /* de is being renamed */
#define DEUPD 0x0008 /* file has been modified */
#define DESHLOCK 0x0010 /* file has shared lock */
#define DEEXLOCK 0x0020 /* file has exclusive lock */
#define DELWAIT 0x0040 /* someone waiting on file lock */
#define DEMOD 0x0080 /* denode wants to be written back to disk */
/*
* Shorthand macros used to reference fields in the direntry contained in
* the denode structure.
*/
#define de_Name de_de.deName
#define de_Extension de_de.deExtension
#define de_Attributes de_de.deAttributes
#define de_Reserved de_de.deReserved
#define de_Time de_de.deTime
#define de_Date de_de.deDate
#define de_StartCluster de_de.deStartCluster
#define de_FileSize de_de.deFileSize
#define de_forw de_chain[0]
#define de_back de_chain[1]
#if defined(KERNEL)
#define VTODE(vp) ((struct denode *)(vp)->v_data)
#define DETOV(de) ((de)->de_vnode)
#define DELOCK(de) delock(de)
#define DEUNLOCK(de) deunlock(de)
#define DEUPDAT(dep, t, waitfor) \
if (dep->de_flag & DEUPD) \
(void) deupdat(dep, t, waitfor);
#define DETIMES(dep, t) \
if (dep->de_flag & DEUPD) { \
(dep)->de_flag |= DEMOD; \
unix2dostime(t, (union dosdate *)&dep->de_Date, \
(union dostime *)&dep->de_Time); \
(dep)->de_flag &= ~DEUPD; \
}
/*
* This overlays the fid sturcture (see mount.h)
*/
struct defid {
u_short defid_len; /* length of structure */
u_short defid_pad; /* force long alignment */
u_long defid_dirclust; /* cluster this dir entry came from */
u_long defid_dirofs; /* index of entry within the cluster */
/* u_long defid_gen; /* generation number */
};
/*
* Prototypes for MSDOSFS vnode operations
*/
int msdosfs_lookup __P((struct vnode * vp, struct nameidata * ndp, struct proc * p));
int msdosfs_create __P((struct nameidata * ndp, struct vattr * vap, struct proc * p));
int msdosfs_mknod __P((struct nameidata * ndp, struct vattr * vap, struct ucred * cred, struct proc * p));
int msdosfs_open __P((struct vnode * vp, int mode, struct ucred * cred, struct proc * p));
int msdosfs_close __P((struct vnode * vp, int fflag, struct ucred * cred, struct proc * p));
int msdosfs_access __P((struct vnode * vp, int mode, struct ucred * cred, struct proc * p));
int msdosfs_getattr __P((struct vnode * vp, struct vattr * vap, struct ucred * cred, struct proc * p));
int msdosfs_setattr __P((struct vnode * vp, struct vattr * vap, struct ucred * cred, struct proc * p));
int msdosfs_read __P((struct vnode * vp, struct uio * uio, int ioflag, struct ucred * cred));
int msdosfs_write __P((struct vnode * vp, struct uio * uio, int ioflag, struct ucred * cred));
int msdosfs_ioctl __P((struct vnode * vp, int command, caddr_t data, int fflag, struct ucred * cred, struct proc * p));
int msdosfs_select __P((struct vnode * vp, int which, int fflags, struct ucred * cred, struct proc * p));
int msdosfs_mmap __P((struct vnode * vp, int fflags, struct ucred * cred, struct proc * p));
int msdosfs_fsync __P((struct vnode * vp, int fflags, struct ucred * cred, int waitfor, struct proc * p));
int msdosfs_seek __P((struct vnode * vp, off_t oldoff, off_t newoff, struct ucred * cred));
int msdosfs_remove __P((struct nameidata * ndp, struct proc * p));
int msdosfs_link __P((struct vnode * vp, struct nameidata * ndp, struct proc * p));
int msdosfs_rename __P((struct nameidata * fndp, struct nameidata * tdnp, struct proc * p));
int msdosfs_mkdir __P((struct nameidata * ndp, struct vattr * vap, struct proc * p));
int msdosfs_rmdir __P((struct nameidata * ndp, struct proc * p));
int msdosfs_symlink __P((struct nameidata * ndp, struct vattr * vap, char *target, struct proc * p));
int msdosfs_readdir __P((struct vnode * vp, struct uio * uio, struct ucred * cred, int *eofflagp, u_int * cookies, int ncookies));
int msdosfs_readlink __P((struct vnode * vp, struct uio * uio, struct ucred * cred));
int msdosfs_abortop __P((struct nameidata * ndp));
int msdosfs_inactive __P((struct vnode * vp, struct proc * p));
int msdosfs_reclaim __P((struct vnode * vp));
int msdosfs_lock __P((struct vnode * vp));
int msdosfs_unlock __P((struct vnode * vp));
int msdosfs_bmap __P((struct vnode * vp, daddr_t bn, struct vnode ** vpp, daddr_t * bnp));
int msdosfs_strategy __P((struct buf * bp));
int msdosfs_print __P((struct vnode * vp));
int msdosfs_islocked __P((struct vnode * vp));
int msdosfs_advlock __P((struct vnode * vp, caddr_t id, int op, struct flock * fl, int flags));
/*
* Internal service routine prototypes.
*/
int deget __P((struct msdosfsmount * pmp, u_long dirclust, u_long diroffset, struct direntry * direntptr, struct denode ** depp));
#endif /* defined(KERNEL) */