[BACK]Return to efs.h CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / fs / efs

File: [cvs.NetBSD.org] / src / sys / fs / efs / efs.h (download)

Revision 1.2, Sat Jun 30 15:56:16 2007 UTC (11 years, 3 months ago) by rumble
Branch: MAIN
CVS Tags: yamt-x86pmap-base4, yamt-x86pmap-base3, yamt-x86pmap-base2, yamt-x86pmap-base, yamt-x86pmap, yamt-pf42-baseX, yamt-pf42-base4, yamt-pf42-base3, yamt-pf42-base2, yamt-pf42-base, yamt-pf42, yamt-pagecache-tag8, yamt-pagecache-base9, yamt-pagecache-base8, yamt-pagecache-base7, yamt-pagecache-base6, yamt-pagecache-base5, yamt-pagecache-base4, yamt-pagecache-base3, yamt-pagecache-base2, yamt-pagecache-base, yamt-pagecache, yamt-nfs-mp-base9, yamt-nfs-mp-base8, yamt-nfs-mp-base7, yamt-nfs-mp-base6, yamt-nfs-mp-base5, yamt-nfs-mp-base4, yamt-nfs-mp-base3, yamt-nfs-mp-base2, yamt-nfs-mp-base11, yamt-nfs-mp-base10, yamt-nfs-mp-base, yamt-nfs-mp, yamt-lazymbuf-base15, yamt-lazymbuf-base14, yamt-kmem-base3, yamt-kmem-base2, yamt-kmem-base, yamt-kmem, wrstuden-revivesa-base-4, wrstuden-revivesa-base-3, wrstuden-revivesa-base-2, wrstuden-revivesa-base-1, wrstuden-revivesa-base, wrstuden-revivesa, vmlocking2-base3, vmlocking2-base2, vmlocking2-base1, vmlocking2, vmlocking-nbase, vmlocking-base, uebayasi-xip-base4, uebayasi-xip-base3, uebayasi-xip-base2, uebayasi-xip-base1, uebayasi-xip-base, uebayasi-xip, tls-maxphys-base-20171202, tls-maxphys-base, tls-maxphys, tls-earlyentropy-base, tls-earlyentropy, simonb-wapbl-nbase, simonb-wapbl-base, simonb-wapbl, rmind-uvmplock-nbase, rmind-uvmplock-base, rmind-uvmplock, rmind-smpnet-nbase, rmind-smpnet-base, rmind-smpnet, riastradh-xf86-video-intel-2-7-1-pre-2-21-15, riastradh-drm2-base3, riastradh-drm2-base2, riastradh-drm2-base1, riastradh-drm2-base, riastradh-drm2, reinoud-bufcleanup-nbase, reinoud-bufcleanup-base, prg-localcount2-base3, prg-localcount2-base2, prg-localcount2-base1, prg-localcount2-base, prg-localcount2, phil-wifi-base, phil-wifi, pgoyette-localcount-base, pgoyette-localcount-20170426, pgoyette-localcount-20170320, pgoyette-localcount-20170107, pgoyette-localcount-20161104, pgoyette-localcount-20160806, pgoyette-localcount-20160726, pgoyette-localcount, pgoyette-compat-base, pgoyette-compat-0930, pgoyette-compat-0906, pgoyette-compat-0728, pgoyette-compat-0625, pgoyette-compat-0521, pgoyette-compat-0502, pgoyette-compat-0422, pgoyette-compat-0415, pgoyette-compat-0407, pgoyette-compat-0330, pgoyette-compat-0322, pgoyette-compat-0315, pgoyette-compat, perseant-stdc-iso10646-base, perseant-stdc-iso10646, nick-nhusb-base-20170825, nick-nhusb-base-20170204, nick-nhusb-base-20161204, nick-nhusb-base-20161004, nick-nhusb-base-20160907, nick-nhusb-base-20160529, nick-nhusb-base-20160422, nick-nhusb-base-20160319, nick-nhusb-base-20151226, nick-nhusb-base-20150921, nick-nhusb-base-20150606, nick-nhusb-base-20150406, nick-nhusb-base, nick-nhusb, nick-net80211-sync-base, nick-net80211-sync, nick-hppapmap-base4, nick-hppapmap-base3, nick-hppapmap-base2, nick-hppapmap-base, nick-hppapmap, nick-csl-alignment-base5, nick-csl-alignment-base, nick-csl-alignment, netbsd-8-base, netbsd-8-0-RELEASE, netbsd-8-0-RC2, netbsd-8-0-RC1, netbsd-8, netbsd-7-nhusb-base-20170116, netbsd-7-nhusb-base, netbsd-7-nhusb, netbsd-7-base, netbsd-7-2-RELEASE, netbsd-7-1-RELEASE, netbsd-7-1-RC2, netbsd-7-1-RC1, netbsd-7-1-2-RELEASE, netbsd-7-1-1-RELEASE, netbsd-7-1, netbsd-7-0-RELEASE, netbsd-7-0-RC3, netbsd-7-0-RC2, netbsd-7-0-RC1, netbsd-7-0-2-RELEASE, netbsd-7-0-1-RELEASE, netbsd-7-0, netbsd-7, netbsd-6-base, netbsd-6-1-RELEASE, netbsd-6-1-RC4, netbsd-6-1-RC3, netbsd-6-1-RC2, netbsd-6-1-RC1, netbsd-6-1-5-RELEASE, netbsd-6-1-4-RELEASE, netbsd-6-1-3-RELEASE, netbsd-6-1-2-RELEASE, netbsd-6-1-1-RELEASE, netbsd-6-1, netbsd-6-0-RELEASE, netbsd-6-0-RC2, netbsd-6-0-RC1, netbsd-6-0-6-RELEASE, netbsd-6-0-5-RELEASE, netbsd-6-0-4-RELEASE, netbsd-6-0-3-RELEASE, netbsd-6-0-2-RELEASE, netbsd-6-0-1-RELEASE, netbsd-6-0, netbsd-6, netbsd-5-base, netbsd-5-2-RELEASE, netbsd-5-2-RC1, netbsd-5-2-3-RELEASE, netbsd-5-2-2-RELEASE, netbsd-5-2-1-RELEASE, netbsd-5-2, netbsd-5-1-RELEASE, netbsd-5-1-RC4, netbsd-5-1-RC3, netbsd-5-1-RC2, netbsd-5-1-RC1, netbsd-5-1-5-RELEASE, netbsd-5-1-4-RELEASE, netbsd-5-1-3-RELEASE, netbsd-5-1-2-RELEASE, netbsd-5-1-1-RELEASE, netbsd-5-1, netbsd-5-0-RELEASE, netbsd-5-0-RC4, netbsd-5-0-RC3, netbsd-5-0-RC2, netbsd-5-0-RC1, netbsd-5-0-2-RELEASE, netbsd-5-0-1-RELEASE, netbsd-5-0, netbsd-5, mjf-ufs-trans-base, mjf-devfs2-base, mjf-devfs2, mjf-devfs-base, mjf-devfs, matt-premerge-20091211, matt-nb8-mediatek-base, matt-nb8-mediatek, matt-nb6-plus-nbase, matt-nb6-plus-base, matt-nb6-plus, matt-nb5-pq3-base, matt-nb5-pq3, matt-nb5-mips64-u2-k2-k4-k7-k8-k9, matt-nb5-mips64-u1-k1-k5, matt-nb5-mips64-premerge-20101231, matt-nb5-mips64-premerge-20091211, matt-nb5-mips64-k15, matt-nb5-mips64, matt-nb4-mips64-k7-u2a-k9b, matt-mips64-premerge-20101231, matt-mips64-base2, matt-mips64-base, matt-mips64, matt-armv6-prevmlocking, matt-armv6-nbase, matt-armv6-base, matt-armv6, localcount-20160914, khorben-n900, keiichi-mipv6-nbase, keiichi-mipv6-base, keiichi-mipv6, jymxensuspend-base, jym-xensuspend-nbase, jym-xensuspend-base, jym-xensuspend, jruoho-x86intr-base, jruoho-x86intr, jmcneill-usbmp-pre-base2, jmcneill-usbmp-base9, jmcneill-usbmp-base8, jmcneill-usbmp-base7, jmcneill-usbmp-base6, jmcneill-usbmp-base5, jmcneill-usbmp-base4, jmcneill-usbmp-base3, jmcneill-usbmp-base2, jmcneill-usbmp-base10, jmcneill-usbmp-base, jmcneill-usbmp, jmcneill-pm-base, jmcneill-pm, jmcneill-base, jmcneill-audiomp3-base, jmcneill-audiomp3, jdolecek-ncq-base, jdolecek-ncq, hpcarm-cleanup-nbase, hpcarm-cleanup-base, hpcarm-cleanup, haad-nbase2, haad-dm-base2, haad-dm-base1, haad-dm-base, haad-dm, cube-autoconf-base, cube-autoconf, cherry-xenmp-base, cherry-xenmp, bouyer-xeni386-nbase, bouyer-xeni386-merge1, bouyer-xeni386-base, bouyer-xeni386, bouyer-xenamd64-base2, bouyer-xenamd64-base, bouyer-xenamd64, bouyer-socketcan-base1, bouyer-socketcan-base, bouyer-socketcan, bouyer-quota2-nbase, bouyer-quota2-base, bouyer-quota2, agc-symver-base, agc-symver, ad-socklock-base1, ad-audiomp2-base, ad-audiomp2, HEAD
Branch point for: yamt-lazymbuf, vmlocking
Changes since 1.1: +14 -4 lines

Additional documentation on extents and some artificial limitations SGI
has introduced (and changed in backwards-incompatible ways) over the years.

/*	$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_ */