Home | History | Annotate | Line # | Download | only in efs
      1  1.2  rumble /*	$NetBSD: efs.h,v 1.2 2007/06/30 15:56:16 rumble Exp $	*/
      2  1.1  rumble 
      3  1.1  rumble /*
      4  1.1  rumble  * Copyright (c) 2006 Stephen M. Rumble <rumble (at) ephemeral.org>
      5  1.1  rumble  *
      6  1.1  rumble  * Permission to use, copy, modify, and distribute this software for any
      7  1.1  rumble  * purpose with or without fee is hereby granted, provided that the above
      8  1.1  rumble  * copyright notice and this permission notice appear in all copies.
      9  1.1  rumble  *
     10  1.1  rumble  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     11  1.1  rumble  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     12  1.1  rumble  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     13  1.1  rumble  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     14  1.1  rumble  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     15  1.1  rumble  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     16  1.1  rumble  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     17  1.1  rumble  */
     18  1.1  rumble 
     19  1.1  rumble /*
     20  1.1  rumble  * See IRIX efs(4)
     21  1.1  rumble  */
     22  1.1  rumble 
     23  1.1  rumble #ifndef _FS_EFS_EFS_H_
     24  1.1  rumble #define _FS_EFS_EFS_H_
     25  1.1  rumble 
     26  1.1  rumble #define EFS_DEBUG
     27  1.1  rumble 
     28  1.1  rumble /*
     29  1.1  rumble  * SGI EFS - Extent File System
     30  1.1  rumble  *
     31  1.1  rumble  * The EFS filesystem is comprised of 512-byte sectors, or "basic blocks" (bb).
     32  1.1  rumble  * These blocks are divided into cylinder groups (cg), from which extents are
     33  1.1  rumble  * allocated. An extent is a contiguous region of blocks with minimal length
     34  1.1  rumble  * of 1 and maximal length of 248.
     35  1.1  rumble  *
     36  1.1  rumble  * The filesystem is limited to 8GB by struct efs_extent's ex_bn field, which
     37  1.1  rumble  * specifies an extent's offset in terms of basic blocks. Unfortunately, it was
     38  1.1  rumble  * squished into a bitfield and given only 24bits so we are left with
     39  1.1  rumble  * 2**24 * 512 bytes. Individual files are maximally 2GB, but not due to any
     40  1.1  rumble  * limitation of on-disk structures. All sizes and offsets are stored as block,
     41  1.1  rumble  * not byte values, with the exception of sb.sb_bmsize and efs_dinode.di_size.
     42  1.1  rumble  *
     43  1.1  rumble  * An EFS filesystem begins with the superblock (struct efs_sb) at bb offset 1
     44  1.1  rumble  * (offset 0 is reserved for bootblocks and other forms of contraband). The
     45  1.1  rumble  * superblock contains various parameters including magic, checksum, filesystem
     46  1.1  rumble  * size, number of cylinder groups, size of cylinder groups, and location of the
     47  1.1  rumble  * first cylinder group. A bitmap may begin at offset bb 2. This is true of
     48  1.1  rumble  * filesystems whose magic flag is EFS_MAGIC. However, the ability to grow an
     49  1.1  rumble  * efs filesystem was added in IRIX 3.3 and a grown efs's bitmap is located
     50  1.1  rumble  * toward the end of the disk, pointed to by sb.sb_bmblock. A grown filesystem
     51  1.1  rumble  * is detected with the EFS_NEWMAGIC flag. See below for more details and
     52  1.1  rumble  * differences.
     53  1.1  rumble  *
     54  1.1  rumble  * In order to promote inode and data locality, the disk is separated into
     55  1.1  rumble  * sb.sb_ncg cylinder groups, which consist of sb.sb_cgfsize blocks each.
     56  1.1  rumble  * The cylinder groups are laid out consecutively beginning from block offset
     57  1.1  rumble  * sb.sb_firstcg. The beginning of each cylinder group is comprised of
     58  1.1  rumble  * sb.sb_cgisize inodes (struct efs_dinode). The remaining space contains
     59  1.1  rumble  * file extents, which are preferentially allocated to files whose inodes are
     60  1.1  rumble  * within the same cylinder group.
     61  1.1  rumble  *
     62  1.1  rumble  * EFS increases I/O performance by storing files in contiguous chunks called
     63  1.1  rumble  * 'extents' (struct efs_extent). Extents are variably sized from 1 to 248
     64  1.1  rumble  * blocks, but please don't ask me why 256 isn't the limit.
     65  1.1  rumble  *
     66  1.1  rumble  * Each inode (struct efs_dinode) contains space for twelve extent descriptors,
     67  1.1  rumble  * allowing for up to 1,523,712 byte files (12 * 248 * 512) to be described
     68  1.1  rumble  * without indirection. When indirection is employed, each of the twelve
     69  1.1  rumble  * descriptors may reference extents that contain up to 248 more direct
     70  1.2  rumble  * descriptors. Since each descriptor is 8 bytes we could theoretically have
     71  1.2  rumble  * in total 15,872 * 12 direct descriptors, allowing for 15,872 * 12 * 248 *
     72  1.2  rumble  * 512 = ~22GB files. However, since ei_numextents is a signed 16-bit quantity,
     73  1.2  rumble  * we're limited to only 32767 indirect extents, which leaves us with a ~3.87GB
     74  1.2  rumble  * maximum file size. (Of course, with a maximum filesystem size of 8GB, such a
     75  1.2  rumble  * restriction isn't so bad.) Note that a single full indirect extent could
     76  1.2  rumble  * reference approximately 1.877GB of data, but SGI strikes again! Earlier
     77  1.2  rumble  * versions of IRIX (4.0.5H certainly, and perhaps prior) limit indirect
     78  1.2  rumble  * extents to 32 basic blocks worth. This caps the number of extents at 12 *
     79  1.2  rumble  * 32 * 64, permitting ~2.91GB files. SGI later raised this limit to 64 blocks
     80  1.2  rumble  * worth, which exceeds the range of ei_numextents and gives a maximum
     81  1.2  rumble  * theoretical file size of ~3.87GB. However, EFS purportedly only permits
     82  1.2  rumble  * files up to 2GB in length.
     83  1.1  rumble  *
     84  1.1  rumble  * The bitmap referred to by sb_bmsize and (optionally) sb_bmblock contains
     85  1.1  rumble  * data block allocation information. I haven't looked at this at all, nor
     86  1.1  rumble  * am I aware of how inode allocation is performed.
     87  1.1  rumble  *
     88  1.1  rumble  * An EFS disk layout looks like the following:
     89  1.1  rumble  *     ____________________________________________________________________
     90  1.1  rumble  *    | unused | superblock | bitmap | pad | cyl grp | ..cyl grps... | pad |
     91  1.1  rumble  *     --------------------------------------------------------------------
     92  1.1  rumble  * bb:     0          1         2          ^-sb.sb_firstcg      sb.sb_size-^
     93  1.1  rumble  *
     94  1.1  rumble  * A cylinder group looks like the following:
     95  1.1  rumble  *     ____________________________________________________________________
     96  1.1  rumble  *    |    inodes    |           ... extents and free space ...            |
     97  1.1  rumble  *     --------------------------------------------------------------------
     98  1.1  rumble  *           0       ^-(sb.sb_cgisize *                      sb.sb_cgfsize-^
     99  1.1  rumble  *                      sizeof(struct efs_dinode))
    100  1.1  rumble  *
    101  1.1  rumble  * So far as I am aware, EFS file systems have always been big endian, existing
    102  1.1  rumble  * on mips (and perhaps earlier on m68k) machines only. While mips chips are
    103  1.1  rumble  * bi-endian, I am unaware of any sgimips machine that was used in mipsel mode.
    104  1.1  rumble  *
    105  1.1  rumble  * See efs_sb.h, efs_dir.h, and efs_dinode.h for more information regarding
    106  1.1  rumble  * directory layout and on-disk inodes, and the superblock accordingly.
    107  1.1  rumble  */
    108  1.1  rumble 
    109  1.1  rumble /*
    110  1.1  rumble  * Basic blocks are always 512 bytes.
    111  1.1  rumble  */
    112  1.1  rumble #define EFS_BB_SHFT	9
    113  1.1  rumble #define EFS_BB_SIZE	(1 << EFS_BB_SHFT)
    114  1.1  rumble 
    115  1.1  rumble /*
    116  1.1  rumble  * EFS basic block layout:
    117  1.1  rumble  */
    118  1.1  rumble #define EFS_BB_UNUSED	0	/* bb 0 is unused */
    119  1.1  rumble #define EFS_BB_SB	1	/* bb 1 is superblock */
    120  1.1  rumble #define EFS_BB_BITMAP	2	/* bb 2 is bitmap (unless moved by growfs) */
    121  1.1  rumble /* bitmap continues, then padding up to first aligned cylinder group */
    122  1.1  rumble 
    123  1.1  rumble /*
    124  1.1  rumble  * basic block <-> byte conversions
    125  1.1  rumble  */
    126  1.1  rumble #define EFS_BB2BY(_x)		((_x) << EFS_BB_SHFT)
    127  1.1  rumble #define EFS_BY2BB(_x)		(((_x) + EFS_BB_SIZE - 1) >> EFS_BB_SHFT)
    128  1.1  rumble 
    129  1.1  rumble /*
    130  1.1  rumble  * Struct efs_extent limits us to 24 bit offsets, therefore the maximum
    131  1.1  rumble  * efs.sb_size is 2**24 blocks (8GB).
    132  1.1  rumble  *
    133  1.1  rumble  * Trivia: IRIX's mkfs_efs(1M) has claimed the maximum to be 0xfffffe for years.
    134  1.1  rumble  */
    135  1.1  rumble #define EFS_SIZE_MAX		0x01000000
    136  1.1  rumble 
    137  1.1  rumble #ifdef _KERNEL
    138  1.1  rumble 
    139  1.1  rumble #define	VFSTOEFS(mp)    ((struct efs_mount *)(mp)->mnt_data)
    140  1.1  rumble 
    141  1.1  rumble /* debug goo */
    142  1.1  rumble #ifdef DEBUG
    143  1.1  rumble #define EFS_DEBUG
    144  1.1  rumble #endif
    145  1.1  rumble #ifdef EFS_DEBUG
    146  1.1  rumble #define EFS_DPRINTF(_x)	printf _x
    147  1.1  rumble #else
    148  1.1  rumble #define EFS_DPRINTF(_x)
    149  1.1  rumble #endif
    150  1.1  rumble 
    151  1.1  rumble #endif
    152  1.1  rumble 
    153  1.1  rumble #endif /* !_FS_EFS_EFS_H_ */
    154