denode.h revision 42249
118334Speter/* $Id: denode.h,v 1.17 1998/11/21 00:20:24 dt Exp $ */ 290075Sobrien/* $NetBSD: denode.h,v 1.25 1997/11/17 15:36:28 ws Exp $ */ 390075Sobrien 418334Speter/*- 590075Sobrien * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. 618334Speter * Copyright (C) 1994, 1995, 1997 TooLs GmbH. 790075Sobrien * All rights reserved. 890075Sobrien * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below). 990075Sobrien * 1090075Sobrien * Redistribution and use in source and binary forms, with or without 1118334Speter * modification, are permitted provided that the following conditions 1290075Sobrien * are met: 1390075Sobrien * 1. Redistributions of source code must retain the above copyright 1490075Sobrien * notice, this list of conditions and the following disclaimer. 1590075Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1618334Speter * notice, this list of conditions and the following disclaimer in the 1718334Speter * documentation and/or other materials provided with the distribution. 1890075Sobrien * 3. All advertising materials mentioning features or use of this software 1990075Sobrien * must display the following acknowledgement: 2090075Sobrien * This product includes software developed by TooLs GmbH. 2118334Speter * 4. The name of TooLs GmbH may not be used to endorse or promote products 2296549Sobrien * derived from this software without specific prior written permission. 2396549Sobrien * 2418334Speter * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 2518334Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2618334Speter * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2718334Speter * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2818334Speter * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2918334Speter * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 3018334Speter * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 3118334Speter * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 3250397Sobrien * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 3390075Sobrien * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3418334Speter */ 3590075Sobrien/* 3690075Sobrien * Written by Paul Popelka (paulp@uts.amdahl.com) 3718334Speter * 3890075Sobrien * You can do anything you want with this software, just don't say you wrote 3918334Speter * it, and don't remove this notice. 4090075Sobrien * 4118334Speter * This software is provided "as is". 4218334Speter * 4350397Sobrien * The author supplies this software to be publicly redistributed on the 4490075Sobrien * understanding that the author is not responsible for the correct 4590075Sobrien * functioning of this software in any circumstances and is not liable for 4650397Sobrien * any damages caused by this software. 4790075Sobrien * 4890075Sobrien * October 1992 4990075Sobrien */ 5090075Sobrien 5196263Sobrien/* 5250397Sobrien * This is the pc filesystem specific portion of the vnode structure. 5318334Speter * 5418334Speter * To describe a file uniquely the de_dirclust, de_diroffset, and 5518334Speter * de_StartCluster fields are used. 5618334Speter * 5718334Speter * de_dirclust contains the cluster number of the directory cluster 5818334Speter * containing the entry for a file or directory. 5996263Sobrien * de_diroffset is the index into the cluster for the entry describing 6018334Speter * a file or directory. 6118334Speter * de_StartCluster is the number of the first cluster of the file or directory. 6218334Speter * 6318334Speter * Now to describe the quirks of the pc filesystem. 6418334Speter * - Clusters 0 and 1 are reserved. 6518334Speter * - The first allocatable cluster is 2. 6618334Speter * - The root directory is of fixed size and all blocks that make it up 6718334Speter * are contiguous. 6890075Sobrien * - Cluster 0 refers to the root directory when it is found in the 6918334Speter * startcluster field of a directory entry that points to another directory. 7018334Speter * - Cluster 0 implies a 0 length file when found in the start cluster field 7118334Speter * of a directory entry that points to a file. 7218334Speter * - You can't use the cluster number 0 to derive the address of the root 7318334Speter * directory. 7418334Speter * - Multiple directory entries can point to a directory. The entry in the 7518334Speter * parent directory points to a child directory. Any directories in the 7618334Speter * child directory contain a ".." entry that points back to the parent. 7718334Speter * The child directory itself contains a "." entry that points to itself. 7818334Speter * - The root directory does not contain a "." or ".." entry. 7918334Speter * - Directory entries for directories are never changed once they are created 8018334Speter * (except when removed). The size stays 0, and the last modification time 8118334Speter * is never changed. This is because so many directory entries can point to 8218334Speter * the physical clusters that make up a directory. It would lead to an 8318334Speter * update nightmare. 8418334Speter * - The length field in a directory entry pointing to a directory contains 0 8518334Speter * (always). The only way to find the end of a directory is to follow the 8618334Speter * cluster chain until the "last cluster" marker is found. 8718334Speter * 8818334Speter * My extensions to make this house of cards work. These apply only to the in 8918334Speter * memory copy of the directory entry. 9018334Speter * - A reference count for each denode will be kept since dos doesn't keep such 9118334Speter * things. 9218334Speter */ 9318334Speter 9418334Speter/* 9518334Speter * Internal pseudo-offset for (nonexistent) directory entry for the root 9618334Speter * dir in the root dir 9718334Speter */ 9818334Speter#define MSDOSFSROOT_OFS 0x1fffffff 9918334Speter 10018334Speter/* 10118334Speter * The fat cache structure. fc_fsrcn is the filesystem relative cluster 10218334Speter * number that corresponds to the file relative cluster number in this 10318334Speter * structure (fc_frcn). 10490075Sobrien */ 10518334Speterstruct fatcache { 10618334Speter u_long fc_frcn; /* file relative cluster number */ 10790075Sobrien u_long fc_fsrcn; /* filesystem relative cluster number */ 10890075Sobrien}; 10990075Sobrien 11090075Sobrien/* 11190075Sobrien * The fat entry cache as it stands helps make extending files a "quick" 11290075Sobrien * operation by avoiding having to scan the fat to discover the last 11390075Sobrien * cluster of the file. The cache also helps sequential reads by 11490075Sobrien * remembering the last cluster read from the file. This also prevents us 11518334Speter * from having to rescan the fat to find the next cluster to read. This 11618334Speter * cache is probably pretty worthless if a file is opened by multiple 11718334Speter * processes. 11818334Speter */ 11918334Speter#define FC_SIZE 2 /* number of entries in the cache */ 12018334Speter#define FC_LASTMAP 0 /* entry the last call to pcbmap() resolved 12118334Speter * to */ 12218334Speter#define FC_LASTFC 1 /* entry for the last cluster in the file */ 12318334Speter 12418334Speter#define FCE_EMPTY 0xffffffff /* doesn't represent an actual cluster # */ 12518334Speter 12618334Speter/* 12718334Speter * Set a slot in the fat cache. 12818334Speter */ 12918334Speter#define fc_setcache(dep, slot, frcn, fsrcn) \ 13018334Speter (dep)->de_fc[slot].fc_frcn = frcn; \ 13118334Speter (dep)->de_fc[slot].fc_fsrcn = fsrcn; 13218334Speter 13318334Speter/* 13418334Speter * This is the in memory variant of a dos directory entry. It is usually 13518334Speter * contained within a vnode. 13618334Speter */ 13718334Speterstruct denode { 13818334Speter struct lock de_lock; /* denode lock >Keep this first< */ 13918334Speter struct denode *de_next; /* Hash chain forward */ 14096263Sobrien struct denode **de_prev; /* Hash chain back */ 14196263Sobrien struct vnode *de_vnode; /* addr of vnode we are part of */ 14296263Sobrien struct vnode *de_devvp; /* vnode of blk dev we live on */ 14396263Sobrien u_long de_flag; /* flag bits */ 14496263Sobrien dev_t de_dev; /* device where direntry lives */ 14518334Speter u_long de_dirclust; /* cluster of the directory file containing this entry */ 14618334Speter u_long de_diroffset; /* offset of this entry in the directory cluster */ 14718334Speter u_long de_fndoffset; /* offset of found dir entry */ 14818334Speter int de_fndcnt; /* number of slots before de_fndoffset */ 14918334Speter long de_refcnt; /* reference count */ 15018334Speter struct msdosfsmount *de_pmp; /* addr of our mount struct */ 15118334Speter u_char de_Name[12]; /* name, from DOS directory entry */ 15218334Speter u_char de_Attributes; /* attributes, from directory entry */ 15318334Speter u_char de_LowerCase; /* NT VFAT lower case flags */ 15418334Speter u_char de_CHun; /* Hundredth of second of CTime*/ 15518334Speter u_short de_CTime; /* creation time */ 15618334Speter u_short de_CDate; /* creation date */ 15718334Speter u_short de_ADate; /* access date */ 15818334Speter u_short de_MTime; /* modification time */ 15918334Speter u_short de_MDate; /* modification date */ 16018334Speter u_long de_StartCluster; /* starting cluster of file */ 16118334Speter u_long de_FileSize; /* size of file in bytes */ 16218334Speter struct fatcache de_fc[FC_SIZE]; /* fat cache */ 16318334Speter u_quad_t de_modrev; /* Revision level for lease. */ 16418334Speter}; 16518334Speter 16618334Speter/* 16718334Speter * Values for the de_flag field of the denode. 16818334Speter */ 16918334Speter#define DE_UPDATE 0x0004 /* Modification time update request */ 17018334Speter#define DE_CREATE 0x0008 /* Creation time update */ 17118334Speter#define DE_ACCESS 0x0010 /* Access time update */ 17218334Speter#define DE_MODIFIED 0x0020 /* Denode has been modified */ 17318334Speter#define DE_RENAME 0x0040 /* Denode is in the process of being renamed */ 17418334Speter 17518334Speter 17618334Speter/* 17718334Speter * Transfer directory entries between internal and external form. 17818334Speter * dep is a struct denode * (internal form), 17918334Speter * dp is a struct direntry * (external form). 18018334Speter */ 18118334Speter#define DE_INTERNALIZE32(dep, dp) \ 18218334Speter ((dep)->de_StartCluster |= getushort((dp)->deHighClust) << 16) 18318334Speter#define DE_INTERNALIZE(dep, dp) \ 18418334Speter (bcopy((dp)->deName, (dep)->de_Name, 11), \ 18518334Speter (dep)->de_Attributes = (dp)->deAttributes, \ 18618334Speter (dep)->de_LowerCase = (dp)->deLowerCase, \ 18718334Speter (dep)->de_CHun = (dp)->deCHundredth, \ 18818334Speter (dep)->de_CTime = getushort((dp)->deCTime), \ 18918334Speter (dep)->de_CDate = getushort((dp)->deCDate), \ 19018334Speter (dep)->de_ADate = getushort((dp)->deADate), \ 19118334Speter (dep)->de_MTime = getushort((dp)->deMTime), \ 19218334Speter (dep)->de_MDate = getushort((dp)->deMDate), \ 19318334Speter (dep)->de_StartCluster = getushort((dp)->deStartCluster), \ 19418334Speter (dep)->de_FileSize = getulong((dp)->deFileSize), \ 19518334Speter (FAT32((dep)->de_pmp) ? DE_INTERNALIZE32((dep), (dp)) : 0)) 19618334Speter 19718334Speter#define DE_EXTERNALIZE(dp, dep) \ 19818334Speter (bcopy((dep)->de_Name, (dp)->deName, 11), \ 19918334Speter (dp)->deAttributes = (dep)->de_Attributes, \ 20018334Speter (dp)->deLowerCase = (dep)->de_LowerCase, \ 20118334Speter (dp)->deCHundredth = (dep)->de_CHun, \ 20218334Speter putushort((dp)->deCTime, (dep)->de_CTime), \ 20318334Speter putushort((dp)->deCDate, (dep)->de_CDate), \ 20418334Speter putushort((dp)->deADate, (dep)->de_ADate), \ 20518334Speter putushort((dp)->deMTime, (dep)->de_MTime), \ 20618334Speter putushort((dp)->deMDate, (dep)->de_MDate), \ 20718334Speter putushort((dp)->deStartCluster, (dep)->de_StartCluster), \ 20818334Speter putulong((dp)->deFileSize, \ 20918334Speter ((dep)->de_Attributes & ATTR_DIRECTORY) ? 0 : (dep)->de_FileSize), \ 21018334Speter putushort((dp)->deHighClust, (dep)->de_StartCluster >> 16)) 21118334Speter 21218334Speter#define de_forw de_chain[0] 21318334Speter#define de_back de_chain[1] 21418334Speter 21518334Speter#ifdef KERNEL 21618334Speter 21718334Speter#define VTODE(vp) ((struct denode *)(vp)->v_data) 21818334Speter#define DETOV(de) ((de)->de_vnode) 21918334Speter 22018334Speter#define DETIMES(dep, acc, mod, cre) do { \ 22190075Sobrien if ((dep)->de_flag & DE_UPDATE) { \ 22218334Speter (dep)->de_flag |= DE_MODIFIED; \ 22318334Speter unix2dostime((mod), &(dep)->de_MDate, &(dep)->de_MTime, \ 22418334Speter NULL); \ 22518334Speter (dep)->de_Attributes |= ATTR_ARCHIVE; \ 22618334Speter } \ 22718334Speter if ((dep)->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95) { \ 22818334Speter (dep)->de_flag &= ~(DE_UPDATE | DE_CREATE | DE_ACCESS); \ 22918334Speter break; \ 23018334Speter } \ 23118334Speter if ((dep)->de_flag & DE_ACCESS) { \ 23290075Sobrien u_int16_t adate; \ 23318334Speter \ 23418334Speter unix2dostime((acc), &adate, NULL, NULL); \ 23518334Speter if (adate != (dep)->de_ADate) { \ 23618334Speter (dep)->de_flag |= DE_MODIFIED; \ 23718334Speter (dep)->de_ADate = adate; \ 23818334Speter } \ 23918334Speter } \ 24018334Speter if ((dep)->de_flag & DE_CREATE) { \ 24118334Speter unix2dostime((cre), &(dep)->de_CDate, &(dep)->de_CTime, \ 24218334Speter &(dep)->de_CHun); \ 24318334Speter (dep)->de_flag |= DE_MODIFIED; \ 24418334Speter } \ 24518334Speter (dep)->de_flag &= ~(DE_UPDATE | DE_CREATE | DE_ACCESS); \ 24618334Speter} while (0); 24718334Speter 24818334Speter/* 24918334Speter * This overlays the fid structure (see mount.h) 25018334Speter */ 25118334Speterstruct defid { 25218334Speter u_short defid_len; /* length of structure */ 25318334Speter u_short defid_pad; /* force long alignment */ 25418334Speter 25518334Speter u_long defid_dirclust; /* cluster this dir entry came from */ 25618334Speter u_long defid_dirofs; /* offset of entry within the cluster */ 25718334Speter#if 0 25818334Speter u_long defid_gen; /* generation number */ 25918334Speter#endif 26018334Speter}; 26190075Sobrien 26218334Speterextern vop_t **msdosfs_vnodeop_p; 26318334Speter 26418334Speterint msdosfs_lookup __P((struct vop_cachedlookup_args *)); 26518334Speterint msdosfs_inactive __P((struct vop_inactive_args *)); 26618334Speterint msdosfs_reclaim __P((struct vop_reclaim_args *)); 26718334Speter 26818334Speter/* 26918334Speter * Internal service routine prototypes. 27018334Speter */ 27118334Speterint deget __P((struct msdosfsmount *, u_long, u_long, struct denode **)); 27218334Speterint uniqdosname __P((struct denode *, struct componentname *, u_char *)); 27318334Speterint findwin95 __P((struct denode *)); 27418334Speter 27518334Speterint readep __P((struct msdosfsmount *pmp, u_long dirclu, u_long dirofs, struct buf **bpp, struct direntry **epp)); 27690075Sobrienint readde __P((struct denode *dep, struct buf **bpp, struct direntry **epp)); 27790075Sobrienint deextend __P((struct denode *dep, u_long length, struct ucred *cred)); 27890075Sobrienint fillinusemap __P((struct msdosfsmount *pmp)); 27990075Sobrienvoid reinsert __P((struct denode *dep)); 28090075Sobrienint dosdirempty __P((struct denode *dep)); 28190075Sobrienint createde __P((struct denode *dep, struct denode *ddep, struct denode **depp, struct componentname *cnp)); 28290075Sobrienint deupdat __P((struct denode *dep, int waitfor)); 28390075Sobrienint removede __P((struct denode *pdep, struct denode *dep)); 28490075Sobrienint detrunc __P((struct denode *dep, u_long length, int flags, struct ucred *cred, struct proc *p)); 28590075Sobrienint doscheckpath __P(( struct denode *source, struct denode *target)); 28690075Sobrien#endif /* KERNEL */ 28796263Sobrien