[BACK]Return to denode.h CVS log [TXT][DIR] Up to [local] / sys / msdosfs

Annotation of sys/msdosfs/denode.h, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: denode.h,v 1.21 2007/06/02 02:04:21 deraadt Exp $     */
                      2: /*     $NetBSD: denode.h,v 1.24 1997/10/17 11:23:39 ws Exp $   */
                      3:
                      4: /*-
                      5:  * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
                      6:  * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
                      7:  * All rights reserved.
                      8:  * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *     This product includes software developed by TooLs GmbH.
                     21:  * 4. The name of TooLs GmbH may not be used to endorse or promote products
                     22:  *    derived from this software without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
                     25:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     26:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     27:  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
                     28:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     29:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     30:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     31:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     32:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     33:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     34:  */
                     35: /*
                     36:  * Written by Paul Popelka (paulp@uts.amdahl.com)
                     37:  *
                     38:  * You can do anything you want with this software, just don't say you wrote
                     39:  * it, and don't remove this notice.
                     40:  *
                     41:  * This software is provided "as is".
                     42:  *
                     43:  * The author supplies this software to be publicly redistributed on the
                     44:  * understanding that the author is not responsible for the correct
                     45:  * functioning of this software in any circumstances and is not liable for
                     46:  * any damages caused by this software.
                     47:  *
                     48:  * October 1992
                     49:  */
                     50:
                     51: /*
                     52:  * This is the pc filesystem specific portion of the vnode structure.
                     53:  *
                     54:  * To describe a file uniquely the de_dirclust, de_diroffset, and
                     55:  * de_StartCluster fields are used.
                     56:  *
                     57:  * de_dirclust contains the cluster number of the directory cluster
                     58:  *     containing the entry for a file or directory.
                     59:  * de_diroffset is the index into the cluster for the entry describing
                     60:  *     a file or directory.
                     61:  * de_StartCluster is the number of the first cluster of the file or directory.
                     62:  *
                     63:  * Now to describe the quirks of the pc filesystem.
                     64:  * - Clusters 0 and 1 are reserved.
                     65:  * - The first allocatable cluster is 2.
                     66:  * - The root directory is of fixed size and all blocks that make it up
                     67:  *   are contiguous.
                     68:  * - Cluster 0 refers to the root directory when it is found in the
                     69:  *   startcluster field of a directory entry that points to another directory.
                     70:  * - Cluster 0 implies a 0 length file when found in the start cluster field
                     71:  *   of a directory entry that points to a file.
                     72:  * - You can't use the cluster number 0 to derive the address of the root
                     73:  *   directory.
                     74:  * - Multiple directory entries can point to a directory. The entry in the
                     75:  *   parent directory points to a child directory.  Any directories in the
                     76:  *   child directory contain a ".." entry that points back to the parent.
                     77:  *   The child directory itself contains a "." entry that points to itself.
                     78:  * - The root directory does not contain a "." or ".." entry.
                     79:  * - Directory entries for directories are never changed once they are created
                     80:  *   (except when removed).  The size stays 0, and the last modification time
                     81:  *   is never changed.  This is because so many directory entries can point to
                     82:  *   the physical clusters that make up a directory.  It would lead to an
                     83:  *   update nightmare.
                     84:  * - The length field in a directory entry pointing to a directory contains 0
                     85:  *   (always).  The only way to find the end of a directory is to follow the
                     86:  *   cluster chain until the "last cluster" marker is found.
                     87:  *
                     88:  * My extensions to make this house of cards work.  These apply only to the in
                     89:  * memory copy of the directory entry.
                     90:  * - A reference count for each denode will be kept since dos doesn't keep such
                     91:  *   things.
                     92:  */
                     93:
                     94: /*
                     95:  * Internal pseudo-offset for (nonexistent) directory entry for the root
                     96:  * dir in the root dir
                     97:  */
                     98: #define        MSDOSFSROOT_OFS 0x1fffffff
                     99:
                    100: /*
                    101:  * The fat cache structure. fc_fsrcn is the filesystem relative cluster
                    102:  * number that corresponds to the file relative cluster number in this
                    103:  * structure (fc_frcn).
                    104:  */
                    105: struct fatcache {
                    106:        uint32_t fc_frcn;               /* file relative cluster number */
                    107:        uint32_t fc_fsrcn;      /* filesystem relative cluster number */
                    108: };
                    109:
                    110: /*
                    111:  * The fat entry cache as it stands helps make extending files a "quick"
                    112:  * operation by avoiding having to scan the fat to discover the last
                    113:  * cluster of the file. The cache also helps sequential reads by
                    114:  * remembering the last cluster read from the file.  This also prevents us
                    115:  * from having to rescan the fat to find the next cluster to read.  This
                    116:  * cache is probably pretty worthless if a file is opened by multiple
                    117:  * processes.
                    118:  */
                    119: #define        FC_SIZE         2       /* number of entries in the cache */
                    120: #define        FC_LASTMAP      0       /* entry the last call to pcbmap() resolved
                    121:                                 * to */
                    122: #define        FC_LASTFC       1       /* entry for the last cluster in the file */
                    123:
                    124: #define        FCE_EMPTY       0xffffffff      /* doesn't represent an actual cluster # */
                    125:
                    126: /*
                    127:  * Set a slot in the fat cache.
                    128:  */
                    129: #define        fc_setcache(dep, slot, frcn, fsrcn) \
                    130:        (dep)->de_fc[slot].fc_frcn = frcn; \
                    131:        (dep)->de_fc[slot].fc_fsrcn = fsrcn;
                    132:
                    133: /*
                    134:  * This is the in memory variant of a dos directory entry.  It is usually
                    135:  * contained within a vnode.
                    136:  */
                    137: struct denode {
                    138:        struct denode *de_next; /* Hash chain forward */
                    139:        struct denode **de_prev; /* Hash chain back */
                    140:        struct vnode *de_vnode; /* addr of vnode we are part of */
                    141:        struct vnode *de_devvp; /* vnode of blk dev we live on */
                    142:        uint32_t de_flag;               /* flag bits */
                    143:        dev_t de_dev;           /* device where direntry lives */
                    144:        daddr64_t de_lastr;
                    145:        uint32_t de_dirclust;   /* cluster of the directory file containing this entry */
                    146:        uint32_t de_diroffset;  /* offset of this entry in the directory cluster */
                    147:        uint32_t de_fndoffset;  /* offset of found dir entry */
                    148:        int de_fndcnt;          /* number of slots before de_fndoffset */
                    149:        long de_refcnt;         /* reference count */
                    150:        struct msdosfsmount *de_pmp;    /* addr of our mount struct */
                    151:        struct lockf *de_lockf; /* byte level lock list */
                    152:        struct lock de_lock;    /* denode lock */
                    153:        u_char de_Name[12];     /* name, from DOS directory entry */
                    154:        u_char de_Attributes;   /* attributes, from directory entry */
                    155:        u_char de_CTimeHundredth; /* creation time, 1/100th of a sec */
                    156:        u_short de_CTime;       /* creation time */
                    157:        u_short de_CDate;       /* creation date */
                    158:        u_short de_ADate;       /* access date */
                    159:        u_short de_MTime;       /* modification time */
                    160:        u_short de_MDate;       /* modification date */
                    161:        uint32_t de_StartCluster; /* starting cluster of file */
                    162:        uint32_t de_FileSize;   /* size of file in bytes */
                    163:        struct fatcache de_fc[FC_SIZE]; /* fat cache */
                    164: };
                    165:
                    166: /*
                    167:  * Values for the de_flag field of the denode.
                    168:  */
                    169: #define        DE_UPDATE       0x0004  /* Modification time update request. */
                    170: #define        DE_CREATE       0x0008  /* Creation time update */
                    171: #define        DE_ACCESS       0x0010  /* Access time update */
                    172: #define        DE_MODIFIED     0x0020  /* Denode has been modified. */
                    173: #define        DE_RENAME       0x0040  /* Denode is in the process of being renamed */
                    174:
                    175: /*
                    176:  * Maximum filename length in Win95
                    177:  * Note: Must be < sizeof(dirent.d_name)
                    178:  */
                    179: #define        WIN_MAXLEN      255
                    180:
                    181: /* Maximum size of a file on a FAT filesystem */
                    182: #define MSDOSFS_FILESIZE_MAX   0xFFFFFFFFLL
                    183:
                    184: /*
                    185:  * Transfer directory entries between internal and external form.
                    186:  * dep is a struct denode * (internal form),
                    187:  * dp is a struct direntry * (external form).
                    188:  */
                    189: #define DE_INTERNALIZE32(dep, dp)                      \
                    190:         ((dep)->de_StartCluster |= getushort((dp)->deHighClust) << 16)
                    191: #define DE_INTERNALIZE(dep, dp)                        \
                    192:        (bcopy((dp)->deName, (dep)->de_Name, 11),       \
                    193:         (dep)->de_Attributes = (dp)->deAttributes,     \
                    194:         (dep)->de_CTimeHundredth = (dp)->deCTimeHundredth, \
                    195:         (dep)->de_CTime = getushort((dp)->deCTime),    \
                    196:         (dep)->de_CDate = getushort((dp)->deCDate),    \
                    197:         (dep)->de_ADate = getushort((dp)->deADate),    \
                    198:         (dep)->de_MTime = getushort((dp)->deMTime),    \
                    199:         (dep)->de_MDate = getushort((dp)->deMDate),    \
                    200:         (dep)->de_StartCluster = getushort((dp)->deStartCluster), \
                    201:         (dep)->de_FileSize = getulong((dp)->deFileSize), \
                    202:         (FAT32((dep)->de_pmp) ? DE_INTERNALIZE32((dep), (dp)) : 0))
                    203:
                    204: #define DE_EXTERNALIZE(dp, dep)                                \
                    205:        (bcopy((dep)->de_Name, (dp)->deName, 11),       \
                    206:         (dp)->deAttributes = (dep)->de_Attributes,     \
                    207:         (dp)->deLowerCase = CASE_LOWER_BASE | CASE_LOWER_EXT,  \
                    208:         (dp)->deCTimeHundredth = (dep)->de_CTimeHundredth, \
                    209:         putushort((dp)->deCTime, (dep)->de_CTime),     \
                    210:         putushort((dp)->deCDate, (dep)->de_CDate),     \
                    211:         putushort((dp)->deADate, (dep)->de_ADate),     \
                    212:         putushort((dp)->deMTime, (dep)->de_MTime),     \
                    213:         putushort((dp)->deMDate, (dep)->de_MDate),     \
                    214:         putushort((dp)->deStartCluster, (dep)->de_StartCluster), \
                    215:         putulong((dp)->deFileSize, \
                    216:             ((dep)->de_Attributes & ATTR_DIRECTORY) ? 0 : (dep)->de_FileSize),\
                    217:         putushort((dp)->deHighClust, \
                    218:             FAT32((dep)->de_pmp) ? (dep)->de_StartCluster >> 16 : 0))
                    219:
                    220: #define        de_forw         de_chain[0]
                    221: #define        de_back         de_chain[1]
                    222:
                    223: #ifdef _KERNEL
                    224:
                    225: #define        VTODE(vp)       ((struct denode *)(vp)->v_data)
                    226: #define        DETOV(de)       ((de)->de_vnode)
                    227:
                    228: #define        DETIMES(dep, acc, mod, cre) \
                    229:        if ((dep)->de_flag & (DE_UPDATE | DE_CREATE | DE_ACCESS)) { \
                    230:                (dep)->de_flag |= DE_MODIFIED; \
                    231:                if ((dep)->de_flag & DE_UPDATE) { \
                    232:                        unix2dostime((mod), &(dep)->de_MDate, &(dep)->de_MTime, NULL); \
                    233:                        (dep)->de_Attributes |= ATTR_ARCHIVE; \
                    234:                } \
                    235:                if (!((dep)->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95)) { \
                    236:                        if ((dep)->de_flag & DE_ACCESS) \
                    237:                                unix2dostime((acc), &(dep)->de_ADate, NULL, NULL); \
                    238:                        if ((dep)->de_flag & DE_CREATE) \
                    239:                                unix2dostime((cre), &(dep)->de_CDate, &(dep)->de_CTime, &(dep)->de_CTimeHundredth); \
                    240:                } \
                    241:                (dep)->de_flag &= ~(DE_UPDATE | DE_CREATE | DE_ACCESS); \
                    242:        }
                    243:
                    244: /*
                    245:  * This overlays the fid structure (see mount.h)
                    246:  */
                    247: struct defid {
                    248:        u_short defid_len;      /* length of structure */
                    249:        u_short defid_pad;      /* force long alignment */
                    250:
                    251:        uint32_t defid_dirclust;        /* cluster this dir entry came from */
                    252:        uint32_t defid_dirofs;  /* offset of entry within the cluster */
                    253: #if 0
                    254:        uint32_t        defid_gen;      /* generation number */
                    255: #endif
                    256: };
                    257:
                    258: /*
                    259:  * Prototypes for MSDOSFS vnode operations
                    260:  */
                    261: int    msdosfs_lookup(void *);
                    262: int    msdosfs_create(void *);
                    263: int    msdosfs_mknod(void *);
                    264: int    msdosfs_open(void *);
                    265: int    msdosfs_close(void *);
                    266: int    msdosfs_access(void *);
                    267: int    msdosfs_getattr(void *);
                    268: int    msdosfs_setattr(void *);
                    269: int    msdosfs_read(void *);
                    270: int    msdosfs_write(void *);
                    271: int    msdosfs_ioctl(void *);
                    272: int    msdosfs_poll(void *);
                    273: int    msdosfs_fsync(void *);
                    274: int    msdosfs_remove(void *);
                    275: int    msdosfs_link(void *);
                    276: int    msdosfs_rename(void *);
                    277: int    msdosfs_mkdir(void *);
                    278: int    msdosfs_rmdir(void *);
                    279: int    msdosfs_symlink(void *);
                    280: int    msdosfs_readdir(void *);
                    281: int    msdosfs_readlink(void *);
                    282: int    msdosfs_inactive(void *);
                    283: int    msdosfs_reclaim(void *);
                    284: int    msdosfs_lock(void *);
                    285: int    msdosfs_unlock(void *);
                    286: int    msdosfs_bmap(void *);
                    287: int    msdosfs_strategy(void *);
                    288: int    msdosfs_print(void *);
                    289: int    msdosfs_islocked(void *);
                    290: int    msdosfs_advlock(void *);
                    291: int    msdosfs_pathconf(void *);
                    292:
                    293: /*
                    294:  * Internal service routine prototypes.
                    295:  */
                    296: int createde(struct denode *, struct denode *, struct denode **, struct componentname *);
                    297: int deextend(struct denode *, uint32_t, struct ucred *);
                    298: int deget(struct msdosfsmount *, uint32_t, uint32_t, struct denode **);
                    299: int detrunc(struct denode *, uint32_t, int, struct ucred *, struct proc *);
                    300: int deupdat(struct denode *, int);
                    301: int doscheckpath(struct denode *, struct denode *);
                    302: int dosdirempty(struct denode *);
                    303: int readde(struct denode *, struct buf **, struct direntry **);
                    304: int readep(struct msdosfsmount *, uint32_t, uint32_t, struct buf **, struct direntry **);
                    305: void reinsert(struct denode *);
                    306: int removede(struct denode *, struct denode *);
                    307: int uniqdosname(struct denode *, struct componentname *, u_char *);
                    308: int findwin95(struct denode *);
                    309: #endif /* _KERNEL */

CVSweb