/*
 * 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/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 dentry *, struct kstatfs *);

/* UDF filesystem type */
static int udf_get_sb(struct file_system_type *fs_type,
		      int flags, const char *dev_name, void *data,
		      struct vfsmount *mnt)
{
	return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super, mnt);
}

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 struct kmem_cache *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,
						       GFP_KERNEL);
	if (!ei)
		return NULL;

	ei->i_unique = 0;
	ei->i_lenExtents = 0;
	ei->i_next_alloc_block = 0;
	ei->i_next_alloc_goal = 0;
	ei->i_strat4096 = 0;

	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, struct kmem_cache *cachep, unsigned long flags)
{
	struct udf_inode_info *ei = (struct udf_inode_info *)foo;

	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 |
						 SLAB_MEM_SPREAD),
					     init_once);
	if (udf_inode_cachep == NULL)
		return -ENOMEM;
	return 0;
}

static void destroy_inodecache(void)
{
	kmem_cache_destroy(udf_inode_cachep);
}

/* Superblock operations */
static const 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) {
			brelse(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)) {
			brelse(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;
		}
		brelse(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 < ARRAY_SIZE(last); 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);
				brelse(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);
					brelse(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);
						brelse(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);
			brelse(bh);

			if (ident == TAG_IDENT_AVDP && location == 256)
				UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
		}
	}

	for (i = 0; i < ARRAY_SIZE(UDF_SB_ANCHOR(sb)); 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 {
				brelse(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) {
			brelse(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);
						brelse(bh);
						break;
					}
				case TAG_IDENT_FSD:
					{
						*fileset = newfileset;
						break;
					}
				default:
					{
						newfileset.logicalBlockNum++;
						brelse(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);
		brelse(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)))
						{
							brelse(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)
			brelse(bh);
		loc.extLength -= sb->s_blocksize;
		loc.extLocation++;
	}
	if (UDF_SB_LVIDBH(sb) != bh)
		brelse(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;
		}
		brelse(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);
					brelse(bh2);
				}
			}
			brelse(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 < ARRAY_SIZE(UDF_SB_ANCHOR(sb)); 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;

			brelse(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 == ARRAY_SIZE(UDF_SB_ANCHOR(sb))) {
		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 uninitialized_var(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);
					if (!bh)
						return 1;
					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;
					brelse(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));

	mutex_init(&sbi->s_alloc_mutex);

	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_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
	    UDF_PART_FLAG_READ_ONLY) {
		printk
		    ("UDF-fs: Partition marked readonly; forcing readonly mount\n");
		sb->s_flags |= MS_RDONLY;
	}

	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++)
				brelse(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);
	brelse(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);
	vsnprintf(error_buf, sizeof(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);
	vsnprintf(error_buf, sizeof(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++)
				brelse(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);
	brelse(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 dentry *dentry, struct kstatfs *buf)
{
	struct super_block *sb = dentry->d_sb;

	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) {
		brelse(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) {
			brelse(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;
		}
	}
	brelse(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 elen;
	kernel_lb_addr eloc;
	int8_t etype;
	struct extent_position epos;

	lock_kernel();

	epos.block = UDF_I_LOCATION(table);
	epos.offset = sizeof(struct unallocSpaceEntry);
	epos.bh = NULL;

	while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
		accum += (elen >> table->i_sb->s_blocksize_bits);
	brelse(epos.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;
}
