/*
 * 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/
 *
 * 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, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore
};

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_uforget, "uid=forget"},
	{Opt_uignore, "uid=ignore"},
	{Opt_gforget, "gid=forget"},
	{Opt_gignore, "gid=ignore"},
	{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
			case Opt_uignore:
				uopt->flags |= (1 << UDF_FLAG_UID_IGNORE);
				break;
			case Opt_uforget:
				uopt->flags |= (1 << UDF_FLAG_UID_FORGET);
				break;
			case Opt_gignore:
			    uopt->flags |= (1 << UDF_FLAG_GID_IGNORE);
				break;
			case Opt_gforget:
			    uopt->flags |= (1 << UDF_FLAG_GID_FORGET);
				break;
			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;
}
