diff --git a/fs/udf/super.c b/fs/udf/super.c
new file mode 100644
index 0000000..15bd4f2
--- /dev/null
+++ b/fs/udf/super.c
@@ -0,0 +1,1934 @@
+/*
+ * super.c
+ *
+ * PURPOSE
+ *  Super block routines for the OSTA-UDF(tm) filesystem.
+ *
+ * DESCRIPTION
+ *  OSTA-UDF(tm) = Optical Storage Technology Association
+ *  Universal Disk Format.
+ *
+ *  This code is based on version 2.00 of the UDF specification,
+ *  and revision 3 of the ECMA 167 standard [equivalent to ISO 13346].
+ *    http://www.osta.org/
+ *    http://www.ecma.ch/
+ *    http://www.iso.org/
+ *
+ * CONTACTS
+ *  E-mail regarding any portion of the Linux UDF file system should be
+ *  directed to the development team mailing list (run by majordomo):
+ *	  linux_udf@hpesjro.fc.hp.com
+ *
+ * COPYRIGHT
+ *  This file is distributed under the terms of the GNU General Public
+ *  License (GPL). Copies of the GPL can be obtained from:
+ *    ftp://prep.ai.mit.edu/pub/gnu/GPL
+ *  Each contributing author retains all rights to their own work.
+ *
+ *  (C) 1998 Dave Boynton
+ *  (C) 1998-2004 Ben Fennema
+ *  (C) 2000 Stelias Computing Inc
+ *
+ * HISTORY
+ *
+ *  09/24/98 dgb  changed to allow compiling outside of kernel, and
+ *                added some debugging.
+ *  10/01/98 dgb  updated to allow (some) possibility of compiling w/2.0.34
+ *  10/16/98      attempting some multi-session support
+ *  10/17/98      added freespace count for "df"
+ *  11/11/98 gr   added novrs option
+ *  11/26/98 dgb  added fileset,anchor mount options
+ *  12/06/98 blf  really hosed things royally. vat/sparing support. sequenced vol descs
+ *                rewrote option handling based on isofs
+ *  12/20/98      find the free space bitmap (if it exists)
+ */
+
+#include "udfdecl.h"    
+
+#include <linux/config.h>
+#include <linux/blkdev.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/parser.h>
+#include <linux/stat.h>
+#include <linux/cdrom.h>
+#include <linux/nls.h>
+#include <linux/smp_lock.h>
+#include <linux/buffer_head.h>
+#include <linux/vfs.h>
+#include <linux/vmalloc.h>
+#include <asm/byteorder.h>
+
+#include <linux/udf_fs.h>
+#include "udf_sb.h"
+#include "udf_i.h"
+
+#include <linux/init.h>
+#include <asm/uaccess.h>
+
+#define VDS_POS_PRIMARY_VOL_DESC	0
+#define VDS_POS_UNALLOC_SPACE_DESC	1
+#define VDS_POS_LOGICAL_VOL_DESC	2
+#define VDS_POS_PARTITION_DESC		3
+#define VDS_POS_IMP_USE_VOL_DESC	4
+#define VDS_POS_VOL_DESC_PTR		5
+#define VDS_POS_TERMINATING_DESC	6
+#define VDS_POS_LENGTH			7
+
+static char error_buf[1024];
+
+/* These are the "meat" - everything else is stuffing */
+static int udf_fill_super(struct super_block *, void *, int);
+static void udf_put_super(struct super_block *);
+static void udf_write_super(struct super_block *);
+static int udf_remount_fs(struct super_block *, int *, char *);
+static int udf_check_valid(struct super_block *, int, int);
+static int udf_vrs(struct super_block *sb, int silent);
+static int udf_load_partition(struct super_block *, kernel_lb_addr *);
+static int udf_load_logicalvol(struct super_block *, struct buffer_head *, kernel_lb_addr *);
+static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad);
+static void udf_find_anchor(struct super_block *);
+static int udf_find_fileset(struct super_block *, kernel_lb_addr *, kernel_lb_addr *);
+static void udf_load_pvoldesc(struct super_block *, struct buffer_head *);
+static void udf_load_fileset(struct super_block *, struct buffer_head *, kernel_lb_addr *);
+static void udf_load_partdesc(struct super_block *, struct buffer_head *);
+static void udf_open_lvid(struct super_block *);
+static void udf_close_lvid(struct super_block *);
+static unsigned int udf_count_free(struct super_block *);
+static int udf_statfs(struct super_block *, struct kstatfs *);
+
+/* UDF filesystem type */
+static struct super_block *udf_get_sb(struct file_system_type *fs_type,
+	int flags, const char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super);
+}
+
+static struct file_system_type udf_fstype = {
+	.owner		= THIS_MODULE,
+	.name		= "udf",
+	.get_sb		= udf_get_sb,
+	.kill_sb	= kill_block_super,
+	.fs_flags	= FS_REQUIRES_DEV,
+};
+
+static kmem_cache_t * udf_inode_cachep;
+
+static struct inode *udf_alloc_inode(struct super_block *sb)
+{
+	struct udf_inode_info *ei;
+	ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, SLAB_KERNEL);
+	if (!ei)
+		return NULL;
+	return &ei->vfs_inode;
+}
+
+static void udf_destroy_inode(struct inode *inode)
+{
+	kmem_cache_free(udf_inode_cachep, UDF_I(inode));
+}
+
+static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+{
+	struct udf_inode_info *ei = (struct udf_inode_info *) foo;
+
+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR)
+	{
+		ei->i_ext.i_data = NULL;
+		inode_init_once(&ei->vfs_inode);
+	}
+}
+
+static int init_inodecache(void)
+{
+	udf_inode_cachep = kmem_cache_create("udf_inode_cache",
+					     sizeof(struct udf_inode_info),
+					     0, SLAB_RECLAIM_ACCOUNT,
+					     init_once, NULL);
+	if (udf_inode_cachep == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
+static void destroy_inodecache(void)
+{
+	if (kmem_cache_destroy(udf_inode_cachep))
+		printk(KERN_INFO "udf_inode_cache: not all structures were freed\n");
+}
+
+/* Superblock operations */
+static struct super_operations udf_sb_ops = {
+	.alloc_inode		= udf_alloc_inode,
+	.destroy_inode		= udf_destroy_inode,
+	.write_inode		= udf_write_inode,
+	.delete_inode		= udf_delete_inode,
+	.clear_inode		= udf_clear_inode,
+	.put_super		= udf_put_super,
+	.write_super		= udf_write_super,
+	.statfs			= udf_statfs,
+	.remount_fs		= udf_remount_fs,
+};
+
+struct udf_options
+{
+	unsigned char novrs;
+	unsigned int blocksize;
+	unsigned int session;
+	unsigned int lastblock;
+	unsigned int anchor;
+	unsigned int volume;
+	unsigned short partition;
+	unsigned int fileset;
+	unsigned int rootdir;
+	unsigned int flags;
+	mode_t umask;
+	gid_t gid;
+	uid_t uid;
+	struct nls_table *nls_map;
+};
+
+static int __init init_udf_fs(void)
+{
+	int err;
+	err = init_inodecache();
+	if (err)
+		goto out1;
+	err = register_filesystem(&udf_fstype);
+	if (err)
+		goto out;
+	return 0;
+out:
+	destroy_inodecache();
+out1:
+	return err;
+}
+
+static void __exit exit_udf_fs(void)
+{
+	unregister_filesystem(&udf_fstype);
+	destroy_inodecache();
+}
+
+module_init(init_udf_fs)
+module_exit(exit_udf_fs)
+
+/*
+ * udf_parse_options
+ *
+ * PURPOSE
+ *	Parse mount options.
+ *
+ * DESCRIPTION
+ *	The following mount options are supported:
+ *
+ *	gid=		Set the default group.
+ *	umask=		Set the default umask.
+ *	uid=		Set the default user.
+ *	bs=		Set the block size.
+ *	unhide		Show otherwise hidden files.
+ *	undelete	Show deleted files in lists.
+ *	adinicb		Embed data in the inode (default)
+ *	noadinicb	Don't embed data in the inode
+ *	shortad		Use short ad's
+ *	longad		Use long ad's (default)
+ *	nostrict	Unset strict conformance
+ *	iocharset=	Set the NLS character set
+ *
+ *	The remaining are for debugging and disaster recovery:
+ *
+ *	novrs		Skip volume sequence recognition 
+ *
+ *	The following expect a offset from 0.
+ *
+ *	session=	Set the CDROM session (default= last session)
+ *	anchor=		Override standard anchor location. (default= 256)
+ *	volume=		Override the VolumeDesc location. (unused)
+ *	partition=	Override the PartitionDesc location. (unused)
+ *	lastblock=	Set the last block of the filesystem/
+ *
+ *	The following expect a offset from the partition root.
+ *
+ *	fileset=	Override the fileset block location. (unused)
+ *	rootdir=	Override the root directory location. (unused)
+ *		WARNING: overriding the rootdir to a non-directory may
+ *		yield highly unpredictable results.
+ *
+ * PRE-CONDITIONS
+ *	options		Pointer to mount options string.
+ *	uopts		Pointer to mount options variable.
+ *
+ * POST-CONDITIONS
+ *	<return>	1	Mount options parsed okay.
+ *	<return>	0	Error parsing mount options.
+ *
+ * HISTORY
+ *	July 1, 1997 - Andrew E. Mileski
+ *	Written, tested, and released.
+ */
+
+enum {
+	Opt_novrs, Opt_nostrict, Opt_bs, Opt_unhide, Opt_undelete,
+	Opt_noadinicb, Opt_adinicb, Opt_shortad, Opt_longad,
+	Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
+	Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
+	Opt_rootdir, Opt_utf8, Opt_iocharset,
+	Opt_err
+};
+
+static match_table_t tokens = {
+	{Opt_novrs, "novrs"},
+	{Opt_nostrict, "nostrict"},
+	{Opt_bs, "bs=%u"},
+	{Opt_unhide, "unhide"},
+	{Opt_undelete, "undelete"},
+	{Opt_noadinicb, "noadinicb"},
+	{Opt_adinicb, "adinicb"},
+	{Opt_shortad, "shortad"},
+	{Opt_longad, "longad"},
+	{Opt_gid, "gid=%u"},
+	{Opt_uid, "uid=%u"},
+	{Opt_umask, "umask=%o"},
+	{Opt_session, "session=%u"},
+	{Opt_lastblock, "lastblock=%u"},
+	{Opt_anchor, "anchor=%u"},
+	{Opt_volume, "volume=%u"},
+	{Opt_partition, "partition=%u"},
+	{Opt_fileset, "fileset=%u"},
+	{Opt_rootdir, "rootdir=%u"},
+	{Opt_utf8, "utf8"},
+	{Opt_iocharset, "iocharset=%s"},
+	{Opt_err, NULL}
+};
+
+static int
+udf_parse_options(char *options, struct udf_options *uopt)
+{
+	char *p;
+	int option;
+
+	uopt->novrs = 0;
+	uopt->blocksize = 2048;
+	uopt->partition = 0xFFFF;
+	uopt->session = 0xFFFFFFFF;
+	uopt->lastblock = 0;
+	uopt->anchor = 0;
+	uopt->volume = 0xFFFFFFFF;
+	uopt->rootdir = 0xFFFFFFFF;
+	uopt->fileset = 0xFFFFFFFF;
+	uopt->nls_map = NULL;
+
+	if (!options)
+		return 1;
+
+	while ((p = strsep(&options, ",")) != NULL)
+	{
+		substring_t args[MAX_OPT_ARGS];
+		int token;
+		if (!*p)
+			continue;
+
+		token = match_token(p, tokens, args);
+		switch (token)
+		{
+			case Opt_novrs:
+				uopt->novrs = 1;
+			case Opt_bs:
+				if (match_int(&args[0], &option))
+					return 0;
+				uopt->blocksize = option;
+				break;
+			case Opt_unhide:
+				uopt->flags |= (1 << UDF_FLAG_UNHIDE);
+				break;
+			case Opt_undelete:
+				uopt->flags |= (1 << UDF_FLAG_UNDELETE);
+				break;
+			case Opt_noadinicb:
+				uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB);
+				break;
+			case Opt_adinicb:
+				uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB);
+				break;
+			case Opt_shortad:
+				uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD);
+				break;
+			case Opt_longad:
+				uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD);
+				break;
+			case Opt_gid:
+				if (match_int(args, &option))
+					return 0;
+				uopt->gid = option;
+				break;
+			case Opt_uid:
+				if (match_int(args, &option))
+					return 0;
+				uopt->uid = option;
+				break;
+			case Opt_umask:
+				if (match_octal(args, &option))
+					return 0;
+				uopt->umask = option;
+				break;
+			case Opt_nostrict:
+				uopt->flags &= ~(1 << UDF_FLAG_STRICT);
+				break;
+			case Opt_session:
+				if (match_int(args, &option))
+					return 0;
+				uopt->session = option;
+				break;
+			case Opt_lastblock:
+				if (match_int(args, &option))
+					return 0;
+				uopt->lastblock = option;
+				break;
+			case Opt_anchor:
+				if (match_int(args, &option))
+					return 0;
+				uopt->anchor = option;
+				break;
+			case Opt_volume:
+				if (match_int(args, &option))
+					return 0;
+				uopt->volume = option;
+				break;
+			case Opt_partition:
+				if (match_int(args, &option))
+					return 0;
+				uopt->partition = option;
+				break;
+			case Opt_fileset:
+				if (match_int(args, &option))
+					return 0;
+				uopt->fileset = option;
+				break;
+			case Opt_rootdir:
+				if (match_int(args, &option))
+					return 0;
+				uopt->rootdir = option;
+				break;
+			case Opt_utf8:
+				uopt->flags |= (1 << UDF_FLAG_UTF8);
+				break;
+#ifdef CONFIG_UDF_NLS
+			case Opt_iocharset:
+				uopt->nls_map = load_nls(args[0].from);
+				uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
+				break;
+#endif
+			default:
+				printk(KERN_ERR "udf: bad mount option \"%s\" "
+						"or missing value\n", p);
+			return 0;
+		}
+	}
+	return 1;
+}
+
+void
+udf_write_super(struct super_block *sb)
+{
+	lock_kernel();
+	if (!(sb->s_flags & MS_RDONLY))
+		udf_open_lvid(sb);
+	sb->s_dirt = 0;
+	unlock_kernel();
+}
+
+static int
+udf_remount_fs(struct super_block *sb, int *flags, char *options)
+{
+	struct udf_options uopt;
+
+	uopt.flags = UDF_SB(sb)->s_flags ;
+	uopt.uid   = UDF_SB(sb)->s_uid ;
+	uopt.gid   = UDF_SB(sb)->s_gid ;
+	uopt.umask = UDF_SB(sb)->s_umask ;
+
+	if ( !udf_parse_options(options, &uopt) )
+		return -EINVAL;
+
+	UDF_SB(sb)->s_flags = uopt.flags;
+	UDF_SB(sb)->s_uid   = uopt.uid;
+	UDF_SB(sb)->s_gid   = uopt.gid;
+	UDF_SB(sb)->s_umask = uopt.umask;
+
+	if (UDF_SB_LVIDBH(sb)) {
+		int write_rev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev);
+		if (write_rev > UDF_MAX_WRITE_VERSION)
+			*flags |= MS_RDONLY;
+	}
+
+	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
+		return 0;
+	if (*flags & MS_RDONLY)
+		udf_close_lvid(sb);
+	else
+		udf_open_lvid(sb);
+
+	return 0;
+}
+
+/*
+ * udf_set_blocksize
+ *
+ * PURPOSE
+ *	Set the block size to be used in all transfers.
+ *
+ * DESCRIPTION
+ *	To allow room for a DMA transfer, it is best to guess big when unsure.
+ *	This routine picks 2048 bytes as the blocksize when guessing. This
+ *	should be adequate until devices with larger block sizes become common.
+ *
+ *	Note that the Linux kernel can currently only deal with blocksizes of
+ *	512, 1024, 2048, 4096, and 8192 bytes.
+ *
+ * PRE-CONDITIONS
+ *	sb			Pointer to _locked_ superblock.
+ *
+ * POST-CONDITIONS
+ *	sb->s_blocksize		Blocksize.
+ *	sb->s_blocksize_bits	log2 of blocksize.
+ *	<return>	0	Blocksize is valid.
+ *	<return>	1	Blocksize is invalid.
+ *
+ * HISTORY
+ *	July 1, 1997 - Andrew E. Mileski
+ *	Written, tested, and released.
+ */
+static  int
+udf_set_blocksize(struct super_block *sb, int bsize)
+{
+	if (!sb_min_blocksize(sb, bsize)) {
+		udf_debug("Bad block size (%d)\n", bsize);
+		printk(KERN_ERR "udf: bad block size (%d)\n", bsize);
+		return 0;
+	}
+	return sb->s_blocksize;
+}
+
+static int
+udf_vrs(struct super_block *sb, int silent)
+{
+	struct volStructDesc *vsd = NULL;
+	int sector = 32768;
+	int sectorsize;
+	struct buffer_head *bh = NULL;
+	int iso9660=0;
+	int nsr02=0;
+	int nsr03=0;
+
+	/* Block size must be a multiple of 512 */
+	if (sb->s_blocksize & 511)
+		return 0;
+
+	if (sb->s_blocksize < sizeof(struct volStructDesc))
+		sectorsize = sizeof(struct volStructDesc);
+	else
+		sectorsize = sb->s_blocksize;
+
+	sector += (UDF_SB_SESSION(sb) << sb->s_blocksize_bits);
+
+	udf_debug("Starting at sector %u (%ld byte sectors)\n",
+		(sector >> sb->s_blocksize_bits), sb->s_blocksize);
+	/* Process the sequence (if applicable) */
+	for (;!nsr02 && !nsr03; sector += sectorsize)
+	{
+		/* Read a block */
+		bh = udf_tread(sb, sector >> sb->s_blocksize_bits);
+		if (!bh)
+			break;
+
+		/* Look for ISO  descriptors */
+		vsd = (struct volStructDesc *)(bh->b_data +
+			(sector & (sb->s_blocksize - 1)));
+
+		if (vsd->stdIdent[0] == 0)
+		{
+			udf_release_data(bh);
+			break;
+		}
+		else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN))
+		{
+			iso9660 = sector;
+			switch (vsd->structType)
+			{
+				case 0: 
+					udf_debug("ISO9660 Boot Record found\n");
+					break;
+				case 1: 
+					udf_debug("ISO9660 Primary Volume Descriptor found\n");
+					break;
+				case 2: 
+					udf_debug("ISO9660 Supplementary Volume Descriptor found\n");
+					break;
+				case 3: 
+					udf_debug("ISO9660 Volume Partition Descriptor found\n");
+					break;
+				case 255: 
+					udf_debug("ISO9660 Volume Descriptor Set Terminator found\n");
+					break;
+				default: 
+					udf_debug("ISO9660 VRS (%u) found\n", vsd->structType);
+					break;
+			}
+		}
+		else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN))
+		{
+		}
+		else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN))
+		{
+			udf_release_data(bh);
+			break;
+		}
+		else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN))
+		{
+			nsr02 = sector;
+		}
+		else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN))
+		{
+			nsr03 = sector;
+		}
+		udf_release_data(bh);
+	}
+
+	if (nsr03)
+		return nsr03;
+	else if (nsr02)
+		return nsr02;
+	else if (sector - (UDF_SB_SESSION(sb) << sb->s_blocksize_bits) == 32768)
+		return -1;
+	else
+		return 0;
+}
+
+/*
+ * udf_find_anchor
+ *
+ * PURPOSE
+ *	Find an anchor volume descriptor.
+ *
+ * PRE-CONDITIONS
+ *	sb			Pointer to _locked_ superblock.
+ *	lastblock		Last block on media.
+ *
+ * POST-CONDITIONS
+ *	<return>		1 if not found, 0 if ok
+ *
+ * HISTORY
+ *	July 1, 1997 - Andrew E. Mileski
+ *	Written, tested, and released.
+ */
+static void
+udf_find_anchor(struct super_block *sb)
+{
+	int lastblock = UDF_SB_LASTBLOCK(sb);
+	struct buffer_head *bh = NULL;
+	uint16_t ident;
+	uint32_t location;
+	int i;
+
+	if (lastblock)
+	{
+		int varlastblock = udf_variable_to_fixed(lastblock);
+		int last[] =  { lastblock, lastblock - 2,
+				lastblock - 150, lastblock - 152,
+				varlastblock, varlastblock - 2,
+				varlastblock - 150, varlastblock - 152 };
+
+		lastblock = 0;
+
+		/* Search for an anchor volume descriptor pointer */
+
+		/*  according to spec, anchor is in either:
+		 *     block 256
+		 *     lastblock-256
+		 *     lastblock
+		 *  however, if the disc isn't closed, it could be 512 */
+
+		for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
+		{
+			if (last[i] < 0 || !(bh = sb_bread(sb, last[i])))
+			{
+				ident = location = 0;
+			}
+			else
+			{
+				ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
+				location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
+				udf_release_data(bh);
+			}
+	
+			if (ident == TAG_IDENT_AVDP)
+			{
+				if (location == last[i] - UDF_SB_SESSION(sb))
+				{
+					lastblock = UDF_SB_ANCHOR(sb)[0] = last[i] - UDF_SB_SESSION(sb);
+					UDF_SB_ANCHOR(sb)[1] = last[i] - 256 - UDF_SB_SESSION(sb);
+				}
+				else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb))
+				{
+					UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+					lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb);
+					UDF_SB_ANCHOR(sb)[1] = lastblock - 256 - UDF_SB_SESSION(sb);
+				}
+				else
+					udf_debug("Anchor found at block %d, location mismatch %d.\n",
+						last[i], location);
+			}
+			else if (ident == TAG_IDENT_FE || ident == TAG_IDENT_EFE)
+			{
+				lastblock = last[i];
+				UDF_SB_ANCHOR(sb)[3] = 512;
+			}
+			else
+			{
+				if (last[i] < 256 || !(bh = sb_bread(sb, last[i] - 256)))
+				{
+					ident = location = 0;
+				}
+				else
+				{
+					ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
+					location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
+					udf_release_data(bh);
+				}
+	
+				if (ident == TAG_IDENT_AVDP &&
+					location == last[i] - 256 - UDF_SB_SESSION(sb))
+				{
+					lastblock = last[i];
+					UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
+				}
+				else
+				{
+					if (last[i] < 312 + UDF_SB_SESSION(sb) || !(bh = sb_bread(sb, last[i] - 312 - UDF_SB_SESSION(sb))))
+					{
+						ident = location = 0;
+					}
+					else
+					{
+						ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
+						location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
+						udf_release_data(bh);
+					}
+	
+					if (ident == TAG_IDENT_AVDP &&
+						location == udf_variable_to_fixed(last[i]) - 256)
+					{
+						UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+						lastblock = udf_variable_to_fixed(last[i]);
+						UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
+					}
+				}
+			}
+		}
+	}
+
+	if (!lastblock)
+	{
+		/* We havn't found the lastblock. check 312 */
+		if ((bh = sb_bread(sb, 312 + UDF_SB_SESSION(sb))))
+		{
+			ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
+			location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
+			udf_release_data(bh);
+
+			if (ident == TAG_IDENT_AVDP && location == 256)
+				UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+		}
+	}
+
+	for (i=0; i<sizeof(UDF_SB_ANCHOR(sb))/sizeof(int); i++)
+	{
+		if (UDF_SB_ANCHOR(sb)[i])
+		{
+			if (!(bh = udf_read_tagged(sb,
+				UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i], &ident)))
+			{
+				UDF_SB_ANCHOR(sb)[i] = 0;
+			}
+			else
+			{
+				udf_release_data(bh);
+				if ((ident != TAG_IDENT_AVDP) && (i ||
+					(ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE)))
+				{
+					UDF_SB_ANCHOR(sb)[i] = 0;
+				}
+			}
+		}
+	}
+
+	UDF_SB_LASTBLOCK(sb) = lastblock;
+}
+
+static int 
+udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr *root)
+{
+	struct buffer_head *bh = NULL;
+	long lastblock;
+	uint16_t ident;
+
+	if (fileset->logicalBlockNum != 0xFFFFFFFF ||
+		fileset->partitionReferenceNum != 0xFFFF)
+	{
+		bh = udf_read_ptagged(sb, *fileset, 0, &ident);
+
+		if (!bh)
+			return 1;
+		else if (ident != TAG_IDENT_FSD)
+		{
+			udf_release_data(bh);
+			return 1;
+		}
+			
+	}
+
+	if (!bh) /* Search backwards through the partitions */
+	{
+		kernel_lb_addr newfileset;
+
+		return 1;
+		
+		for (newfileset.partitionReferenceNum=UDF_SB_NUMPARTS(sb)-1;
+			(newfileset.partitionReferenceNum != 0xFFFF &&
+				fileset->logicalBlockNum == 0xFFFFFFFF &&
+				fileset->partitionReferenceNum == 0xFFFF);
+			newfileset.partitionReferenceNum--)
+		{
+			lastblock = UDF_SB_PARTLEN(sb, newfileset.partitionReferenceNum);
+			newfileset.logicalBlockNum = 0;
+
+			do
+			{
+				bh = udf_read_ptagged(sb, newfileset, 0, &ident);
+				if (!bh)
+				{
+					newfileset.logicalBlockNum ++;
+					continue;
+				}
+
+				switch (ident)
+				{
+					case TAG_IDENT_SBD:
+					{
+						struct spaceBitmapDesc *sp;
+						sp = (struct spaceBitmapDesc *)bh->b_data;
+						newfileset.logicalBlockNum += 1 +
+							((le32_to_cpu(sp->numOfBytes) + sizeof(struct spaceBitmapDesc) - 1)
+								>> sb->s_blocksize_bits);
+						udf_release_data(bh);
+						break;
+					}
+					case TAG_IDENT_FSD:
+					{
+						*fileset = newfileset;
+						break;
+					}
+					default:
+					{
+						newfileset.logicalBlockNum ++;
+						udf_release_data(bh);
+						bh = NULL;
+						break;
+					}
+				}
+			}
+			while (newfileset.logicalBlockNum < lastblock &&
+				fileset->logicalBlockNum == 0xFFFFFFFF &&
+				fileset->partitionReferenceNum == 0xFFFF);
+		}
+	}
+
+	if ((fileset->logicalBlockNum != 0xFFFFFFFF ||
+		fileset->partitionReferenceNum != 0xFFFF) && bh)
+	{
+		udf_debug("Fileset at block=%d, partition=%d\n",
+			fileset->logicalBlockNum, fileset->partitionReferenceNum);
+
+		UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum;
+		udf_load_fileset(sb, bh, root);
+		udf_release_data(bh);
+		return 0;
+	}
+	return 1;
+}
+
+static void 
+udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
+{
+	struct primaryVolDesc *pvoldesc;
+	time_t recording;
+	long recording_usec;
+	struct ustr instr;
+	struct ustr outstr;
+
+	pvoldesc = (struct primaryVolDesc *)bh->b_data;
+
+	if ( udf_stamp_to_time(&recording, &recording_usec,
+		lets_to_cpu(pvoldesc->recordingDateAndTime)) )
+	{
+		kernel_timestamp ts;
+		ts = lets_to_cpu(pvoldesc->recordingDateAndTime);
+		udf_debug("recording time %ld/%ld, %04u/%02u/%02u %02u:%02u (%x)\n",
+			recording, recording_usec,
+			ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.typeAndTimezone);
+		UDF_SB_RECORDTIME(sb).tv_sec = recording;
+		UDF_SB_RECORDTIME(sb).tv_nsec = recording_usec * 1000;
+	}
+
+	if ( !udf_build_ustr(&instr, pvoldesc->volIdent, 32) )
+	{
+		if (udf_CS0toUTF8(&outstr, &instr))
+		{
+			strncpy( UDF_SB_VOLIDENT(sb), outstr.u_name,
+				outstr.u_len > 31 ? 31 : outstr.u_len);
+			udf_debug("volIdent[] = '%s'\n", UDF_SB_VOLIDENT(sb));
+		}
+	}
+
+	if ( !udf_build_ustr(&instr, pvoldesc->volSetIdent, 128) )
+	{
+		if (udf_CS0toUTF8(&outstr, &instr))
+			udf_debug("volSetIdent[] = '%s'\n", outstr.u_name);
+	}
+}
+
+static void 
+udf_load_fileset(struct super_block *sb, struct buffer_head *bh, kernel_lb_addr *root)
+{
+	struct fileSetDesc *fset;
+
+	fset = (struct fileSetDesc *)bh->b_data;
+
+	*root = lelb_to_cpu(fset->rootDirectoryICB.extLocation);
+
+	UDF_SB_SERIALNUM(sb) = le16_to_cpu(fset->descTag.tagSerialNum);
+
+	udf_debug("Rootdir at block=%d, partition=%d\n", 
+		root->logicalBlockNum, root->partitionReferenceNum);
+}
+
+static void 
+udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
+{
+	struct partitionDesc *p;
+	int i;
+
+	p = (struct partitionDesc *)bh->b_data;
+
+	for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
+	{
+		udf_debug("Searching map: (%d == %d)\n", 
+			UDF_SB_PARTMAPS(sb)[i].s_partition_num, le16_to_cpu(p->partitionNumber));
+		if (UDF_SB_PARTMAPS(sb)[i].s_partition_num == le16_to_cpu(p->partitionNumber))
+		{
+			UDF_SB_PARTLEN(sb,i) = le32_to_cpu(p->partitionLength); /* blocks */
+			UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation);
+			if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_READ_ONLY)
+				UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_READ_ONLY;
+			if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_WRITE_ONCE)
+				UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_WRITE_ONCE;
+			if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_REWRITABLE)
+				UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_REWRITABLE;
+			if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_OVERWRITABLE)
+				UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_OVERWRITABLE;
+
+			if (!strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) ||
+				!strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03))
+			{
+				struct partitionHeaderDesc *phd;
+
+				phd = (struct partitionHeaderDesc *)(p->partitionContentsUse);
+				if (phd->unallocSpaceTable.extLength)
+				{
+					kernel_lb_addr loc = { le32_to_cpu(phd->unallocSpaceTable.extPosition), i };
+
+					UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table =
+						udf_iget(sb, loc);
+					UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_TABLE;
+					udf_debug("unallocSpaceTable (part %d) @ %ld\n",
+						i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table->i_ino);
+				}
+				if (phd->unallocSpaceBitmap.extLength)
+				{
+					UDF_SB_ALLOC_BITMAP(sb, i, s_uspace);
+					if (UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap != NULL)
+					{
+						UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extLength =
+							le32_to_cpu(phd->unallocSpaceBitmap.extLength);
+						UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition =
+							le32_to_cpu(phd->unallocSpaceBitmap.extPosition);
+						UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_BITMAP;
+						udf_debug("unallocSpaceBitmap (part %d) @ %d\n",
+							i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition);
+					}
+				}
+				if (phd->partitionIntegrityTable.extLength)
+					udf_debug("partitionIntegrityTable (part %d)\n", i);
+				if (phd->freedSpaceTable.extLength)
+				{
+					kernel_lb_addr loc = { le32_to_cpu(phd->freedSpaceTable.extPosition), i };
+
+					UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table =
+						udf_iget(sb, loc);
+					UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_TABLE;
+					udf_debug("freedSpaceTable (part %d) @ %ld\n",
+						i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table->i_ino);
+				}
+				if (phd->freedSpaceBitmap.extLength)
+				{
+					UDF_SB_ALLOC_BITMAP(sb, i, s_fspace);
+					if (UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap != NULL)
+					{
+						UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extLength =
+							le32_to_cpu(phd->freedSpaceBitmap.extLength);
+						UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition =
+							le32_to_cpu(phd->freedSpaceBitmap.extPosition);
+						UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_BITMAP;
+						udf_debug("freedSpaceBitmap (part %d) @ %d\n",
+							i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition);
+					}
+				}
+			}
+			break;
+		}
+	}
+	if (i == UDF_SB_NUMPARTS(sb))
+	{
+		udf_debug("Partition (%d) not found in partition map\n", le16_to_cpu(p->partitionNumber));
+	}
+	else
+	{
+		udf_debug("Partition (%d:%d type %x) starts at physical %d, block length %d\n",
+			le16_to_cpu(p->partitionNumber), i, UDF_SB_PARTTYPE(sb,i),
+			UDF_SB_PARTROOT(sb,i), UDF_SB_PARTLEN(sb,i));
+	}
+}
+
+static int 
+udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_addr *fileset)
+{
+	struct logicalVolDesc *lvd;
+	int i, j, offset;
+	uint8_t type;
+
+	lvd = (struct logicalVolDesc *)bh->b_data;
+
+	UDF_SB_ALLOC_PARTMAPS(sb, le32_to_cpu(lvd->numPartitionMaps));
+
+	for (i=0,offset=0;
+		 i<UDF_SB_NUMPARTS(sb) && offset<le32_to_cpu(lvd->mapTableLength);
+		 i++,offset+=((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapLength)
+	{
+		type = ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapType;
+		if (type == 1)
+		{
+			struct genericPartitionMap1 *gpm1 = (struct genericPartitionMap1 *)&(lvd->partitionMaps[offset]);
+			UDF_SB_PARTTYPE(sb,i) = UDF_TYPE1_MAP15;
+			UDF_SB_PARTVSN(sb,i) = le16_to_cpu(gpm1->volSeqNum);
+			UDF_SB_PARTNUM(sb,i) = le16_to_cpu(gpm1->partitionNum);
+			UDF_SB_PARTFUNC(sb,i) = NULL;
+		}
+		else if (type == 2)
+		{
+			struct udfPartitionMap2 *upm2 = (struct udfPartitionMap2 *)&(lvd->partitionMaps[offset]);
+			if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL)))
+			{
+				if (le16_to_cpu(((__le16 *)upm2->partIdent.identSuffix)[0]) == 0x0150)
+				{
+					UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP15;
+					UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt15;
+				}
+				else if (le16_to_cpu(((__le16 *)upm2->partIdent.identSuffix)[0]) == 0x0200)
+				{
+					UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP20;
+					UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt20;
+				}
+			}
+			else if (!strncmp(upm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE)))
+			{
+				uint32_t loc;
+				uint16_t ident;
+				struct sparingTable *st;
+				struct sparablePartitionMap *spm = (struct sparablePartitionMap *)&(lvd->partitionMaps[offset]);
+
+				UDF_SB_PARTTYPE(sb,i) = UDF_SPARABLE_MAP15;
+				UDF_SB_TYPESPAR(sb,i).s_packet_len = le16_to_cpu(spm->packetLength);
+				for (j=0; j<spm->numSparingTables; j++)
+				{
+					loc = le32_to_cpu(spm->locSparingTable[j]);
+					UDF_SB_TYPESPAR(sb,i).s_spar_map[j] =
+						udf_read_tagged(sb, loc, loc, &ident);
+					if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL)
+					{
+						st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,i).s_spar_map[j]->b_data;
+						if (ident != 0 ||
+							strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)))
+						{
+							udf_release_data(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]);
+							UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL;
+						}
+					}
+				}
+				UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_spar15;
+			}
+			else
+			{
+				udf_debug("Unknown ident: %s\n", upm2->partIdent.ident);
+				continue;
+			}
+			UDF_SB_PARTVSN(sb,i) = le16_to_cpu(upm2->volSeqNum);
+			UDF_SB_PARTNUM(sb,i) = le16_to_cpu(upm2->partitionNum);
+		}
+		udf_debug("Partition (%d:%d) type %d on volume %d\n",
+			i, UDF_SB_PARTNUM(sb,i), type, UDF_SB_PARTVSN(sb,i));
+	}
+
+	if (fileset)
+	{
+		long_ad *la = (long_ad *)&(lvd->logicalVolContentsUse[0]);
+
+		*fileset = lelb_to_cpu(la->extLocation);
+		udf_debug("FileSet found in LogicalVolDesc at block=%d, partition=%d\n",
+			fileset->logicalBlockNum,
+			fileset->partitionReferenceNum);
+	}
+	if (lvd->integritySeqExt.extLength)
+		udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt));
+	return 0;
+}
+
+/*
+ * udf_load_logicalvolint
+ *
+ */
+static void
+udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc)
+{
+	struct buffer_head *bh = NULL;
+	uint16_t ident;
+
+	while (loc.extLength > 0 &&
+		(bh = udf_read_tagged(sb, loc.extLocation,
+			loc.extLocation, &ident)) &&
+		ident == TAG_IDENT_LVID)
+	{
+		UDF_SB_LVIDBH(sb) = bh;
+		
+		if (UDF_SB_LVID(sb)->nextIntegrityExt.extLength)
+			udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt));
+		
+		if (UDF_SB_LVIDBH(sb) != bh)
+			udf_release_data(bh);
+		loc.extLength -= sb->s_blocksize;
+		loc.extLocation ++;
+	}
+	if (UDF_SB_LVIDBH(sb) != bh)
+		udf_release_data(bh);
+}
+
+/*
+ * udf_process_sequence
+ *
+ * PURPOSE
+ *	Process a main/reserve volume descriptor sequence.
+ *
+ * PRE-CONDITIONS
+ *	sb			Pointer to _locked_ superblock.
+ *	block			First block of first extent of the sequence.
+ *	lastblock		Lastblock of first extent of the sequence.
+ *
+ * HISTORY
+ *	July 1, 1997 - Andrew E. Mileski
+ *	Written, tested, and released.
+ */
+static  int
+udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_lb_addr *fileset)
+{
+	struct buffer_head *bh = NULL;
+	struct udf_vds_record vds[VDS_POS_LENGTH];
+	struct generic_desc *gd;
+	struct volDescPtr *vdp;
+	int done=0;
+	int i,j;
+	uint32_t vdsn;
+	uint16_t ident;
+	long next_s = 0, next_e = 0;
+
+	memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
+
+	/* Read the main descriptor sequence */
+	for (;(!done && block <= lastblock); block++)
+	{
+
+		bh = udf_read_tagged(sb, block, block, &ident);
+		if (!bh) 
+			break;
+
+		/* Process each descriptor (ISO 13346 3/8.3-8.4) */
+		gd = (struct generic_desc *)bh->b_data;
+		vdsn = le32_to_cpu(gd->volDescSeqNum);
+		switch (ident)
+		{
+			case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
+				if (vdsn >= vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum)
+				{
+					vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum = vdsn;
+					vds[VDS_POS_PRIMARY_VOL_DESC].block = block;
+				}
+				break;
+			case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */
+				if (vdsn >= vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum)
+				{
+					vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum = vdsn;
+					vds[VDS_POS_VOL_DESC_PTR].block = block;
+
+					vdp = (struct volDescPtr *)bh->b_data;
+					next_s = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);
+					next_e = le32_to_cpu(vdp->nextVolDescSeqExt.extLength);
+					next_e = next_e >> sb->s_blocksize_bits;
+					next_e += next_s;
+				}
+				break;
+			case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
+				if (vdsn >= vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum)
+				{
+					vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum = vdsn;
+					vds[VDS_POS_IMP_USE_VOL_DESC].block = block;
+				}
+				break;
+			case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
+				if (!vds[VDS_POS_PARTITION_DESC].block)
+					vds[VDS_POS_PARTITION_DESC].block = block;
+				break;
+			case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */
+				if (vdsn >= vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum)
+				{
+					vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum = vdsn;
+					vds[VDS_POS_LOGICAL_VOL_DESC].block = block;
+				}
+				break;
+			case TAG_IDENT_USD: /* ISO 13346 3/10.8 */
+				if (vdsn >= vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum)
+				{
+					vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum = vdsn;
+					vds[VDS_POS_UNALLOC_SPACE_DESC].block = block;
+				}
+				break;
+			case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
+				vds[VDS_POS_TERMINATING_DESC].block = block;
+				if (next_e)
+				{
+					block = next_s;
+					lastblock = next_e;
+					next_s = next_e = 0;
+				}
+				else
+					done = 1;
+				break;
+		}
+		udf_release_data(bh);
+	}
+	for (i=0; i<VDS_POS_LENGTH; i++)
+	{
+		if (vds[i].block)
+		{
+			bh = udf_read_tagged(sb, vds[i].block, vds[i].block, &ident);
+
+			if (i == VDS_POS_PRIMARY_VOL_DESC)
+				udf_load_pvoldesc(sb, bh);
+			else if (i == VDS_POS_LOGICAL_VOL_DESC)
+				udf_load_logicalvol(sb, bh, fileset);
+			else if (i == VDS_POS_PARTITION_DESC)
+			{
+				struct buffer_head *bh2 = NULL;
+				udf_load_partdesc(sb, bh);
+				for (j=vds[i].block+1; j<vds[VDS_POS_TERMINATING_DESC].block; j++)
+				{
+					bh2 = udf_read_tagged(sb, j, j, &ident);
+					gd = (struct generic_desc *)bh2->b_data;
+					if (ident == TAG_IDENT_PD)
+						udf_load_partdesc(sb, bh2);
+					udf_release_data(bh2);
+				}
+			}
+			udf_release_data(bh);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * udf_check_valid()
+ */
+static int
+udf_check_valid(struct super_block *sb, int novrs, int silent)
+{
+	long block;
+
+	if (novrs)
+	{
+		udf_debug("Validity check skipped because of novrs option\n");
+		return 0;
+	}
+	/* Check that it is NSR02 compliant */
+	/* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */
+	else if ((block = udf_vrs(sb, silent)) == -1)
+	{
+		udf_debug("Failed to read byte 32768. Assuming open disc. Skipping validity check\n");
+		if (!UDF_SB_LASTBLOCK(sb))
+			UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
+		return 0;
+	}
+	else 
+		return !block;
+}
+
+static int
+udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
+{
+	struct anchorVolDescPtr *anchor;
+	uint16_t ident;
+	struct buffer_head *bh;
+	long main_s, main_e, reserve_s, reserve_e;
+	int i, j;
+
+	if (!sb)
+		return 1;
+
+	for (i=0; i<sizeof(UDF_SB_ANCHOR(sb))/sizeof(int); i++)
+	{
+		if (UDF_SB_ANCHOR(sb)[i] && (bh = udf_read_tagged(sb,
+			UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i], &ident)))
+		{
+			anchor = (struct anchorVolDescPtr *)bh->b_data;
+
+			/* Locate the main sequence */
+			main_s = le32_to_cpu( anchor->mainVolDescSeqExt.extLocation );
+			main_e = le32_to_cpu( anchor->mainVolDescSeqExt.extLength );
+			main_e = main_e >> sb->s_blocksize_bits;
+			main_e += main_s;
+	
+			/* Locate the reserve sequence */
+			reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation);
+			reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength);
+			reserve_e = reserve_e >> sb->s_blocksize_bits;
+			reserve_e += reserve_s;
+
+			udf_release_data(bh);
+
+			/* Process the main & reserve sequences */
+			/* responsible for finding the PartitionDesc(s) */
+			if (!(udf_process_sequence(sb, main_s, main_e, fileset) &&
+				udf_process_sequence(sb, reserve_s, reserve_e, fileset)))
+			{
+				break;
+			}
+		}
+	}
+
+	if (i == sizeof(UDF_SB_ANCHOR(sb))/sizeof(int))
+	{
+		udf_debug("No Anchor block found\n");
+		return 1;
+	}
+	else
+		udf_debug("Using anchor in block %d\n", UDF_SB_ANCHOR(sb)[i]);
+
+	for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
+	{
+		switch UDF_SB_PARTTYPE(sb, i)
+		{
+			case UDF_VIRTUAL_MAP15:
+			case UDF_VIRTUAL_MAP20:
+			{
+				kernel_lb_addr ino;
+
+				if (!UDF_SB_LASTBLOCK(sb))
+				{
+					UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
+					udf_find_anchor(sb);
+				}
+
+				if (!UDF_SB_LASTBLOCK(sb))
+				{
+					udf_debug("Unable to determine Lastblock (For Virtual Partition)\n");
+					return 1;
+				}
+
+				for (j=0; j<UDF_SB_NUMPARTS(sb); j++)
+				{
+					if (j != i &&
+						UDF_SB_PARTVSN(sb,i) == UDF_SB_PARTVSN(sb,j) &&
+						UDF_SB_PARTNUM(sb,i) == UDF_SB_PARTNUM(sb,j))
+					{
+						ino.partitionReferenceNum = j;
+						ino.logicalBlockNum = UDF_SB_LASTBLOCK(sb) -
+							UDF_SB_PARTROOT(sb,j);
+						break;
+					}
+				}
+
+				if (j == UDF_SB_NUMPARTS(sb))
+					return 1;
+
+				if (!(UDF_SB_VAT(sb) = udf_iget(sb, ino)))
+					return 1;
+
+				if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP15)
+				{
+					UDF_SB_TYPEVIRT(sb,i).s_start_offset = udf_ext0_offset(UDF_SB_VAT(sb));
+					UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - 36) >> 2;
+				}
+				else if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP20)
+				{
+					struct buffer_head *bh = NULL;
+					uint32_t pos;
+
+					pos = udf_block_map(UDF_SB_VAT(sb), 0);
+					bh = sb_bread(sb, pos);
+					UDF_SB_TYPEVIRT(sb,i).s_start_offset =
+						le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +
+							udf_ext0_offset(UDF_SB_VAT(sb));
+					UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size -
+						UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2;
+					udf_release_data(bh);
+				}
+				UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0);
+				UDF_SB_PARTLEN(sb,i) = UDF_SB_PARTLEN(sb,ino.partitionReferenceNum);
+			}
+		}
+	}
+	return 0;
+}
+
+static void udf_open_lvid(struct super_block *sb)
+{
+	if (UDF_SB_LVIDBH(sb))
+	{
+		int i;
+		kernel_timestamp cpu_time;
+
+		UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
+		UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
+		if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))
+			UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
+		UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_OPEN;
+
+		UDF_SB_LVID(sb)->descTag.descCRC =
+			cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
+			le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0));
+
+		UDF_SB_LVID(sb)->descTag.tagChecksum = 0;
+		for (i=0; i<16; i++)
+			if (i != 4)
+				UDF_SB_LVID(sb)->descTag.tagChecksum +=
+					((uint8_t *)&(UDF_SB_LVID(sb)->descTag))[i];
+
+		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
+	}
+}
+
+static void udf_close_lvid(struct super_block *sb)
+{
+	if (UDF_SB_LVIDBH(sb) &&
+		UDF_SB_LVID(sb)->integrityType == LVID_INTEGRITY_TYPE_OPEN)
+	{
+		int i;
+		kernel_timestamp cpu_time;
+
+		UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
+		UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
+		if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))
+			UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
+		if (UDF_MAX_WRITE_VERSION > le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev))
+			UDF_SB_LVIDIU(sb)->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION);
+		if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev))
+			UDF_SB_LVIDIU(sb)->minUDFReadRev = cpu_to_le16(UDF_SB_UDFREV(sb));
+		if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev))
+			UDF_SB_LVIDIU(sb)->minUDFWriteRev = cpu_to_le16(UDF_SB_UDFREV(sb));
+		UDF_SB_LVID(sb)->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
+
+		UDF_SB_LVID(sb)->descTag.descCRC =
+			cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
+			le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0));
+
+		UDF_SB_LVID(sb)->descTag.tagChecksum = 0;
+		for (i=0; i<16; i++)
+			if (i != 4)
+				UDF_SB_LVID(sb)->descTag.tagChecksum +=
+					((uint8_t *)&(UDF_SB_LVID(sb)->descTag))[i];
+
+		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
+	}
+}
+
+/*
+ * udf_read_super
+ *
+ * PURPOSE
+ *	Complete the specified super block.
+ *
+ * PRE-CONDITIONS
+ *	sb			Pointer to superblock to complete - never NULL.
+ *	sb->s_dev		Device to read suberblock from.
+ *	options			Pointer to mount options.
+ *	silent			Silent flag.
+ *
+ * HISTORY
+ *	July 1, 1997 - Andrew E. Mileski
+ *	Written, tested, and released.
+ */
+static int udf_fill_super(struct super_block *sb, void *options, int silent)
+{
+	int i;
+	struct inode *inode=NULL;
+	struct udf_options uopt;
+	kernel_lb_addr rootdir, fileset;
+	struct udf_sb_info *sbi;
+
+	uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
+	uopt.uid = -1;
+	uopt.gid = -1;
+	uopt.umask = 0;
+
+	sbi = kmalloc(sizeof(struct udf_sb_info), GFP_KERNEL);
+	if (!sbi)
+		return -ENOMEM;
+	sb->s_fs_info = sbi;
+	memset(UDF_SB(sb), 0x00, sizeof(struct udf_sb_info));
+
+	init_MUTEX(&sbi->s_alloc_sem);
+
+	if (!udf_parse_options((char *)options, &uopt))
+		goto error_out;
+
+	if (uopt.flags & (1 << UDF_FLAG_UTF8) &&
+	    uopt.flags & (1 << UDF_FLAG_NLS_MAP))
+	{
+		udf_error(sb, "udf_read_super",
+			"utf8 cannot be combined with iocharset\n");
+		goto error_out;
+	}
+#ifdef CONFIG_UDF_NLS
+	if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map)
+	{
+		uopt.nls_map = load_nls_default();
+		if (!uopt.nls_map)
+			uopt.flags &= ~(1 << UDF_FLAG_NLS_MAP);
+		else
+			udf_debug("Using default NLS map\n");
+	}
+#endif
+	if (!(uopt.flags & (1 << UDF_FLAG_NLS_MAP)))
+		uopt.flags |= (1 << UDF_FLAG_UTF8);
+
+	fileset.logicalBlockNum = 0xFFFFFFFF;
+	fileset.partitionReferenceNum = 0xFFFF;
+
+	UDF_SB(sb)->s_flags = uopt.flags;
+	UDF_SB(sb)->s_uid = uopt.uid;
+	UDF_SB(sb)->s_gid = uopt.gid;
+	UDF_SB(sb)->s_umask = uopt.umask;
+	UDF_SB(sb)->s_nls_map = uopt.nls_map;
+
+	/* Set the block size for all transfers */
+	if (!udf_set_blocksize(sb, uopt.blocksize))
+		goto error_out;
+
+	if ( uopt.session == 0xFFFFFFFF )
+		UDF_SB_SESSION(sb) = udf_get_last_session(sb);
+	else
+		UDF_SB_SESSION(sb) = uopt.session;
+
+	udf_debug("Multi-session=%d\n", UDF_SB_SESSION(sb));
+
+	UDF_SB_LASTBLOCK(sb) = uopt.lastblock;
+	UDF_SB_ANCHOR(sb)[0] = UDF_SB_ANCHOR(sb)[1] = 0;
+	UDF_SB_ANCHOR(sb)[2] = uopt.anchor;
+	UDF_SB_ANCHOR(sb)[3] = 256;
+
+	if (udf_check_valid(sb, uopt.novrs, silent)) /* read volume recognition sequences */
+	{
+		printk("UDF-fs: No VRS found\n");
+ 		goto error_out;
+	}
+
+	udf_find_anchor(sb);
+
+	/* Fill in the rest of the superblock */
+	sb->s_op = &udf_sb_ops;
+	sb->dq_op = NULL;
+	sb->s_dirt = 0;
+	sb->s_magic = UDF_SUPER_MAGIC;
+	sb->s_time_gran = 1000;
+
+	if (udf_load_partition(sb, &fileset))
+	{
+		printk("UDF-fs: No partition found (1)\n");
+		goto error_out;
+	}
+
+	udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
+
+	if ( UDF_SB_LVIDBH(sb) )
+	{
+		uint16_t minUDFReadRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev);
+		uint16_t minUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev);
+		/* uint16_t maxUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev); */
+
+		if (minUDFReadRev > UDF_MAX_READ_VERSION)
+		{
+			printk("UDF-fs: minUDFReadRev=%x (max is %x)\n",
+				le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev),
+				UDF_MAX_READ_VERSION);
+			goto error_out;
+		}
+		else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION)
+		{
+			sb->s_flags |= MS_RDONLY;
+		}
+
+		UDF_SB_UDFREV(sb) = minUDFWriteRev;
+
+		if (minUDFReadRev >= UDF_VERS_USE_EXTENDED_FE)
+			UDF_SET_FLAG(sb, UDF_FLAG_USE_EXTENDED_FE);
+		if (minUDFReadRev >= UDF_VERS_USE_STREAMS)
+			UDF_SET_FLAG(sb, UDF_FLAG_USE_STREAMS);
+	}
+
+	if ( !UDF_SB_NUMPARTS(sb) )
+	{
+		printk("UDF-fs: No partition found (2)\n");
+		goto error_out;
+	}
+
+	if ( udf_find_fileset(sb, &fileset, &rootdir) )
+	{
+		printk("UDF-fs: No fileset found\n");
+		goto error_out;
+	}
+
+	if (!silent)
+	{
+		kernel_timestamp ts;
+		udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb));
+		udf_info("UDF %s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
+			UDFFS_VERSION, UDFFS_DATE,
+			UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute,
+			ts.typeAndTimezone);
+	}
+	if (!(sb->s_flags & MS_RDONLY))
+		udf_open_lvid(sb);
+
+	/* Assign the root inode */
+	/* assign inodes by physical block number */
+	/* perhaps it's not extensible enough, but for now ... */
+	inode = udf_iget(sb, rootdir); 
+	if (!inode)
+	{
+		printk("UDF-fs: Error in udf_iget, block=%d, partition=%d\n",
+			rootdir.logicalBlockNum, rootdir.partitionReferenceNum);
+		goto error_out;
+	}
+
+	/* Allocate a dentry for the root inode */
+	sb->s_root = d_alloc_root(inode);
+	if (!sb->s_root)
+	{
+		printk("UDF-fs: Couldn't allocate root dentry\n");
+		iput(inode);
+		goto error_out;
+	}
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
+	return 0;
+
+error_out:
+	if (UDF_SB_VAT(sb))
+		iput(UDF_SB_VAT(sb));
+	if (UDF_SB_NUMPARTS(sb))
+	{
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
+			iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
+			iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
+			UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace);
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
+			UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace);
+		if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
+		{
+			for (i=0; i<4; i++)
+				udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+		}
+	}
+#ifdef CONFIG_UDF_NLS
+	if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
+		unload_nls(UDF_SB(sb)->s_nls_map);
+#endif
+	if (!(sb->s_flags & MS_RDONLY))
+		udf_close_lvid(sb);
+	udf_release_data(UDF_SB_LVIDBH(sb));
+	UDF_SB_FREE(sb);
+	kfree(sbi);
+	sb->s_fs_info = NULL;
+	return -EINVAL;
+}
+
+void udf_error(struct super_block *sb, const char *function,
+	const char *fmt, ...)
+{
+	va_list args;
+
+	if (!(sb->s_flags & MS_RDONLY))
+	{
+		/* mark sb error */
+		sb->s_dirt = 1;
+	}
+	va_start(args, fmt);
+	vsprintf(error_buf, fmt, args);
+	va_end(args);
+	printk (KERN_CRIT "UDF-fs error (device %s): %s: %s\n",
+		sb->s_id, function, error_buf);
+}
+
+void udf_warning(struct super_block *sb, const char *function,
+	const char *fmt, ...)
+{
+	va_list args;
+
+	va_start (args, fmt);
+	vsprintf(error_buf, fmt, args);
+	va_end(args);
+	printk(KERN_WARNING "UDF-fs warning (device %s): %s: %s\n",
+		sb->s_id, function, error_buf);
+}
+
+/*
+ * udf_put_super
+ *
+ * PURPOSE
+ *	Prepare for destruction of the superblock.
+ *
+ * DESCRIPTION
+ *	Called before the filesystem is unmounted.
+ *
+ * HISTORY
+ *	July 1, 1997 - Andrew E. Mileski
+ *	Written, tested, and released.
+ */
+static void
+udf_put_super(struct super_block *sb)
+{
+	int i;
+
+	if (UDF_SB_VAT(sb))
+		iput(UDF_SB_VAT(sb));
+	if (UDF_SB_NUMPARTS(sb))
+	{
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
+			iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
+			iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
+			UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace);
+		if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
+			UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace);
+		if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
+		{
+			for (i=0; i<4; i++)
+				udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+		}
+	}
+#ifdef CONFIG_UDF_NLS
+	if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
+		unload_nls(UDF_SB(sb)->s_nls_map);
+#endif
+	if (!(sb->s_flags & MS_RDONLY))
+		udf_close_lvid(sb);
+	udf_release_data(UDF_SB_LVIDBH(sb));
+	UDF_SB_FREE(sb);
+	kfree(sb->s_fs_info);
+	sb->s_fs_info = NULL;
+}
+
+/*
+ * udf_stat_fs
+ *
+ * PURPOSE
+ *	Return info about the filesystem.
+ *
+ * DESCRIPTION
+ *	Called by sys_statfs()
+ *
+ * HISTORY
+ *	July 1, 1997 - Andrew E. Mileski
+ *	Written, tested, and released.
+ */
+static int
+udf_statfs(struct super_block *sb, struct kstatfs *buf)
+{
+	buf->f_type = UDF_SUPER_MAGIC;
+	buf->f_bsize = sb->s_blocksize;
+	buf->f_blocks = UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb));
+	buf->f_bfree = udf_count_free(sb);
+	buf->f_bavail = buf->f_bfree;
+	buf->f_files = (UDF_SB_LVIDBH(sb) ?
+		(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) +
+		le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)) : 0) + buf->f_bfree;
+	buf->f_ffree = buf->f_bfree;
+	/* __kernel_fsid_t f_fsid */
+	buf->f_namelen = UDF_NAME_LEN-2;
+
+	return 0;
+}
+
+static unsigned char udf_bitmap_lookup[16] = {
+	0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
+};
+
+static unsigned int
+udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
+{
+	struct buffer_head *bh = NULL;
+	unsigned int accum = 0;
+	int index;
+	int block = 0, newblock;
+	kernel_lb_addr loc;
+	uint32_t bytes;
+	uint8_t value;
+	uint8_t *ptr;
+	uint16_t ident;
+	struct spaceBitmapDesc *bm;
+
+	lock_kernel();
+
+	loc.logicalBlockNum = bitmap->s_extPosition;
+	loc.partitionReferenceNum = UDF_SB_PARTITION(sb);
+	bh = udf_read_ptagged(sb, loc, 0, &ident);
+
+	if (!bh)
+	{
+		printk(KERN_ERR "udf: udf_count_free failed\n");
+		goto out;
+	}
+	else if (ident != TAG_IDENT_SBD)
+	{
+		udf_release_data(bh);
+		printk(KERN_ERR "udf: udf_count_free failed\n");
+		goto out;
+	}
+
+	bm = (struct spaceBitmapDesc *)bh->b_data;
+	bytes = le32_to_cpu(bm->numOfBytes);
+	index = sizeof(struct spaceBitmapDesc); /* offset in first block only */
+	ptr = (uint8_t *)bh->b_data;
+
+	while ( bytes > 0 )
+	{
+		while ((bytes > 0) && (index < sb->s_blocksize))
+		{
+			value = ptr[index];
+			accum += udf_bitmap_lookup[ value & 0x0f ];
+			accum += udf_bitmap_lookup[ value >> 4 ];
+			index++;
+			bytes--;
+		}
+		if ( bytes )
+		{
+			udf_release_data(bh);
+			newblock = udf_get_lb_pblock(sb, loc, ++block);
+			bh = udf_tread(sb, newblock);
+			if (!bh)
+			{
+				udf_debug("read failed\n");
+				goto out;
+			}
+			index = 0;
+			ptr = (uint8_t *)bh->b_data;
+		}
+	}
+	udf_release_data(bh);
+
+out:
+	unlock_kernel();
+
+	return accum;
+}
+
+static unsigned int
+udf_count_free_table(struct super_block *sb, struct inode * table)
+{
+	unsigned int accum = 0;
+	uint32_t extoffset, elen;
+	kernel_lb_addr bloc, eloc;
+	int8_t etype;
+	struct buffer_head *bh = NULL;
+
+	lock_kernel();
+
+	bloc = UDF_I_LOCATION(table);
+	extoffset = sizeof(struct unallocSpaceEntry);
+
+	while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
+	{
+		accum += (elen >> table->i_sb->s_blocksize_bits);
+	}
+	udf_release_data(bh);
+
+	unlock_kernel();
+
+	return accum;
+}
+	
+static unsigned int
+udf_count_free(struct super_block *sb)
+{
+	unsigned int accum = 0;
+
+	if (UDF_SB_LVIDBH(sb))
+	{
+		if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
+		{
+			accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
+
+			if (accum == 0xFFFFFFFF)
+				accum = 0;
+		}
+	}
+
+	if (accum)
+		return accum;
+
+	if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
+	{
+		accum += udf_count_free_bitmap(sb,
+			UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_bitmap);
+	}
+	if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
+	{
+		accum += udf_count_free_bitmap(sb,
+			UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_bitmap);
+	}
+	if (accum)
+		return accum;
+
+	if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
+	{
+		accum += udf_count_free_table(sb,
+			UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
+	}
+	if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
+	{
+		accum += udf_count_free_table(sb,
+			UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
+	}
+
+	return accum;
+}
