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