Index: bootcd/isolinux/syslinux-6.03/extlinux/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,67 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
+##
+##   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, Inc., 53 Temple Place Ste 330,
+##   Boston MA 02111-1307, USA; either version 2 of the License, or
+##   (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+##
+## Linux vfat, ntfs, ext2/ext3/ext4 and btrfs installer
+##
+
+include $(MAKEDIR)/syslinux.mk
+
+OPTFLAGS = -g -Os
+INCLUDES = -I$(SRC) -I$(objdir) -I$(SRC)/../libinstaller
+CFLAGS	 = $(GCCWARN) -Wno-sign-compare -D_FILE_OFFSET_BITS=64 \
+	   $(OPTFLAGS) $(INCLUDES)
+LDFLAGS	 = 
+
+SRCS     = main.c \
+	   mountinfo.c \
+	   ../libinstaller/syslxmod.c \
+	   ../libinstaller/syslxopt.c \
+	   ../libinstaller/syslxcom.c \
+	   ../libinstaller/setadv.c \
+	   ../libinstaller/advio.c \
+	   ../libinstaller/bootsect_bin.c \
+	   ../libinstaller/ldlinuxc32_bin.c \
+	   ../libinstaller/ldlinux_bin.c
+OBJS	 = $(patsubst %.c,%.o,$(notdir $(SRCS)))
+
+.SUFFIXES: .c .o .i .s .S
+
+VPATH = $(SRC):$(SRC)/../libinstaller:$(OBJ)/../libinstaller
+
+all: installer
+
+tidy dist:
+	-rm -f *.o *.i *.s *.a .*.d *.tmp
+
+clean: tidy
+	-rm -f extlinux
+
+spotless: clean
+	-rm -f *~
+
+installer: extlinux
+
+extlinux: $(OBJS)
+	$(CC) $(LDFLAGS) -o $@ $^
+
+strip:
+	$(STRIP) extlinux
+
+%.o: %.c
+	$(CC) $(UMAKEDEPS) $(CFLAGS) -c -o $@ $<
+%.i: %.c
+	$(CC) $(UMAKEDEPS) $(CFLAGS) -E -o $@ $<
+%.s: %.c
+	$(CC) $(UMAKEDEPS) $(CFLAGS) -S -o $@ $<
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/extlinux/btrfs.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/btrfs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/btrfs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,191 @@
+#ifndef _BTRFS_H_
+#define _BTRFS_H_
+
+#include <asm/types.h>
+#include <linux/ioctl.h>
+
+#define BTRFS_SUPER_MAGIC 0x9123683E
+#define BTRFS_SUPER_INFO_OFFSET (64 * 1024)
+#define BTRFS_SUPER_INFO_SIZE 4096
+#define BTRFS_MAGIC "_BHRfS_M"
+#define BTRFS_MAGIC_L 8
+#define BTRFS_CSUM_SIZE 32
+#define BTRFS_FSID_SIZE 16
+#define BTRFS_UUID_SIZE 16
+
+/* Fixed areas reserved for the boot loader */
+#define BTRFS_BOOT_AREA_A_OFFSET	0
+#define BTRFS_BOOT_AREA_A_SIZE		BTRFS_SUPER_INFO_OFFSET
+#define BTRFS_BOOT_AREA_B_OFFSET	(256 * 1024)
+#define BTRFS_BOOT_AREA_B_SIZE		((1024-256) * 1024)
+
+typedef __u64 u64;
+typedef __u32 u32;
+typedef __u16 u16;
+typedef __u8 u8;
+typedef u64 __le64;
+typedef u16 __le16;
+
+#define BTRFS_ROOT_BACKREF_KEY  144
+#define BTRFS_ROOT_TREE_DIR_OBJECTID 6ULL
+#define BTRFS_DIR_ITEM_KEY      84
+
+/*
+ *  * this is used for both forward and backward root refs
+ *   */
+struct btrfs_root_ref {
+        __le64 dirid;
+        __le64 sequence;
+        __le16 name_len;
+} __attribute__ ((__packed__));
+
+struct btrfs_disk_key {
+        __le64 objectid;
+        u8 type;
+        __le64 offset;
+} __attribute__ ((__packed__));
+
+struct btrfs_dir_item {
+        struct btrfs_disk_key location;
+        __le64 transid;
+        __le16 data_len;
+        __le16 name_len;
+        u8 type;
+} __attribute__ ((__packed__));
+
+struct btrfs_super_block {
+        uint8_t csum[32];
+        uint8_t fsid[16];
+        uint64_t bytenr;
+        uint64_t flags;
+        uint8_t magic[8];
+        uint64_t generation;
+        uint64_t root;
+        uint64_t chunk_root;
+        uint64_t log_root;
+        uint64_t log_root_transid;
+        uint64_t total_bytes;
+        uint64_t bytes_used;
+        uint64_t root_dir_objectid;
+        uint64_t num_devices;
+        uint32_t sectorsize;
+        uint32_t nodesize;
+        uint32_t leafsize;
+        uint32_t stripesize;
+        uint32_t sys_chunk_array_size;
+        uint64_t chunk_root_generation;
+        uint64_t compat_flags;
+        uint64_t compat_ro_flags;
+        uint64_t incompat_flags;
+        uint16_t csum_type;
+        uint8_t root_level;
+        uint8_t chunk_root_level;
+        uint8_t log_root_level;
+        struct btrfs_dev_item {
+                uint64_t devid;
+                uint64_t total_bytes;
+                uint64_t bytes_used;
+                uint32_t io_align;
+                uint32_t io_width;
+                uint32_t sector_size;
+                uint64_t type;
+                uint64_t generation;
+                uint64_t start_offset;
+                uint32_t dev_group;
+                uint8_t seek_speed;
+                uint8_t bandwidth;
+                uint8_t uuid[16];
+                uint8_t fsid[16];
+        } __attribute__ ((__packed__)) dev_item;
+        uint8_t label[256];
+} __attribute__ ((__packed__));
+
+#define BTRFS_IOCTL_MAGIC 0x94
+#define BTRFS_VOL_NAME_MAX 255
+#define BTRFS_PATH_NAME_MAX 4087
+
+struct btrfs_ioctl_vol_args {
+	__s64 fd;
+	char name[BTRFS_PATH_NAME_MAX + 1];
+};
+
+struct btrfs_ioctl_search_key {
+	/* which root are we searching.  0 is the tree of tree roots */
+	__u64 tree_id;
+
+	/* keys returned will be >= min and <= max */
+	__u64 min_objectid;
+	__u64 max_objectid;
+
+	/* keys returned will be >= min and <= max */
+	__u64 min_offset;
+	__u64 max_offset;
+
+	/* max and min transids to search for */
+	__u64 min_transid;
+	__u64 max_transid;
+
+	/* keys returned will be >= min and <= max */
+	__u32 min_type;
+	__u32 max_type;
+
+	/*
+	 * how many items did userland ask for, and how many are we
+	 * returning
+	 */
+	__u32 nr_items;
+
+	/* align to 64 bits */
+	__u32 unused;
+
+	/* some extra for later */
+	__u64 unused1;
+	__u64 unused2;
+	__u64 unused3;
+	__u64 unused4;
+};
+
+struct btrfs_ioctl_search_header {
+	__u64 transid;
+	__u64 objectid;
+	__u64 offset;
+	__u32 type;
+	__u32 len;
+} __attribute__((may_alias));
+
+#define BTRFS_DEVICE_PATH_NAME_MAX 1024
+struct btrfs_ioctl_dev_info_args {
+	__u64 devid;				/* in/out */
+	__u8 uuid[BTRFS_UUID_SIZE];		/* in/out */
+	__u64 bytes_used;			/* out */
+	__u64 total_bytes;			/* out */
+	__u64 unused[379];			/* pad to 4k */
+	__u8 path[BTRFS_DEVICE_PATH_NAME_MAX];	/* out */
+};
+
+struct btrfs_ioctl_fs_info_args {
+	__u64 max_id;				/* out */
+	__u64 num_devices;			/* out */
+	__u8 fsid[BTRFS_FSID_SIZE];		/* out */
+	__u64 reserved[124];			/* pad to 1k */
+};
+
+#define BTRFS_SEARCH_ARGS_BUFSIZE (4096 - sizeof(struct btrfs_ioctl_search_key))
+/*
+ * the buf is an array of search headers where
+ * each header is followed by the actual item
+ * the type field is expanded to 32 bits for alignment
+ */
+struct btrfs_ioctl_search_args {
+	struct btrfs_ioctl_search_key key;
+	char buf[BTRFS_SEARCH_ARGS_BUFSIZE];
+};
+
+#define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, \
+                                   struct btrfs_ioctl_search_args)
+#define BTRFS_IOC_DEV_INFO _IOWR(BTRFS_IOCTL_MAGIC, 30, \
+				 struct btrfs_ioctl_dev_info_args)
+#define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, \
+			       struct btrfs_ioctl_fs_info_args)
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/extlinux/fat.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/fat.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/fat.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,7 @@
+#ifndef _H_FAT_
+#define _H_FAT_
+
+#define MSDOS_SUPER_MAGIC       0x4d44          /* MD */
+/* The rest is defined in syslxint.h */
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/extlinux/main.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/main.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/main.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1548 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1998-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2014 Intel Corporation; author: H. Peter Anvin
+ *
+ *   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, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * extlinux.c
+ *
+ * Install the syslinux boot block on an fat, ntfs, ext2/3/4, btrfs, xfs,
+ * and ufs1/2 filesystem.
+ */
+
+#define  _GNU_SOURCE		/* Enable everything */
+#include <inttypes.h>
+/* This is needed to deal with the kernel headers imported into glibc 3.3.3. */
+#include <alloca.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <dirent.h>
+#ifndef __KLIBC__
+#include <mntent.h>
+#endif
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <sysexits.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/vfs.h>
+
+#include "linuxioctl.h"
+
+#include "btrfs.h"
+#include "fat.h"
+#include "ntfs.h"
+#include "xfs.h"
+#include "xfs_types.h"
+#include "xfs_sb.h"
+#include "ufs.h"
+#include "ufs_fs.h"
+#include "misc.h"
+#include "version.h"
+#include "syslxint.h"
+#include "syslxcom.h" /* common functions shared with extlinux and syslinux */
+#include "syslxfs.h"
+#include "setadv.h"
+#include "syslxopt.h" /* unified options */
+#include "mountinfo.h"
+
+#ifdef DEBUG
+# define dprintf printf
+#else
+# define dprintf(...) ((void)0)
+#endif
+
+#ifndef EXT2_SUPER_OFFSET
+#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_SHIFT)
+#define XFS_SUPPORTED_BLOCKSIZE 4096 /* 4 KiB filesystem block size */
+
+/*
+ * btrfs has two discontiguous areas reserved for the boot loader.
+ * Use the first one (Boot Area A) for the boot sector and the ADV,
+ * and the second one for "ldlinux.sys".
+ */
+#define BTRFS_EXTLINUX_OFFSET	BTRFS_BOOT_AREA_B_OFFSET
+#define BTRFS_EXTLINUX_SIZE	BTRFS_BOOT_AREA_B_SIZE
+#define BTRFS_SUBVOL_MAX 256	/* By btrfs specification */
+static char subvol[BTRFS_SUBVOL_MAX];
+
+#define BTRFS_ADV_OFFSET (BTRFS_BOOT_AREA_A_OFFSET + BTRFS_BOOT_AREA_A_SIZE \
+			  - 2*ADV_SIZE)
+
+/*
+ * Get the size of a block device
+ */
+static uint64_t get_size(int devfd)
+{
+    uint64_t bytes;
+    uint32_t sects;
+    struct stat st;
+
+#ifdef BLKGETSIZE64
+    if (!ioctl(devfd, BLKGETSIZE64, &bytes))
+	return bytes;
+#endif
+    if (!ioctl(devfd, BLKGETSIZE, &sects))
+	return (uint64_t) sects << 9;
+    else if (!fstat(devfd, &st) && st.st_size)
+	return st.st_size;
+    else
+	return 0;
+}
+
+/*
+ * Get device geometry and partition offset
+ */
+struct geometry_table {
+    uint64_t bytes;
+    struct hd_geometry g;
+};
+
+static int sysfs_get_offset(int devfd, unsigned long *start)
+{
+    struct stat st;
+    char sysfs_name[128];
+    FILE *f;
+    int rv;
+
+    if (fstat(devfd, &st))
+	return -1;
+
+    if ((size_t)snprintf(sysfs_name, sizeof sysfs_name,
+			 "/sys/dev/block/%u:%u/start",
+			 major(st.st_rdev), minor(st.st_rdev))
+	>= sizeof sysfs_name)
+	return -1;
+
+    f = fopen(sysfs_name, "r");
+    if (!f)
+	return -1;
+
+    rv = fscanf(f, "%lu", start);
+    fclose(f);
+
+    return (rv == 1) ? 0 : -1;
+}
+
+/* Standard floppy disk geometries, plus LS-120.  Zipdisk geometry
+   (x/64/32) is the final fallback.  I don't know what LS-240 has
+   as its geometry, since I don't have one and don't know anyone that does,
+   and Google wasn't helpful... */
+static const struct geometry_table standard_geometries[] = {
+    {360 * 1024, {2, 9, 40, 0}},
+    {720 * 1024, {2, 9, 80, 0}},
+    {1200 * 1024, {2, 15, 80, 0}},
+    {1440 * 1024, {2, 18, 80, 0}},
+    {1680 * 1024, {2, 21, 80, 0}},
+    {1722 * 1024, {2, 21, 80, 0}},
+    {2880 * 1024, {2, 36, 80, 0}},
+    {3840 * 1024, {2, 48, 80, 0}},
+    {123264 * 1024, {8, 32, 963, 0}},	/* LS120 */
+    {0, {0, 0, 0, 0}}
+};
+
+int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo)
+{
+    struct floppy_struct fd_str;
+    struct loop_info li;
+    struct loop_info64 li64;
+    const struct geometry_table *gp;
+    int rv = 0;
+
+    memset(geo, 0, sizeof *geo);
+
+    if (!ioctl(devfd, HDIO_GETGEO, geo)) {
+	goto ok;
+    } else if (!ioctl(devfd, FDGETPRM, &fd_str)) {
+	geo->heads = fd_str.head;
+	geo->sectors = fd_str.sect;
+	geo->cylinders = fd_str.track;
+	geo->start = 0;
+	goto ok;
+    }
+
+    /* Didn't work.  Let's see if this is one of the standard geometries */
+    for (gp = standard_geometries; gp->bytes; gp++) {
+	if (gp->bytes == totalbytes) {
+	    memcpy(geo, &gp->g, sizeof *geo);
+	    goto ok;
+	}
+    }
+
+    /* Didn't work either... assign a geometry of 64 heads, 32 sectors; this is
+       what zipdisks use, so this would help if someone has a USB key that
+       they're booting in USB-ZIP mode. */
+
+    geo->heads = opt.heads ? : 64;
+    geo->sectors = opt.sectors ? : 32;
+    geo->cylinders = totalbytes / (geo->heads * geo->sectors << SECTOR_SHIFT);
+    geo->start = 0;
+
+    if (!opt.sectors && !opt.heads) {
+	fprintf(stderr,
+		"Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n"
+		"         (on hard disks, this is usually harmless.)\n",
+		geo->heads, geo->sectors);
+	rv = 1;			/* Suboptimal result */
+    }
+
+ok:
+    /* If this is a loopback device, try to set the start */
+    if (!ioctl(devfd, LOOP_GET_STATUS64, &li64))
+	geo->start = li64.lo_offset >> SECTOR_SHIFT;
+    else if (!ioctl(devfd, LOOP_GET_STATUS, &li))
+	geo->start = (unsigned int)li.lo_offset >> SECTOR_SHIFT;
+    else if (!sysfs_get_offset(devfd, &geo->start)) {
+	/* OK */
+    }
+
+    return rv;
+}
+
+/*
+ * Query the device geometry and put it into the boot sector.
+ * Map the file and put the map in the boot sector and file.
+ * Stick the "current directory" inode number into the file.
+ *
+ * Returns the number of modified bytes in the boot file.
+ */
+static int patch_file_and_bootblock(int fd, const char *dir, int devfd)
+{
+    struct stat dirst, xdst;
+    struct hd_geometry geo;
+    sector_t *sectp;
+    uint64_t totalbytes, totalsectors;
+    int nsect;
+    struct fat_boot_sector *sbs;
+    char *dirpath, *subpath, *xdirpath;
+    int rv;
+
+    dirpath = realpath(dir, NULL);
+    if (!dirpath || stat(dir, &dirst)) {
+	perror("accessing install directory");
+	exit(255);		/* This should never happen */
+    }
+
+    if (lstat(dirpath, &xdst) ||
+	dirst.st_ino != xdst.st_ino ||
+	dirst.st_dev != xdst.st_dev) {
+	perror("realpath returned nonsense");
+	exit(255);
+    }
+
+    subpath = strchr(dirpath, '\0');
+    for (;;) {
+	if (*subpath == '/') {
+	    if (subpath > dirpath) {
+		*subpath = '\0';
+		xdirpath = dirpath;
+	    } else {
+		xdirpath = "/";
+	    }
+	    if (lstat(xdirpath, &xdst) || dirst.st_dev != xdst.st_dev) {
+		subpath = strchr(subpath+1, '/');
+		if (!subpath)
+		    subpath = "/"; /* It's the root of the filesystem */
+		break;
+	    }
+	    *subpath = '/';
+	}
+
+	if (subpath == dirpath)
+	    break;
+
+	subpath--;
+    }
+
+    /* Now subpath should contain the path relative to the fs base */
+    dprintf("subpath = %s\n", subpath);
+
+    totalbytes = get_size(devfd);
+    get_geometry(devfd, totalbytes, &geo);
+
+    if (opt.heads)
+	geo.heads = opt.heads;
+    if (opt.sectors)
+	geo.sectors = opt.sectors;
+
+    /* Patch this into a fake FAT superblock.  This isn't because
+       FAT is a good format in any way, it's because it lets the
+       early bootstrap share code with the FAT version. */
+    dprintf("heads = %u, sect = %u\n", geo.heads, geo.sectors);
+
+    sbs = (struct fat_boot_sector *)syslinux_bootsect;
+
+    totalsectors = totalbytes >> SECTOR_SHIFT;
+    if (totalsectors >= 65536) {
+	set_16(&sbs->bsSectors, 0);
+    } else {
+	set_16(&sbs->bsSectors, totalsectors);
+    }
+    set_32(&sbs->bsHugeSectors, totalsectors);
+
+    set_16(&sbs->bsBytesPerSec, SECTOR_SIZE);
+    set_16(&sbs->bsSecPerTrack, geo.sectors);
+    set_16(&sbs->bsHeads, geo.heads);
+    set_32(&sbs->bsHiddenSecs, geo.start);
+
+    /* Construct the boot file map */
+
+    dprintf("directory inode = %lu\n", (unsigned long)dirst.st_ino);
+    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 ||
+	fs_type == XFS || fs_type == UFS1 || fs_type == UFS2) {
+	if (sectmap(fd, sectp, nsect)) {
+		perror("bmap");
+		exit(1);
+	}
+    } else if (fs_type == BTRFS) {
+	int i;
+	sector_t *sp = sectp;
+
+	for (i = 0; i < nsect - 2; i++)
+	    *sp++ = BTRFS_EXTLINUX_OFFSET/SECTOR_SIZE + i;
+	for (i = 0; i < 2; i++)
+	    *sp++ = BTRFS_ADV_OFFSET/SECTOR_SIZE + i;
+    }
+
+    /* Create the modified image in memory */
+    rv = syslinux_patch(sectp, nsect, opt.stupid_mode,
+			opt.raid_mode, subpath, subvol);
+
+    free(dirpath);
+    return rv;
+}
+
+/*
+ * Install the boot block on the specified device.
+ * Must be run AFTER install_file()!
+ */
+int install_bootblock(int fd, const char *device)
+{
+    struct ext2_super_block sb;
+    struct btrfs_super_block sb2;
+    struct fat_boot_sector sb3;
+    struct ntfs_boot_sector sb4;
+    xfs_sb_t sb5;
+    struct ufs_super_block sb6;
+    bool ok = false;
+
+    if (fs_type == EXT2) {
+	if (xpread(fd, &sb, sizeof sb, EXT2_SUPER_OFFSET) != sizeof sb) {
+		perror("reading superblock");
+		return 1;
+	}
+
+	if (sb.s_magic == EXT2_SUPER_MAGIC)
+		ok = true;
+    } else if (fs_type == BTRFS) {
+	if (xpread(fd, &sb2, sizeof sb2, BTRFS_SUPER_INFO_OFFSET)
+			!= sizeof sb2) {
+		perror("reading superblock");
+		return 1;
+	}
+	if (!memcmp(sb2.magic, BTRFS_MAGIC, BTRFS_MAGIC_L))
+		ok = true;
+    } else if (fs_type == VFAT) {
+	if (xpread(fd, &sb3, sizeof sb3, 0) != sizeof sb3) {
+		perror("reading fat superblock");
+		return 1;
+	}
+
+	if (fat_check_sb_fields(&sb3))
+		ok = true;
+    } else if (fs_type == NTFS) {
+        if (xpread(fd, &sb4, sizeof(sb4), 0) != sizeof(sb4)) {
+            perror("reading ntfs superblock");
+            return 1;
+        }
+
+        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) {
+	    if (be32_to_cpu(sb5.sb_blocksize) != XFS_SUPPORTED_BLOCKSIZE) {
+		fprintf(stderr,
+			"You need to have 4 KiB filesystem block size for "
+			" being able to install Syslinux in your XFS "
+			"partition (because there is no enough space in MBR to "
+			"determine where Syslinux bootsector can be installed "
+			"regardless the filesystem block size)\n");
+		return 1;
+	    }
+
+	    ok = true;
+	}
+    } else if (fs_type == UFS1 || fs_type == UFS2) {
+	uint32_t sblock_off = (fs_type == UFS1) ?
+	    SBLOCK_UFS1 : SBLOCK_UFS2;
+	uint32_t ufs_smagic = (fs_type == UFS1) ?
+	    UFS1_SUPER_MAGIC : UFS2_SUPER_MAGIC;
+
+	if (xpread(fd, &sb6, sizeof sb6, sblock_off) != sizeof sb6) {
+		perror("reading superblock");
+		return 1;
+	}
+
+	if (sb6.fs_magic == ufs_smagic)
+		ok = true;
+    }
+
+    if (!ok) {
+	fprintf(stderr,
+		"no fat, ntfs, ext2/3/4, btrfs, xfs "
+		"or ufs1/2 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 ||
+	    xpwrite(fd, &sbs->FAT_bsCode, FAT_bsCodeLen,
+		    offsetof(struct fat_boot_sector, FAT_bsCode)) != FAT_bsCodeLen) {
+	    perror("writing fat bootblock");
+	    return 1;
+	}
+    } else if (fs_type == NTFS) {
+        struct ntfs_boot_sector *sbs =
+                (struct ntfs_boot_sector *)syslinux_bootsect;
+        if (xpwrite(fd, &sbs->NTFS_bsHead,
+                    NTFS_bsHeadLen, 0) != NTFS_bsHeadLen ||
+                    xpwrite(fd, &sbs->NTFS_bsCode, NTFS_bsCodeLen,
+                    offsetof(struct ntfs_boot_sector,
+                    NTFS_bsCode)) != NTFS_bsCodeLen) {
+            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) {
+	    perror("writing bootblock");
+	    return 1;
+	}
+    }
+
+    return 0;
+}
+
+static int rewrite_boot_image(int devfd, const char *path, const char *filename)
+{
+    int fd;
+    int ret;
+    int modbytes;
+
+    /* 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, (const char _force *)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;
+    }
+
+    /* 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, (const char _force *)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, *c32file;
+    int fd = -1, dirfd = -1;
+    int r1, r2, r3;
+
+    r1 = asprintf(&file, "%s%sldlinux.sys",
+		  path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/");
+    r2 = asprintf(&oldfile, "%s%sextlinux.sys",
+		  path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/");
+    r3 = asprintf(&c32file, "%s%sldlinux.c32",
+		  path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/");
+    if (r1 < 0 || !file || r2 < 0 || !oldfile || r3 < 0 || !c32file) {
+	perror(program);
+	return 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, path, 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);
+
+    /* Look if we have the old filename */
+    fd = open(oldfile, O_RDONLY);
+    if (fd >= 0) {
+	clear_attributes(fd);
+	close(fd);
+	unlink(oldfile);
+    }
+
+    fd = open(c32file, O_WRONLY | O_TRUNC | O_CREAT | O_SYNC,
+	      S_IRUSR | S_IRGRP | S_IROTH);
+    if (fd < 0) {
+	perror(c32file);
+	goto bail;
+    }
+
+    r3 = xpwrite(fd, (const char _force *)syslinux_ldlinuxc32,
+		 syslinux_ldlinuxc32_len, 0);
+    if (r3 != syslinux_ldlinuxc32_len) {
+	fprintf(stderr, "%s: write failure on %s\n", program, c32file);
+	goto bail;
+    }
+
+    free(file);
+    free(oldfile);
+    free(c32file);
+    return 0;
+
+bail:
+    if (dirfd >= 0)
+	close(dirfd);
+    if (fd >= 0)
+	close(fd);
+
+    free(file);
+    free(oldfile);
+    free(c32file);
+    return 1;
+}
+
+/* btrfs has to install the ldlinux.sys in the first 64K blank area, which
+   is not managered by btrfs tree, so actually this is not installed as files.
+   since the cow feature of btrfs will move the ldlinux.sys every where */
+int btrfs_install_file(const char *path, int devfd, struct stat *rst)
+{
+    char *file;
+    int fd, rv;
+
+    patch_file_and_bootblock(-1, path, devfd);
+    if (xpwrite(devfd, (const char _force *)boot_image,
+		boot_image_len, BTRFS_EXTLINUX_OFFSET)
+		!= boot_image_len) {
+	perror("writing bootblock");
+	return 1;
+    }
+    dprintf("write boot_image to 0x%x\n", BTRFS_EXTLINUX_OFFSET);
+    if (xpwrite(devfd, syslinux_adv, 2 * ADV_SIZE, BTRFS_ADV_OFFSET)
+	!= 2 * ADV_SIZE) {
+	perror("writing adv");
+	return 1;
+    }
+    dprintf("write adv to 0x%x\n", BTRFS_ADV_OFFSET);
+    if (stat(path, rst)) {
+	perror(path);
+	return 1;
+    }
+
+    /*
+     * Note that we *can* install ldinux.c32 as a regular file because
+     * it doesn't need to be within the first 64K. The Syslinux core
+     * has enough smarts to search the btrfs dirs and find this file.
+     */
+    rv = asprintf(&file, "%s%sldlinux.c32",
+		  path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/");
+    if (rv < 0 || !file) {
+	perror(program);
+	return 1;
+    }
+
+    fd = open(file, O_WRONLY | O_TRUNC | O_CREAT | O_SYNC,
+	      S_IRUSR | S_IRGRP | S_IROTH);
+    if (fd < 0) {
+	perror(file);
+	free(file);
+	return 1;
+    }
+
+    rv = xpwrite(fd, (const char _force *)syslinux_ldlinuxc32,
+		 syslinux_ldlinuxc32_len, 0);
+    if (rv != (int)syslinux_ldlinuxc32_len) {
+	fprintf(stderr, "%s: write failure on %s\n", program, file);
+	rv = 1;
+    } else
+	rv = 0;
+
+    close(fd);
+    free(file);
+    return rv;
+}
+
+/*
+ * 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 + 1];
+    static char c32file[PATH_MAX + 1];
+    int dirfd = -1;
+    int fd = -1;
+    int retval;
+
+    snprintf(file, PATH_MAX + 1, "%s%sldlinux.sys", path,
+	     path[0] && path[strlen(path) - 1] == '/' ? "" : "/");
+    snprintf(c32file, PATH_MAX + 1, "%s%sldlinux.c32", 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, path, 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);
+
+    dirfd = -1;
+    fd = -1;
+
+    fd = open(c32file, O_WRONLY | O_TRUNC | O_CREAT | O_SYNC,
+	      S_IRUSR | S_IRGRP | S_IROTH);
+    if (fd < 0) {
+	perror(c32file);
+	goto bail;
+    }
+
+    retval = xpwrite(fd, (const char _force *)syslinux_ldlinuxc32,
+		     syslinux_ldlinuxc32_len, 0);
+    if (retval != (int)syslinux_ldlinuxc32_len) {
+	fprintf(stderr, "%s: write failure on %s\n", program, file);
+	goto bail;
+    }
+
+    close(fd);
+
+    sync();
+
+    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
+ *     * 1-> path exists and it is  a subvolume
+ *      * -1 -> path is unaccessible
+ *       */
+static int test_issubvolume(char *path)
+{
+
+        struct stat     st;
+        int             res;
+
+        res = stat(path, &st);
+        if(res < 0 )
+                return -1;
+
+        return (st.st_ino == 256) && S_ISDIR(st.st_mode);
+
+}
+
+/*
+ * Get the default subvolume of a btrfs filesystem
+ *   rootdir: btrfs root dir
+ *   subvol:  this function will save the default subvolume name here
+ */
+static char * get_default_subvol(char * rootdir, char * subvol)
+{
+    struct btrfs_ioctl_search_args args;
+    struct btrfs_ioctl_search_key *sk = &args.key;
+    struct btrfs_ioctl_search_header *sh;
+    int ret, i;
+    int fd;
+    struct btrfs_root_ref *ref;
+    struct btrfs_dir_item *dir_item;
+    unsigned long off = 0;
+    int name_len;
+    char *name;
+    char dirname[4096];
+    u64 defaultsubvolid = 0;
+
+    ret = test_issubvolume(rootdir);
+    if (ret == 1) {
+        fd = open(rootdir, O_RDONLY);
+        if (fd < 0) {
+            fprintf(stderr, "ERROR: failed to open %s\n", rootdir);
+        }
+        ret = fd;
+    }
+    if (ret <= 0) {
+        subvol[0] = '\0';
+        return NULL;
+    }
+
+    memset(&args, 0, sizeof(args));
+
+   /* search in the tree of tree roots */
+   sk->tree_id = 1;
+
+   /*
+    * set the min and max to backref keys.  The search will
+    * only send back this type of key now.
+    */
+   sk->max_type = BTRFS_DIR_ITEM_KEY;
+   sk->min_type = BTRFS_DIR_ITEM_KEY;
+
+   /*
+    * set all the other params to the max, we'll take any objectid
+    * and any trans
+    */
+   sk->min_objectid = BTRFS_ROOT_TREE_DIR_OBJECTID;
+   sk->max_objectid = BTRFS_ROOT_TREE_DIR_OBJECTID;
+
+   sk->max_offset = (u64)-1;
+   sk->min_offset = 0;
+   sk->max_transid = (u64)-1;
+
+   /* just a big number, doesn't matter much */
+   sk->nr_items = 4096;
+
+   while(1) {
+       ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
+       if (ret < 0) {
+           fprintf(stderr, "ERROR: can't perform the search\n");
+           subvol[0] = '\0';
+           return NULL;
+       }
+       /* the ioctl returns the number of item it found in nr_items */
+       if (sk->nr_items == 0) {
+           break;
+       }
+
+       off = 0;
+
+       /*
+        * for each item, pull the key out of the header and then
+        * read the root_ref item it contains
+        */
+       for (i = 0; i < sk->nr_items; i++) {
+           sh = (struct btrfs_ioctl_search_header *)(args.buf + off);
+           off += sizeof(*sh);
+           if (sh->type == BTRFS_DIR_ITEM_KEY) {
+               dir_item = (struct btrfs_dir_item *)(args.buf + off);
+               name_len = dir_item->name_len;
+               name = (char *)(dir_item + 1);
+
+
+               /*add_root(&root_lookup, sh->objectid, sh->offset,
+                        dir_id, name, name_len);*/
+               strncpy(dirname, name, name_len);
+               dirname[name_len] = '\0';
+               if (strcmp(dirname, "default") == 0) {
+                   defaultsubvolid = dir_item->location.objectid;
+                   break;
+               }
+           }
+           off += sh->len;
+
+           /*
+            * record the mins in sk so we can make sure the
+            * next search doesn't repeat this root
+            */
+           sk->min_objectid = sh->objectid;
+           sk->min_type = sh->type;
+           sk->max_type = sh->type;
+           sk->min_offset = sh->offset;
+       }
+       if (defaultsubvolid != 0)
+           break;
+       sk->nr_items = 4096;
+       /* this iteration is done, step forward one root for the next
+        * ioctl
+        */
+       if (sk->min_objectid < (u64)-1) {
+           sk->min_objectid = BTRFS_ROOT_TREE_DIR_OBJECTID;
+           sk->max_objectid = BTRFS_ROOT_TREE_DIR_OBJECTID;
+           sk->max_type = BTRFS_ROOT_BACKREF_KEY;
+           sk->min_type = BTRFS_ROOT_BACKREF_KEY;
+           sk->min_offset = 0;
+       } else
+           break;
+   }
+
+   if (defaultsubvolid == 0) {
+       subvol[0] = '\0';
+       return NULL;
+   }
+
+   memset(&args, 0, sizeof(args));
+
+   /* search in the tree of tree roots */
+   sk->tree_id = 1;
+
+   /*
+    * set the min and max to backref keys.  The search will
+    * only send back this type of key now.
+    */
+   sk->max_type = BTRFS_ROOT_BACKREF_KEY;
+   sk->min_type = BTRFS_ROOT_BACKREF_KEY;
+
+   /*
+    * set all the other params to the max, we'll take any objectid
+    * and any trans
+    */
+   sk->max_objectid = (u64)-1;
+   sk->max_offset = (u64)-1;
+   sk->max_transid = (u64)-1;
+
+   /* just a big number, doesn't matter much */
+   sk->nr_items = 4096;
+
+   while(1) {
+       ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
+       if (ret < 0) {
+           fprintf(stderr, "ERROR: can't perform the search\n");
+           subvol[0] = '\0';
+           return NULL;
+       }
+       /* the ioctl returns the number of item it found in nr_items */
+       if (sk->nr_items == 0)
+           break;
+
+       off = 0;
+
+       /*
+        * for each item, pull the key out of the header and then
+        * read the root_ref item it contains
+        */
+       for (i = 0; i < sk->nr_items; i++) {
+           sh = (struct btrfs_ioctl_search_header *)(args.buf + off);
+           off += sizeof(*sh);
+           if (sh->type == BTRFS_ROOT_BACKREF_KEY) {
+               ref = (struct btrfs_root_ref *)(args.buf + off);
+               name_len = ref->name_len;
+               name = (char *)(ref + 1);
+
+               if (sh->objectid == defaultsubvolid) {
+                   strncpy(subvol, name, name_len);
+                   subvol[name_len] = '\0';
+                   dprintf("The default subvolume: %s, ID: %llu\n",
+			   subvol, sh->objectid);
+                   break;
+               }
+
+           }
+
+           off += sh->len;
+
+           /*
+            * record the mins in sk so we can make sure the
+            * next search doesn't repeat this root
+            */
+           sk->min_objectid = sh->objectid;
+           sk->min_type = sh->type;
+           sk->min_offset = sh->offset;
+       }
+       if (subvol[0] != '\0')
+           break;
+       sk->nr_items = 4096;
+       /* this iteration is done, step forward one root for the next
+        * ioctl
+        */
+       if (sk->min_objectid < (u64)-1) {
+           sk->min_objectid++;
+           sk->min_type = BTRFS_ROOT_BACKREF_KEY;
+           sk->min_offset = 0;
+       } else
+           break;
+   }
+   return subvol;
+}
+
+static int install_file(const char *path, int devfd, struct stat *rst)
+{
+    if (fs_type == EXT2 || fs_type == VFAT || fs_type == NTFS
+	|| fs_type == UFS1 || fs_type == UFS2)
+	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__
+static char devname_buf[64];
+
+static void device_cleanup(void)
+{
+    unlink(devname_buf);
+}
+#endif
+
+/* Verify that a device fd and a pathname agree.
+   Return 0 on valid, -1 on error. */
+static int validate_device_btrfs(int pathfd, int devfd);
+static int validate_device(const char *path, int devfd)
+{
+    struct stat pst, dst;
+    struct statfs sfs;
+    int pfd;
+    int rv = -1;
+
+    pfd = open(path, O_RDONLY|O_DIRECTORY);
+    if (pfd < 0)
+	goto err;
+
+    if (fstat(pfd, &pst) || fstat(devfd, &dst) || statfs(path, &sfs))
+	goto err;
+
+    /* btrfs st_dev is not matched with mnt st_rdev, it is a known issue */
+    if (fs_type == BTRFS) {
+	if (sfs.f_type == BTRFS_SUPER_MAGIC)
+	    rv = validate_device_btrfs(pfd, devfd);
+    } else {
+	rv = (pst.st_dev == dst.st_rdev) ? 0 : -1;
+    }
+
+err:
+    if (pfd >= 0)
+	close(pfd);
+    return rv;
+}
+
+#ifndef __KLIBC__
+static const char *find_device(const char *mtab_file, dev_t dev)
+{
+    struct mntent *mnt;
+    struct stat dst;
+    FILE *mtab;
+    const char *devname = NULL;
+    bool done;
+
+    mtab = setmntent(mtab_file, "r");
+    if (!mtab)
+	return NULL;
+
+    done = false;
+    while ((mnt = getmntent(mtab))) {
+	/* btrfs st_dev is not matched with mnt st_rdev, it is a known issue */
+	switch (fs_type) {
+	case BTRFS:
+	    if (!strcmp(mnt->mnt_type, "btrfs") &&
+		!stat(mnt->mnt_dir, &dst) &&
+		dst.st_dev == dev) {
+		if (!subvol[0])
+		    get_default_subvol(mnt->mnt_dir, subvol);
+		done = true;
+	    }
+	    break;
+	case EXT2:
+	    if ((!strcmp(mnt->mnt_type, "ext2") ||
+		 !strcmp(mnt->mnt_type, "ext3") ||
+		 !strcmp(mnt->mnt_type, "ext4")) &&
+		!stat(mnt->mnt_fsname, &dst) &&
+		dst.st_rdev == dev) {
+		done = true;
+		break;
+	    }
+	case VFAT:
+	    if ((!strcmp(mnt->mnt_type, "vfat")) &&
+		!stat(mnt->mnt_fsname, &dst) &&
+		dst.st_rdev == dev) {
+		done = true;
+		break;
+	    }
+	case NTFS:
+	    if ((!strcmp(mnt->mnt_type, "fuseblk") /* ntfs-3g */ ||
+		 !strcmp(mnt->mnt_type, "ntfs")) &&
+		!stat(mnt->mnt_fsname, &dst) &&
+		dst.st_rdev == dev) {
+		done = true;
+		break;
+	    }
+
+	    break;
+	case XFS:
+	    if (!strcmp(mnt->mnt_type, "xfs") && !stat(mnt->mnt_fsname, &dst) &&
+		dst.st_rdev == dev) {
+		done = true;
+		break;
+	    }
+
+	    break;
+	case UFS1:
+	case UFS2:
+	    if (!strcmp(mnt->mnt_type, "ufs") && !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;
+}
+#endif
+
+/*
+ * On newer Linux kernels we can use sysfs to get a backwards mapping
+ * from device names to standard filenames
+ */
+static const char *find_device_sysfs(dev_t dev)
+{
+    char sysname[64];
+    char linkname[PATH_MAX];
+    ssize_t llen;
+    char *p, *q;
+    char *buf = NULL;
+    struct stat st;
+
+    snprintf(sysname, sizeof sysname, "/sys/dev/block/%u:%u",
+	     major(dev), minor(dev));
+
+    llen = readlink(sysname, linkname, sizeof linkname);
+    if (llen < 0 || llen >= sizeof linkname)
+	goto err;
+
+    linkname[llen] = '\0';
+
+    p = strrchr(linkname, '/');
+    p = p ? p+1 : linkname;	/* Leave basename */
+
+    buf = q = malloc(strlen(p) + 6);
+    if (!buf)
+	goto err;
+
+    memcpy(q, "/dev/", 5);
+    q += 5;
+
+    while (*p) {
+	*q++ = (*p == '!') ? '/' : *p;
+	p++;
+    }
+
+    *q = '\0';
+
+    if (!stat(buf, &st) && st.st_dev == dev)
+	return buf;		/* Found it! */
+
+err:
+    if (buf)
+	free(buf);
+    return NULL;
+}
+
+static const char *find_device_mountinfo(const char *path, dev_t dev)
+{
+    const struct mountinfo *m;
+    struct stat st;
+
+    m = find_mount(path, NULL);
+    if (!m)
+	return NULL;
+
+    if (m->devpath[0] == '/' && m->dev == dev &&
+	!stat(m->devpath, &st) && S_ISBLK(st.st_mode) && st.st_rdev == dev)
+	return m->devpath;
+    else
+	return NULL;
+}
+
+static int validate_device_btrfs(int pfd, int dfd)
+{
+    struct btrfs_ioctl_fs_info_args fsinfo;
+    static struct btrfs_ioctl_dev_info_args devinfo;
+    struct btrfs_super_block sb2;
+
+    if (ioctl(pfd, BTRFS_IOC_FS_INFO, &fsinfo))
+	return -1;
+
+    /* We do not support multi-device btrfs yet */
+    if (fsinfo.num_devices != 1)
+	return -1;
+
+    /* The one device will have the max devid */
+    memset(&devinfo, 0, sizeof devinfo);
+    devinfo.devid = fsinfo.max_id;
+    if (ioctl(pfd, BTRFS_IOC_DEV_INFO, &devinfo))
+	return -1;
+
+    if (devinfo.path[0] != '/')
+	return -1;
+
+    if (xpread(dfd, &sb2, sizeof sb2, BTRFS_SUPER_INFO_OFFSET) != sizeof sb2)
+	return -1;
+
+    if (memcmp(sb2.magic, BTRFS_MAGIC, BTRFS_MAGIC_L))
+	return -1;
+
+    if (memcmp(sb2.fsid, fsinfo.fsid, sizeof fsinfo.fsid))
+	return -1;
+
+    if (sb2.num_devices != 1)
+	return -1;
+
+    if (sb2.dev_item.devid != devinfo.devid)
+	return -1;
+
+    if (memcmp(sb2.dev_item.uuid, devinfo.uuid, sizeof devinfo.uuid))
+	return -1;
+
+    if (memcmp(sb2.dev_item.fsid, fsinfo.fsid, sizeof fsinfo.fsid))
+	return -1;
+
+    return 0;			/* It's good! */
+}
+
+static const char *find_device_btrfs(const char *path)
+{
+    int pfd, dfd;
+    struct btrfs_ioctl_fs_info_args fsinfo;
+    static struct btrfs_ioctl_dev_info_args devinfo;
+    const char *rv = NULL;
+
+    pfd = dfd = -1;
+
+    pfd = open(path, O_RDONLY);
+    if (pfd < 0)
+	goto err;
+
+    if (ioctl(pfd, BTRFS_IOC_FS_INFO, &fsinfo))
+	goto err;
+
+    /* We do not support multi-device btrfs yet */
+    if (fsinfo.num_devices != 1)
+	goto err;
+
+    /* The one device will have the max devid */
+    memset(&devinfo, 0, sizeof devinfo);
+    devinfo.devid = fsinfo.max_id;
+    if (ioctl(pfd, BTRFS_IOC_DEV_INFO, &devinfo))
+	goto err;
+
+    if (devinfo.path[0] != '/')
+	goto err;
+
+    dfd = open((const char *)devinfo.path, O_RDONLY);
+    if (dfd < 0)
+	goto err;
+
+    if (!validate_device_btrfs(pfd, dfd))
+	rv = (const char *)devinfo.path; /* It's good! */
+
+err:
+    if (pfd >= 0)
+	close(pfd);
+    if (dfd >= 0)
+	close(dfd);
+    return rv;
+}
+
+static const char *get_devname(const char *path)
+{
+    const char *devname = NULL;
+    struct stat st;
+    struct statfs sfs;
+
+    if (stat(path, &st) || !S_ISDIR(st.st_mode)) {
+	fprintf(stderr, "%s: Not a directory: %s\n", program, path);
+	return devname;
+    }
+    if (statfs(path, &sfs)) {
+	fprintf(stderr, "%s: statfs %s: %s\n", program, path, strerror(errno));
+	return devname;
+    }
+
+    if (opt.device)
+	devname = opt.device;
+
+    if (!devname){
+	if (fs_type == BTRFS) {
+	    /* For btrfs try to get the device name from btrfs itself */
+	    devname = find_device_btrfs(path);
+	}
+    }
+
+    if (!devname) {
+	devname = find_device_mountinfo(path, st.st_dev);
+    }
+
+#ifdef __KLIBC__
+    if (!devname) {
+	devname = find_device_sysfs(st.st_dev);
+    }
+    if (!devname) {
+	/* klibc doesn't have getmntent and friends; instead, just create
+	   a new device with the appropriate device type */
+	snprintf(devname_buf, sizeof devname_buf, "/tmp/dev-%u:%u",
+		 major(st.st_dev), minor(st.st_dev));
+
+	if (mknod(devname_buf, S_IFBLK | 0600, st.st_dev)) {
+	    fprintf(stderr, "%s: cannot create device %s\n", program, devname);
+	    return devname;
+	}
+
+	atexit(device_cleanup);	/* unlink the device node on exit */
+	devname = devname_buf;
+    }
+
+#else
+    if (!devname) {
+	devname = find_device("/proc/mounts", st.st_dev);
+    }
+    if (!devname) {
+	/* Didn't find it in /proc/mounts, try /etc/mtab */
+        devname = find_device("/etc/mtab", st.st_dev);
+    }
+    if (!devname) {
+	devname = find_device_sysfs(st.st_dev);
+
+	fprintf(stderr, "%s: cannot find device for path %s\n", program, path);
+	return devname;
+    }
+
+    fprintf(stderr, "%s is device %s\n", path, devname);
+
+#endif
+    return devname;
+}
+
+static int open_device(const char *path, struct stat *st, const char **_devname)
+{
+    int devfd;
+    const char *devname = NULL;
+    struct statfs sfs;
+
+    if (st)
+	if (stat(path, st) || !S_ISDIR(st->st_mode)) {
+		fprintf(stderr, "%s: Not a directory: %s\n", program, path);
+		return -1;
+	}
+
+    if (statfs(path, &sfs)) {
+	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)
+	fs_type = BTRFS;
+    else if (sfs.f_type == MSDOS_SUPER_MAGIC)
+	fs_type = VFAT;
+    else if (sfs.f_type == NTFS_SB_MAGIC ||
+                sfs.f_type == FUSE_SUPER_MAGIC /* ntfs-3g */)
+	fs_type = NTFS;
+    else if (sfs.f_type == XFS_SUPER_MAGIC)
+	fs_type = XFS;
+    else if (sfs.f_type == UFS1_SUPER_MAGIC)
+	fs_type = UFS1;
+    else if (sfs.f_type == UFS2_SUPER_MAGIC)
+	fs_type = UFS2;
+
+    if (!fs_type) {
+	fprintf(stderr,
+		"%s: not a fat, ntfs, ext2/3/4, btrfs, xfs or"
+		"ufs1/2 filesystem: %s\n",
+		program, path);
+	return -1;
+    }
+
+    devfd = -1;
+    devname = get_devname(path);
+    if (_devname)
+	*_devname = devname;
+
+    if ((devfd = open(devname, O_RDWR | O_SYNC)) < 0) {
+	fprintf(stderr, "%s: cannot open device %s\n", program, devname);
+	return -1;
+    }
+
+    /* Verify that the device we opened is the device intended */
+    if (validate_device(path, devfd)) {
+	fprintf(stderr, "%s: path %s doesn't match device %s\n",
+		program, path, devname);
+	close(devfd);
+	return -1;
+    }
+    return devfd;
+}
+
+static int btrfs_read_adv(int devfd)
+{
+    if (xpread(devfd, syslinux_adv, 2 * ADV_SIZE, BTRFS_ADV_OFFSET)
+	!= 2 * ADV_SIZE)
+	return -1;
+
+    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;
+    const char *name;
+
+    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 */
+	    err = read_adv(path, name = "extlinux.sys");
+	if (namep)
+	    *namep = name;
+	return err;
+    }
+}
+
+static int ext_write_adv(const char *path, const char *cfg, int devfd)
+{
+    if (fs_type == BTRFS) { /* btrfs "ldlinux.sys" is in 64k blank area */
+	if (xpwrite(devfd, syslinux_adv, 2 * ADV_SIZE,
+		BTRFS_ADV_OFFSET) != 2 * ADV_SIZE) {
+		perror("writing adv");
+		return 1;
+	}
+	return 0;
+    }
+    return write_adv(path, cfg);
+}
+
+static int install_loader(const char *path, int update_only)
+{
+    struct stat st, fst;
+    int devfd, rv;
+    const char *devname;
+
+    devfd = open_device(path, &st, &devname);
+    if (devfd < 0)
+	return 1;
+
+    if (update_only && !syslinux_already_installed(devfd)) {
+	fprintf(stderr, "%s: no previous syslinux boot sector found\n",
+		program);
+	close(devfd);
+	return 1;
+    }
+
+    /* Read a pre-existing ADV, if already installed */
+    if (opt.reset_adv) {
+	syslinux_reset_adv(syslinux_adv);
+    } else if (ext_read_adv(path, devfd, NULL) < 0) {
+	close(devfd);
+	return 1;
+    }
+
+    if (modify_adv() < 0) {
+	close(devfd);
+	return 1;
+    }
+
+    /* Install ldlinux.sys */
+    if (install_file(path, devfd, &fst)) {
+	close(devfd);
+	return 1;
+    }
+    if (fst.st_dev != st.st_dev) {
+	fprintf(stderr, "%s: file system changed under us - aborting!\n",
+		program);
+	close(devfd);
+	return 1;
+    }
+
+    sync();
+    rv = install_bootblock(devfd, devname);
+    close(devfd);
+    sync();
+
+    return rv;
+}
+
+/*
+ * Modify the ADV of an existing installation
+ */
+int modify_existing_adv(const char *path)
+{
+    const char *filename;
+    int devfd;
+
+    devfd = open_device(path, NULL, NULL);
+    if (devfd < 0)
+	return 1;
+
+    if (ext_read_adv(path, devfd, &filename) < 0) {
+	close(devfd);
+	return 1;
+    }
+    if (modify_adv() < 0) {
+	close(devfd);
+	return 1;
+    }
+    if (ext_write_adv(path, filename, devfd) < 0) {
+	close(devfd);
+	return 1;
+    }
+    close(devfd);
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    parse_options(argc, argv, MODE_EXTLINUX);
+
+    if (!opt.directory || opt.install_mbr || opt.activate_partition)
+	usage(EX_USAGE, 0);
+
+    if (opt.update_only == -1) {
+	if (opt.reset_adv || opt.set_once || opt.menu_save)
+	    return modify_existing_adv(opt.directory);
+	else
+	    usage(EX_USAGE, MODE_EXTLINUX);
+    }
+
+    return install_loader(opt.directory, opt.update_only);
+}
Index: bootcd/isolinux/syslinux-6.03/extlinux/misc.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/misc.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/misc.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012 Paulo Alcantara <pcacjr@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 MISC_H_
+#define MISC_H_
+
+/* Return a 64-bit litte-endian value from a given 64-bit big-endian one */
+static inline uint64_t be64_to_cpu(uint64_t val)
+{
+    return (uint64_t)((((uint64_t)val & (uint64_t)0x00000000000000ffULL) << 56) |
+		      (((uint64_t)val & (uint64_t)0x000000000000ff00ULL) << 40) |
+		      (((uint64_t)val & (uint64_t)0x0000000000ff0000ULL) << 24) |
+		      (((uint64_t)val & (uint64_t)0x00000000ff000000ULL) <<  8) |
+		      (((uint64_t)val & (uint64_t)0x000000ff00000000ULL) >>  8) |
+		      (((uint64_t)val & (uint64_t)0x0000ff0000000000ULL) >> 24) |
+		      (((uint64_t)val & (uint64_t)0x00ff000000000000ULL) >> 40) |
+		      (((uint64_t)val & (uint64_t)0xff00000000000000ULL) >> 56));
+}
+
+/* Return a 32-bit litte-endian value from a given 32-bit big-endian one */
+static inline uint32_t be32_to_cpu(uint32_t val)
+{
+    return (uint32_t)((((uint32_t)val & (uint32_t)0x000000ffUL) << 24) |
+		      (((uint32_t)val & (uint32_t)0x0000ff00UL) <<  8) |
+		      (((uint32_t)val & (uint32_t)0x00ff0000UL) >>  8) |
+		      (((uint32_t)val & (uint32_t)0xff000000UL) >> 24));
+}
+
+/* Return a 16-bit litte-endian value from a given 16-bit big-endian one */
+static inline uint16_t be16_to_cpu(uint16_t val)
+{
+    return (uint16_t)((((uint16_t)val & (uint16_t)0x00ffU) << 8) |
+		      (((uint16_t)val & (uint16_t)0xff00U) >> 8));
+}
+
+#endif /* MISC_H_ */
Index: bootcd/isolinux/syslinux-6.03/extlinux/mountinfo.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/mountinfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/mountinfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,277 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2012 Intel Corporation; All Rights Reserved
+ *
+ *   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, Inc., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include "mountinfo.h"
+
+/*
+ * Parse /proc/self/mountinfo
+ */
+static int get_string(FILE *f, char *string_buf, size_t string_len, char *ec)
+{
+    int ch;
+    char *p = string_buf;
+
+    for (;;) {
+	if (!string_len)
+	    return -2;		/* String too long */
+
+	ch = getc(f);
+	if (ch == EOF) {
+	    return -1;		/* Got EOF */
+	} else if (ch == ' ' || ch == '\t' || ch == '\n') {
+	    *ec = ch;
+	    *p = '\0';
+	    return p - string_buf;
+	} else if (ch == '\\') {
+	    /* Should always be followed by 3 octal digits in 000..377 */
+	    int oc = 0;
+	    int i;
+	    for (i = 0; i < 3; i++) {
+		ch = getc(f);
+		if (ch < '0' || ch > '7' || (i == 0 && ch > '3'))
+		    return -1;	/* Bad escape sequence */
+		oc = (oc << 3) + (ch - '0');
+	    }
+	    if (!oc)
+		return -1;	/* We can't handle \000 */
+	    *p++ = oc;
+	    string_len--;
+	} else {
+	    *p++ = ch;
+	    string_len--;
+	}
+    }
+}
+
+static void free_mountinfo(struct mountinfo *m)
+{
+    struct mountinfo *nx;
+
+    while (m) {
+	free((char *)m->root);
+	free((char *)m->path);
+	free((char *)m->fstype);
+	free((char *)m->devpath);
+	free((char *)m->mountopt);
+	nx = m->next;
+	free(m);
+	m = nx;
+    }
+}
+
+static struct mountinfo *head = NULL, **tail = &head;
+
+static void parse_mountinfo(void)
+{
+    FILE *f;
+    struct mountinfo *m, *mm;
+    char string_buf[PATH_MAX*8];
+    int n;
+    char ec, *ep;
+    unsigned int ma, mi;
+
+    f = fopen("/proc/self/mountinfo", "r");
+    if (!f)
+	return;
+
+    for (;;) {
+	m = malloc(sizeof(struct mountinfo));
+	if (!m)
+	    break;
+	memset(m, 0, sizeof *m);
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 0 || ec == '\n')
+	    break;
+
+	m->mountid = strtoul(string_buf, &ep, 10);
+	if (*ep)
+	    break;
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 0 || ec == '\n')
+	    break;
+
+	m->parentid = strtoul(string_buf, &ep, 10);
+	if (*ep)
+	    break;
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 0 || ec == '\n')
+	    break;
+
+	if (sscanf(string_buf, "%u:%u", &ma, &mi) != 2)
+	    break;
+
+	m->dev = makedev(ma, mi);
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 1 || ec == '\n' || string_buf[0] != '/')
+	    break;
+
+	m->root = strdup(string_buf);
+	if (!m->root)
+	    break;
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 1 || ec == '\n' || string_buf[0] != '/')
+	    break;
+
+	m->path = strdup(string_buf);
+	m->pathlen = (n == 1) ? 0 : n; /* Treat / as empty */
+
+	/* Skip tagged attributes */
+	do {
+	    n = get_string(f, string_buf, sizeof string_buf, &ec);
+	    if (n < 0 || ec == '\n')
+		goto quit;
+	} while (n != 1 || string_buf[0] != '-');
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 0 || ec == '\n')
+	    break;
+
+	m->fstype = strdup(string_buf);
+	if (!m->fstype)
+	    break;
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 0 || ec == '\n')
+	    break;
+
+	m->devpath = strdup(string_buf);
+	if (!m->devpath)
+	    break;
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 0)
+	    break;
+
+	m->mountopt = strdup(string_buf);
+	if (!m->mountopt)
+	    break;
+
+	/* Skip any previously unknown fields */
+	while (ec != '\n' && ec != EOF)
+	    ec = getc(f);
+
+	*tail = m;
+	tail = &m->next;
+    }
+quit:
+    fclose(f);
+    free_mountinfo(m);
+
+    /* Create parent links */
+    for (m = head; m; m = m->next) {
+	for (mm = head; mm; mm = mm->next) {
+	    if (m->parentid == mm->mountid) {
+		m->parent = mm;
+		if (!strcmp(m->path, mm->path))
+		    mm->hidden = 1; /* Hidden under another mount */
+		break;
+	    }
+	}
+    }
+}
+
+const struct mountinfo *find_mount(const char *path, char **subpath)
+{
+    static int done_init;
+    char *real_path;
+    const struct mountinfo *m, *best;
+    struct stat st;
+    int len, matchlen;
+
+    if (!done_init) {
+	parse_mountinfo();
+	done_init = 1;
+    }
+
+    if (stat(path, &st))
+	return NULL;
+
+    real_path = realpath(path, NULL);
+    if (!real_path)
+	return NULL;
+
+    /*
+     * Tricky business: we need the longest matching subpath
+     * which isn't a parent of the same subpath.
+     */
+    len = strlen(real_path);
+    matchlen = 0;
+    best = NULL;
+    for (m = head; m; m = m->next) {
+	if (m->hidden)
+	    continue;		/* Hidden underneath another mount */
+
+	if (m->pathlen > len)
+	    continue;		/* Cannot possibly match */
+
+	if (m->pathlen < matchlen)
+	    continue;		/* No point in testing this one */
+
+	if (st.st_dev == m->dev &&
+	    !memcmp(m->path, real_path, m->pathlen) &&
+	    (real_path[m->pathlen] == '/' || real_path[m->pathlen] == '\0')) {
+	    matchlen = m->pathlen;
+	    best = m;
+	}
+    }
+
+    if (best && subpath) {
+	if (real_path[best->pathlen] == '\0')
+	    *subpath = strdup("/");
+	else
+	    *subpath = strdup(real_path + best->pathlen);
+    }
+
+    return best;
+}
+
+#ifdef TEST
+
+int main(int argc, char *argv[])
+{
+    int i;
+    const struct mountinfo *m;
+    char *subpath;
+
+    parse_mountinfo();
+
+    for (i = 1; i < argc; i++) {
+	m = find_mount(argv[i], &subpath);
+	if (!m) {
+	    printf("%s: %s\n", argv[i], strerror(errno));
+	    continue;
+	}
+
+	printf("%s -> %s @ %s(%u,%u):%s %s %s\n",
+	       argv[i], subpath, m->devpath, major(m->dev), minor(m->dev),
+	       m->root, m->fstype, m->mountopt);
+	printf("Usable device: %s\n", find_device(m->dev, m->devpath));
+	free(subpath);
+    }
+
+    return 0;
+}
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/extlinux/mountinfo.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/mountinfo.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/mountinfo.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,35 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2012 Intel Corporation; All Rights Reserved
+ *
+ *   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, Inc., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef SYSLINUX_MOUNTINFO_H
+#define SYSLINUX_MOUNTINFO_H
+
+#include <sys/types.h>
+
+struct mountinfo {
+    struct mountinfo *next;
+    struct mountinfo *parent;
+    const char *root;
+    const char *path;
+    const char *fstype;
+    const char *devpath;
+    const char *mountopt;
+    int mountid;
+    int parentid;
+    int pathlen;
+    int hidden;
+    dev_t dev;
+};
+
+const struct mountinfo *find_mount(const char *path, char **subpath);
+
+#endif /* SYSLINUX_MOUNTINFO_H */
Index: bootcd/isolinux/syslinux-6.03/extlinux/ntfs.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/ntfs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/ntfs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,19 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Paulo Alcantara <pcacjr@gmail.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, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _NTFS_H_
+#define _NTFS_H_
+
+#define NTFS_SB_MAGIC 0x5346544E
+#define FUSE_SUPER_MAGIC 0x65735546
+
+#endif /* _NTFS_H_ */
Index: bootcd/isolinux/syslinux-6.03/extlinux/ufs.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/ufs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/ufs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2013 Raphael S. Carvalho <raphael.scarv@gmail.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 UFS_H_
+#define UFS_H_
+
+#define UFS1_SUPER_MAGIC 0x00011954
+#define UFS2_SUPER_MAGIC 0x19540119
+
+#endif /* UFS_H_ */
Index: bootcd/isolinux/syslinux-6.03/extlinux/ufs_fs.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/ufs_fs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/ufs_fs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,307 @@
+/*
+ * Taken from Linux kernel tree (linux/fs/ufs)
+ * linux/include/linux/ufs_fs.h
+ *
+ * Copyright (C) 1996
+ * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
+ * Laboratory for Computer Science Research Computing Facility
+ * Rutgers, The State University of New Jersey
+ *
+ * Copyright (c) 2013 Raphael S. Carvalho <raphael.scarv@gmail.com>
+ *
+ * Clean swab support by Fare <fare@tunes.org>
+ * just hope no one is using NNUUXXI on __?64 structure elements
+ * 64-bit clean thanks to Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+ *
+ * 4.4BSD (FreeBSD) support added on February 1st 1998 by
+ * Niels Kristian Bech Jensen <nkbj@image.dk> partially based
+ * on code by Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de>.
+ *
+ * NeXTstep support added on February 5th 1998 by
+ * Niels Kristian Bech Jensen <nkbj@image.dk>.
+ *
+ * Write support by Daniel Pirkl <daniel.pirkl@email.cz>
+ *
+ * HP/UX hfs filesystem support added by
+ * Martin K. Petersen <mkp@mkp.net>, August 1999
+ *
+ * UFS2 (of FreeBSD 5.x) support added by
+ * Niraj Kumar <niraj17@iitbombay.org>  , Jan 2004
+ *
+ */
+
+#ifndef __LINUX_UFS_FS_H
+#define __LINUX_UFS_FS_H
+
+#include <inttypes.h>
+
+typedef uint64_t __fs64;
+typedef uint32_t __fs32;
+typedef uint16_t __fs16;
+
+#define UFS_BBLOCK 0
+#define UFS_BBSIZE 8192
+#define UFS_SBLOCK 8192
+#define UFS_SBSIZE 8192
+
+#define UFS_SECTOR_SIZE 512
+#define UFS_SECTOR_BITS 9
+#define UFS_MAGIC  0x00011954
+#define UFS_MAGIC_BW 0x0f242697
+#define UFS2_MAGIC 0x19540119
+#define UFS_CIGAM  0x54190100 /* byteswapped MAGIC */
+
+/* Copied from FreeBSD */
+/*
+ * Each disk drive contains some number of filesystems.
+ * A filesystem consists of a number of cylinder groups.
+ * Each cylinder group has inodes and data.
+ *
+ * A filesystem is described by its super-block, which in turn
+ * describes the cylinder groups.  The super-block is critical
+ * data and is replicated in each cylinder group to protect against
+ * catastrophic loss.  This is done at `newfs' time and the critical
+ * super-block data does not change, so the copies need not be
+ * referenced further unless disaster strikes.
+ *
+ * For filesystem fs, the offsets of the various blocks of interest
+ * are given in the super block as:
+ *      [fs->fs_sblkno]         Super-block
+ *      [fs->fs_cblkno]         Cylinder group block
+ *      [fs->fs_iblkno]         Inode blocks
+ *      [fs->fs_dblkno]         Data blocks
+ * The beginning of cylinder group cg in fs, is given by
+ * the ``cgbase(fs, cg)'' macro.
+ *
+ * Depending on the architecture and the media, the superblock may
+ * reside in any one of four places. For tiny media where every block
+ * counts, it is placed at the very front of the partition. Historically,
+ * UFS1 placed it 8K from the front to leave room for the disk label and
+ * a small bootstrap. For UFS2 it got moved to 64K from the front to leave
+ * room for the disk label and a bigger bootstrap, and for really piggy
+ * systems we check at 256K from the front if the first three fail. In
+ * all cases the size of the superblock will be SBLOCKSIZE. All values are
+ * given in byte-offset form, so they do not imply a sector size. The
+ * SBLOCKSEARCH specifies the order in which the locations should be searched.
+ */
+#define SBLOCK_FLOPPY        0
+#define SBLOCK_UFS1       8192
+#define SBLOCK_UFS2      65536
+#define SBLOCK_PIGGY    262144
+#define SBLOCKSIZE        8192
+#define SBLOCKSEARCH \
+        { SBLOCK_UFS2, SBLOCK_UFS1, SBLOCK_FLOPPY, SBLOCK_PIGGY, -1 }
+
+#define	UFS_MAXNAMLEN 255
+#define UFS_MAXMNTLEN 512
+#define UFS2_MAXMNTLEN 468
+#define UFS2_MAXVOLLEN 32
+#define UFS_MAXCSBUFS 31
+#define UFS_LINK_MAX 32000
+/*
+#define	UFS2_NOCSPTRS	((128 / sizeof(void *)) - 4)
+*/
+#define	UFS2_NOCSPTRS	28
+
+/*
+ * UFS_DIR_PAD defines the directory entries boundaries
+ * (must be a multiple of 4)
+ */
+#define UFS_DIR_PAD			4
+#define UFS_DIR_ROUND			(UFS_DIR_PAD - 1)
+#define UFS_DIR_REC_LEN(name_len)	(((name_len) + 1 + 8 + UFS_DIR_ROUND) & ~UFS_DIR_ROUND)
+
+struct ufs_timeval {
+	__fs32	tv_sec;
+	__fs32	tv_usec;
+};
+
+struct ufs_dir_entry {
+	__fs32  d_ino;			/* inode number of this entry */
+	__fs16  d_reclen;		/* length of this entry */
+	union {
+		__fs16	d_namlen;		/* actual length of d_name */
+		struct {
+			__u8	d_type;		/* file type */
+			__u8	d_namlen;	/* length of string in d_name */
+		} d_44;
+	} d_u;
+	__u8	d_name[UFS_MAXNAMLEN + 1];	/* file name */
+};
+
+struct ufs_csum {
+	__fs32	cs_ndir;	/* number of directories */
+	__fs32	cs_nbfree;	/* number of free blocks */
+	__fs32	cs_nifree;	/* number of free inodes */
+	__fs32	cs_nffree;	/* number of free frags */
+};
+struct ufs2_csum_total {
+	__fs64	cs_ndir;	/* number of directories */
+	__fs64	cs_nbfree;	/* number of free blocks */
+	__fs64	cs_nifree;	/* number of free inodes */
+	__fs64	cs_nffree;	/* number of free frags */
+	__fs64   cs_numclusters;	/* number of free clusters */
+	__fs64   cs_spare[3];	/* future expansion */
+};
+
+struct ufs_csum_core {
+	__u64	cs_ndir;	/* number of directories */
+	__u64	cs_nbfree;	/* number of free blocks */
+	__u64	cs_nifree;	/* number of free inodes */
+	__u64	cs_nffree;	/* number of free frags */
+	__u64   cs_numclusters;	/* number of free clusters */
+};
+
+struct ufs_super_block {
+	union {
+		struct {
+			__fs32	fs_link;	/* UNUSED */
+		} fs_42;
+		struct {
+			__fs32	fs_state;	/* file system state flag */
+		} fs_sun;
+	} fs_u0;
+	__fs32	fs_rlink;	/* UNUSED */
+	__fs32	fs_sblkno;	/* addr of super-block in filesys */
+	__fs32	fs_cblkno;	/* offset of cyl-block in filesys */
+	__fs32	fs_iblkno;	/* offset of inode-blocks in filesys */
+	__fs32	fs_dblkno;	/* offset of first data after cg */
+	__fs32	fs_cgoffset;	/* cylinder group offset in cylinder */
+	__fs32	fs_cgmask;	/* used to calc mod fs_ntrak */
+	__fs32	fs_time;	/* last time written -- time_t */
+	__fs32	fs_size;	/* number of blocks in fs */
+	__fs32	fs_dsize;	/* number of data blocks in fs */
+	__fs32	fs_ncg;		/* number of cylinder groups */
+	__fs32	fs_bsize;	/* size of basic blocks in fs */
+	__fs32	fs_fsize;	/* size of frag blocks in fs */
+	__fs32	fs_frag;	/* number of frags in a block in fs */
+/* these are configuration parameters */
+	__fs32	fs_minfree;	/* minimum percentage of free blocks */
+	__fs32	fs_rotdelay;	/* num of ms for optimal next block */
+	__fs32	fs_rps;		/* disk revolutions per second */
+/* these fields can be computed from the others */
+	__fs32	fs_bmask;	/* ``blkoff'' calc of blk offsets */
+	__fs32	fs_fmask;	/* ``fragoff'' calc of frag offsets */
+	__fs32	fs_bshift;	/* ``lblkno'' calc of logical blkno */
+	__fs32	fs_fshift;	/* ``numfrags'' calc number of frags */
+/* these are configuration parameters */
+	__fs32	fs_maxcontig;	/* max number of contiguous blks */
+	__fs32	fs_maxbpg;	/* max number of blks per cyl group */
+/* these fields can be computed from the others */
+	__fs32	fs_fragshift;	/* block to frag shift */
+	__fs32	fs_fsbtodb;	/* fsbtodb and dbtofsb shift constant */
+	__fs32	fs_sbsize;	/* actual size of super block */
+	__fs32	fs_csmask;	/* csum block offset */
+	__fs32	fs_csshift;	/* csum block number */
+	__fs32	fs_nindir;	/* value of NINDIR */
+	__fs32	fs_inopb;	/* value of INOPB */
+	__fs32	fs_nspf;	/* value of NSPF */
+/* yet another configuration parameter */
+	__fs32	fs_optim;	/* optimization preference, see below */
+/* these fields are derived from the hardware */
+	union {
+		struct {
+			__fs32	fs_npsect;	/* # sectors/track including spares */
+		} fs_sun;
+		struct {
+			__fs32	fs_state;	/* file system state time stamp */
+		} fs_sunx86;
+	} fs_u1;
+	__fs32	fs_interleave;	/* hardware sector interleave */
+	__fs32	fs_trackskew;	/* sector 0 skew, per track */
+/* a unique id for this filesystem (currently unused and unmaintained) */
+/* In 4.3 Tahoe this space is used by fs_headswitch and fs_trkseek */
+/* Neither of those fields is used in the Tahoe code right now but */
+/* there could be problems if they are.                            */
+	__fs32	fs_id[2];	/* file system id */
+/* sizes determined by number of cylinder groups and their sizes */
+	__fs32	fs_csaddr;	/* blk addr of cyl grp summary area */
+	__fs32	fs_cssize;	/* size of cyl grp summary area */
+	__fs32	fs_cgsize;	/* cylinder group size */
+/* these fields are derived from the hardware */
+	__fs32	fs_ntrak;	/* tracks per cylinder */
+	__fs32	fs_nsect;	/* sectors per track */
+	__fs32	fs_spc;		/* sectors per cylinder */
+/* this comes from the disk driver partitioning */
+	__fs32	fs_ncyl;	/* cylinders in file system */
+/* these fields can be computed from the others */
+	__fs32	fs_cpg;		/* cylinders per group */
+	__fs32	fs_ipg;		/* inodes per cylinder group */
+	__fs32	fs_fpg;		/* blocks per group * fs_frag */
+/* this data must be re-computed after crashes */
+	struct ufs_csum fs_cstotal;	/* cylinder summary information */
+/* these fields are cleared at mount time */
+	__s8	fs_fmod;	/* super block modified flag */
+	__s8	fs_clean;	/* file system is clean flag */
+	__s8	fs_ronly;	/* mounted read-only flag */
+	__s8	fs_flags;
+	union {
+		struct {
+			__s8	fs_fsmnt[UFS_MAXMNTLEN];/* name mounted on */
+			__fs32	fs_cgrotor;	/* last cg searched */
+			__fs32	fs_csp[UFS_MAXCSBUFS];/*list of fs_cs info buffers */
+			__fs32	fs_maxcluster;
+			__fs32	fs_cpc;		/* cyl per cycle in postbl */
+			__fs16	fs_opostbl[16][8]; /* old rotation block list head */
+		} fs_u1;
+		struct {
+			__s8  fs_fsmnt[UFS2_MAXMNTLEN];	/* name mounted on */
+			__u8   fs_volname[UFS2_MAXVOLLEN]; /* volume name */
+			__fs64  fs_swuid;		/* system-wide uid */
+			__fs32  fs_pad;	/* due to alignment of fs_swuid */
+			__fs32   fs_cgrotor;     /* last cg searched */
+			__fs32   fs_ocsp[UFS2_NOCSPTRS]; /*list of fs_cs info buffers */
+			__fs32   fs_contigdirs;/*# of contiguously allocated dirs */
+			__fs32   fs_csp;	/* cg summary info buffer for fs_cs */
+			__fs32   fs_maxcluster;
+			__fs32   fs_active;/* used by snapshots to track fs */
+			__fs32   fs_old_cpc;	/* cyl per cycle in postbl */
+			__fs32   fs_maxbsize;/*maximum blocking factor permitted */
+			__fs64   fs_sparecon64[17];/*old rotation block list head */
+			__fs64   fs_sblockloc; /* byte offset of standard superblock */
+			struct  ufs2_csum_total fs_cstotal;/*cylinder summary information*/
+			struct  ufs_timeval    fs_time;		/* last time written */
+			__fs64    fs_size;		/* number of blocks in fs */
+			__fs64    fs_dsize;	/* number of data blocks in fs */
+			__fs64   fs_csaddr;	/* blk addr of cyl grp summary area */
+			__fs64    fs_pendingblocks;/* blocks in process of being freed */
+			__fs32    fs_pendinginodes;/*inodes in process of being freed */
+		} fs_u2;
+	}  fs_u11;
+	union {
+		struct {
+			__fs32	fs_sparecon[53];/* reserved for future constants */
+			__fs32	fs_reclaim;
+			__fs32	fs_sparecon2[1];
+			__fs32	fs_state;	/* file system state time stamp */
+			__fs32	fs_qbmask[2];	/* ~usb_bmask */
+			__fs32	fs_qfmask[2];	/* ~usb_fmask */
+		} fs_sun;
+		struct {
+			__fs32	fs_sparecon[53];/* reserved for future constants */
+			__fs32	fs_reclaim;
+			__fs32	fs_sparecon2[1];
+			__fs32	fs_npsect;	/* # sectors/track including spares */
+			__fs32	fs_qbmask[2];	/* ~usb_bmask */
+			__fs32	fs_qfmask[2];	/* ~usb_fmask */
+		} fs_sunx86;
+		struct {
+			__fs32	fs_sparecon[50];/* reserved for future constants */
+			__fs32	fs_contigsumsize;/* size of cluster summary array */
+			__fs32	fs_maxsymlinklen;/* max length of an internal symlink */
+			__fs32	fs_inodefmt;	/* format of on-disk inodes */
+			__fs32	fs_maxfilesize[2];	/* max representable file size */
+			__fs32	fs_qbmask[2];	/* ~usb_bmask */
+			__fs32	fs_qfmask[2];	/* ~usb_fmask */
+			__fs32	fs_state;	/* file system state time stamp */
+		} fs_44;
+	} fs_u2;
+	__fs32	fs_postblformat;	/* format of positional layout tables */
+	__fs32	fs_nrpos;		/* number of rotational positions */
+	__fs32	fs_postbloff;		/* (__s16) rotation block list head */
+	__fs32	fs_rotbloff;		/* (__u8) blocks for each rotation */
+	__fs32	fs_magic;		/* magic number */
+	__u8	fs_space[1];		/* list of blocks for each rotation */
+}; /*struct ufs_super_block*/
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/extlinux/xfs.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/xfs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/xfs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012 Paulo Alcantara <pcacjr@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_ */
Index: bootcd/isolinux/syslinux-6.03/extlinux/xfs_fs.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/xfs_fs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/xfs_fs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -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@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_ */
Index: bootcd/isolinux/syslinux-6.03/extlinux/xfs_sb.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/xfs_sb.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/xfs_sb.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -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@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_ */
Index: bootcd/isolinux/syslinux-6.03/extlinux/xfs_types.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/xfs_types.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/xfs_types.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -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@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_ */
