diff --git a/os/imagezip/ntfs/libntfs/GNUmakefile.in b/os/imagezip/ntfs/libntfs/GNUmakefile.in
index 8280a5486c0d60ac0203213e2039f9629a68ea53..0832f04c53a130bbe395b539b5aa10b099c7d3f4 100644
--- a/os/imagezip/ntfs/libntfs/GNUmakefile.in
+++ b/os/imagezip/ntfs/libntfs/GNUmakefile.in
@@ -1,6 +1,6 @@
 #
 # EMULAB-COPYRIGHT
-# Copyright (c) 2000-2004 University of Utah and the Flux Group.
+# Copyright (c) 2000-2005 University of Utah and the Flux Group.
 # All rights reserved.
 #
 
@@ -71,7 +71,9 @@ $(SRCS): $(LIBSRCDIR)/patched
 $(LIBSRCDIR)/patched:
 	$(FETCH) http://$(PKGHOST)/$(NTFSVER).tar.gz
 	$(UNPACK) $(NTFSVER).tar.gz
-ifndef LINUX
+ifdef LINUX
+	$(PATCH) < $(SRCDIR)/ntfs.linuxpatch
+else
 	$(PATCH) < $(SRCDIR)/ntfs.patch
 endif
 	$(MV) $(NTFSVER) $(NTFSDIR)
diff --git a/os/imagezip/ntfs/libntfs/ntfs.linuxpatch b/os/imagezip/ntfs/libntfs/ntfs.linuxpatch
new file mode 100644
index 0000000000000000000000000000000000000000..2f83d61c030900e48b87234e0038a7d7204efec8
--- /dev/null
+++ b/os/imagezip/ntfs/libntfs/ntfs.linuxpatch
@@ -0,0 +1,414 @@
+diff -ru ntfsprogs-1.7.1/include/disk_io.h ntfsprogs-linux/include/disk_io.h
+--- ntfsprogs-1.7.1/include/disk_io.h	2003-02-06 08:24:56.000000000 -0700
++++ ntfsprogs-linux/include/disk_io.h	2005-03-17 16:16:58.000000000 -0700
+@@ -24,8 +24,10 @@
+ 
+ #include "volume.h"
+ 
+-extern s64 ntfs_pread(const int fd, const s64 pos, s64 count, const void *b);
+-extern s64 ntfs_pwrite(const int fd, const s64 pos, s64 count, const void *b);
++extern void ntfs_setiobase(const int fd, const s64 base);
++
++extern s64 ntfs_pread(const int fd, s64 pos, s64 count, const void *b);
++extern s64 ntfs_pwrite(const int fd, s64 pos, s64 count, const void *b);
+ 
+ extern s64 ntfs_mst_pread(const int fd, const s64 pos, s64 count,
+ 		const u32 bksize, const void *b);
+diff -ru ntfsprogs-1.7.1/include/layout.h ntfsprogs-linux/include/layout.h
+--- ntfsprogs-1.7.1/include/layout.h	2003-02-06 08:24:56.000000000 -0700
++++ ntfsprogs-linux/include/layout.h	2005-03-17 16:14:29.000000000 -0700
+@@ -292,7 +292,11 @@
+  */
+ typedef struct {
+ /*Ofs*/
+-/*  0*/	NTFS_RECORD;		/* Usually the magic is "FILE". */
++/*  0	NTFS_RECORD; -- Unfolded here as gcc doesn't like unnamed structs. */
++	NTFS_RECORD_TYPES magic;/* Usually the magic is "FILE". */
++	u16 usa_ofs;		/* See NTFS_RECORD definition above. */
++	u16 usa_count;		/* See NTFS_RECORD definition above. */
++
+ /*  8*/	u64 lsn;		/* $LogFile sequence number for this record.
+ 				   Changed every time the record is modified. */
+ /* 16*/	u16 sequence_number;	/* Number of times this mft record has been
+@@ -475,8 +479,8 @@
+ 					   FIXME: What does it mean? (AIA) */
+ /* 88*/ COLLATION_RULES collation_rule;	/* Default collation rule. */
+ /* 8c*/	ATTR_DEF_FLAGS flags;		/* Flags describing the attribute. */
+-/* 90*/	u64 min_size;			/* Optional minimum attribute size. */
+-/* 98*/	u64 max_size;			/* Maximum size of attribute. */
++/* 90*/	s64 min_size;			/* Optional minimum attribute size. */
++/* 98*/	s64 max_size;			/* Maximum size of attribute. */
+ /* sizeof() = 0xa0 or 160 bytes */
+ } __attribute__ ((__packed__)) ATTR_DEF;
+ 
+@@ -593,8 +597,8 @@
+ /* 12*/	ATTR_FLAGS flags;	/* Flags describing the attribute. */
+ /* 14*/	u16 instance;		/* The instance of this attribute record. This
+ 				   number is unique within this mft record (see
+-				   MFT_RECORD/next_attribute_instance notes in
+-				   in mft.h for more details). */
++				   MFT_RECORD/next_attribute_instance notes
++				   above for more details). */
+ /* 16*/	union {
+ 		/* Resident attributes. */
+ 		struct {
+@@ -1428,9 +1432,13 @@
+  * ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, SYSTEM_AUDIT_ACE, SYSTEM_ALARM_ACE
+  */
+ typedef struct {
+-	ACE_HEADER;		/* The ACE header. */
+-	ACCESS_MASK mask;	/* Access mask associated with the ACE. */
+-	SID sid;		/* The SID associated with the ACE. */
++/*  0	ACE_HEADER; -- Unfolded here as gcc doesn't like unnamed structs. */
++	ACE_TYPES type;		/* Type of the ACE. */
++	ACE_FLAGS flags;	/* Flags describing the ACE. */
++	u16 size;		/* Size in bytes of the ACE. */
++
++/*  4*/	ACCESS_MASK mask;	/* Access mask associated with the ACE. */
++/*  8*/	SID sid;		/* The SID associated with the ACE. */
+ } __attribute__ ((__packed__)) ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE,
+ 			       SYSTEM_AUDIT_ACE, SYSTEM_ALARM_ACE;
+ 
+@@ -1443,12 +1451,16 @@
+ } OBJECT_ACE_FLAGS;
+ 
+ typedef struct {
+-	ACE_HEADER;		/* The ACE_HEADER. */
+-	ACCESS_MASK mask;	/* Access mask associated with the ACE. */
+-	OBJECT_ACE_FLAGS flags;	/* Flags describing the object ACE. */
+-	GUID object_type;
+-	GUID inherited_object_type;
+-	SID sid;		/* The SID associated with the ACE. */
++/*  0	ACE_HEADER; -- Unfolded here as gcc doesn't like unnamed structs. */
++	ACE_TYPES type;		/* Type of the ACE. */
++	ACE_FLAGS flags;	/* Flags describing the ACE. */
++	u16 size;		/* Size in bytes of the ACE. */
++
++/*  4*/	ACCESS_MASK mask;	/* Access mask associated with the ACE. */
++/*  8*/	OBJECT_ACE_FLAGS object_flags;	/* Flags describing the object ACE. */
++/* 12*/	GUID object_type;
++/* 28*/	GUID inherited_object_type;
++/* 44*/	SID sid;		/* The SID associated with the ACE. */
+ } __attribute__ ((__packed__)) ACCESS_ALLOWED_OBJECT_ACE,
+ 			       ACCESS_DENIED_OBJECT_ACE,
+ 			       SYSTEM_AUDIT_OBJECT_ACE,
+@@ -1692,8 +1704,13 @@
+  * $SDS data stream and the second copy will be at offset 0x451d0.
+  */
+ typedef struct {
+-	SECURITY_DESCRIPTOR_HEADER;	  /* The security descriptor header. */
+-	SECURITY_DESCRIPTOR_RELATIVE sid; /* The self-relative security
++/*  0	SECURITY_DESCRIPTOR_HEADER; -- Unfolded here as gcc doesn't like
++				       unnamed structs. */
++	u32 hash;	   /* Hash of the security descriptor. */
++	u32 security_id;   /* The security_id assigned to the descriptor. */
++	u64 offset;	   /* Byte offset of this entry in the $SDS stream. */
++	u32 length;	   /* Size in bytes of this entry in $SDS stream. */
++/* 20*/	SECURITY_DESCRIPTOR_RELATIVE sid; /* The self-relative security
+ 					     descriptor. */
+ } __attribute__ ((__packed__)) SDS_ENTRY;
+ 
+@@ -1867,7 +1884,11 @@
+  * index entries (INDEX_ENTRY structures), as described by the INDEX_HEADER.
+  */
+ typedef struct {
+-/*  0*/	NTFS_RECORD;		/* Magic is "INDX". */
++/*  0	NTFS_RECORD; -- Unfolded here as gcc doesn't like unnamed structs. */
++	NTFS_RECORD_TYPES magic;/* Magic is "INDX". */
++	u16 usa_ofs;		/* See NTFS_RECORD definition. */
++	u16 usa_count;		/* See NTFS_RECORD definition. */
++
+ /*  8*/	s64 lsn;		/* $LogFile sequence number of the last
+ 				   modification of this index block. */
+ /* 16*/	VCN index_block_vcn;	/* Virtual cluster number of the index block. */
+@@ -2018,7 +2039,30 @@
+  * NOTE: Before NTFS 3.0 only filename attributes were indexed.
+  */
+ typedef struct {
+-/*  0*/ INDEX_ENTRY_HEADER;	/* The index entry header (see above). */
++/*  0	INDEX_ENTRY_HEADER; -- Unfolded here as gcc dislikes unnamed structs. */
++	union {
++		struct { /* Only valid when INDEX_ENTRY_END is not set. */
++			MFT_REF indexed_file;	/* The mft reference of the file
++						   described by this index
++						   entry. Used for directory
++						   indexes. */
++		} __attribute__ ((__packed__));
++		struct { /* Used for views/indexes to find the entry's data. */
++			u16 data_offset;	/* Data byte offset from this
++						   INDEX_ENTRY. Follows the
++						   index key. */
++			u16 data_length;	/* Data length in bytes. */
++			u32 reservedV;		/* Reserved (zero). */
++		} __attribute__ ((__packed__));
++	} __attribute__ ((__packed__));
++	u16 length;		 /* Byte size of this index entry, multiple of
++				    8-bytes. */
++	u16 key_length;		 /* Byte size of the key value, which is in the
++				    index entry. It follows field reserved. Not
++				    multiple of 8-bytes. */
++	INDEX_ENTRY_FLAGS flags; /* Bit field of INDEX_ENTRY_* flags. */
++	u16 reserved;		 /* Reserved/align to 8-byte boundary. */
++
+ /* 16*/	union {		/* The key of the indexed attribute. NOTE: Only present
+ 			   if INDEX_ENTRY_END bit in flags is not set. NOTE: On
+ 			   NTFS versions before 3.0 the only valid key is the
+@@ -2030,7 +2074,8 @@
+ 		GUID object_id;		/* $O index in FILE_Extend/$ObjId: The
+ 					   object_id of the mft record found in
+ 					   the data part of the index. */
+-		REPARSE_INDEX_KEY;	/* $R index in FILE_Extend/$Reparse. */
++		REPARSE_INDEX_KEY reparse;	/* $R index in
++						   FILE_Extend/$Reparse. */
+ 		SID sid;		/* $O index in FILE_Extend/$Quota:
+ 					   SID of the owner of the user_id. */
+ 		u32 owner_id;		/* $Q index in FILE_Extend/$Quota:
+diff -ru ntfsprogs-1.7.1/include/volume.h ntfsprogs-linux/include/volume.h
+--- ntfsprogs-1.7.1/include/volume.h	2003-02-06 08:24:56.000000000 -0700
++++ ntfsprogs-linux/include/volume.h	2005-03-17 16:20:29.000000000 -0700
+@@ -156,6 +156,7 @@
+ 
+ extern ntfs_volume *ntfs_volume_startup(const char *name, unsigned long rwflag);
+ extern ntfs_volume *ntfs_mount(const char *name, unsigned long rwflag);
++extern ntfs_volume *ntfs_mount_with_offset(const char *name, unsigned long rwflag, const s64 doffset);
+ 
+ extern int ntfs_umount(ntfs_volume *vol, const BOOL force);
+ 
+diff -ru ntfsprogs-1.7.1/libntfs/attrib.c ntfsprogs-linux/libntfs/attrib.c
+--- ntfsprogs-1.7.1/libntfs/attrib.c	2003-02-13 03:25:30.000000000 -0700
++++ ntfsprogs-linux/libntfs/attrib.c	2005-03-17 16:26:14.000000000 -0700
+@@ -383,8 +383,8 @@
+ {
+ 	if (NAttrNonResident(na) && na->rl)
+ 		free(na->rl);
+-	if (na->name != AT_UNNAMED)
+-		free(na->name);
++	/* if (na->name != AT_UNNAMED) */
++	/*	free(na->name); */
+ 	free(na);
+ 	return;
+ }
+diff -ru ntfsprogs-1.7.1/libntfs/dir.c ntfsprogs-linux/libntfs/dir.c
+--- ntfsprogs-1.7.1/libntfs/dir.c	2003-02-06 08:24:56.000000000 -0700
++++ ntfsprogs-linux/libntfs/dir.c	2005-03-17 16:14:29.000000000 -0700
+@@ -22,6 +22,7 @@
+ #include <stdlib.h>
+ #include <errno.h>
+ #include <string.h>
++#include <assert.h>
+ 
+ #include "types.h"
+ #include "debug.h"
+@@ -78,6 +79,10 @@
+ 	int eo, rc;
+ 	u32 index_block_size, index_vcn_size;
+ 	u8 index_vcn_size_bits;
++	assert(sizeof(u8) == 1);
++	assert(sizeof(u32) == 4);
++	assert(sizeof(s64) == 8);
++	assert(sizeof(u64) == 8);
+ 
+ 	if (!dir_ni || !dir_ni->mrec || !uname || uname_len <= 0) {
+ 		errno = EINVAL;
+@@ -89,7 +94,7 @@
+ 		return -1;
+ 
+ 	/* Find the index root attribute in the mft record. */
+-	if (!ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL,
++	if (ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL, /*Russ FreeBSD change.  I changed a not because I thought it was wrong*/
+ 			0, ctx)) {
+ 		Dprintf("Index root attribute missing in directory inode "
+ 				"0x%Lx: %s\n",
+@@ -103,7 +108,7 @@
+ 	index_block_size = le32_to_cpu(ir->index_block_size);
+ 	if (index_block_size < NTFS_SECTOR_SIZE ||
+ 			index_block_size & (index_block_size - 1)) {
+-		Dprintf("Index block size %u is invalid.\n", index_block_size);
++		Dprintf("Index block size 0x%08x is invalid.\n", index_block_size);
+ 		goto put_err_out;
+ 	}
+ 	index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
+diff -ru ntfsprogs-1.7.1/libntfs/disk_io.c ntfsprogs-linux/libntfs/disk_io.c
+--- ntfsprogs-1.7.1/libntfs/disk_io.c	2003-02-06 08:24:56.000000000 -0700
++++ ntfsprogs-linux/libntfs/disk_io.c	2005-03-17 16:30:28.000000000 -0700
+@@ -40,6 +40,15 @@
+ #	define BLKGETSIZE _IO(0x12,96) /* Get device size in 512byte blocks. */
+ #endif
+ 
++static int iofd = -1;
++static s64 iobase = 0LL;
++
++void ntfs_setiobase(const int fd, const s64 base)
++{
++	iofd = fd;
++	iobase = base;
++}
++
+ /**
+  * ntfs_pread - positioned read from disk
+  * @fd:		file descriptor to read from
+@@ -59,7 +68,7 @@
+  * to the return code of either lseek, read, or set to EINVAL in case of
+  * invalid arguments.
+  */
+-s64 ntfs_pread(const int fd, const s64 pos, s64 count, const void *b)
++s64 ntfs_pread(const int fd, s64 pos, s64 count, const void *b)
+ {
+ 	s64 br, total;
+ 
+@@ -71,6 +80,11 @@
+ 	}
+ 	if (!count)
+ 		return 0;
++
++	/* Account for static offset. */
++	if (fd == iofd)
++		pos += iobase;
++
+ 	/* Locate to position. */
+ 	if (lseek(fd, pos, SEEK_SET) == (off_t)-1) {
+ 		Dprintf("ntfs_pread: lseek to 0x%Lx returned error: %s\n", pos,
+@@ -112,7 +126,7 @@
+  * appropriately to the return code of either lseek, write, or set
+  * to EINVAL in case of invalid arguments.
+  */
+-s64 ntfs_pwrite(const int fd, const s64 pos, s64 count, const void *b)
++s64 ntfs_pwrite(const int fd, s64 pos, s64 count, const void *b)
+ {
+ 	s64 written, total;
+ 
+@@ -124,6 +138,11 @@
+ 	}
+ 	if (!count)
+ 		return 0;
++
++	/* Account for static offset. */
++	if (fd == iofd)
++		pos += iobase;
++
+ 	/* Locate to position. */
+ 	if (lseek(fd, pos, SEEK_SET) == (off_t)-1) {
+ 		Dprintf("ntfs_pwrite: lseek to 0x%Lx returned error: %s\n",
+@@ -353,6 +372,10 @@
+ {
+ 	char ch;
+ 
++	/* Account for static offset. */
++	if (f == iofd)
++		ofs += iobase;
++
+ 	if (lseek(f, ofs, SEEK_SET) >= 0 && read(f, &ch, 1) == 1)
+ 		return 0;
+ 	return -1;
+@@ -371,6 +394,11 @@
+ s64 ntfs_device_size_get(int f, int block_size)
+ {
+ 	s64 high, low;
++
++	/* Account for static offset. */
++	if (f == iofd)
++		Dprintf("WARNING: cannot correctly determine device size\n");
++
+ #ifdef BLKGETSIZE
+ 	long size;
+ 
+diff -ru ntfsprogs-1.7.1/libntfs/lcnalloc.c ntfsprogs-linux/libntfs/lcnalloc.c
+--- ntfsprogs-1.7.1/libntfs/lcnalloc.c	2003-02-06 08:24:56.000000000 -0700
++++ ntfsprogs-linux/libntfs/lcnalloc.c	2005-03-17 16:14:29.000000000 -0700
+@@ -101,8 +101,8 @@
+ 	int err = 0, rlpos, rlsize, buf_size;
+ 	u8 pass, done_zones, search_zone, need_writeback, bit;
+ 
+-	Dprintf("%s(): Entering with count = 0x%Lx, start_lcn = 0x%Lx,
+-			zone = %s_ZONE.\n", (long long)count,
++	Dprintf("%s(): Entering with count = 0x%Lx, start_lcn = 0x%Lx,"
++			"zone = %s_ZONE.\n", (long long)count,
+ 			(long long)start_lcn,
+ 			zone == MFT_ZONE ? "MFT" : "DATA");
+ 	if (!vol || count < 0 || start_lcn < -1 || !vol->lcnbmp_na ||
+diff -ru ntfsprogs-1.7.1/libntfs/mft.c ntfsprogs-linux/libntfs/mft.c
+--- ntfsprogs-1.7.1/libntfs/mft.c	2003-02-13 03:02:28.000000000 -0700
++++ ntfsprogs-linux/libntfs/mft.c	2005-03-17 16:31:50.000000000 -0700
+@@ -59,7 +59,8 @@
+ 	s64 br;
+ 	VCN m;
+ 
+-	Dprintf("%s(): Entering for inode 0x%Lx.\n", __FUNCTION__, MREF(mref));
++  	Dprintf("%s(): Entering for inode 0x%Lx.\n", __FUNCTION__, MREF(mref));
++
+ 	if (!vol || !vol->mft_na || !b || count < 0) {
+ 		errno = EINVAL;
+ 		return -1;
+diff -ru ntfsprogs-1.7.1/libntfs/volume.c ntfsprogs-linux/libntfs/volume.c
+--- ntfsprogs-1.7.1/libntfs/volume.c	2003-02-06 08:24:56.000000000 -0700
++++ ntfsprogs-linux/libntfs/volume.c	2005-03-17 16:32:57.000000000 -0700
+@@ -71,6 +71,7 @@
+ 		ntfs_inode_close(v->mftmirr_ni);
+ 	if (v->fd) {
+ 		fdatasync(v->fd);
++		ntfs_setiobase(-1, 0LL);
+ 		close(v->fd);
+ 	}
+ 	if (v->dev_name)
+@@ -361,6 +362,9 @@
+ 	return -1;
+ }
+ 
++/* Internal */
++static ntfs_volume *ntfs_volume_startup_internal(const char *name, unsigned long rwflag, const s64 doffset);
++
+ /**
+  * ntfs_volume_startup - allocate and setup an ntfs volume
+  * @name:	name of device/file to open
+@@ -375,6 +379,11 @@
+  */
+ ntfs_volume *ntfs_volume_startup(const char *name, unsigned long rwflag)
+ {
++	return ntfs_volume_startup_internal(name, rwflag, 0LL);
++}
++
++static ntfs_volume *ntfs_volume_startup_internal(const char *name, unsigned long rwflag, const s64 doffset)
++{
+ 	LCN mft_zone_size, mft_lcn;
+ 	s64 br;
+ 	const char *OK = "OK";
+@@ -389,6 +398,8 @@
+ #endif
+ 
+ 	/* Allocate the volume structure. */
++
++
+ 	vol = __ntfs_volume_allocate();
+ 	if (!vol)
+ 		return NULL;
+@@ -406,6 +417,9 @@
+ 		Dperror("Error opening partition file");
+ 		goto error_exit;
+ 	}
++	/* XXX set the disk offset if there is one. */
++	if (doffset)
++		ntfs_setiobase(vol->fd, doffset);
+ 	/* Now read the bootsector. */
+ 	br = ntfs_pread(vol->fd, 0, sizeof(NTFS_BOOT_SECTOR), bs);
+ 	if (br != sizeof(NTFS_BOOT_SECTOR)) {
+@@ -563,6 +577,11 @@
+  */
+ ntfs_volume *ntfs_mount(const char *name, unsigned long rwflag)
+ {
++	return ntfs_mount_with_offset(name, rwflag, 0LL);
++}
++
++ntfs_volume *ntfs_mount_with_offset(const char *name, unsigned long rwflag, const s64 doffset)
++{
+ 	s64 l;
+ 	const char *OK = "OK";
+ 	const char *FAILED = "FAILED";
+@@ -582,7 +601,7 @@
+ 		return NULL;
+ 	}
+ 
+-	vol = ntfs_volume_startup(name, rwflag);
++	vol = ntfs_volume_startup_internal(name, rwflag, doffset);
+ 	if (!vol) {
+ 		Dperror("Failed to startup volume");
+ 		return NULL;