Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 69176 Details for
Bug 107103
Add support for XFS to aboot
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch against sys-boot/aboot-1.0_pre20040408
aboot-xfs.diff (text/plain), 49.59 KB, created by
Mike Hlavac
on 2005-09-24 12:18:58 UTC
(
hide
)
Description:
Patch against sys-boot/aboot-1.0_pre20040408
Filename:
MIME Type:
Creator:
Mike Hlavac
Created:
2005-09-24 12:18:58 UTC
Size:
49.59 KB
patch
obsolete
>Files aboot-1.0_pre20040408/.Makefile.swp and aboot-1.0_pre20040408-xfs/.Makefile.swp differ >diff -ruN aboot-1.0_pre20040408/Makefile aboot-1.0_pre20040408-xfs/Makefile >--- aboot-1.0_pre20040408/Makefile 2004-04-08 08:19:01 -0700 >+++ aboot-1.0_pre20040408-xfs/Makefile 2005-09-24 12:10:36 -0700 >@@ -17,7 +17,7 @@ > #TESTING = yes > > # for boot testing >-#CFGDEFS = -DDEBUG_ISO -DDEBUG_ROCK -DDEBUG_EXT2 -DDEBUG >+#CFGDEFS = -DDEBUG_ISO -DDEBUG_ROCK -DDEBUG_EXT2 -DDEBUG_XFS -DDEBUG > > # root, aka prefix > root = >@@ -58,7 +58,7 @@ > $(CC) $(ASFLAGS) -D__ASSEMBLY__ -traditional -c -o $*.o $< > > NET_OBJS = net.o >-DISK_OBJS = disk.o fs/ext2.o fs/ufs.o fs/dummy.o fs/iso.o >+DISK_OBJS = disk.o fs/ext2.o fs/ufs.o fs/dummy.o fs/iso.o fs/xfs.o > ifeq ($(TESTING),) > ABOOT_OBJS = \ > head.o aboot.o cons.o utils.o \ >diff -ruN aboot-1.0_pre20040408/disk.c aboot-1.0_pre20040408-xfs/disk.c >--- aboot-1.0_pre20040408/disk.c 2004-04-08 11:14:06 -0700 >+++ aboot-1.0_pre20040408-xfs/disk.c 2005-09-24 09:36:39 -0700 >@@ -42,6 +42,7 @@ > extern struct bootfs iso; > extern struct bootfs ufs; > extern struct bootfs dummyfs; >+extern struct bootfs xfsfs; > > struct disklabel * label; > int boot_part = -1; >@@ -49,7 +50,8 @@ > static struct bootfs *bootfs[] = { > &ext2fs, > &iso, >- &ufs >+ &ufs, >+ &xfsfs > }; > > /* >@@ -329,23 +331,18 @@ > return 0; > } > part = &label->d_partitions[partition - 1]; >- for (i = 0; bootfs[i]->fs_type != part->p_fstype; ++i) { >- if (i + 1 >- >= (int) (sizeof(bootfs)/sizeof(bootfs[0]))) >- { >- printf("aboot: don't know how to mount " >- "partition %d (filesystem type %d)\n", >- partition, part->p_fstype); >- return 0; >+ for (i = 0; i < (int)(sizeof(bootfs)/sizeof(bootfs[0])); i++) { >+ if (bootfs[i]->fs_type == part->p_fstype) { >+ fs = bootfs[i]; >+ if (!((*fs->mount)(dev, (long)(part->p_offset) * (long)(label->d_secsize), 1) >+ < 0)) >+ return fs; > } > } >- fs = bootfs[i]; >- if ((*fs->mount)(dev, (long)(part->p_offset) * (long)(label->d_secsize), 0) >- < 0) { >- printf("aboot: mount of partition %d failed\n", >- partition); >- return 0; >- } >+ printf("aboot: don't know how to mount " >+ "partition %d (filesystem type %d)\n", >+ partition, part->p_fstype); >+ return 0; > } > return fs; > } >diff -ruN aboot-1.0_pre20040408/fs/xfs.c aboot-1.0_pre20040408-xfs/fs/xfs.c >--- aboot-1.0_pre20040408/fs/xfs.c 1969-12-31 16:00:00 -0800 >+++ aboot-1.0_pre20040408-xfs/fs/xfs.c 2005-09-24 10:43:12 -0700 >@@ -0,0 +1,816 @@ >+/* >+ * xfs.c - an implementation of the SGI XFS file system for aboot >+ * Jan-Jaap van der Heijden <J.J.vanderHeijden@home.nl> >+ * >+ * Based on fsys_xfs.c from GRUB -- GRand Unified Bootloader >+ * Copyright (C) 2001,2002,2004 Free Software Foundation, Inc. >+ */ >+/* >+ * This program is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 2 of the License, or >+ * (at your option) any later version. >+ * >+ * This program is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program; if not, write to the Free Software >+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. >+ */ >+ >+#include <asm/system.h> >+#include "config.h" >+#include "aboot.h" >+#include "bootfs.h" >+#include "cons.h" >+#include "disklabel.h" >+#include "utils.h" >+#include "xfs.h" >+ >+static int xfs_mount(long cons_dev, long p_offset, long quiet); >+static int xfs_bread(int fd, long blkno, long nblks, char *buffer); >+static int xfs_open(const char *dirname); >+static void xfs_close(int fd); >+static const char *xfs_readdir(int fd, int rewind); >+static int xfs_fstat(int fd, struct stat* buf); >+ >+struct bootfs xfsfs = { >+ FS_EXT2, >+ 0, >+ xfs_mount, >+ xfs_open, >+ xfs_bread, >+ xfs_close, >+ xfs_readdir, >+ xfs_fstat >+}; >+ >+static long dev = -1; >+static long partition_offset; >+static long filepos; >+static long filemax; /* filelen */ >+ >+static long xfs_read (void *buf, long len); >+ >+#define isspace(c) ((c) == 0x10) >+ >+static int >+devread(long sector, long start, long length, void *buf) >+{ >+ long pos = sector * SECT_SIZE; >+ pos += partition_offset + start; >+#ifdef DEBUG_XFS >+ printf("Reading %ld bytes, starting at sector %ld, disk offset %ld\n", >+ length, sector, pos); >+#endif >+ return cons_read(dev, buf, length, pos); >+} >+ >+#define MAXNAMELEN 256 >+#define SECTOR_BITS 9 >+#define MAX_LINK_COUNT 8 >+ >+typedef struct xad { >+ xfs_fileoff_t offset; >+ xfs_fsblock_t start; >+ xfs_filblks_t len; >+} xad_t; >+ >+struct xfs_info { >+ int bsize; >+ int dirbsize; >+ int isize; >+ unsigned int agblocks; >+ int bdlog; >+ int blklog; >+ int inopblog; >+ int agblklog; >+ int agnolog; >+ unsigned int nextents; >+ xfs_daddr_t next; >+ xfs_daddr_t daddr; >+ xfs_dablk_t forw; >+ xfs_dablk_t dablk; >+ xfs_bmbt_rec_32_t *xt; >+ xfs_bmbt_ptr_t ptr0; >+ int btnode_ptr0_off; >+ int i8param; >+ int dirpos; >+ int dirmax; >+ int blkoff; >+ int fpos; >+ xfs_ino_t rootino; >+ xfs_ino_t new_ino; >+}; >+ >+static struct xfs_info xfs; >+ >+#ifdef __alpha__ /* take care of alignment*/ >+ static long FSYS_BUF[32768/sizeof(long)]; >+ #define dirbuf ((long *)FSYS_BUF) >+ #define filebuf ((long *)FSYS_BUF + 4096/sizeof(long)) >+ #define inode ((xfs_dinode_t *)((long *)FSYS_BUF + 8192/sizeof(long))) >+#else >+ static char FSYS_BUF[32768]; >+ #define dirbuf ((char *)FSYS_BUF) >+ #define filebuf ((char *)FSYS_BUF + 4096) >+ #define inode ((xfs_dinode_t *)((char *)FSYS_BUF + 8192)) >+#endif >+ >+#define icore (inode->di_core) >+#define mask32lo(n) (((uint32_t)1 << (n)) - 1) >+ >+#define XFS_INO_MASK(k) ((uint32_t)((1ULL << (k)) - 1)) >+#define XFS_INO_OFFSET_BITS xfs.inopblog >+#define XFS_INO_AGBNO_BITS xfs.agblklog >+#define XFS_INO_AGINO_BITS (xfs.agblklog + xfs.inopblog) >+#define XFS_INO_AGNO_BITS xfs.agnolog >+ >+static inline xfs_agblock_t >+agino2agbno (xfs_agino_t agino) >+{ >+ return agino >> XFS_INO_OFFSET_BITS; >+} >+ >+static inline xfs_agnumber_t >+ino2agno (xfs_ino_t ino) >+{ >+ return ino >> XFS_INO_AGINO_BITS; >+} >+ >+static inline xfs_agino_t >+ino2agino (xfs_ino_t ino) >+{ >+ return ino & XFS_INO_MASK(XFS_INO_AGINO_BITS); >+} >+ >+static inline int >+ino2offset (xfs_ino_t ino) >+{ >+ return ino & XFS_INO_MASK(XFS_INO_OFFSET_BITS); >+} >+ >+/* XFS is big endian, alpha is little endian */ >+#define le16(x) __swab16(x) >+#define le32(x) __swab32(x) >+#define le64(x) __swab64(x) >+ >+static xfs_fsblock_t >+xt_start (xfs_bmbt_rec_32_t *r) >+{ >+ return (((xfs_fsblock_t)(le32 (r->l1) & mask32lo(9))) << 43) | >+ (((xfs_fsblock_t)le32 (r->l2)) << 11) | >+ (((xfs_fsblock_t)le32 (r->l3)) >> 21); >+} >+ >+static xfs_fileoff_t >+xt_offset (xfs_bmbt_rec_32_t *r) >+{ >+ return (((xfs_fileoff_t)le32 (r->l0) & >+ mask32lo(31)) << 23) | >+ (((xfs_fileoff_t)le32 (r->l1)) >> 9); >+} >+ >+static xfs_filblks_t >+xt_len (xfs_bmbt_rec_32_t *r) >+{ >+ return le32(r->l3) & mask32lo(21); >+} >+ >+static const char xfs_highbit[256] = { >+ -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */ >+ 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */ >+ 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */ >+ 4, 4, 4, 4, 4, 4, 4, 4, /* 18 .. 1f */ >+ 5, 5, 5, 5, 5, 5, 5, 5, /* 20 .. 27 */ >+ 5, 5, 5, 5, 5, 5, 5, 5, /* 28 .. 2f */ >+ 5, 5, 5, 5, 5, 5, 5, 5, /* 30 .. 37 */ >+ 5, 5, 5, 5, 5, 5, 5, 5, /* 38 .. 3f */ >+ 6, 6, 6, 6, 6, 6, 6, 6, /* 40 .. 47 */ >+ 6, 6, 6, 6, 6, 6, 6, 6, /* 48 .. 4f */ >+ 6, 6, 6, 6, 6, 6, 6, 6, /* 50 .. 57 */ >+ 6, 6, 6, 6, 6, 6, 6, 6, /* 58 .. 5f */ >+ 6, 6, 6, 6, 6, 6, 6, 6, /* 60 .. 67 */ >+ 6, 6, 6, 6, 6, 6, 6, 6, /* 68 .. 6f */ >+ 6, 6, 6, 6, 6, 6, 6, 6, /* 70 .. 77 */ >+ 6, 6, 6, 6, 6, 6, 6, 6, /* 78 .. 7f */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* 80 .. 87 */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* 88 .. 8f */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* 90 .. 97 */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* 98 .. 9f */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* a0 .. a7 */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* a8 .. af */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* b0 .. b7 */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* b8 .. bf */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* c0 .. c7 */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* c8 .. cf */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* d0 .. d7 */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* d8 .. df */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* e0 .. e7 */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* e8 .. ef */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* f0 .. f7 */ >+ 7, 7, 7, 7, 7, 7, 7, 7, /* f8 .. ff */ >+}; >+ >+static int >+xfs_highbit32(uint32_t v) >+{ >+ int i; >+ >+ if (v & 0xffff0000) >+ if (v & 0xff000000) >+ i = 24; >+ else >+ i = 16; >+ else if (v & 0x0000ffff) >+ if (v & 0x0000ff00) >+ i = 8; >+ else >+ i = 0; >+ else >+ return -1; >+ return i + xfs_highbit[(v >> i) & 0xff]; >+} >+ >+static int >+isinxt (xfs_fileoff_t key, xfs_fileoff_t offset, xfs_filblks_t len) >+{ >+ return (key >= offset) ? (key < offset + len ? 1 : 0) : 0; >+} >+ >+static xfs_daddr_t >+agb2daddr (xfs_agnumber_t agno, xfs_agblock_t agbno) >+{ >+ return ((xfs_fsblock_t)agno*xfs.agblocks + agbno) << xfs.bdlog; >+} >+ >+static xfs_daddr_t >+fsb2daddr (xfs_fsblock_t fsbno) >+{ >+ return agb2daddr ((xfs_agnumber_t)(fsbno >> xfs.agblklog), >+ (xfs_agblock_t)(fsbno & mask32lo(xfs.agblklog))); >+} >+ >+#undef offsetof >+#define offsetof(t,m) ((int)&(((t *)0)->m)) >+ >+static inline int >+btroot_maxrecs (void) >+{ >+ int tmp = icore.di_forkoff ? (icore.di_forkoff << 3) : xfs.isize; >+ >+ return (tmp - sizeof(xfs_bmdr_block_t) - offsetof(xfs_dinode_t, di_u)) / >+ (sizeof (xfs_bmbt_key_t) + sizeof (xfs_bmbt_ptr_t)); >+} >+ >+static int >+di_read (xfs_ino_t ino) >+{ >+ xfs_agino_t agino; >+ xfs_agnumber_t agno; >+ xfs_agblock_t agbno; >+ xfs_daddr_t daddr; >+ int offset; >+ >+ agno = ino2agno (ino); >+ agino = ino2agino (ino); >+ agbno = agino2agbno (agino); >+ offset = ino2offset (ino); >+ daddr = agb2daddr (agno, agbno); >+ >+ devread (daddr, offset*xfs.isize, xfs.isize, (char *)inode); >+ >+ xfs.ptr0 = *(xfs_bmbt_ptr_t *) >+ (inode->di_u.di_c + sizeof(xfs_bmdr_block_t) >+ + btroot_maxrecs ()*sizeof(xfs_bmbt_key_t)); >+ >+ return 1; >+} >+ >+static void >+init_extents (void) >+{ >+ xfs_bmbt_ptr_t ptr0; >+ xfs_btree_lblock_t h; >+ >+ switch (icore.di_format) { >+ case XFS_DINODE_FMT_EXTENTS: >+ xfs.xt = inode->di_u.di_bmx; >+ xfs.nextents = le32 (icore.di_nextents); >+ break; >+ case XFS_DINODE_FMT_BTREE: >+ ptr0 = xfs.ptr0; >+ for (;;) { >+ xfs.daddr = fsb2daddr (le64(ptr0)); >+ devread (xfs.daddr, 0, >+ sizeof(xfs_btree_lblock_t), (char *)&h); >+ if (!h.bb_level) { >+ xfs.nextents = le16(h.bb_numrecs); >+ xfs.next = fsb2daddr (le64(h.bb_rightsib)); >+ xfs.fpos = sizeof(xfs_btree_block_t); >+ return; >+ } >+ devread (xfs.daddr, xfs.btnode_ptr0_off, >+ sizeof(xfs_bmbt_ptr_t), (char *)&ptr0); >+ } >+ } >+} >+ >+static xad_t * >+next_extent (void) >+{ >+ static xad_t xad; >+ >+ switch (icore.di_format) { >+ case XFS_DINODE_FMT_EXTENTS: >+ if (xfs.nextents == 0) >+ return NULL; >+ break; >+ case XFS_DINODE_FMT_BTREE: >+ if (xfs.nextents == 0) { >+ xfs_btree_lblock_t h; >+ if (xfs.next == 0) >+ return NULL; >+ xfs.daddr = xfs.next; >+ devread (xfs.daddr, 0, sizeof(xfs_btree_lblock_t), (char *)&h); >+ xfs.nextents = le16(h.bb_numrecs); >+ xfs.next = fsb2daddr (le64(h.bb_rightsib)); >+ xfs.fpos = sizeof(xfs_btree_block_t); >+ } >+ /* Yeah, I know that's slow, but I really don't care */ >+ devread (xfs.daddr, xfs.fpos, sizeof(xfs_bmbt_rec_t), filebuf); >+ xfs.xt = (xfs_bmbt_rec_32_t *)filebuf; >+ xfs.fpos += sizeof(xfs_bmbt_rec_32_t); >+ } >+ xad.offset = xt_offset (xfs.xt); >+ xad.start = xt_start (xfs.xt); >+ xad.len = xt_len (xfs.xt); >+ ++xfs.xt; >+ --xfs.nextents; >+ >+ return &xad; >+} >+ >+/* >+ * Name lies - the function reads only first 100 bytes >+ */ >+static void >+xfs_dabread (void) >+{ >+ xad_t *xad; >+ xfs_fileoff_t offset;; >+ >+ init_extents (); >+ while ((xad = next_extent ())) { >+ offset = xad->offset; >+ if (isinxt (xfs.dablk, offset, xad->len)) { >+ devread (fsb2daddr (xad->start + xfs.dablk - offset), >+ 0, 100, dirbuf); >+ break; >+ } >+ } >+} >+ >+static inline xfs_ino_t >+sf_ino (char *sfe, int namelen) >+{ >+ void *p = sfe + namelen + 3; >+#ifdef __alpha__ >+ xfs_ino_t ino = 0; >+ if (xfs.i8param == 0) { >+ memcpy(&ino, p, sizeof(xfs_dir2_ino8_t)); >+ return le64(ino); >+ } else { >+ memcpy(&ino, p, sizeof(xfs_dir2_ino4_t)); >+ return le32(ino); >+ } >+#else >+ /* unaligned access */ >+ return (xfs.i8param == 0) >+ ? le64(*(xfs_ino_t *)p) : le32(*(uint32_t *)p); >+#endif >+} >+ >+static inline xfs_ino_t >+sf_parent_ino (void) >+{ >+#ifdef __alpha__ >+ void *p = &inode->di_u.di_dir2sf.hdr.parent; >+ xfs_ino_t ino = 0; >+ if (xfs.i8param == 0) { >+ memcpy(&ino, p, sizeof(xfs_dir2_ino8_t)); >+ return le64(ino); >+ } else { >+ memcpy(&ino, p, sizeof(xfs_dir2_ino4_t)); >+ return le32(ino); >+ } >+#else >+ /* unaligned access */ >+ return (xfs.i8param == 0) >+ ? le64(*(xfs_ino_t *)(&inode->di_u.di_dir2sf.hdr.parent)) >+ : le32(*(uint32_t *)(&inode->di_u.di_dir2sf.hdr.parent)); >+#endif >+} >+ >+static inline int >+roundup8 (int n) >+{ >+ return ((n+7)&~7); >+} >+ >+static char * >+next_dentry (xfs_ino_t *ino) >+{ >+ int namelen; >+ int toread; >+ static xfs_dir2_sf_entry_t *sfe; >+ char *name = NULL; >+ >+ if (xfs.dirpos >= xfs.dirmax) { >+ if (xfs.forw == 0) >+ return NULL; >+ xfs.dablk = xfs.forw; >+ xfs_dabread (); >+#define h ((xfs_dir2_leaf_hdr_t *)dirbuf) >+ xfs.dirmax = le16 (h->count) - le16 (h->stale); >+ xfs.forw = le32 (h->info.forw); >+#undef h >+ xfs.dirpos = 0; >+ } >+ >+ switch (icore.di_format) { >+ case XFS_DINODE_FMT_LOCAL: >+ switch (xfs.dirpos) { >+ case -2: >+ *ino = 0; >+ name = "."; >+ namelen = 1; >+ break; >+ case -1: /* ".." */ >+ *ino = sf_parent_ino (); >+ name = ".."; >+ namelen = 2; >+ sfe = (xfs_dir2_sf_entry_t *) >+ (inode->di_u.di_c >+ + sizeof(xfs_dir2_sf_hdr_t) >+ - xfs.i8param); >+ break; >+ default: >+ namelen = sfe->namelen; >+ *ino = sf_ino ((char *)sfe, namelen); >+ name = sfe->name; >+ name[namelen] = 0; >+ sfe = (xfs_dir2_sf_entry_t *) >+ ((char *)sfe + namelen + 11 - xfs.i8param); >+ } >+ break; >+ case XFS_DINODE_FMT_BTREE: >+ case XFS_DINODE_FMT_EXTENTS: >+#define dau ((xfs_dir2_data_union_t *)dirbuf) >+ for (;;) { >+ if (xfs.blkoff >= xfs.dirbsize) { >+ xfs.blkoff = sizeof(xfs_dir2_data_hdr_t); >+ filepos &= ~(xfs.dirbsize - 1); >+ filepos |= xfs.blkoff; >+ } >+ xfs.blkoff += 4; >+ if (dau->unused.freetag == XFS_DIR2_DATA_FREE_TAG) { >+ toread = roundup8 (le16(dau->unused.length)) - 4; >+ xfs.blkoff += toread; >+ filepos += toread; >+ continue; >+ } >+ break; >+ } >+ xfs_read ((char *)dirbuf + 4, 5); >+ *ino = le64 (dau->entry.inumber); >+ namelen = dau->entry.namelen; >+#undef dau >+ toread = roundup8 (namelen + 11) - 9; >+ xfs_read (dirbuf, toread); >+ name = (char *)dirbuf; >+ name[namelen] = 0; >+ xfs.blkoff += toread + 5; >+ } >+ ++xfs.dirpos; >+ >+ return name; >+} >+ >+static char * >+first_dentry (xfs_ino_t *ino) >+{ >+ xfs.forw = 0; >+ switch (icore.di_format) { >+ case XFS_DINODE_FMT_LOCAL: >+ xfs.dirmax = inode->di_u.di_dir2sf.hdr.count; >+ xfs.i8param = inode->di_u.di_dir2sf.hdr.i8count ? 0 : 4; >+ xfs.dirpos = -2; >+ break; >+ case XFS_DINODE_FMT_EXTENTS: >+ case XFS_DINODE_FMT_BTREE: >+ filepos = 0; >+ xfs_read (dirbuf, sizeof(xfs_dir2_data_hdr_t)); >+ if (((xfs_dir2_data_hdr_t *)dirbuf)->magic == le32(XFS_DIR2_BLOCK_MAGIC)) { >+#define tail ((xfs_dir2_block_tail_t *)dirbuf) >+ filepos = xfs.dirbsize - sizeof(*tail); >+ xfs_read (dirbuf, sizeof(*tail)); >+ xfs.dirmax = le32 (tail->count) - le32 (tail->stale); >+#undef tail >+ } else { >+ xfs.dablk = (1ULL << 35) >> xfs.blklog; >+#define h ((xfs_dir2_leaf_hdr_t *)dirbuf) >+#define n ((xfs_da_intnode_t *)dirbuf) >+ for (;;) { >+ xfs_dabread (); >+ if ((n->hdr.info.magic == le16(XFS_DIR2_LEAFN_MAGIC)) >+ || (n->hdr.info.magic == le16(XFS_DIR2_LEAF1_MAGIC))) { >+ xfs.dirmax = le16 (h->count) - le16 (h->stale); >+ xfs.forw = le32 (h->info.forw); >+ break; >+ } >+ xfs.dablk = le32 (n->btree[0].before); >+ } >+#undef n >+#undef h >+ } >+ xfs.blkoff = sizeof(xfs_dir2_data_hdr_t); >+ filepos = xfs.blkoff; >+ xfs.dirpos = 0; >+ } >+ return next_dentry (ino); >+} >+ >+ >+ >+/* >+ * Initialize an XFS partition starting at offset P_OFFSET; this is >+ * sort-of the same idea as "mounting" it. Read in the relevant >+ * control structures and make them available to the user. Returns 0 >+ * if successful, -1 on failure. >+ */ >+static int >+xfs_mount(long cons_dev, long p_offset, long quiet) >+{ >+ xfs_sb_t super; >+ >+ partition_offset = p_offset; >+ >+ if (cons_read (cons_dev, &super, sizeof(super), partition_offset) != sizeof(super)) { >+ printf("xfs_mount: read_disk_block failed!\n"); >+ return -1; >+ } else if (le32(super.sb_magicnum) != XFS_SB_MAGIC) { >+ printf("xfs_mount: Bad magic: %x\n", super.sb_magicnum); >+ return -1; >+ } else if ((le16(super.sb_versionnum) & XFS_SB_VERSION_NUMBITS) != XFS_SB_VERSION_4) { >+ printf("xfs_mount: Bad version: %x\n", super.sb_versionnum); >+ return -1; >+ } >+ >+ xfs.bsize = le32 (super.sb_blocksize); >+ xfs.blklog = super.sb_blocklog; >+ xfs.bdlog = xfs.blklog - SECTOR_BITS; >+ xfs.rootino = le64 (super.sb_rootino); >+ xfs.isize = le16 (super.sb_inodesize); >+ xfs.agblocks = le32 (super.sb_agblocks); >+ xfs.dirbsize = xfs.bsize << super.sb_dirblklog; >+ >+ xfs.inopblog = super.sb_inopblog; >+ xfs.agblklog = super.sb_agblklog; >+ xfs.agnolog = xfs_highbit32 (le32(super.sb_agcount)); >+ >+ xfs.btnode_ptr0_off = >+ ((xfs.bsize - sizeof(xfs_btree_block_t)) / >+ (sizeof (xfs_bmbt_key_t) + sizeof (xfs_bmbt_ptr_t))) >+ * sizeof(xfs_bmbt_key_t) + sizeof(xfs_btree_block_t); >+ >+#ifdef DEBUG >+ printf("XFS: version = %d\n",le16(super.sb_versionnum) & XFS_SB_VERSION_NUMBITS); >+ printf("XFS: blocksize = %d\n",xfs.bsize); >+#endif >+ dev = cons_dev; >+ xfsfs.blocksize = xfs.bsize; >+ return 0; >+} >+ >+static long >+xfs_read (void *buf, long len) >+{ >+ xad_t *xad; >+ xfs_fileoff_t endofprev, endofcur, offset; >+ xfs_filblks_t xadlen; >+ int toread, startpos, endpos; >+ >+ if (icore.di_format == XFS_DINODE_FMT_LOCAL) { >+ memmove (buf, inode->di_u.di_c + filepos, len); >+ filepos += len; >+ return len; >+ } >+ >+ startpos = filepos; >+ endpos = filepos + len; >+ endofprev = (xfs_fileoff_t)-1; >+ init_extents (); >+ while (len > 0 && (xad = next_extent ())) { >+ offset = xad->offset; >+ xadlen = xad->len; >+ if (isinxt (filepos >> xfs.blklog, offset, xadlen)) { >+ endofcur = (offset + xadlen) << xfs.blklog; >+ toread = (endofcur >= endpos) >+ ? len : (endofcur - filepos); >+ devread (fsb2daddr (xad->start), >+ filepos - (offset << xfs.blklog), toread, buf); >+ buf += toread; >+ len -= toread; >+ filepos += toread; >+ } else if (offset > endofprev) { >+ toread = ((offset << xfs.blklog) >= endpos) >+ ? len : ((offset - endofprev) << xfs.blklog); >+ len -= toread; >+ filepos += toread; >+ for (; toread; toread--) { >+ *(char*)buf++ = 0; >+ } >+ continue; >+ } >+ endofprev = offset + xadlen; >+ } >+ >+ return filepos - startpos; >+} >+ >+/* >+ * Read block number "blkno". >+ */ >+ >+static int >+xfs_bread(int fd, long blkno, long nblks, char *buffer) >+{ >+ if (fd == 1) { >+ /* >+ * Duh. XFS doesn't read past EOF >+ * aboot does just that by trying to read nblks*blksize, >+ * where nblks*blksize > filesize >+ */ >+ memset(buffer,0,nblks*xfs.bsize); >+ long nbytes = xfs_read(buffer, nblks*xfs.bsize); >+ if (nbytes == le64(icore.di_size)) >+ return nblks*xfs.bsize; >+ return (int)nbytes; >+ } >+ printf("XFS error: bad file descriptor!\n"); >+ return -1; >+} >+ >+/* >+ * Unix-like open routine. Returns a small integer >+ * (does not care what file, we say it's OK) >+ */ >+static int xfs_open(const char *dirname) >+{ >+ xfs_ino_t ino, parent_ino; >+ xfs_fsize_t di_size; >+ int di_mode; >+ int cmp, n, link_count; >+ char linkbuf[xfs.bsize]; >+ char *rest, *name, ch; >+ char namebuf[MAXNAMELEN]; >+ strncpy(namebuf,dirname,MAXNAMELEN); >+ char *filename = namebuf; >+ >+#ifdef DEBUG_XFS >+ printf("xfs_open(): filename = %s\n", filename); >+#endif >+ >+ parent_ino = ino = xfs.rootino; >+ link_count = 0; >+ for (;;) { >+ di_read (ino); >+ di_size = le64 (icore.di_size); >+ di_mode = le16 (icore.di_mode); >+ >+#ifdef DEBUG_XFS >+ printf("xfs_open(): di_mode = %o\n", di_mode); >+#endif >+ if ((di_mode & IFMT) == IFLNK) { >+ if (++link_count > MAX_LINK_COUNT) { >+ printf("XFS error: symlink loop!\n"); >+ return 0; >+ } >+ if (di_size < xfs.bsize - 1) { >+ filepos = 0; >+ filemax = di_size; >+ n = xfs_read (linkbuf, filemax); >+ } else { >+ printf("XFS error: bad file length!\n"); >+ return 0; >+ } >+ >+ ino = (linkbuf[0] == '/') ? xfs.rootino : parent_ino; >+ while (n < (xfs.bsize - 1) && (linkbuf[n++] = *filename++)); >+ linkbuf[n] = 0; >+ filename = linkbuf; >+ continue; >+ } >+ >+ if (!*filename || isspace (*filename)) { >+ if (((di_mode & IFMT) != IFREG) >+ && ((di_mode & IFMT) != IFDIR)) { >+ printf("XFS error: bad file type!\n"); >+ return 0; >+ } >+ filepos = 0; >+ filemax = di_size; >+ return 1; >+ } >+ >+ if ((di_mode & IFMT) != IFDIR) { >+ printf("XFS error: bad file type!\n"); >+ return 0; >+ } >+ >+ for (; *filename == '/'; filename++); >+ >+ if (!strcmp(filename,"")) { >+ filepos = 0; >+ filemax = 0; >+ return 1; >+ } >+ >+ for (rest = filename; (ch = *rest) && !isspace (ch) && ch != '/'; rest++); >+ *rest = 0; >+ >+ name = first_dentry (&xfs.new_ino); >+ for (;;) { >+#ifdef DEBUG >+ printf("xfs_open(): found %s\n", name); >+#endif >+ cmp = (!*filename) ? -1 : strcmp (filename, name); >+ if (cmp == 0) { >+ parent_ino = ino; >+ if (xfs.new_ino) >+ ino = xfs.new_ino; >+ *(filename = rest) = ch; >+ break; >+ } >+ name = next_dentry (&xfs.new_ino); >+ if (name == NULL) { >+ *rest = ch; >+ return -1; >+ } >+ } >+ } >+} >+ >+/* >+ * Only one file is opened at any time, so close is a nop. >+ */ >+static void xfs_close(int fd) >+{ >+} >+ >+/* >+ * Return the next directory entry. >+ * Must have opened the directory with xfs_open() >+ */ >+static const char * >+xfs_readdir(int fd, int rewind) >+{ >+ if (fd != 1) >+ return NULL; >+ if ((le16 (icore.di_mode) & IFMT) != IFDIR) { >+ printf("Not a directory!\n"); >+ return NULL; >+ } >+ if (rewind) >+ return first_dentry (&xfs.new_ino); >+ return next_dentry (&xfs.new_ino); >+} >+ >+/* >+ * Get file status >+ */ >+static int >+xfs_fstat(int fd, struct stat* buf) >+{ >+ if (fd != 1) >+ return -1; >+ >+ memset(buf, 0, sizeof(struct stat)); >+ buf->st_mode = le16(icore.di_mode); >+ buf->st_flags = le16(icore.di_flags); >+ buf->st_nlink = le16(icore.di_onlink); >+ buf->st_uid = le32(icore.di_uid); >+ buf->st_gid = le32(icore.di_gid); >+ buf->st_size = le64(icore.di_size); >+ buf->st_blocks = le64(icore.di_nblocks); >+ buf->st_atime = le32(icore.di_atime.t_sec); >+ buf->st_mtime = le32(icore.di_mtime.t_sec); >+ buf->st_ctime = le32(icore.di_ctime.t_sec); >+ return 0; >+} >+ >+ >diff -ruN aboot-1.0_pre20040408/fs/xfs.h aboot-1.0_pre20040408-xfs/fs/xfs.h >--- aboot-1.0_pre20040408/fs/xfs.h 1969-12-31 16:00:00 -0800 >+++ aboot-1.0_pre20040408-xfs/fs/xfs.h 2005-09-24 10:42:03 -0700 >@@ -0,0 +1,536 @@ >+/* >+ * xfs.h - an extraction from xfsprogs-1.3.5/include/xfs* into one file >+ * >+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of version 2 of the GNU General Public License as >+ * published by the Free Software Foundation. >+ * >+ * This program is distributed in the hope that it would be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. >+ * >+ * Further, this software is distributed without any warranty that it is >+ * free of the rightful claim of any third person regarding infringement >+ * or the like. Any license provided herein, whether implied or >+ * otherwise, applies only to this software file. Patent licenses, if >+ * any, provided herein do not apply to combinations of this program with >+ * other software, or any other product whatsoever. >+ * >+ * You should have received a copy of the GNU General Public License along >+ * with this program; if not, write the Free Software Foundation, Inc., 59 >+ * Temple Place - Suite 330, Boston MA 02111-1307, USA. >+ * >+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, >+ * Mountain View, CA 94043, or: >+ * >+ * http://www.sgi.com >+ * >+ * For further information regarding this notice, see: >+ * >+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ >+ */ >+ >+typedef uint64_t xfs_ino_t; >+typedef uint32_t xfs_agino_t; >+typedef int64_t xfs_daddr_t; >+typedef int64_t xfs_off_t; >+typedef uint8_t uuid_t[16]; >+ >+ >+/* those are from xfs_types.h */ >+ >+typedef uint32_t xfs_agblock_t; /* blockno in alloc. group */ >+typedef uint32_t xfs_extlen_t; /* extent length in blocks */ >+typedef uint32_t xfs_agnumber_t; /* allocation group number */ >+typedef int32_t xfs_extnum_t; /* # of extents in a file */ >+typedef int16_t xfs_aextnum_t; /* # extents in an attribute fork */ >+typedef int64_t xfs_fsize_t; /* bytes in a file */ >+ >+typedef uint32_t xfs_dablk_t; /* dir/attr block number (in file) */ >+typedef uint32_t xfs_dahash_t; /* dir/attr hash value */ >+ >+/* >+ * Disk based types: >+ */ >+typedef uint64_t xfs_dfsbno_t; /* blockno in filesystem (agno|agbno) */ >+typedef uint64_t xfs_drfsbno_t; /* blockno in filesystem (raw) */ >+typedef uint64_t xfs_drtbno_t; /* extent (block) in realtime area */ >+typedef uint64_t xfs_dfiloff_t; /* block number in a file */ >+ >+typedef uint64_t xfs_fsblock_t; /* blockno in filesystem (agno|agbno) */ >+typedef uint64_t xfs_fileoff_t; /* block number in a file */ >+typedef uint64_t xfs_filblks_t; /* number of blocks in a file */ >+ >+ >+/* those are from xfs_sb.h */ >+ >+#define XFS_SB_MAGIC 0x58465342 /* 'XFSB'*/ >+#define XFS_SB_VERSION_4 4 /* 6.2+ - bitmask version */ >+#define XFS_SB_VERSION_NUMBITS 0x000f >+ >+typedef struct xfs_sb >+{ >+ uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ >+ uint32_t sb_blocksize; /* logical block size, bytes */ >+ xfs_drfsbno_t sb_dblocks; /* number of data blocks */ >+ xfs_drfsbno_t sb_rblocks; /* number of realtime blocks */ >+ xfs_drtbno_t sb_rextents; /* number of realtime extents */ >+ uuid_t sb_uuid; /* file system unique id */ >+ xfs_dfsbno_t sb_logstart; /* starting block of log if internal */ >+ xfs_ino_t sb_rootino; /* root inode number */ >+ xfs_ino_t sb_rbmino; /* bitmap inode for realtime extents */ >+ xfs_ino_t sb_rsumino; /* summary inode for rt bitmap */ >+ xfs_agblock_t sb_rextsize; /* realtime extent size, blocks */ >+ xfs_agblock_t sb_agblocks; /* size of an allocation group */ >+ xfs_agnumber_t sb_agcount; /* number of allocation groups */ >+ xfs_extlen_t sb_rbmblocks; /* number of rt bitmap blocks */ >+ xfs_extlen_t sb_logblocks; /* number of log blocks */ >+ uint16_t sb_versionnum; /* header version == XFS_SB_VERSION */ >+ uint16_t sb_sectsize; /* volume sector size, bytes */ >+ uint16_t sb_inodesize; /* inode size, bytes */ >+ uint16_t sb_inopblock; /* inodes per block */ >+ char sb_fname[12]; /* file system name */ >+ uint8_t sb_blocklog; /* log2 of sb_blocksize */ >+ uint8_t sb_sectlog; /* log2 of sb_sectsize */ >+ uint8_t sb_inodelog; /* log2 of sb_inodesize */ >+ uint8_t sb_inopblog; /* log2 of sb_inopblock */ >+ uint8_t sb_agblklog; /* log2 of sb_agblocks (rounded up) */ >+ uint8_t sb_rextslog; /* log2 of sb_rextents */ >+ uint8_t sb_inprogress; /* mkfs is in progress, don't mount */ >+ uint8_t sb_imax_pct; /* max % of fs for inode space */ >+ /* statistics */ >+ /* >+ * These fields must remain contiguous. If you really >+ * want to change their layout, make sure you fix the >+ * code in xfs_trans_apply_sb_deltas(). >+ */ >+ uint64_t sb_icount; /* allocated inodes */ >+ uint64_t sb_ifree; /* free inodes */ >+ uint64_t sb_fdblocks; /* free data blocks */ >+ uint64_t sb_frextents; /* free realtime extents */ >+ /* >+ * End contiguous fields. >+ */ >+ xfs_ino_t sb_uquotino; /* user quota inode */ >+ xfs_ino_t sb_gquotino; /* group quota inode */ >+ uint16_t sb_qflags; /* quota flags */ >+ uint8_t sb_flags; /* misc. flags */ >+ uint8_t sb_shared_vn; /* shared version number */ >+ xfs_extlen_t sb_inoalignmt; /* inode chunk alignment, fsblocks */ >+ uint32_t sb_unit; /* stripe or raid unit */ >+ uint32_t sb_width; /* stripe or raid width */ >+ uint8_t sb_dirblklog; /* log2 of dir block size (fsbs) */ >+ uint8_t sb_dummy[7]; /* padding */ >+} xfs_sb_t; >+ >+ >+/* those are from xfs_btree.h */ >+ >+/* >+ * Long form header: bmap btrees. >+ */ >+typedef struct xfs_btree_lblock >+{ >+ uint32_t bb_magic; /* magic number for block type */ >+ uint16_t bb_level; /* 0 is a leaf */ >+ uint16_t bb_numrecs; /* current # of data records */ >+ xfs_dfsbno_t bb_leftsib; /* left sibling block or NULLDFSBNO */ >+ xfs_dfsbno_t bb_rightsib; /* right sibling block or NULLDFSBNO */ >+} xfs_btree_lblock_t; >+ >+/* >+ * Combined header and structure, used by common code. >+ */ >+typedef struct xfs_btree_hdr >+{ >+ uint32_t bb_magic; /* magic number for block type */ >+ uint16_t bb_level; /* 0 is a leaf */ >+ uint16_t bb_numrecs; /* current # of data records */ >+} xfs_btree_hdr_t; >+ >+typedef struct xfs_btree_block >+{ >+ xfs_btree_hdr_t bb_h; /* header */ >+ union { >+ struct { >+ xfs_agblock_t bb_leftsib; >+ xfs_agblock_t bb_rightsib; >+ } s; /* short form pointers */ >+ struct { >+ xfs_dfsbno_t bb_leftsib; >+ xfs_dfsbno_t bb_rightsib; >+ } l; /* long form pointers */ >+ } bb_u; /* rest */ >+} xfs_btree_block_t; >+ >+/* those are from xfs_bmap_btree.h */ >+ >+/* >+ * Bmap root header, on-disk form only. >+ */ >+typedef struct xfs_bmdr_block >+{ >+ uint16_t bb_level; /* 0 is a leaf */ >+ uint16_t bb_numrecs; /* current # of data records */ >+} xfs_bmdr_block_t; >+ >+/* >+ * Bmap btree record and extent descriptor. >+ * For 32-bit kernels, >+ * l0:31 is an extent flag (value 1 indicates non-normal). >+ * l0:0-30 and l1:9-31 are startoff. >+ * l1:0-8, l2:0-31, and l3:21-31 are startblock. >+ * l3:0-20 are blockcount. >+ * For 64-bit kernels, >+ * l0:63 is an extent flag (value 1 indicates non-normal). >+ * l0:9-62 are startoff. >+ * l0:0-8 and l1:21-63 are startblock. >+ * l1:0-20 are blockcount. >+ */ >+ >+#define BMBT_USE_64 1 >+ >+typedef struct xfs_bmbt_rec_32 >+{ >+ uint32_t l0, l1, l2, l3; >+} xfs_bmbt_rec_32_t; >+typedef struct xfs_bmbt_rec_64 >+{ >+ uint64_t l0, l1; >+} xfs_bmbt_rec_64_t; >+ >+#if BMBT_USE_64 >+typedef uint64_t xfs_bmbt_rec_base_t; /* use this for casts */ >+typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t; >+#else /* !BMBT_USE_64 */ >+typedef uint32_t xfs_bmbt_rec_base_t; /* use this for casts */ >+typedef xfs_bmbt_rec_32_t xfs_bmbt_rec_t, xfs_bmdr_rec_t; >+#endif /* BMBT_USE_64 */ >+ >+/* >+ * Key structure for non-leaf levels of the tree. >+ */ >+typedef struct xfs_bmbt_key >+{ >+ xfs_dfiloff_t br_startoff; /* starting file offset */ >+} xfs_bmbt_key_t, xfs_bmdr_key_t; >+ >+typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; /* btree pointer type */ >+ /* btree block header type */ >+typedef struct xfs_btree_lblock xfs_bmbt_block_t; >+ >+ >+ >+/* those are from xfs_dir2.h */ >+/* >+ * Directory version 2. >+ * There are 4 possible formats: >+ * shortform >+ * single block - data with embedded leaf at the end >+ * multiple data blocks, single leaf+freeindex block >+ * data blocks, node&leaf blocks (btree), freeindex blocks >+ * >+ * The shortform format is in xfs_dir2_sf.h. >+ * The single block format is in xfs_dir2_block.h. >+ * The data block format is in xfs_dir2_data.h. >+ * The leaf and freeindex block formats are in xfs_dir2_leaf.h. >+ * Node blocks are the same as the other version, in xfs_da_btree.h. >+ */ >+ >+/* >+ * Byte offset in data block and shortform entry. >+ */ >+typedef uint16_t xfs_dir2_data_off_t; >+ >+/* >+ * Byte offset in a directory. >+ */ >+typedef xfs_off_t xfs_dir2_off_t; >+ >+/* those are from xfs_da_btree.h */ >+/*======================================================================== >+ * Directory Structure when greater than XFS_LBSIZE(mp) bytes. >+ *========================================================================*/ >+ >+/* >+ * This structure is common to both leaf nodes and non-leaf nodes in the Btree. >+ * >+ * Is is used to manage a doubly linked list of all blocks at the same >+ * level in the Btree, and to identify which type of block this is. >+ */ >+#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ >+#define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ >+ >+typedef struct xfs_da_blkinfo { >+ xfs_dablk_t forw; /* previous block in list */ >+ xfs_dablk_t back; /* following block in list */ >+ uint16_t magic; /* validity check on block */ >+ uint16_t pad; /* unused */ >+} xfs_da_blkinfo_t; >+ >+/* >+ * This is the structure of the root and intermediate nodes in the Btree. >+ * The leaf nodes are defined above. >+ * >+ * Entries are not packed. >+ * >+ * Since we have duplicate keys, use a binary search but always follow >+ * all match in the block, not just the first match found. >+ */ >+ >+typedef struct xfs_da_intnode { >+ struct xfs_da_node_hdr { /* constant-structure header block */ >+ xfs_da_blkinfo_t info; /* block type, links, etc. */ >+ uint16_t count; /* count of active entries */ >+ uint16_t level; /* level above leaves (leaf == 0) */ >+ } hdr; >+ struct xfs_da_node_entry { >+ xfs_dahash_t hashval; /* hash value for this descendant */ >+ xfs_dablk_t before; /* Btree block before this key */ >+ } btree[1]; /* variable sized array of keys */ >+} xfs_da_intnode_t; >+ >+ >+/* those are from xfs_dir2_data.h */ >+/* >+ * Directory format 2, data block structures. >+ */ >+ >+/* >+ * Constants. >+ */ >+#define XFS_DIR2_DATA_FREE_TAG 0xffff >+#define XFS_DIR2_DATA_FD_COUNT 3 >+ >+/* >+ * Structures. >+ */ >+ >+/* >+ * Describe a free area in the data block. >+ * The freespace will be formatted as a xfs_dir2_data_unused_t. >+ */ >+typedef struct xfs_dir2_data_free { >+ xfs_dir2_data_off_t offset; /* start of freespace */ >+ xfs_dir2_data_off_t length; /* length of freespace */ >+} xfs_dir2_data_free_t; >+ >+/* >+ * Header for the data blocks. >+ * Always at the beginning of a directory-sized block. >+ * The code knows that XFS_DIR2_DATA_FD_COUNT is 3. >+ */ >+typedef struct xfs_dir2_data_hdr { >+ uint32_t magic; /* XFS_DIR2_DATA_MAGIC */ >+ /* or XFS_DIR2_BLOCK_MAGIC */ >+ xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT]; >+} xfs_dir2_data_hdr_t; >+ >+/* >+ * Active entry in a data block. Aligned to 8 bytes. >+ * Tag appears as the last 2 bytes. >+ */ >+typedef struct xfs_dir2_data_entry { >+ xfs_ino_t inumber; /* inode number */ >+ uint8_t namelen; /* name length */ >+ uint8_t name[1]; /* name bytes, no null */ >+ /* variable offset */ >+ xfs_dir2_data_off_t tag; /* starting offset of us */ >+} xfs_dir2_data_entry_t; >+ >+/* >+ * Unused entry in a data block. Aligned to 8 bytes. >+ * Tag appears as the last 2 bytes. >+ */ >+typedef struct xfs_dir2_data_unused { >+ uint16_t freetag; /* XFS_DIR2_DATA_FREE_TAG */ >+ xfs_dir2_data_off_t length; /* total free length */ >+ /* variable offset */ >+ xfs_dir2_data_off_t tag; /* starting offset of us */ >+} xfs_dir2_data_unused_t; >+ >+typedef union { >+ xfs_dir2_data_entry_t entry; >+ xfs_dir2_data_unused_t unused; >+} xfs_dir2_data_union_t; >+ >+ >+/* those are from xfs_dir2_leaf.h */ >+/* >+ * Directory version 2, leaf block structures. >+ */ >+ >+/* >+ * Leaf block header. >+ */ >+typedef struct xfs_dir2_leaf_hdr { >+ xfs_da_blkinfo_t info; /* header for da routines */ >+ uint16_t count; /* count of entries */ >+ uint16_t stale; /* count of stale entries */ >+} xfs_dir2_leaf_hdr_t; >+ >+ >+/* those are from xfs_dir2_block.h */ >+/* >+ * xfs_dir2_block.h >+ * Directory version 2, single block format structures >+ */ >+ >+/* >+ * The single block format is as follows: >+ * xfs_dir2_data_hdr_t structure >+ * xfs_dir2_data_entry_t and xfs_dir2_data_unused_t structures >+ * xfs_dir2_leaf_entry_t structures >+ * xfs_dir2_block_tail_t structure >+ */ >+ >+#define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: for one block dirs */ >+ >+typedef struct xfs_dir2_block_tail { >+ uint32_t count; /* count of leaf entries */ >+ uint32_t stale; /* count of stale lf entries */ >+} xfs_dir2_block_tail_t; >+ >+ >+/* those are from xfs_dir2_sf.h */ >+ >+/* >+ * Directory layout when stored internal to an inode. >+ * >+ * Small directories are packed as tightly as possible so as to >+ * fit into the literal area of the inode. >+ */ >+ >+/* >+ * Inode number stored as 8 8-bit values. >+ */ >+typedef struct { uint8_t i[8]; } xfs_dir2_ino8_t; >+ >+/* >+ * Inode number stored as 4 8-bit values. >+ * Works a lot of the time, when all the inode numbers in a directory >+ * fit in 32 bits. >+ */ >+typedef struct { uint8_t i[4]; } xfs_dir2_ino4_t; >+ >+typedef union { >+ xfs_dir2_ino8_t i8; >+ xfs_dir2_ino4_t i4; >+} xfs_dir2_inou_t; >+ >+/* >+ * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t. >+ * Only need 16 bits, this is the byte offset into the single block form. >+ */ >+typedef struct { uint8_t i[2]; } xfs_dir2_sf_off_t; >+ >+/* >+ * The parent directory has a dedicated field, and the self-pointer must >+ * be calculated on the fly. >+ * >+ * Entries are packed toward the top as tightly as possible. The header >+ * and the elements must be bcopy()'d out into a work area to get correct >+ * alignment for the inode number fields. >+ */ >+typedef struct xfs_dir2_sf_hdr { >+ uint8_t count; /* count of entries */ >+ uint8_t i8count; /* count of 8-byte inode #s */ >+ xfs_dir2_inou_t parent; /* parent dir inode number */ >+} xfs_dir2_sf_hdr_t; >+ >+typedef struct xfs_dir2_sf_entry { >+ uint8_t namelen; /* actual name length */ >+ xfs_dir2_sf_off_t offset; /* saved offset */ >+ uint8_t name[1]; /* name, variable size */ >+ xfs_dir2_inou_t inumber; /* inode number, var. offset */ >+} xfs_dir2_sf_entry_t; >+ >+typedef struct xfs_dir2_sf { >+ xfs_dir2_sf_hdr_t hdr; /* shortform header */ >+ xfs_dir2_sf_entry_t list[1]; /* shortform entries */ >+} xfs_dir2_sf_t; >+ >+/* those are from xfs_dinode.h */ >+ >+#define XFS_DINODE_VERSION_1 1 >+#define XFS_DINODE_VERSION_2 2 >+#define XFS_DINODE_MAGIC 0x494e /* 'IN' */ >+ >+/* >+ * Disk inode structure. >+ * This is just the header; the inode is expanded to fill a variable size >+ * with the last field expanding. It is split into the core and "other" >+ * because we only need the core part in the in-core inode. >+ */ >+typedef struct xfs_timestamp { >+ int32_t t_sec; /* timestamp seconds */ >+ int32_t t_nsec; /* timestamp nanoseconds */ >+} xfs_timestamp_t; >+ >+/* >+ * Note: Coordinate changes to this structure with the XFS_DI_* #defines >+ * below and the offsets table in xfs_ialloc_log_di(). >+ */ >+typedef struct xfs_dinode_core >+{ >+ uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ >+ uint16_t di_mode; /* mode and type of file */ >+ int8_t di_version; /* inode version */ >+ int8_t di_format; /* format of di_c data */ >+ uint16_t di_onlink; /* old number of links to file */ >+ uint32_t di_uid; /* owner's user id */ >+ uint32_t di_gid; /* owner's group id */ >+ uint32_t di_nlink; /* number of links to file */ >+ uint16_t di_projid; /* owner's project id */ >+ uint8_t di_pad[10]; /* unused, zeroed space */ >+ xfs_timestamp_t di_atime; /* time last accessed */ >+ xfs_timestamp_t di_mtime; /* time last modified */ >+ xfs_timestamp_t di_ctime; /* time created/inode modified */ >+ xfs_fsize_t di_size; /* number of bytes in file */ >+ xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */ >+ xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ >+ xfs_extnum_t di_nextents; /* number of extents in data fork */ >+ xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ >+ uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ >+ int8_t di_aformat; /* format of attr fork's data */ >+ uint32_t di_dmevmask; /* DMIG event mask */ >+ uint16_t di_dmstate; /* DMIG state info */ >+ uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ >+ uint32_t di_gen; /* generation number */ >+} xfs_dinode_core_t; >+ >+typedef struct xfs_dinode >+{ >+ xfs_dinode_core_t di_core; >+ xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */ >+ union { >+ xfs_bmdr_block_t di_bmbt; /* btree root block */ >+ xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */ >+ xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */ >+ char di_c[1]; /* local contents */ >+ } di_u; >+} xfs_dinode_t; >+ >+/* >+ * Values for di_format >+ */ >+typedef enum xfs_dinode_fmt >+{ >+ XFS_DINODE_FMT_DEV, /* CHR, BLK: di_dev */ >+ XFS_DINODE_FMT_LOCAL, /* DIR, REG: di_c */ >+ /* LNK: di_symlink */ >+ XFS_DINODE_FMT_EXTENTS, /* DIR, REG, LNK: di_bmx */ >+ XFS_DINODE_FMT_BTREE, /* DIR, REG, LNK: di_bmbt */ >+ XFS_DINODE_FMT_UUID /* MNT: di_uuid */ >+} xfs_dinode_fmt_t; >+ >+/* >+ * File types (mode field) >+ */ >+#define IFMT 0170000 /* type of file */ >+#define IFDIR 0040000 /* directory */ >+#define IFREG 0100000 /* regular */ >+#define IFLNK 0120000 /* symbolic link */ >+
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 107103
: 69176