[syslinux:elflink] EXTLINUX: Initial XFS filesystem support

syslinux-bot for Paulo Alcantara pcacjr at zytor.com
Tue Nov 27 12:57:03 PST 2012


Commit-ID:  a126f17f663c438ef264a459fa130951dbac780d
Gitweb:     http://www.syslinux.org/commit/a126f17f663c438ef264a459fa130951dbac780d
Author:     Paulo Alcantara <pcacjr at zytor.com>
AuthorDate: Fri, 8 Jun 2012 16:20:15 -0300
Committer:  Paulo Alcantara <pcacjr at zytor.com>
CommitDate: Sat, 21 Jul 2012 01:21:44 -0300

EXTLINUX: Initial XFS filesystem support

XFS filesystems are divided into a number of equally sized chunks called
Allocation Groups (AGs). Each AG can almost be thought of as an
individual filesystem that maintains its own's space usage.

Each AG has the following structure:
     - A super block describing the overall filesystem info
     - Free space management
     - Inode allocation and tracking

So, due to historical reasons (SGI IRIX's design of disk layouts), the
first sector in the primary AG on XFS filesystems contains the
superblock, which is a problem with bootloaders that rely on BIOSes (that
load VBRs which are located in the first sector of the partition).

This patch adds support to the EXTLINUX installer to be able to install
Syslinux in an XFS partition, but with a limitation (temporarily) of
relying on the filesystem block size being 4+ KiB, otherwise there won't
be enough space to store the Syslinux boot sector in the blank area around
the 2048 to 4096 bytes of the primary AG/superblock.

Signed-off-by: Paulo Alcantara <pcacjr at zytor.com>

---
 extlinux/main.c        | 223 ++++++++++++++++++----
 extlinux/xfs.h         |  25 +++
 extlinux/xfs_fs.h      | 501 +++++++++++++++++++++++++++++++++++++++++++++++++
 extlinux/xfs_sb.h      | 476 ++++++++++++++++++++++++++++++++++++++++++++++
 extlinux/xfs_types.h   | 135 +++++++++++++
 libinstaller/syslxfs.h |   5 +-
 6 files changed, 1324 insertions(+), 41 deletions(-)

diff --git a/extlinux/main.c b/extlinux/main.c
index 73f3fbe..a9531d5 100644
--- a/extlinux/main.c
+++ b/extlinux/main.c
@@ -46,6 +46,9 @@
 #include "btrfs.h"
 #include "fat.h"
 #include "ntfs.h"
+#include "xfs.h"
+#include "xfs_types.h"
+#include "xfs_sb.h"
 #include "../version.h"
 #include "syslxint.h"
 #include "syslxcom.h" /* common functions shared with extlinux and syslinux */
@@ -64,6 +67,12 @@
 #define EXT2_SUPER_OFFSET 1024
 #endif
 
+/* Since we have unused 2048 bytes in the primary AG of an XFS partition,
+ * we will use the first 0~512 bytes starting from 2048 for the Syslinux
+ * boot sector.
+ */
+#define XFS_BOOTSECT_OFFSET	4 * SECTOR_SIZE
+
 /* the btrfs partition first 64K blank area is used to store boot sector and
    boot image, the boot sector is from 0~512, the boot image starts after */
 #define BTRFS_BOOTSECT_AREA	65536
@@ -295,7 +304,8 @@ int patch_file_and_bootblock(int fd, const char *dir, int devfd)
     nsect = (boot_image_len + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
     nsect += 2;			/* Two sectors for the ADV */
     sectp = alloca(sizeof(sector_t) * nsect);
-    if (fs_type == EXT2 || fs_type == VFAT || fs_type == NTFS) {
+    if (fs_type == EXT2 || fs_type == VFAT || fs_type == NTFS ||
+	fs_type == XFS) {
 	if (sectmap(fd, sectp, nsect)) {
 		perror("bmap");
 		exit(1);
@@ -328,6 +338,7 @@ int install_bootblock(int fd, const char *device)
     struct btrfs_super_block sb2;
     struct fat_boot_sector sb3;
     struct ntfs_boot_sector sb4;
+    xfs_sb_t sb5;
     bool ok = false;
 
     if (fs_type == EXT2) {
@@ -335,6 +346,7 @@ int install_bootblock(int fd, const char *device)
 		perror("reading superblock");
 		return 1;
 	}
+
 	if (sb.s_magic == EXT2_SUPER_MAGIC)
 		ok = true;
     } else if (fs_type == BTRFS) {
@@ -350,6 +362,7 @@ int install_bootblock(int fd, const char *device)
 		perror("reading fat superblock");
 		return 1;
 	}
+
 	if (fat_check_sb_fields(&sb3))
 		ok = true;
     } else if (fs_type == NTFS) {
@@ -360,12 +373,23 @@ int install_bootblock(int fd, const char *device)
 
         if (ntfs_check_sb_fields(&sb4))
              ok = true;
+    } else if (fs_type == XFS) {
+	if (xpread(fd, &sb5, sizeof sb5, 0) != sizeof sb5) {
+	    perror("reading xfs superblock");
+	    return 1;
+	}
+
+	if (sb5.sb_magicnum == *(u32 *)XFS_SB_MAGIC)
+	    ok = true;
     }
+
     if (!ok) {
-	fprintf(stderr, "no fat, ntfs, ext2/3/4 or btrfs superblock found on %s\n",
-			device);
+	fprintf(stderr,
+		"no fat, ntfs, ext2/3/4, btrfs or xfs superblock found on %s\n",
+		device);
 	return 1;
     }
+
     if (fs_type == VFAT) {
 	struct fat_boot_sector *sbs = (struct fat_boot_sector *)syslinux_bootsect;
         if (xpwrite(fd, &sbs->FAT_bsHead, FAT_bsHeadLen, 0) != FAT_bsHeadLen ||
@@ -385,6 +409,12 @@ int install_bootblock(int fd, const char *device)
             perror("writing ntfs bootblock");
             return 1;
         }
+    } else if (fs_type == XFS) {
+	if (xpwrite(fd, syslinux_bootsect, syslinux_bootsect_len,
+		    XFS_BOOTSECT_OFFSET) != syslinux_bootsect_len) {
+	    perror("writing xfs bootblock");
+	    return 1;
+	}
     } else {
 	if (xpwrite(fd, syslinux_bootsect, syslinux_bootsect_len, 0)
 	    != syslinux_bootsect_len) {
@@ -396,11 +426,61 @@ int install_bootblock(int fd, const char *device)
     return 0;
 }
 
+static int rewrite_boot_image(int devfd, const char *filename)
+{
+    int fd;
+    int ret;
+    int modbytes;
+    char path[PATH_MAX];
+    char slash;
+
+    /* Let's create LDLINUX.SYS file again (if it already exists, of course) */
+    fd = open(filename,  O_WRONLY | O_TRUNC | O_CREAT | O_SYNC,
+	      S_IRUSR | S_IRGRP | S_IROTH);
+    if (fd < 0) {
+	perror(filename);
+	return -1;
+    }
+
+    /* Write boot image data into LDLINUX.SYS file */
+    ret = xpwrite(fd, boot_image, boot_image_len, 0);
+    if (ret != boot_image_len) {
+	perror("writing bootblock");
+	goto error;
+    }
+
+    /* Write ADV */
+    ret = xpwrite(fd, syslinux_adv, 2 * ADV_SIZE, boot_image_len);
+    if (ret != 2 * ADV_SIZE) {
+	fprintf(stderr, "%s: write failure on %s\n", program, filename);
+	goto error;
+    }
+
+    sscanf(filename, "%s%cldlinux.sys", path, &slash);
+
+    /* Map the file, and patch the initial sector accordingly */
+    modbytes = patch_file_and_bootblock(fd, path, devfd);
+
+    /* Write the patch area again - this relies on the file being overwritten
+     * in place! */
+    ret = xpwrite(fd, boot_image, modbytes, 0);
+    if (ret != modbytes) {
+	fprintf(stderr, "%s: write failure on %s\n", program, filename);
+	goto error;
+    }
+
+    return fd;
+
+error:
+    close(fd);
+
+    return -1;
+}
+
 int ext2_fat_install_file(const char *path, int devfd, struct stat *rst)
 {
     char *file, *oldfile;
     int fd = -1, dirfd = -1;
-    int modbytes;
     int r1, r2;
 
     r1 = asprintf(&file, "%s%sldlinux.sys",
@@ -429,34 +509,7 @@ int ext2_fat_install_file(const char *path, int devfd, struct stat *rst)
     }
     close(fd);
 
-    fd = open(file, O_WRONLY | O_TRUNC | O_CREAT | O_SYNC,
-	      S_IRUSR | S_IRGRP | S_IROTH);
-    if (fd < 0) {
-	perror(file);
-	goto bail;
-    }
-
-    /* Write it the first time */
-    if (xpwrite(fd, boot_image, boot_image_len, 0) != boot_image_len ||
-	xpwrite(fd, syslinux_adv, 2 * ADV_SIZE,
-		boot_image_len) != 2 * ADV_SIZE) {
-	fprintf(stderr, "%s: write failure on %s\n", program, file);
-	goto bail;
-    }
-
-    /* Map the file, and patch the initial sector accordingly */
-    modbytes = patch_file_and_bootblock(fd, path, devfd);
-
-    /* Write the patch area again - this relies on the file being
-       overwritten in place! */
-    if (xpwrite(fd, boot_image, modbytes, 0) != modbytes) {
-	fprintf(stderr, "%s: write failure on %s\n", program, file);
-	goto bail;
-    }
-
-    /* Attempt to set immutable flag and remove all write access */
-    /* Only set immutable flag if file is owned by root */
-    set_attributes(fd);
+    fd = rewrite_boot_image(devfd, file);
 
     if (fstat(fd, rst)) {
 	perror(file);
@@ -515,6 +568,70 @@ int btrfs_install_file(const char *path, int devfd, struct stat *rst)
 }
 
 /*
+ * Due to historical reasons (SGI IRIX's design of disk layouts), the first
+ * sector in the primary AG on XFS filesystems contains the superblock, which is
+ * a problem with bootloaders that rely on BIOSes (that load VBRs which are
+ * (located in the first sector of the partition).
+ *
+ * Thus, we need to handle this issue, otherwise Syslinux will damage the XFS's
+ * superblock.
+ */
+static int xfs_install_file(const char *path, int devfd, struct stat *rst)
+{
+    static char file[PATH_MAX];
+    int dirfd = -1;
+    int fd = -1;
+
+    snprintf(file, PATH_MAX, "%s%sldlinux.sys",
+	     path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/");
+
+    dirfd = open(path, O_RDONLY | O_DIRECTORY);
+    if (dirfd < 0) {
+	perror(path);
+	goto bail;
+    }
+
+    fd = open(file, O_RDONLY);
+    if (fd < 0) {
+	if (errno != ENOENT) {
+	    perror(file);
+	    goto bail;
+	}
+    } else {
+	clear_attributes(fd);
+    }
+
+    close(fd);
+
+    fd = rewrite_boot_image(devfd, file);
+    if (fd < 0)
+	goto bail;
+
+    /* Attempt to set immutable flag and remove all write access */
+    /* Only set immutable flag if file is owned by root */
+    set_attributes(fd);
+
+    if (fstat(fd, rst)) {
+	perror(file);
+	goto bail;
+    }
+
+    close(dirfd);
+    close(fd);
+
+    return 0;
+
+bail:
+    if (dirfd >= 0)
+	close(dirfd);
+
+    if (fd >= 0)
+	close(fd);
+
+    return 1;
+}
+
+/*
  *  * test if path is a subvolume:
  *   * this function return
  *    * 0-> path exists but it is not a subvolume
@@ -748,11 +865,14 @@ static char * get_default_subvol(char * rootdir, char * subvol)
 
 int install_file(const char *path, int devfd, struct stat *rst)
 {
-	if (fs_type == EXT2 || fs_type == VFAT || fs_type == NTFS)
-		return ext2_fat_install_file(path, devfd, rst);
-	else if (fs_type == BTRFS)
-		return btrfs_install_file(path, devfd, rst);
-	return 1;
+    if (fs_type == EXT2 || fs_type == VFAT || fs_type == NTFS)
+	return ext2_fat_install_file(path, devfd, rst);
+    else if (fs_type == BTRFS)
+	return btrfs_install_file(path, devfd, rst);
+    else if (fs_type == XFS)
+	return xfs_install_file(path, devfd, rst);
+
+    return 1;
 }
 
 #ifdef __KLIBC__
@@ -847,14 +967,22 @@ static const char *find_device(const char *mtab_file, dev_t dev)
 	    }
 
 	    break;
+	case XFS:
+	    if (!strcmp(mnt->mnt_type, "xfs") && !stat(mnt->mnt_fsname, &dst) &&
+		dst.st_rdev == dev) {
+		done = true;
+		break;
+	    }
 	case NONE:
 	    break;
 	}
+
 	if (done) {
 	    devname = strdup(mnt->mnt_fsname);
 	    break;
 	}
     }
+
     endmntent(mtab);
 
     return devname;
@@ -1098,6 +1226,7 @@ static int open_device(const char *path, struct stat *st, const char **_devname)
 	fprintf(stderr, "%s: statfs %s: %s\n", program, path, strerror(errno));
 	return -1;
     }
+
     if (sfs.f_type == EXT2_SUPER_MAGIC)
 	fs_type = EXT2;
     else if (sfs.f_type == BTRFS_SUPER_MAGIC)
@@ -1106,10 +1235,13 @@ static int open_device(const char *path, struct stat *st, const char **_devname)
 	fs_type = VFAT;
     else if (sfs.f_type == NTFS_SB_MAGIC ||
                 sfs.f_type == FUSE_SUPER_MAGIC /* ntfs-3g */)
-        fs_type = NTFS;
+	fs_type = NTFS;
+    else if (sfs.f_type == XFS_SUPER_MAGIC)
+	fs_type = XFS;
 
     if (!fs_type) {
-	fprintf(stderr, "%s: not a fat, ntfs, ext2/3/4 or btrfs filesystem: %s\n",
+	fprintf(stderr,
+		"%s: not a fat, ntfs, ext2/3/4, btrfs or xfs filesystem: %s\n",
 		program, path);
 	return -1;
     }
@@ -1143,6 +1275,16 @@ static int btrfs_read_adv(int devfd)
     return syslinux_validate_adv(syslinux_adv) ? 1 : 0;
 }
 
+static inline int xfs_read_adv(int devfd)
+{
+    const size_t adv_size = 2 * ADV_SIZE;
+
+    if (xpread(devfd, syslinux_adv, adv_size, boot_image_len) != adv_size)
+	return -1;
+
+    return syslinux_validate_adv(syslinux_adv) ? 1 : 0;
+}
+
 static int ext_read_adv(const char *path, int devfd, const char **namep)
 {
     int err;
@@ -1151,6 +1293,9 @@ static int ext_read_adv(const char *path, int devfd, const char **namep)
     if (fs_type == BTRFS) {
 	/* btrfs "ldlinux.sys" is in 64k blank area */
 	return btrfs_read_adv(devfd);
+    } else if (fs_type == XFS) {
+	/* XFS "ldlinux.sys" is in the first 2048 bytes of the primary AG */
+	return xfs_read_adv(devfd);
     } else {
 	err = read_adv(path, name = "ldlinux.sys");
 	if (err == 2)		/* ldlinux.sys does not exist */
diff --git a/extlinux/xfs.h b/extlinux/xfs.h
new file mode 100644
index 0000000..412c266
--- /dev/null
+++ b/extlinux/xfs.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012 Paulo Alcantara <pcacjr at zytor.com>
+ *
+ * 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.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef XFS_H_
+#define XFS_H_
+
+#define XFS_SUPER_MAGIC 0x58465342
+
+#endif /* XFS_H_ */
diff --git a/extlinux/xfs_fs.h b/extlinux/xfs_fs.h
new file mode 100644
index 0000000..587820e
--- /dev/null
+++ b/extlinux/xfs_fs.h
@@ -0,0 +1,501 @@
+/*
+ * Taken from Linux kernel tree (linux/fs/xfs)
+ *
+ * Copyright (c) 1995-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * Copyright (c) 2012 Paulo Alcantara <pcacjr at zytor.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef XFS_FS_H_
+#define XFS_FS_H_
+
+/*
+ * SGI's XFS filesystem's major stuff (constants, structures)
+ */
+
+/*
+ * Direct I/O attribute record used with XFS_IOC_DIOINFO
+ * d_miniosz is the min xfer size, xfer size multiple and file seek offset
+ * alignment.
+ */
+struct dioattr {
+	uint32_t		d_mem;		/* data buffer memory alignment */
+	uint32_t		d_miniosz;	/* min xfer size		*/
+	uint32_t		d_maxiosz;	/* max xfer size		*/
+};
+
+/*
+ * Structure for XFS_IOC_FSGETXATTR[A] and XFS_IOC_FSSETXATTR.
+ */
+struct fsxattr {
+	uint32_t		fsx_xflags;	/* xflags field value (get/set) */
+	uint32_t		fsx_extsize;	/* extsize field value (get/set)*/
+	uint32_t		fsx_nextents;	/* nextents field value (get)	*/
+	uint32_t		fsx_projid;	/* project identifier (get/set) */
+	unsigned char	fsx_pad[12];
+};
+
+/*
+ * Flags for the bs_xflags/fsx_xflags field
+ * There should be a one-to-one correspondence between these flags and the
+ * XFS_DIFLAG_s.
+ */
+#define XFS_XFLAG_REALTIME	0x00000001	/* data in realtime volume */
+#define XFS_XFLAG_PREALLOC	0x00000002	/* preallocated file extents */
+#define XFS_XFLAG_IMMUTABLE	0x00000008	/* file cannot be modified */
+#define XFS_XFLAG_APPEND	0x00000010	/* all writes append */
+#define XFS_XFLAG_SYNC		0x00000020	/* all writes synchronous */
+#define XFS_XFLAG_NOATIME	0x00000040	/* do not update access time */
+#define XFS_XFLAG_NODUMP	0x00000080	/* do not include in backups */
+#define XFS_XFLAG_RTINHERIT	0x00000100	/* create with rt bit set */
+#define XFS_XFLAG_PROJINHERIT	0x00000200	/* create with parents projid */
+#define XFS_XFLAG_NOSYMLINKS	0x00000400	/* disallow symlink creation */
+#define XFS_XFLAG_EXTSIZE	0x00000800	/* extent size allocator hint */
+#define XFS_XFLAG_EXTSZINHERIT	0x00001000	/* inherit inode extent size */
+#define XFS_XFLAG_NODEFRAG	0x00002000  	/* do not defragment */
+#define XFS_XFLAG_FILESTREAM	0x00004000	/* use filestream allocator */
+#define XFS_XFLAG_HASATTR	0x80000000	/* no DIFLAG for this	*/
+
+/*
+ * Structure for XFS_IOC_GETBMAP.
+ * On input, fill in bmv_offset and bmv_length of the first structure
+ * to indicate the area of interest in the file, and bmv_entries with
+ * the number of array elements given back.  The first structure is
+ * updated on return to give the offset and length for the next call.
+ */
+struct getbmap {
+	int64_t		bmv_offset;	/* file offset of segment in blocks */
+	int64_t		bmv_block;	/* starting block (64-bit daddr_t)  */
+	int64_t		bmv_length;	/* length of segment, blocks	    */
+	int32_t		bmv_count;	/* # of entries in array incl. 1st  */
+	int32_t		bmv_entries;	/* # of entries filled in (output)  */
+};
+
+/*
+ *	Structure for XFS_IOC_GETBMAPX.	 Fields bmv_offset through bmv_entries
+ *	are used exactly as in the getbmap structure.  The getbmapx structure
+ *	has additional bmv_iflags and bmv_oflags fields. The bmv_iflags field
+ *	is only used for the first structure.  It contains input flags
+ *	specifying XFS_IOC_GETBMAPX actions.  The bmv_oflags field is filled
+ *	in by the XFS_IOC_GETBMAPX command for each returned structure after
+ *	the first.
+ */
+struct getbmapx {
+	int64_t		bmv_offset;	/* file offset of segment in blocks */
+	int64_t		bmv_block;	/* starting block (64-bit daddr_t)  */
+	int64_t		bmv_length;	/* length of segment, blocks	    */
+	int32_t		bmv_count;	/* # of entries in array incl. 1st  */
+	int32_t		bmv_entries;	/* # of entries filled in (output). */
+	int32_t		bmv_iflags;	/* input flags (1st structure)	    */
+	int32_t		bmv_oflags;	/* output flags (after 1st structure)*/
+	int32_t		bmv_unused1;	/* future use			    */
+	int32_t		bmv_unused2;	/* future use			    */
+};
+
+/*	bmv_iflags values - set by XFS_IOC_GETBMAPX caller.	*/
+#define BMV_IF_ATTRFORK		0x1	/* return attr fork rather than data */
+#define BMV_IF_NO_DMAPI_READ	0x2	/* Do not generate DMAPI read event  */
+#define BMV_IF_PREALLOC		0x4	/* rtn status BMV_OF_PREALLOC if req */
+#define BMV_IF_DELALLOC		0x8	/* rtn status BMV_OF_DELALLOC if req */
+#define BMV_IF_NO_HOLES		0x10	/* Do not return holes */
+#define BMV_IF_VALID	\
+	(BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC|	\
+	 BMV_IF_DELALLOC|BMV_IF_NO_HOLES)
+
+/*	bmv_oflags values - returned for each non-header segment */
+#define BMV_OF_PREALLOC		0x1	/* segment = unwritten pre-allocation */
+#define BMV_OF_DELALLOC		0x2	/* segment = delayed allocation */
+#define BMV_OF_LAST		0x4	/* segment is the last in the file */
+
+/*
+ * Structure for XFS_IOC_FSSETDM.
+ * For use by backup and restore programs to set the XFS on-disk inode
+ * fields di_dmevmask and di_dmstate.  These must be set to exactly and
+ * only values previously obtained via xfs_bulkstat!  (Specifically the
+ * xfs_bstat_t fields bs_dmevmask and bs_dmstate.)
+ */
+struct fsdmidata {
+	uint32_t		fsd_dmevmask;	/* corresponds to di_dmevmask */
+	__u16		fsd_padding;
+	__u16		fsd_dmstate;	/* corresponds to di_dmstate  */
+};
+
+/*
+ * File segment locking set data type for 64 bit access.
+ * Also used for all the RESV/FREE interfaces.
+ */
+typedef struct xfs_flock64 {
+	__s16		l_type;
+	__s16		l_whence;
+	int64_t		l_start;
+	int64_t		l_len;		/* len == 0 means until end of file */
+	int32_t		l_sysid;
+	uint32_t		l_pid;
+	int32_t		l_pad[4];	/* reserve area			    */
+} xfs_flock64_t;
+
+/*
+ * Output for XFS_IOC_FSGEOMETRY_V1
+ */
+typedef struct xfs_fsop_geom_v1 {
+	uint32_t		blocksize;	/* filesystem (data) block size */
+	uint32_t		rtextsize;	/* realtime extent size		*/
+	uint32_t		agblocks;	/* fsblocks in an AG		*/
+	uint32_t		agcount;	/* number of allocation groups	*/
+	uint32_t		logblocks;	/* fsblocks in the log		*/
+	uint32_t		sectsize;	/* (data) sector size, bytes	*/
+	uint32_t		inodesize;	/* inode size in bytes		*/
+	uint32_t		imaxpct;	/* max allowed inode space(%)	*/
+	uint64_t		datablocks;	/* fsblocks in data subvolume	*/
+	uint64_t		rtblocks;	/* fsblocks in realtime subvol	*/
+	uint64_t		rtextents;	/* rt extents in realtime subvol*/
+	uint64_t		logstart;	/* starting fsblock of the log	*/
+	unsigned char	uuid[16];	/* unique id of the filesystem	*/
+	uint32_t		sunit;		/* stripe unit, fsblocks	*/
+	uint32_t		swidth;		/* stripe width, fsblocks	*/
+	int32_t		version;	/* structure version		*/
+	uint32_t		flags;		/* superblock version flags	*/
+	uint32_t		logsectsize;	/* log sector size, bytes	*/
+	uint32_t		rtsectsize;	/* realtime sector size, bytes	*/
+	uint32_t		dirblocksize;	/* directory block size, bytes	*/
+} xfs_fsop_geom_v1_t;
+
+/*
+ * Output for XFS_IOC_FSGEOMETRY
+ */
+typedef struct xfs_fsop_geom {
+	uint32_t		blocksize;	/* filesystem (data) block size */
+	uint32_t		rtextsize;	/* realtime extent size		*/
+	uint32_t		agblocks;	/* fsblocks in an AG		*/
+	uint32_t		agcount;	/* number of allocation groups	*/
+	uint32_t		logblocks;	/* fsblocks in the log		*/
+	uint32_t		sectsize;	/* (data) sector size, bytes	*/
+	uint32_t		inodesize;	/* inode size in bytes		*/
+	uint32_t		imaxpct;	/* max allowed inode space(%)	*/
+	uint64_t		datablocks;	/* fsblocks in data subvolume	*/
+	uint64_t		rtblocks;	/* fsblocks in realtime subvol	*/
+	uint64_t		rtextents;	/* rt extents in realtime subvol*/
+	uint64_t		logstart;	/* starting fsblock of the log	*/
+	unsigned char	uuid[16];	/* unique id of the filesystem	*/
+	uint32_t		sunit;		/* stripe unit, fsblocks	*/
+	uint32_t		swidth;		/* stripe width, fsblocks	*/
+	int32_t		version;	/* structure version		*/
+	uint32_t		flags;		/* superblock version flags	*/
+	uint32_t		logsectsize;	/* log sector size, bytes	*/
+	uint32_t		rtsectsize;	/* realtime sector size, bytes	*/
+	uint32_t		dirblocksize;	/* directory block size, bytes	*/
+	uint32_t		logsunit;	/* log stripe unit, bytes */
+} xfs_fsop_geom_t;
+
+/* Output for XFS_FS_COUNTS */
+typedef struct xfs_fsop_counts {
+	uint64_t	freedata;	/* free data section blocks */
+	uint64_t	freertx;	/* free rt extents */
+	uint64_t	freeino;	/* free inodes */
+	uint64_t	allocino;	/* total allocated inodes */
+} xfs_fsop_counts_t;
+
+/* Input/Output for XFS_GET_RESBLKS and XFS_SET_RESBLKS */
+typedef struct xfs_fsop_resblks {
+	uint64_t  resblks;
+	uint64_t  resblks_avail;
+} xfs_fsop_resblks_t;
+
+#define XFS_FSOP_GEOM_VERSION	0
+
+#define XFS_FSOP_GEOM_FLAGS_ATTR	0x0001	/* attributes in use	*/
+#define XFS_FSOP_GEOM_FLAGS_NLINK	0x0002	/* 32-bit nlink values	*/
+#define XFS_FSOP_GEOM_FLAGS_QUOTA	0x0004	/* quotas enabled	*/
+#define XFS_FSOP_GEOM_FLAGS_IALIGN	0x0008	/* inode alignment	*/
+#define XFS_FSOP_GEOM_FLAGS_DALIGN	0x0010	/* large data alignment */
+#define XFS_FSOP_GEOM_FLAGS_SHARED	0x0020	/* read-only shared	*/
+#define XFS_FSOP_GEOM_FLAGS_EXTFLG	0x0040	/* special extent flag	*/
+#define XFS_FSOP_GEOM_FLAGS_DIRV2	0x0080	/* directory version 2	*/
+#define XFS_FSOP_GEOM_FLAGS_LOGV2	0x0100	/* log format version 2	*/
+#define XFS_FSOP_GEOM_FLAGS_SECTOR	0x0200	/* sector sizes >1BB	*/
+#define XFS_FSOP_GEOM_FLAGS_ATTR2	0x0400	/* inline attributes rework */
+#define XFS_FSOP_GEOM_FLAGS_DIRV2CI	0x1000	/* ASCII only CI names */
+#define XFS_FSOP_GEOM_FLAGS_LAZYSB	0x4000	/* lazy superblock counters */
+
+
+/*
+ * Minimum and maximum sizes need for growth checks
+ */
+#define XFS_MIN_AG_BLOCKS	64
+#define XFS_MIN_LOG_BLOCKS	512ULL
+#define XFS_MAX_LOG_BLOCKS	(1024 * 1024ULL)
+#define XFS_MIN_LOG_BYTES	(10 * 1024 * 1024ULL)
+
+/* keep the maximum size under 2^31 by a small amount */
+#define XFS_MAX_LOG_BYTES \
+	((2 * 1024 * 1024 * 1024ULL) - XFS_MIN_LOG_BYTES)
+
+/* Used for sanity checks on superblock */
+#define XFS_MAX_DBLOCKS(s) ((xfs_drfsbno_t)(s)->sb_agcount * (s)->sb_agblocks)
+#define XFS_MIN_DBLOCKS(s) ((xfs_drfsbno_t)((s)->sb_agcount - 1) *	\
+			 (s)->sb_agblocks + XFS_MIN_AG_BLOCKS)
+
+/*
+ * Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT
+ */
+typedef struct xfs_growfs_data {
+	uint64_t		newblocks;	/* new data subvol size, fsblocks */
+	uint32_t		imaxpct;	/* new inode space percentage limit */
+} xfs_growfs_data_t;
+
+typedef struct xfs_growfs_log {
+	uint32_t		newblocks;	/* new log size, fsblocks */
+	uint32_t		isint;		/* 1 if new log is internal */
+} xfs_growfs_log_t;
+
+typedef struct xfs_growfs_rt {
+	uint64_t		newblocks;	/* new realtime size, fsblocks */
+	uint32_t		extsize;	/* new realtime extent size, fsblocks */
+} xfs_growfs_rt_t;
+
+
+/*
+ * Structures returned from ioctl XFS_IOC_FSBULKSTAT & XFS_IOC_FSBULKSTAT_SINGLE
+ */
+typedef struct xfs_bstime {
+	time_t		tv_sec;		/* seconds		*/
+	int32_t		tv_nsec;	/* and nanoseconds	*/
+} xfs_bstime_t;
+
+typedef struct xfs_bstat {
+	uint64_t		bs_ino;		/* inode number			*/
+	__u16		bs_mode;	/* type and mode		*/
+	__u16		bs_nlink;	/* number of links		*/
+	uint32_t		bs_uid;		/* user id			*/
+	uint32_t		bs_gid;		/* group id			*/
+	uint32_t		bs_rdev;	/* device value			*/
+	int32_t		bs_blksize;	/* block size			*/
+	int64_t		bs_size;	/* file size			*/
+	xfs_bstime_t	bs_atime;	/* access time			*/
+	xfs_bstime_t	bs_mtime;	/* modify time			*/
+	xfs_bstime_t	bs_ctime;	/* inode change time		*/
+	int64_t		bs_blocks;	/* number of blocks		*/
+	uint32_t		bs_xflags;	/* extended flags		*/
+	int32_t		bs_extsize;	/* extent size			*/
+	int32_t		bs_extents;	/* number of extents		*/
+	uint32_t		bs_gen;		/* generation count		*/
+	__u16		bs_projid_lo;	/* lower part of project id	*/
+#define	bs_projid	bs_projid_lo	/* (previously just bs_projid)	*/
+	__u16		bs_forkoff;	/* inode fork offset in bytes	*/
+	__u16		bs_projid_hi;	/* higher part of project id	*/
+	unsigned char	bs_pad[10];	/* pad space, unused		*/
+	uint32_t		bs_dmevmask;	/* DMIG event mask		*/
+	__u16		bs_dmstate;	/* DMIG state info		*/
+	__u16		bs_aextents;	/* attribute number of extents	*/
+} xfs_bstat_t;
+
+/*
+ * The user-level BulkStat Request interface structure.
+ */
+typedef struct xfs_fsop_bulkreq {
+	uint64_t		__user *lastip;	/* last inode # pointer		*/
+	int32_t		icount;		/* count of entries in buffer	*/
+	void		__user *ubuffer;/* user buffer for inode desc.	*/
+	int32_t		__user *ocount;	/* output count pointer		*/
+} xfs_fsop_bulkreq_t;
+
+
+/*
+ * Structures returned from xfs_inumbers routine (XFS_IOC_FSINUMBERS).
+ */
+typedef struct xfs_inogrp {
+	uint64_t		xi_startino;	/* starting inode number	*/
+	int32_t		xi_alloccount;	/* # bits set in allocmask	*/
+	uint64_t		xi_allocmask;	/* mask of allocated inodes	*/
+} xfs_inogrp_t;
+
+
+/*
+ * Error injection.
+ */
+typedef struct xfs_error_injection {
+	int32_t		fd;
+	int32_t		errtag;
+} xfs_error_injection_t;
+
+
+/*
+ * The user-level Handle Request interface structure.
+ */
+typedef struct xfs_fsop_handlereq {
+	uint32_t		fd;		/* fd for FD_TO_HANDLE		*/
+	void		__user *path;	/* user pathname		*/
+	uint32_t		oflags;		/* open flags			*/
+	void		__user *ihandle;/* user supplied handle		*/
+	uint32_t		ihandlen;	/* user supplied length		*/
+	void		__user *ohandle;/* user buffer for handle	*/
+	uint32_t		__user *ohandlen;/* user buffer length		*/
+} xfs_fsop_handlereq_t;
+
+/*
+ * Compound structures for passing args through Handle Request interfaces
+ * xfs_fssetdm_by_handle, xfs_attrlist_by_handle, xfs_attrmulti_by_handle
+ * - ioctls: XFS_IOC_FSSETDM_BY_HANDLE, XFS_IOC_ATTRLIST_BY_HANDLE, and
+ *	     XFS_IOC_ATTRMULTI_BY_HANDLE
+ */
+
+typedef struct xfs_fsop_setdm_handlereq {
+	struct xfs_fsop_handlereq	hreq;	/* handle information	*/
+	struct fsdmidata		__user *data;	/* DMAPI data	*/
+} xfs_fsop_setdm_handlereq_t;
+
+typedef struct xfs_attrlist_cursor {
+	uint32_t		opaque[4];
+} xfs_attrlist_cursor_t;
+
+typedef struct xfs_fsop_attrlist_handlereq {
+	struct xfs_fsop_handlereq	hreq; /* handle interface structure */
+	struct xfs_attrlist_cursor	pos; /* opaque cookie, list offset */
+	uint32_t				flags;	/* which namespace to use */
+	uint32_t				buflen;	/* length of buffer supplied */
+	void				__user *buffer;	/* returned names */
+} xfs_fsop_attrlist_handlereq_t;
+
+typedef struct xfs_attr_multiop {
+	uint32_t		am_opcode;
+#define ATTR_OP_GET	1	/* return the indicated attr's value */
+#define ATTR_OP_SET	2	/* set/create the indicated attr/value pair */
+#define ATTR_OP_REMOVE	3	/* remove the indicated attr */
+	int32_t		am_error;
+	void		__user *am_attrname;
+	void		__user *am_attrvalue;
+	uint32_t		am_length;
+	uint32_t		am_flags;
+} xfs_attr_multiop_t;
+
+typedef struct xfs_fsop_attrmulti_handlereq {
+	struct xfs_fsop_handlereq	hreq; /* handle interface structure */
+	uint32_t				opcount;/* count of following multiop */
+	struct xfs_attr_multiop		__user *ops; /* attr_multi data */
+} xfs_fsop_attrmulti_handlereq_t;
+
+/*
+ * per machine unique filesystem identifier types.
+ */
+typedef struct { uint32_t val[2]; } xfs_fsid_t; /* file system id type */
+
+typedef struct xfs_fid {
+	__u16	fid_len;		/* length of remainder	*/
+	__u16	fid_pad;
+	uint32_t	fid_gen;		/* generation number	*/
+	uint64_t	fid_ino;		/* 64 bits inode number */
+} xfs_fid_t;
+
+typedef struct xfs_handle {
+	union {
+		int64_t	    align;	/* force alignment of ha_fid	 */
+		xfs_fsid_t  _ha_fsid;	/* unique file system identifier */
+	} ha_u;
+	xfs_fid_t	ha_fid;		/* file system specific file ID	 */
+} xfs_handle_t;
+#define ha_fsid ha_u._ha_fsid
+
+#define XFS_HSIZE(handle)	(((char *) &(handle).ha_fid.fid_pad	 \
+				 - (char *) &(handle))			  \
+				 + (handle).ha_fid.fid_len)
+
+/*
+ * Flags for going down operation
+ */
+#define XFS_FSOP_GOING_FLAGS_DEFAULT		0x0	/* going down */
+#define XFS_FSOP_GOING_FLAGS_LOGFLUSH		0x1	/* flush log but not data */
+#define XFS_FSOP_GOING_FLAGS_NOLOGFLUSH		0x2	/* don't flush log nor data */
+
+/*
+ * ioctl commands that are used by Linux filesystems
+ */
+#define XFS_IOC_GETXFLAGS	FS_IOC_GETFLAGS
+#define XFS_IOC_SETXFLAGS	FS_IOC_SETFLAGS
+#define XFS_IOC_GETVERSION	FS_IOC_GETVERSION
+
+/*
+ * ioctl commands that replace IRIX fcntl()'s
+ * For 'documentation' purposed more than anything else,
+ * the "cmd #" field reflects the IRIX fcntl number.
+ */
+#define XFS_IOC_ALLOCSP		_IOW ('X', 10, struct xfs_flock64)
+#define XFS_IOC_FREESP		_IOW ('X', 11, struct xfs_flock64)
+#define XFS_IOC_DIOINFO		_IOR ('X', 30, struct dioattr)
+#define XFS_IOC_FSGETXATTR	_IOR ('X', 31, struct fsxattr)
+#define XFS_IOC_FSSETXATTR	_IOW ('X', 32, struct fsxattr)
+#define XFS_IOC_ALLOCSP64	_IOW ('X', 36, struct xfs_flock64)
+#define XFS_IOC_FREESP64	_IOW ('X', 37, struct xfs_flock64)
+#define XFS_IOC_GETBMAP		_IOWR('X', 38, struct getbmap)
+#define XFS_IOC_FSSETDM		_IOW ('X', 39, struct fsdmidata)
+#define XFS_IOC_RESVSP		_IOW ('X', 40, struct xfs_flock64)
+#define XFS_IOC_UNRESVSP	_IOW ('X', 41, struct xfs_flock64)
+#define XFS_IOC_RESVSP64	_IOW ('X', 42, struct xfs_flock64)
+#define XFS_IOC_UNRESVSP64	_IOW ('X', 43, struct xfs_flock64)
+#define XFS_IOC_GETBMAPA	_IOWR('X', 44, struct getbmap)
+#define XFS_IOC_FSGETXATTRA	_IOR ('X', 45, struct fsxattr)
+/*	XFS_IOC_SETBIOSIZE ---- deprecated 46	   */
+/*	XFS_IOC_GETBIOSIZE ---- deprecated 47	   */
+#define XFS_IOC_GETBMAPX	_IOWR('X', 56, struct getbmap)
+#define XFS_IOC_ZERO_RANGE	_IOW ('X', 57, struct xfs_flock64)
+
+/*
+ * ioctl commands that replace IRIX syssgi()'s
+ */
+#define XFS_IOC_FSGEOMETRY_V1	     _IOR ('X', 100, struct xfs_fsop_geom_v1)
+#define XFS_IOC_FSBULKSTAT	     _IOWR('X', 101, struct xfs_fsop_bulkreq)
+#define XFS_IOC_FSBULKSTAT_SINGLE    _IOWR('X', 102, struct xfs_fsop_bulkreq)
+#define XFS_IOC_FSINUMBERS	     _IOWR('X', 103, struct xfs_fsop_bulkreq)
+#define XFS_IOC_PATH_TO_FSHANDLE     _IOWR('X', 104, struct xfs_fsop_handlereq)
+#define XFS_IOC_PATH_TO_HANDLE	     _IOWR('X', 105, struct xfs_fsop_handlereq)
+#define XFS_IOC_FD_TO_HANDLE	     _IOWR('X', 106, struct xfs_fsop_handlereq)
+#define XFS_IOC_OPEN_BY_HANDLE	     _IOWR('X', 107, struct xfs_fsop_handlereq)
+#define XFS_IOC_READLINK_BY_HANDLE   _IOWR('X', 108, struct xfs_fsop_handlereq)
+#define XFS_IOC_SWAPEXT		     _IOWR('X', 109, struct xfs_swapext)
+#define XFS_IOC_FSGROWFSDATA	     _IOW ('X', 110, struct xfs_growfs_data)
+#define XFS_IOC_FSGROWFSLOG	     _IOW ('X', 111, struct xfs_growfs_log)
+#define XFS_IOC_FSGROWFSRT	     _IOW ('X', 112, struct xfs_growfs_rt)
+#define XFS_IOC_FSCOUNTS	     _IOR ('X', 113, struct xfs_fsop_counts)
+#define XFS_IOC_SET_RESBLKS	     _IOWR('X', 114, struct xfs_fsop_resblks)
+#define XFS_IOC_GET_RESBLKS	     _IOR ('X', 115, struct xfs_fsop_resblks)
+#define XFS_IOC_ERROR_INJECTION	     _IOW ('X', 116, struct xfs_error_injection)
+#define XFS_IOC_ERROR_CLEARALL	     _IOW ('X', 117, struct xfs_error_injection)
+/*	XFS_IOC_ATTRCTL_BY_HANDLE -- deprecated 118	 */
+/*	XFS_IOC_FREEZE		  -- FIFREEZE   119	 */
+/*	XFS_IOC_THAW		  -- FITHAW     120	 */
+#define XFS_IOC_FSSETDM_BY_HANDLE    _IOW ('X', 121, struct xfs_fsop_setdm_handlereq)
+#define XFS_IOC_ATTRLIST_BY_HANDLE   _IOW ('X', 122, struct xfs_fsop_attrlist_handlereq)
+#define XFS_IOC_ATTRMULTI_BY_HANDLE  _IOW ('X', 123, struct xfs_fsop_attrmulti_handlereq)
+#define XFS_IOC_FSGEOMETRY	     _IOR ('X', 124, struct xfs_fsop_geom)
+#define XFS_IOC_GOINGDOWN	     _IOR ('X', 125, __uint32_t)
+/*	XFS_IOC_GETFSUUID ---------- deprecated 140	 */
+
+
+#ifndef HAVE_BBMACROS
+/*
+ * Block I/O parameterization.	A basic block (BB) is the lowest size of
+ * filesystem allocation, and must equal 512.  Length units given to bio
+ * routines are in BB's.
+ */
+#define BBSHIFT		9
+#define BBSIZE		(1<<BBSHIFT)
+#define BBMASK		(BBSIZE-1)
+#define BTOBB(bytes)	(((uint64_t)(bytes) + BBSIZE - 1) >> BBSHIFT)
+#define BTOBBT(bytes)	((uint64_t)(bytes) >> BBSHIFT)
+#define BBTOB(bbs)	((bbs) << BBSHIFT)
+#endif
+
+#endif	/* XFS_FS_H_ */
diff --git a/extlinux/xfs_sb.h b/extlinux/xfs_sb.h
new file mode 100644
index 0000000..8f72d6a
--- /dev/null
+++ b/extlinux/xfs_sb.h
@@ -0,0 +1,476 @@
+/*
+ * Taken from Linux kernel tree (linux/fs/xfs)
+ *
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * Copyright (c) 2012 Paulo Alcantara <pcacjr at zytor.com>
+ *
+ * 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.
+ *
+ * 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.  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 the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#ifndef XFS_SB_H_
+#define	XFS_SB_H__
+
+#include <stddef.h>
+
+#include <sys/types.h>
+#include <uuid/uuid.h>
+
+/*
+ * Super block
+ * Fits into a sector-sized buffer at address 0 of each allocation group.
+ * Only the first of these is ever updated except during growfs.
+ */
+
+struct xfs_buf;
+struct xfs_mount;
+
+#define	XFS_SB_MAGIC		"XFSB"		/* 'XFSB' */
+#define	XFS_SB_VERSION_1	1		/* 5.3, 6.0.1, 6.1 */
+#define	XFS_SB_VERSION_2	2		/* 6.2 - attributes */
+#define	XFS_SB_VERSION_3	3		/* 6.2 - new inode version */
+#define	XFS_SB_VERSION_4	4		/* 6.2+ - bitmask version */
+#define	XFS_SB_VERSION_NUMBITS		0x000f
+#define	XFS_SB_VERSION_ALLFBITS		0xfff0
+#define	XFS_SB_VERSION_SASHFBITS	0xf000
+#define	XFS_SB_VERSION_REALFBITS	0x0ff0
+#define	XFS_SB_VERSION_ATTRBIT		0x0010
+#define	XFS_SB_VERSION_NLINKBIT		0x0020
+#define	XFS_SB_VERSION_QUOTABIT		0x0040
+#define	XFS_SB_VERSION_ALIGNBIT		0x0080
+#define	XFS_SB_VERSION_DALIGNBIT	0x0100
+#define	XFS_SB_VERSION_SHAREDBIT	0x0200
+#define XFS_SB_VERSION_LOGV2BIT		0x0400
+#define XFS_SB_VERSION_SECTORBIT	0x0800
+#define	XFS_SB_VERSION_EXTFLGBIT	0x1000
+#define	XFS_SB_VERSION_DIRV2BIT		0x2000
+#define	XFS_SB_VERSION_BORGBIT		0x4000	/* ASCII only case-insens. */
+#define	XFS_SB_VERSION_MOREBITSBIT	0x8000
+#define	XFS_SB_VERSION_OKSASHFBITS	\
+	(XFS_SB_VERSION_EXTFLGBIT | \
+	 XFS_SB_VERSION_DIRV2BIT | \
+	 XFS_SB_VERSION_BORGBIT)
+#define	XFS_SB_VERSION_OKREALFBITS	\
+	(XFS_SB_VERSION_ATTRBIT | \
+	 XFS_SB_VERSION_NLINKBIT | \
+	 XFS_SB_VERSION_QUOTABIT | \
+	 XFS_SB_VERSION_ALIGNBIT | \
+	 XFS_SB_VERSION_DALIGNBIT | \
+	 XFS_SB_VERSION_SHAREDBIT | \
+	 XFS_SB_VERSION_LOGV2BIT | \
+	 XFS_SB_VERSION_SECTORBIT | \
+	 XFS_SB_VERSION_MOREBITSBIT)
+#define	XFS_SB_VERSION_OKREALBITS	\
+	(XFS_SB_VERSION_NUMBITS | \
+	 XFS_SB_VERSION_OKREALFBITS | \
+	 XFS_SB_VERSION_OKSASHFBITS)
+
+/*
+ * There are two words to hold XFS "feature" bits: the original
+ * word, sb_versionnum, and sb_features2.  Whenever a bit is set in
+ * sb_features2, the feature bit XFS_SB_VERSION_MOREBITSBIT must be set.
+ *
+ * These defines represent bits in sb_features2.
+ */
+#define XFS_SB_VERSION2_REALFBITS	0x00ffffff	/* Mask: features */
+#define XFS_SB_VERSION2_RESERVED1BIT	0x00000001
+#define XFS_SB_VERSION2_LAZYSBCOUNTBIT	0x00000002	/* Superblk counters */
+#define XFS_SB_VERSION2_RESERVED4BIT	0x00000004
+#define XFS_SB_VERSION2_ATTR2BIT	0x00000008	/* Inline attr rework */
+#define XFS_SB_VERSION2_PARENTBIT	0x00000010	/* parent pointers */
+#define XFS_SB_VERSION2_PROJID32BIT	0x00000080	/* 32 bit project id */
+
+#define	XFS_SB_VERSION2_OKREALFBITS	\
+	(XFS_SB_VERSION2_LAZYSBCOUNTBIT	| \
+	 XFS_SB_VERSION2_ATTR2BIT	| \
+	 XFS_SB_VERSION2_PROJID32BIT)
+#define	XFS_SB_VERSION2_OKSASHFBITS	\
+	(0)
+#define XFS_SB_VERSION2_OKREALBITS	\
+	(XFS_SB_VERSION2_OKREALFBITS |	\
+	 XFS_SB_VERSION2_OKSASHFBITS )
+
+/*
+ * Superblock - in core version.  Must match the ondisk version below.
+ * Must be padded to 64 bit alignment.
+ */
+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_logsectlog;	/* log2 of the log sector size */
+	uint16_t	sb_logsectsize;	/* sector size for the log, bytes */
+	uint32_t	sb_logsunit;	/* stripe unit size for the log */
+	uint32_t	sb_features2;	/* additional feature bits */
+
+	/*
+	 * bad features2 field as a result of failing to pad the sb
+	 * structure to 64 bits. Some machines will be using this field
+	 * for features2 bits. Easiest just to mark it bad and not use
+	 * it for anything else.
+	 */
+	uint32_t	sb_bad_features2;
+
+	/* must be padded to 64 bit alignment */
+} xfs_sb_t;
+
+/*
+ * Sequence number values for the fields.
+ */
+typedef enum {
+	XFS_SBS_MAGICNUM, XFS_SBS_BLOCKSIZE, XFS_SBS_DBLOCKS, XFS_SBS_RBLOCKS,
+	XFS_SBS_REXTENTS, XFS_SBS_UUID, XFS_SBS_LOGSTART, XFS_SBS_ROOTINO,
+	XFS_SBS_RBMINO, XFS_SBS_RSUMINO, XFS_SBS_REXTSIZE, XFS_SBS_AGBLOCKS,
+	XFS_SBS_AGCOUNT, XFS_SBS_RBMBLOCKS, XFS_SBS_LOGBLOCKS,
+	XFS_SBS_VERSIONNUM, XFS_SBS_SECTSIZE, XFS_SBS_INODESIZE,
+	XFS_SBS_INOPBLOCK, XFS_SBS_FNAME, XFS_SBS_BLOCKLOG,
+	XFS_SBS_SECTLOG, XFS_SBS_INODELOG, XFS_SBS_INOPBLOG, XFS_SBS_AGBLKLOG,
+	XFS_SBS_REXTSLOG, XFS_SBS_INPROGRESS, XFS_SBS_IMAX_PCT, XFS_SBS_ICOUNT,
+	XFS_SBS_IFREE, XFS_SBS_FDBLOCKS, XFS_SBS_FREXTENTS, XFS_SBS_UQUOTINO,
+	XFS_SBS_GQUOTINO, XFS_SBS_QFLAGS, XFS_SBS_FLAGS, XFS_SBS_SHARED_VN,
+	XFS_SBS_INOALIGNMT, XFS_SBS_UNIT, XFS_SBS_WIDTH, XFS_SBS_DIRBLKLOG,
+	XFS_SBS_LOGSECTLOG, XFS_SBS_LOGSECTSIZE, XFS_SBS_LOGSUNIT,
+	XFS_SBS_FEATURES2, XFS_SBS_BAD_FEATURES2,
+	XFS_SBS_FIELDCOUNT
+} xfs_sb_field_t;
+
+/*
+ * Mask values, defined based on the xfs_sb_field_t values.
+ * Only define the ones we're using.
+ */
+#define	XFS_SB_MVAL(x)		(1LL << XFS_SBS_ ## x)
+#define	XFS_SB_UUID		XFS_SB_MVAL(UUID)
+#define	XFS_SB_FNAME		XFS_SB_MVAL(FNAME)
+#define	XFS_SB_ROOTINO		XFS_SB_MVAL(ROOTINO)
+#define	XFS_SB_RBMINO		XFS_SB_MVAL(RBMINO)
+#define	XFS_SB_RSUMINO		XFS_SB_MVAL(RSUMINO)
+#define	XFS_SB_VERSIONNUM	XFS_SB_MVAL(VERSIONNUM)
+#define XFS_SB_UQUOTINO		XFS_SB_MVAL(UQUOTINO)
+#define XFS_SB_GQUOTINO		XFS_SB_MVAL(GQUOTINO)
+#define XFS_SB_QFLAGS		XFS_SB_MVAL(QFLAGS)
+#define XFS_SB_SHARED_VN	XFS_SB_MVAL(SHARED_VN)
+#define XFS_SB_UNIT		XFS_SB_MVAL(UNIT)
+#define XFS_SB_WIDTH		XFS_SB_MVAL(WIDTH)
+#define XFS_SB_ICOUNT		XFS_SB_MVAL(ICOUNT)
+#define XFS_SB_IFREE		XFS_SB_MVAL(IFREE)
+#define XFS_SB_FDBLOCKS		XFS_SB_MVAL(FDBLOCKS)
+#define XFS_SB_FEATURES2	XFS_SB_MVAL(FEATURES2)
+#define XFS_SB_BAD_FEATURES2	XFS_SB_MVAL(BAD_FEATURES2)
+#define	XFS_SB_NUM_BITS		((int)XFS_SBS_FIELDCOUNT)
+#define	XFS_SB_ALL_BITS		((1LL << XFS_SB_NUM_BITS) - 1)
+#define	XFS_SB_MOD_BITS		\
+	(XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \
+	 XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \
+	 XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \
+	 XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2 | \
+	 XFS_SB_BAD_FEATURES2)
+
+
+/*
+ * Misc. Flags - warning - these will be cleared by xfs_repair unless
+ * a feature bit is set when the flag is used.
+ */
+#define XFS_SBF_NOFLAGS		0x00	/* no flags set */
+#define XFS_SBF_READONLY	0x01	/* only read-only mounts allowed */
+
+/*
+ * define max. shared version we can interoperate with
+ */
+#define XFS_SB_MAX_SHARED_VN	0
+
+#define	XFS_SB_VERSION_NUM(sbp)	((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS)
+
+static inline int xfs_sb_good_version(xfs_sb_t *sbp)
+{
+	/* We always support version 1-3 */
+	if (sbp->sb_versionnum >= XFS_SB_VERSION_1 &&
+	    sbp->sb_versionnum <= XFS_SB_VERSION_3)
+		return 1;
+
+	/* We support version 4 if all feature bits are supported */
+	if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) {
+		if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKREALBITS) ||
+		    ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
+		     (sbp->sb_features2 & ~XFS_SB_VERSION2_OKREALBITS)))
+			return 0;
+
+		if ((sbp->sb_versionnum & XFS_SB_VERSION_SHAREDBIT) &&
+		    sbp->sb_shared_vn > XFS_SB_MAX_SHARED_VN)
+			return 0;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * Detect a mismatched features2 field.  Older kernels read/wrote
+ * this into the wrong slot, so to be safe we keep them in sync.
+ */
+static inline int xfs_sb_has_mismatched_features2(xfs_sb_t *sbp)
+{
+	return (sbp->sb_bad_features2 != sbp->sb_features2);
+}
+
+static inline unsigned xfs_sb_version_tonew(unsigned v)
+{
+	if (v == XFS_SB_VERSION_1)
+		return XFS_SB_VERSION_4;
+
+	if (v == XFS_SB_VERSION_2)
+		return XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT;
+
+	return XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT |
+		XFS_SB_VERSION_NLINKBIT;
+}
+
+static inline unsigned xfs_sb_version_toold(unsigned v)
+{
+	if (v & (XFS_SB_VERSION_QUOTABIT | XFS_SB_VERSION_ALIGNBIT))
+		return 0;
+	if (v & XFS_SB_VERSION_NLINKBIT)
+		return XFS_SB_VERSION_3;
+	if (v & XFS_SB_VERSION_ATTRBIT)
+		return XFS_SB_VERSION_2;
+	return XFS_SB_VERSION_1;
+}
+
+static inline int xfs_sb_version_hasattr(xfs_sb_t *sbp)
+{
+	return sbp->sb_versionnum == XFS_SB_VERSION_2 ||
+		sbp->sb_versionnum == XFS_SB_VERSION_3 ||
+		(XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
+		 (sbp->sb_versionnum & XFS_SB_VERSION_ATTRBIT));
+}
+
+static inline void xfs_sb_version_addattr(xfs_sb_t *sbp)
+{
+	if (sbp->sb_versionnum == XFS_SB_VERSION_1)
+		sbp->sb_versionnum = XFS_SB_VERSION_2;
+	else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4)
+		sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT;
+	else
+		sbp->sb_versionnum = XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT;
+}
+
+static inline int xfs_sb_version_hasnlink(xfs_sb_t *sbp)
+{
+	return sbp->sb_versionnum == XFS_SB_VERSION_3 ||
+		 (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
+		  (sbp->sb_versionnum & XFS_SB_VERSION_NLINKBIT));
+}
+
+static inline void xfs_sb_version_addnlink(xfs_sb_t *sbp)
+{
+	if (sbp->sb_versionnum <= XFS_SB_VERSION_2)
+		sbp->sb_versionnum = XFS_SB_VERSION_3;
+	else
+		sbp->sb_versionnum |= XFS_SB_VERSION_NLINKBIT;
+}
+
+static inline int xfs_sb_version_hasquota(xfs_sb_t *sbp)
+{
+	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
+		(sbp->sb_versionnum & XFS_SB_VERSION_QUOTABIT);
+}
+
+static inline void xfs_sb_version_addquota(xfs_sb_t *sbp)
+{
+	if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4)
+		sbp->sb_versionnum |= XFS_SB_VERSION_QUOTABIT;
+	else
+		sbp->sb_versionnum = xfs_sb_version_tonew(sbp->sb_versionnum) |
+					XFS_SB_VERSION_QUOTABIT;
+}
+
+static inline int xfs_sb_version_hasalign(xfs_sb_t *sbp)
+{
+	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
+		(sbp->sb_versionnum & XFS_SB_VERSION_ALIGNBIT);
+}
+
+static inline int xfs_sb_version_hasdalign(xfs_sb_t *sbp)
+{
+	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
+		(sbp->sb_versionnum & XFS_SB_VERSION_DALIGNBIT);
+}
+
+static inline int xfs_sb_version_hasshared(xfs_sb_t *sbp)
+{
+	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
+		(sbp->sb_versionnum & XFS_SB_VERSION_SHAREDBIT);
+}
+
+static inline int xfs_sb_version_hasdirv2(xfs_sb_t *sbp)
+{
+	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
+		(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
+}
+
+static inline int xfs_sb_version_haslogv2(xfs_sb_t *sbp)
+{
+	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
+		(sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT);
+}
+
+static inline int xfs_sb_version_hasextflgbit(xfs_sb_t *sbp)
+{
+	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
+		(sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT);
+}
+
+static inline int xfs_sb_version_hassector(xfs_sb_t *sbp)
+{
+	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
+		(sbp->sb_versionnum & XFS_SB_VERSION_SECTORBIT);
+}
+
+static inline int xfs_sb_version_hasasciici(xfs_sb_t *sbp)
+{
+	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
+		(sbp->sb_versionnum & XFS_SB_VERSION_BORGBIT);
+}
+
+static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp)
+{
+	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
+		(sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT);
+}
+
+/*
+ * sb_features2 bit version macros.
+ *
+ * For example, for a bit defined as XFS_SB_VERSION2_FUNBIT, has a macro:
+ *
+ * SB_VERSION_HASFUNBIT(xfs_sb_t *sbp)
+ *	((xfs_sb_version_hasmorebits(sbp) &&
+ *	 ((sbp)->sb_features2 & XFS_SB_VERSION2_FUNBIT)
+ */
+
+static inline int xfs_sb_version_haslazysbcount(xfs_sb_t *sbp)
+{
+	return xfs_sb_version_hasmorebits(sbp) &&
+		(sbp->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT);
+}
+
+static inline int xfs_sb_version_hasattr2(xfs_sb_t *sbp)
+{
+	return xfs_sb_version_hasmorebits(sbp) &&
+		(sbp->sb_features2 & XFS_SB_VERSION2_ATTR2BIT);
+}
+
+static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp)
+{
+	sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
+	sbp->sb_features2 |= XFS_SB_VERSION2_ATTR2BIT;
+}
+
+static inline void xfs_sb_version_removeattr2(xfs_sb_t *sbp)
+{
+	sbp->sb_features2 &= ~XFS_SB_VERSION2_ATTR2BIT;
+	if (!sbp->sb_features2)
+		sbp->sb_versionnum &= ~XFS_SB_VERSION_MOREBITSBIT;
+}
+
+static inline int xfs_sb_version_hasprojid32bit(xfs_sb_t *sbp)
+{
+	return xfs_sb_version_hasmorebits(sbp) &&
+		(sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT);
+}
+
+/*
+ * end of superblock version macros
+ */
+
+#define XFS_SB_DADDR		((xfs_daddr_t)0) /* daddr in filesystem/ag */
+#define	XFS_SB_BLOCK(mp)	XFS_HDR_BLOCK(mp, XFS_SB_DADDR)
+#define XFS_BUF_TO_SBP(bp)	((xfs_dsb_t *)((bp)->b_addr))
+
+#define	XFS_HDR_BLOCK(mp,d)	((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d))
+#define	XFS_DADDR_TO_FSB(mp,d)	XFS_AGB_TO_FSB(mp, \
+			xfs_daddr_to_agno(mp,d), xfs_daddr_to_agbno(mp,d))
+#define	XFS_FSB_TO_DADDR(mp,fsbno)	XFS_AGB_TO_DADDR(mp, \
+			XFS_FSB_TO_AGNO(mp,fsbno), XFS_FSB_TO_AGBNO(mp,fsbno))
+
+/*
+ * File system sector to basic block conversions.
+ */
+#define XFS_FSS_TO_BB(mp,sec)	((sec) << (mp)->m_sectbb_log)
+
+/*
+ * File system block to basic block conversions.
+ */
+#define	XFS_FSB_TO_BB(mp,fsbno)	((fsbno) << (mp)->m_blkbb_log)
+#define	XFS_BB_TO_FSB(mp,bb)	\
+	(((bb) + (XFS_FSB_TO_BB(mp,1) - 1)) >> (mp)->m_blkbb_log)
+#define	XFS_BB_TO_FSBT(mp,bb)	((bb) >> (mp)->m_blkbb_log)
+
+/*
+ * File system block to byte conversions.
+ */
+#define XFS_FSB_TO_B(mp,fsbno)	((xfs_fsize_t)(fsbno) << (mp)->m_sb.sb_blocklog)
+#define XFS_B_TO_FSB(mp,b)	\
+	((((uint64_t)(b)) + (mp)->m_blockmask) >> (mp)->m_sb.sb_blocklog)
+#define XFS_B_TO_FSBT(mp,b)	(((uint64_t)(b)) >> (mp)->m_sb.sb_blocklog)
+#define XFS_B_FSB_OFFSET(mp,b)	((b) & (mp)->m_blockmask)
+
+#endif	/* XFS_SB_H_ */
diff --git a/extlinux/xfs_types.h b/extlinux/xfs_types.h
new file mode 100644
index 0000000..9280886
--- /dev/null
+++ b/extlinux/xfs_types.h
@@ -0,0 +1,135 @@
+/*
+ * Taken from Linux kernel tree (linux/fs/xfs)
+ *
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * Copyright (c) 2012 Paulo Alcantara <pcacjr at zytor.com>
+ *
+ * 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.
+ *
+ * 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.  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 the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#ifndef XFS_TYPES_H_
+#define	XFS_TYPES_H_
+
+#include <stddef.h>
+
+#include <sys/types.h>
+
+typedef enum { B_FALSE,B_TRUE }	boolean_t;
+typedef uint32_t		prid_t;		/* project ID */
+typedef uint32_t		inst_t;		/* an instruction */
+
+typedef int64_t			xfs_off_t;	/* <file offset> type */
+typedef unsigned long long	xfs_ino_t;	/* <inode> type */
+typedef int64_t			xfs_daddr_t;	/* <disk address> type */
+typedef char *			xfs_caddr_t;	/* <core address> type */
+typedef uint32_t			xfs_dev_t;
+typedef uint32_t			xfs_nlink_t;
+
+/* __psint_t is the same size as a pointer */
+typedef int32_t __psint_t;
+typedef uint32_t __psunsigned_t;
+
+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 uint64_t	xfs_ufsize_t;	/* unsigned bytes in a file */
+
+typedef	int32_t	xfs_suminfo_t;	/* type of bitmap summary info */
+typedef	int32_t	xfs_rtword_t;	/* word type for bitmap manipulations */
+
+typedef	int64_t	xfs_lsn_t;	/* log sequence number */
+typedef	int32_t	xfs_tid_t;	/* transaction identifier */
+
+typedef	uint32_t	xfs_dablk_t;	/* dir/attr block number (in file) */
+typedef	uint32_t	xfs_dahash_t;	/* dir/attr hash value */
+
+/*
+ * These types are 64 bits on disk but are either 32 or 64 bits in memory.
+ * 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_dfilblks_t;	/* number of blocks in a file */
+
+/*
+ * Memory based types are conditional.
+ */
+typedef	uint64_t	xfs_fsblock_t;	/* blockno in filesystem (agno|agbno) */
+typedef uint64_t	xfs_rfsblock_t;	/* blockno in filesystem (raw) */
+typedef uint64_t	xfs_rtblock_t;	/* extent (block) in realtime area */
+typedef	int64_t	xfs_srtblock_t;	/* signed version of xfs_rtblock_t */
+
+typedef uint64_t	xfs_fileoff_t;	/* block number in a file */
+typedef int64_t	xfs_sfiloff_t;	/* signed block number in a file */
+typedef uint64_t	xfs_filblks_t;	/* number of blocks in a file */
+
+/*
+ * Null values for the types.
+ */
+#define	NULLDFSBNO	((xfs_dfsbno_t)-1)
+#define	NULLDRFSBNO	((xfs_drfsbno_t)-1)
+#define	NULLDRTBNO	((xfs_drtbno_t)-1)
+#define	NULLDFILOFF	((xfs_dfiloff_t)-1)
+
+#define	NULLFSBLOCK	((xfs_fsblock_t)-1)
+#define	NULLRFSBLOCK	((xfs_rfsblock_t)-1)
+#define	NULLRTBLOCK	((xfs_rtblock_t)-1)
+#define	NULLFILEOFF	((xfs_fileoff_t)-1)
+
+#define	NULLAGBLOCK	((xfs_agblock_t)-1)
+#define	NULLAGNUMBER	((xfs_agnumber_t)-1)
+#define	NULLEXTNUM	((xfs_extnum_t)-1)
+
+#define NULLCOMMITLSN	((xfs_lsn_t)-1)
+
+/*
+ * Max values for extlen, extnum, aextnum.
+ */
+#define	MAXEXTLEN	((xfs_extlen_t)0x001fffff)	/* 21 bits */
+#define	MAXEXTNUM	((xfs_extnum_t)0x7fffffff)	/* signed int */
+#define	MAXAEXTNUM	((xfs_aextnum_t)0x7fff)		/* signed short */
+
+/*
+ * Min numbers of data/attr fork btree root pointers.
+ */
+#define MINDBTPTRS	3
+#define MINABTPTRS	2
+
+/*
+ * MAXNAMELEN is the length (including the terminating null) of
+ * the longest permissible file (component) name.
+ */
+#define MAXNAMELEN	256
+
+typedef enum {
+	XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi
+} xfs_lookup_t;
+
+typedef enum {
+	XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_BMAPi, XFS_BTNUM_INOi,
+	XFS_BTNUM_MAX
+} xfs_btnum_t;
+
+struct xfs_name {
+	const unsigned char	*name;
+	int			len;
+};
+
+#endif	/* XFS_TYPES_H_ */
diff --git a/libinstaller/syslxfs.h b/libinstaller/syslxfs.h
index 7a23146..4d8f3b2 100644
--- a/libinstaller/syslxfs.h
+++ b/libinstaller/syslxfs.h
@@ -1,5 +1,5 @@
 /*
- *   Copyright 2011 Paulo Alcantara <pcacjr at gmail.com>
+ *   Copyright 2011-2012 Paulo Alcantara <pcacjr at zytor.com>
  *
  *   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
@@ -12,13 +12,14 @@
 #ifndef _SYSLXFS_H_
 #define _SYSLXFS_H_
 
-/* Global fs_type for handling fat, ntfs, ext2/3/4 and btrfs */
+/* Global fs_type for handling fat, ntfs, ext2/3/4, btrfs and xfs */
 enum filesystem {
     NONE,
     EXT2,
     BTRFS,
     VFAT,
     NTFS,
+    XFS,
 };
 
 extern int fs_type;


More information about the Syslinux-commits mailing list