Annotation of nono/host/ffs_dir.h, revision 1.1.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.