Annotation of nono/host/ffs_dir.h, revision 1.1

1.1     ! root        1: /*     $NetBSD: dir.h,v 1.27 2019/05/05 15:07:12 christos Exp $        */
        !             2: 
        !             3: /*
        !             4:  * Copyright (c) 1982, 1986, 1989, 1993
        !             5:  *     The Regents of the University of California.  All rights reserved.
        !             6:  * (c) UNIX System Laboratories, Inc.
        !             7:  * All or some portions of this file are derived from material licensed
        !             8:  * to the University of California by American Telephone and Telegraph
        !             9:  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
        !            10:  * the permission of UNIX System Laboratories, Inc.
        !            11:  *
        !            12:  * Redistribution and use in source and binary forms, with or without
        !            13:  * modification, are permitted provided that the following conditions
        !            14:  * are met:
        !            15:  * 1. Redistributions of source code must retain the above copyright
        !            16:  *    notice, this list of conditions and the following disclaimer.
        !            17:  * 2. Redistributions in binary form must reproduce the above copyright
        !            18:  *    notice, this list of conditions and the following disclaimer in the
        !            19:  *    documentation and/or other materials provided with the distribution.
        !            20:  * 3. Neither the name of the University nor the names of its contributors
        !            21:  *    may be used to endorse or promote products derived from this software
        !            22:  *    without specific prior written permission.
        !            23:  *
        !            24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            34:  * SUCH DAMAGE.
        !            35:  *
        !            36:  *     @(#)dir.h       8.5 (Berkeley) 4/27/95
        !            37:  */
        !            38: 
        !            39: #ifndef _UFS_UFS_DIR_H_
        !            40: #define        _UFS_UFS_DIR_H_
        !            41: 
        !            42: /*
        !            43:  * Theoretically, directories can be more than 2Gb in length; however, in
        !            44:  * practice this seems unlikely. So, we define the type doff_t as a 32-bit
        !            45:  * quantity to keep down the cost of doing lookup on a 32-bit machine.
        !            46:  */
        !            47: #define        doff_t          int32_t
        !            48: #define        UFS_MAXDIRSIZE  (0x7fffffff)
        !            49: 
        !            50: /*
        !            51:  * A directory consists of some number of blocks of UFS_DIRBLKSIZ
        !            52:  * bytes, where UFS_DIRBLKSIZ is chosen such that it can be transferred
        !            53:  * to disk in a single atomic operation (e.g. 512 bytes on most machines).
        !            54:  *
        !            55:  * Each UFS_DIRBLKSIZ byte block contains some number of directory entry
        !            56:  * structures, which are of variable length.  Each directory entry has
        !            57:  * a struct direct at the front of it, containing its inode number,
        !            58:  * the length of the entry, and the length of the name contained in
        !            59:  * the entry.  These are followed by the name padded to a 4 byte boundary.
        !            60:  * All names are guaranteed null terminated.
        !            61:  * The maximum length of a name in a directory is FFS_MAXNAMLEN.
        !            62:  *
        !            63:  * The macro UFS_DIRSIZ(fmt, dp) gives the amount of space required to represent
        !            64:  * a directory entry.  Free space in a directory is represented by
        !            65:  * entries which have dp->d_reclen > DIRSIZ(fmt, dp).  All UFS_DIRBLKSIZ bytes
        !            66:  * in a directory block are claimed by the directory entries.  This
        !            67:  * usually results in the last entry in a directory having a large
        !            68:  * dp->d_reclen.  When entries are deleted from a directory, the
        !            69:  * space is returned to the previous entry in the same directory
        !            70:  * block by increasing its dp->d_reclen.  If the first entry of
        !            71:  * a directory block is free, then its dp->d_ino is set to 0.
        !            72:  * Entries other than the first in a directory do not normally have
        !            73:  * dp->d_ino set to 0.
        !            74:  */
        !            75: #undef UFS_DIRBLKSIZ
        !            76: #define        UFS_DIRBLKSIZ   DEV_BSIZE
        !            77: #define        FFS_MAXNAMLEN   255
        !            78: #define APPLEUFS_DIRBLKSIZ 1024
        !            79: 
        !            80: #define d_ino d_fileno
        !            81: struct direct {
        !            82:        u_int32_t d_fileno;             /* inode number of entry */
        !            83:        u_int16_t d_reclen;             /* length of this record */
        !            84:        u_int8_t  d_type;               /* file type, see below */
        !            85:        u_int8_t  d_namlen;             /* length of string in d_name */
        !            86:        char      d_name[FFS_MAXNAMLEN + 1];/* name with length <= FFS_MAXNAMLEN */
        !            87: };
        !            88: 
        !            89: /*
        !            90:  * File types
        !            91:  */
        !            92: #define        DT_UNKNOWN       0
        !            93: #define        DT_FIFO          1
        !            94: #define        DT_CHR           2
        !            95: #define        DT_DIR           4
        !            96: #define        DT_BLK           6
        !            97: #define        DT_REG           8
        !            98: #define        DT_LNK          10
        !            99: #define        DT_SOCK         12
        !           100: #define        DT_WHT          14
        !           101: 
        !           102: /*
        !           103:  * Convert between stat structure types and directory types.
        !           104:  */
        !           105: #define        IFTODT(mode)    (((mode) & 0170000) >> 12)
        !           106: #define        DTTOIF(dirtype) ((dirtype) << 12)
        !           107: 
        !           108: /*
        !           109:  * The UFS_DIRSIZ macro gives the minimum record length which will hold
        !           110:  * the directory entry.  This requires the amount of space in struct direct
        !           111:  * without the d_name field, plus enough space for the name with a terminating
        !           112:  * NUL byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
        !           113:  * The UFS_NAMEPAD macro gives the number bytes of padding needed including
        !           114:  * the NUL terminating byte.
        !           115:  */
        !           116: #define DIR_ROUNDUP    4
        !           117: #define UFS_NAMEROUNDUP(namlen)        (((namlen) + DIR_ROUNDUP) & ~(DIR_ROUNDUP - 1))
        !           118: #define UFS_NAMEPAD(namlen)    (DIR_ROUNDUP - ((namlen) & (DIR_ROUNDUP - 1)))
        !           119: #define        UFS_DIRECTSIZ(namlen) \
        !           120:        ((sizeof(struct direct) - (FFS_MAXNAMLEN+1)) + UFS_NAMEROUNDUP(namlen))
        !           121: 
        !           122: #if (BYTE_ORDER == LITTLE_ENDIAN)
        !           123: #define UFS_DIRSIZ(oldfmt, dp, needswap)       \
        !           124:     (((oldfmt) && !(needswap)) ?               \
        !           125:     UFS_DIRECTSIZ((dp)->d_type) : UFS_DIRECTSIZ((dp)->d_namlen))
        !           126: #else
        !           127: #define UFS_DIRSIZ(oldfmt, dp, needswap)       \
        !           128:     (((oldfmt) && (needswap)) ?                        \
        !           129:     UFS_DIRECTSIZ((dp)->d_type) : UFS_DIRECTSIZ((dp)->d_namlen))
        !           130: #endif
        !           131: 
        !           132: /*
        !           133:  * UFS_OLDDIRFMT and UFS_NEWDIRFMT are code numbers for a directory
        !           134:  * format change that happened in ffs a long time ago. (Back in the
        !           135:  * 80s, if I'm not mistaken.)
        !           136:  *
        !           137:  * These code numbers do not appear on disk. They're generated from
        !           138:  * runtime logic that is cued by other things, which is why
        !           139:  * UFS_OLDDIRFMT is confusingly 1 and UFS_NEWDIRFMT is confusingly 0.
        !           140:  *
        !           141:  * Relatedly, the FFS_EI byte swapping logic for directories is a
        !           142:  * horrible mess. For example, to access the namlen field, one
        !           143:  * currently does the following:
        !           144:  *
        !           145:  * #if (BYTE_ORDER == LITTLE_ENDIAN)
        !           146:  *         swap = (UFS_IPNEEDSWAP(VTOI(vp)) == 0);
        !           147:  * #else
        !           148:  *         swap = (UFS_IPNEEDSWAP(VTOI(vp)) != 0);
        !           149:  * #endif
        !           150:  *         return ((FSFMT(vp) && swap) ? dp->d_type : dp->d_namlen);
        !           151:  *
        !           152:  * UFS_IPNEEDSWAP() returns true if the volume is opposite-endian. This
        !           153:  * horrible "swap" logic is cutpasted all over everywhere but amounts
        !           154:  * to the following:
        !           155:  *
        !           156:  *    running code      volume          lfs_dobyteswap  "swap"
        !           157:  *    ----------------------------------------------------------
        !           158:  *    LITTLE_ENDIAN     LITTLE_ENDIAN   false           true
        !           159:  *    LITTLE_ENDIAN     BIG_ENDIAN      true            false
        !           160:  *    BIG_ENDIAN        LITTLE_ENDIAN   true            true
        !           161:  *    BIG_ENDIAN        BIG_ENDIAN      false           false
        !           162:  *
        !           163:  * which you'll note boils down to "volume is little-endian".
        !           164:  *
        !           165:  * Meanwhile, FSFMT(vp) yields UFS_OLDDIRFMT or UFS_NEWDIRFMT via
        !           166:  * perverted logic of its own. Since UFS_OLDDIRFMT is 1 (contrary to
        !           167:  * what one might expect approaching this cold) what this mess means
        !           168:  * is: on OLDDIRFMT volumes that are little-endian, we read the
        !           169:  * namlen value out of the type field. This is because on OLDDIRFMT
        !           170:  * volumes there is no d_type field, just a 16-bit d_namlen; so if
        !           171:  * the 16-bit d_namlen is little-endian, the useful part of it is
        !           172:  * in the first byte, which in the NEWDIRFMT structure is the d_type
        !           173:  * field.
        !           174:  */
        !           175: 
        !           176: #define UFS_OLDDIRFMT  1
        !           177: #define UFS_NEWDIRFMT  0
        !           178: 
        !           179: /*
        !           180:  * Template for manipulating directories.  Should use struct direct's,
        !           181:  * but the name field is FFS_MAXNAMLEN - 1, and this just won't do.
        !           182:  */
        !           183: struct dirtemplate {
        !           184:        u_int32_t       dot_ino;
        !           185:        int16_t         dot_reclen;
        !           186:        u_int8_t        dot_type;
        !           187:        u_int8_t        dot_namlen;
        !           188:        char            dot_name[4];    /* must be multiple of 4 */
        !           189:        u_int32_t       dotdot_ino;
        !           190:        int16_t         dotdot_reclen;
        !           191:        u_int8_t        dotdot_type;
        !           192:        u_int8_t        dotdot_namlen;
        !           193:        char            dotdot_name[4]; /* ditto */
        !           194: };
        !           195: 
        !           196: /*
        !           197:  * This is the old format of directories, sans type element.
        !           198:  */
        !           199: struct odirtemplate {
        !           200:        u_int32_t       dot_ino;
        !           201:        int16_t         dot_reclen;
        !           202:        u_int16_t       dot_namlen;
        !           203:        char            dot_name[4];    /* must be multiple of 4 */
        !           204:        u_int32_t       dotdot_ino;
        !           205:        int16_t         dotdot_reclen;
        !           206:        u_int16_t       dotdot_namlen;
        !           207:        char            dotdot_name[4]; /* ditto */
        !           208: };
        !           209: #endif /* !_UFS_UFS_DIR_H_ */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.