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