/*
 * inode.c
 *
 * PURPOSE
 *  Inode handling routines for the OSTA-UDF(tm) filesystem.
 *
 * 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) 1999-2000 Stelias Computing Inc
 *
 * HISTORY
 *
 *  10/04/98 dgb  Added rudimentary directory functions
 *  10/07/98      Fully working udf_block_map! It works!
 *  11/25/98      bmap altered to better support extents
 *  12/06/98 blf  partition support in udf_iget, udf_block_map and udf_read_inode
 *  12/12/98      rewrote udf_block_map to handle next extents and descs across
 *                block boundaries (which is not actually allowed)
 *  12/20/98      added support for strategy 4096
 *  03/07/99      rewrote udf_block_map (again)
 *                New funcs, inode_bmap, udf_next_aext
 *  04/19/99      Support for writing device EA's for major/minor #
 */

#include "udfdecl.h"
#include <linux/mm.h>
#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
#include <linux/writeback.h>
#include <linux/slab.h>

#include "udf_i.h"
#include "udf_sb.h"

MODULE_AUTHOR("Ben Fennema");
MODULE_DESCRIPTION("Universal Disk Format Filesystem");
MODULE_LICENSE("GPL");

#define EXTENT_MERGE_SIZE 5

static mode_t udf_convert_permissions(struct fileEntry *);
static int udf_update_inode(struct inode *, int);
static void udf_fill_inode(struct inode *, struct buffer_head *);
static struct buffer_head *inode_getblk(struct inode *, long, int *,
	long *, int *);
static int8_t udf_insert_aext(struct inode *, kernel_lb_addr, int,
	kernel_lb_addr, uint32_t, struct buffer_head *);
static void udf_split_extents(struct inode *, int *, int, int,
	kernel_long_ad [EXTENT_MERGE_SIZE], int *);
static void udf_prealloc_extents(struct inode *, int, int,
	 kernel_long_ad [EXTENT_MERGE_SIZE], int *);
static void udf_merge_extents(struct inode *,
	 kernel_long_ad [EXTENT_MERGE_SIZE], int *);
static void udf_update_extents(struct inode *,
	kernel_long_ad [EXTENT_MERGE_SIZE], int, int,
	kernel_lb_addr, uint32_t, struct buffer_head **);
static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);

/*
 * udf_delete_inode
 *
 * PURPOSE
 *	Clean-up before the specified inode is destroyed.
 *
 * DESCRIPTION
 *	This routine is called when the kernel destroys an inode structure
 *	ie. when iput() finds i_count == 0.
 *
 * HISTORY
 *	July 1, 1997 - Andrew E. Mileski
 *	Written, tested, and released.
 *
 *  Called at the last iput() if i_nlink is zero.
 */
void udf_delete_inode(struct inode * inode)
{
	truncate_inode_pages(&inode->i_data, 0);

	if (is_bad_inode(inode))
		goto no_delete;

	inode->i_size = 0;
	udf_truncate(inode);
	lock_kernel();

	udf_update_inode(inode, IS_SYNC(inode));
	udf_free_inode(inode);

	unlock_kernel();
	return;
no_delete:
	clear_inode(inode);
}

void udf_clear_inode(struct inode *inode)
{
	if (!(inode->i_sb->s_flags & MS_RDONLY)) {
		lock_kernel();
		udf_discard_prealloc(inode);
		unlock_kernel();
	}

	kfree(UDF_I_DATA(inode));
	UDF_I_DATA(inode) = NULL;
}

static int udf_writepage(struct page *page, struct writeback_control *wbc)
{
	return block_write_full_page(page, udf_get_block, wbc);
}

static int udf_readpage(struct file *file, struct page *page)
{
	return block_read_full_page(page, udf_get_block);
}

static int udf_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
{
	return block_prepare_write(page, from, to, udf_get_block);
}

static sector_t udf_bmap(struct address_space *mapping, sector_t block)
{
	return generic_block_bmap(mapping,block,udf_get_block);
}

const struct address_space_operations udf_aops = {
	.readpage		= udf_readpage,
	.writepage		= udf_writepage,
	.sync_page		= block_sync_page,
	.prepare_write		= udf_prepare_write,
	.commit_write		= generic_commit_write,
	.bmap			= udf_bmap,
};

void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
{
	struct page *page;
	char *kaddr;
	struct writeback_control udf_wbc = {
		.sync_mode = WB_SYNC_NONE,
		.nr_to_write = 1,
	};

	/* from now on we have normal address_space methods */
	inode->i_data.a_ops = &udf_aops;

	if (!UDF_I_LENALLOC(inode))
	{
		if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
			UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
		else
			UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
		mark_inode_dirty(inode);
		return;
	}

	page = grab_cache_page(inode->i_mapping, 0);
	BUG_ON(!PageLocked(page));

	if (!PageUptodate(page))
	{
		kaddr = kmap(page);
		memset(kaddr + UDF_I_LENALLOC(inode), 0x00,
			PAGE_CACHE_SIZE - UDF_I_LENALLOC(inode));
		memcpy(kaddr, UDF_I_DATA(inode) + UDF_I_LENEATTR(inode),
			UDF_I_LENALLOC(inode));
		flush_dcache_page(page);
		SetPageUptodate(page);
		kunmap(page);
	}
	memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0x00,
		UDF_I_LENALLOC(inode));
	UDF_I_LENALLOC(inode) = 0;
	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
	else
		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;

	inode->i_data.a_ops->writepage(page, &udf_wbc);
	page_cache_release(page);

	mark_inode_dirty(inode);
}

struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err)
{
	int newblock;
	struct buffer_head *sbh = NULL, *dbh = NULL;
	kernel_lb_addr bloc, eloc;
	uint32_t elen, extoffset;
	uint8_t alloctype;

	struct udf_fileident_bh sfibh, dfibh;
	loff_t f_pos = udf_ext0_offset(inode) >> 2;
	int size = (udf_ext0_offset(inode) + inode->i_size) >> 2;
	struct fileIdentDesc cfi, *sfi, *dfi;

	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
		alloctype = ICBTAG_FLAG_AD_SHORT;
	else
		alloctype = ICBTAG_FLAG_AD_LONG;

	if (!inode->i_size)
	{
		UDF_I_ALLOCTYPE(inode) = alloctype;
		mark_inode_dirty(inode);
		return NULL;
	}

	/* alloc block, and copy data to it */
	*block = udf_new_block(inode->i_sb, inode,
		UDF_I_LOCATION(inode).partitionReferenceNum,
		UDF_I_LOCATION(inode).logicalBlockNum, err);

	if (!(*block))
		return NULL;
	newblock = udf_get_pblock(inode->i_sb, *block,
		UDF_I_LOCATION(inode).partitionReferenceNum, 0);
	if (!newblock)
		return NULL;
	dbh = udf_tgetblk(inode->i_sb, newblock);
	if (!dbh)
		return NULL;
	lock_buffer(dbh);
	memset(dbh->b_data, 0x00, inode->i_sb->s_blocksize);
	set_buffer_uptodate(dbh);
	unlock_buffer(dbh);
	mark_buffer_dirty_inode(dbh, inode);

	sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
	sbh = sfibh.sbh = sfibh.ebh = NULL;
	dfibh.soffset = dfibh.eoffset = 0;
	dfibh.sbh = dfibh.ebh = dbh;
	while ( (f_pos < size) )
	{
		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
		sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL, NULL, NULL);
		if (!sfi)
		{
			udf_release_data(dbh);
			return NULL;
		}
		UDF_I_ALLOCTYPE(inode) = alloctype;
		sfi->descTag.tagLocation = cpu_to_le32(*block);
		dfibh.soffset = dfibh.eoffset;
		dfibh.eoffset += (sfibh.eoffset - sfibh.soffset);
		dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset);
		if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse,
			sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse)))
		{
			UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
			udf_release_data(dbh);
			return NULL;
		}
	}
	mark_buffer_dirty_inode(dbh, inode);

	memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode));
	UDF_I_LENALLOC(inode) = 0;
	bloc = UDF_I_LOCATION(inode);
	eloc.logicalBlockNum = *block;
	eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
	elen = inode->i_size;
	UDF_I_LENEXTENTS(inode) = elen;
	extoffset = udf_file_entry_alloc_offset(inode);
	udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0);
	/* UniqueID stuff */

	udf_release_data(sbh);
	mark_inode_dirty(inode);
	return dbh;
}

static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create)
{
	int err, new;
	struct buffer_head *bh;
	unsigned long phys;

	if (!create)
	{
		phys = udf_block_map(inode, block);
		if (phys)
			map_bh(bh_result, inode->i_sb, phys);
		return 0;
	}

	err = -EIO;
	new = 0;
	bh = NULL;

	lock_kernel();

	if (block < 0)
		goto abort_negative;

	if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1)
	{
		UDF_I_NEXT_ALLOC_BLOCK(inode) ++;
		UDF_I_NEXT_ALLOC_GOAL(inode) ++;
	}

	err = 0;

	bh = inode_getblk(inode, block, &err, &phys, &new);
	BUG_ON(bh);
	if (err)
		goto abort;
	BUG_ON(!phys);

	if (new)
		set_buffer_new(bh_result);
	map_bh(bh_result, inode->i_sb, phys);
abort:
	unlock_kernel();
	return err;

abort_negative:
	udf_warning(inode->i_sb, "udf_get_block", "block < 0");
	goto abort;
}

static struct buffer_head *
udf_getblk(struct inode *inode, long block, int create, int *err)
{
	struct buffer_head dummy;

	dummy.b_state = 0;
	dummy.b_blocknr = -1000;
	*err = udf_get_block(inode, block, &dummy, create);
	if (!*err && buffer_mapped(&dummy))
	{
		struct buffer_head *bh;
		bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
		if (buffer_new(&dummy))
		{
			lock_buffer(bh);
			memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
			set_buffer_uptodate(bh);
			unlock_buffer(bh);
			mark_buffer_dirty_inode(bh, inode);
		}
		return bh;
	}
	return NULL;
}

static struct buffer_head * inode_getblk(struct inode * inode, long block,
	int *err, long *phys, int *new)
{
	struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL;
	kernel_long_ad laarr[EXTENT_MERGE_SIZE];
	uint32_t pextoffset = 0, cextoffset = 0, nextoffset = 0;
	int count = 0, startnum = 0, endnum = 0;
	uint32_t elen = 0;
	kernel_lb_addr eloc, pbloc, cbloc, nbloc;
	int c = 1;
	uint64_t lbcount = 0, b_off = 0;
	uint32_t newblocknum, newblock, offset = 0;
	int8_t etype;
	int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
	char lastblock = 0;

	pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode);
	b_off = (uint64_t)block << inode->i_sb->s_blocksize_bits;
	pbloc = cbloc = nbloc = UDF_I_LOCATION(inode);

	/* find the extent which contains the block we are looking for.
       alternate between laarr[0] and laarr[1] for locations of the
       current extent, and the previous extent */
	do
	{
		if (pbh != cbh)
		{
			udf_release_data(pbh);
			atomic_inc(&cbh->b_count);
			pbh = cbh;
		}
		if (cbh != nbh)
		{
			udf_release_data(cbh);
			atomic_inc(&nbh->b_count);
			cbh = nbh;
		}

		lbcount += elen;

		pbloc = cbloc;
		cbloc = nbloc;

		pextoffset = cextoffset;
		cextoffset = nextoffset;

		if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) == -1)
			break;

		c = !c;

		laarr[c].extLength = (etype << 30) | elen;
		laarr[c].extLocation = eloc;

		if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
			pgoal = eloc.logicalBlockNum +
				((elen + inode->i_sb->s_blocksize - 1) >>
				inode->i_sb->s_blocksize_bits);

		count ++;
	} while (lbcount + elen <= b_off);

	b_off -= lbcount;
	offset = b_off >> inode->i_sb->s_blocksize_bits;

	/* if the extent is allocated and recorded, return the block
       if the extent is not a multiple of the blocksize, round up */

	if (etype == (EXT_RECORDED_ALLOCATED >> 30))
	{
		if (elen & (inode->i_sb->s_blocksize - 1))
		{
			elen = EXT_RECORDED_ALLOCATED |
				((elen + inode->i_sb->s_blocksize - 1) &
				~(inode->i_sb->s_blocksize - 1));
			etype = udf_write_aext(inode, nbloc, &cextoffset, eloc, elen, nbh, 1);
		}
		udf_release_data(pbh);
		udf_release_data(cbh);
		udf_release_data(nbh);
		newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset);
		*phys = newblock;
		return NULL;
	}

	if (etype == -1)
	{
		endnum = startnum = ((count > 1) ? 1 : count);
		if (laarr[c].extLength & (inode->i_sb->s_blocksize - 1))
		{
			laarr[c].extLength =
				(laarr[c].extLength & UDF_EXTENT_FLAG_MASK) |
				(((laarr[c].extLength & UDF_EXTENT_LENGTH_MASK) +
					inode->i_sb->s_blocksize - 1) &
				~(inode->i_sb->s_blocksize - 1));
			UDF_I_LENEXTENTS(inode) =
				(UDF_I_LENEXTENTS(inode) + inode->i_sb->s_blocksize - 1) &
					~(inode->i_sb->s_blocksize - 1);
		}
		c = !c;
		laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
			((offset + 1) << inode->i_sb->s_blocksize_bits);
		memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr));
		count ++;
		endnum ++;
		lastblock = 1;
	}
	else
		endnum = startnum = ((count > 2) ? 2 : count);

	/* if the current extent is in position 0, swap it with the previous */
	if (!c && count != 1)
	{
		laarr[2] = laarr[0];
		laarr[0] = laarr[1];
		laarr[1] = laarr[2];
		c = 1;
	}

	/* if the current block is located in a extent, read the next extent */
	if (etype != -1)
	{
		if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 0)) != -1)
		{
			laarr[c+1].extLength = (etype << 30) | elen;
			laarr[c+1].extLocation = eloc;
			count ++;
			startnum ++;
			endnum ++;
		}
		else
			lastblock = 1;
	}
	udf_release_data(cbh);
	udf_release_data(nbh);

	/* if the current extent is not recorded but allocated, get the
		block in the extent corresponding to the requested block */
	if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
		newblocknum = laarr[c].extLocation.logicalBlockNum + offset;
	else /* otherwise, allocate a new block */
	{
		if (UDF_I_NEXT_ALLOC_BLOCK(inode) == block)
			goal = UDF_I_NEXT_ALLOC_GOAL(inode);

		if (!goal)
		{
			if (!(goal = pgoal))
				goal = UDF_I_LOCATION(inode).logicalBlockNum + 1;
		}

		if (!(newblocknum = udf_new_block(inode->i_sb, inode,
			UDF_I_LOCATION(inode).partitionReferenceNum, goal, err)))
		{
			udf_release_data(pbh);
			*err = -ENOSPC;
			return NULL;
		}
		UDF_I_LENEXTENTS(inode) += inode->i_sb->s_blocksize;
	}

	/* if the extent the requsted block is located in contains multiple blocks,
       split the extent into at most three extents. blocks prior to requested
       block, requested block, and blocks after requested block */
	udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);

#ifdef UDF_PREALLOCATE
	/* preallocate blocks */
	udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
#endif

	/* merge any continuous blocks in laarr */
	udf_merge_extents(inode, laarr, &endnum);

	/* write back the new extents, inserting new extents if the new number
       of extents is greater than the old number, and deleting extents if
       the new number of extents is less than the old number */
	udf_update_extents(inode, laarr, startnum, endnum, pbloc, pextoffset, &pbh);

	udf_release_data(pbh);

	if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,
		UDF_I_LOCATION(inode).partitionReferenceNum, 0)))
	{
		return NULL;
	}
	*phys = newblock;
	*err = 0;
	*new = 1;
	UDF_I_NEXT_ALLOC_BLOCK(inode) = block;
	UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;
	inode->i_ctime = current_fs_time(inode->i_sb);

	if (IS_SYNC(inode))
		udf_sync_inode(inode);
	else
		mark_inode_dirty(inode);
	return result;
}

static void udf_split_extents(struct inode *inode, int *c, int offset, int newblocknum,
	kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
{
	if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) ||
		(laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
	{
		int curr = *c;
		int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) +
			inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
		int8_t etype = (laarr[curr].extLength >> 30);

		if (blen == 1)
			;
		else if (!offset || blen == offset + 1)
		{
			laarr[curr+2] = laarr[curr+1];
			laarr[curr+1] = laarr[curr];
		}
		else
		{
			laarr[curr+3] = laarr[curr+1];
			laarr[curr+2] = laarr[curr+1] = laarr[curr];
		}

		if (offset)
		{
			if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
			{
				udf_free_blocks(inode->i_sb, inode, laarr[curr].extLocation, 0, offset);
				laarr[curr].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
					(offset << inode->i_sb->s_blocksize_bits);
				laarr[curr].extLocation.logicalBlockNum = 0;
				laarr[curr].extLocation.partitionReferenceNum = 0;
			}
			else
				laarr[curr].extLength = (etype << 30) |
					(offset << inode->i_sb->s_blocksize_bits);
			curr ++;
			(*c) ++;
			(*endnum) ++;
		}
		
		laarr[curr].extLocation.logicalBlockNum = newblocknum;
		if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
			laarr[curr].extLocation.partitionReferenceNum =
				UDF_I_LOCATION(inode).partitionReferenceNum;
		laarr[curr].extLength = EXT_RECORDED_ALLOCATED |
			inode->i_sb->s_blocksize;
		curr ++;

		if (blen != offset + 1)
		{
			if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
				laarr[curr].extLocation.logicalBlockNum += (offset + 1);
			laarr[curr].extLength = (etype << 30) |
				((blen - (offset + 1)) << inode->i_sb->s_blocksize_bits);
			curr ++;
			(*endnum) ++;
		}
	}
}

static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
	 kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
{
	int start, length = 0, currlength = 0, i;

	if (*endnum >= (c+1))
	{
		if (!lastblock)
			return;
		else
			start = c;
	}
	else
	{
		if ((laarr[c+1].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
		{
			start = c+1;
			length = currlength = (((laarr[c+1].extLength & UDF_EXTENT_LENGTH_MASK) +
				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
		}
		else
			start = c;
	}

	for (i=start+1; i<=*endnum; i++)
	{
		if (i == *endnum)
		{
			if (lastblock)
				length += UDF_DEFAULT_PREALLOC_BLOCKS;
		}
		else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
			length += (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
		else
			break;
	}

	if (length)
	{
		int next = laarr[start].extLocation.logicalBlockNum +
			(((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
			inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
		int numalloc = udf_prealloc_blocks(inode->i_sb, inode,
			laarr[start].extLocation.partitionReferenceNum,
			next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? length :
				UDF_DEFAULT_PREALLOC_BLOCKS) - currlength);

		if (numalloc)
		{
			if (start == (c+1))
				laarr[start].extLength +=
					(numalloc << inode->i_sb->s_blocksize_bits);
			else
			{
				memmove(&laarr[c+2], &laarr[c+1],
					sizeof(long_ad) * (*endnum - (c+1)));
				(*endnum) ++;
				laarr[c+1].extLocation.logicalBlockNum = next;
				laarr[c+1].extLocation.partitionReferenceNum =
					laarr[c].extLocation.partitionReferenceNum;
				laarr[c+1].extLength = EXT_NOT_RECORDED_ALLOCATED |
					(numalloc << inode->i_sb->s_blocksize_bits);
				start = c+1;
			}

			for (i=start+1; numalloc && i<*endnum; i++)
			{
				int elen = ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
					inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;

				if (elen > numalloc)
				{
					laarr[i].extLength -=
						(numalloc << inode->i_sb->s_blocksize_bits);
					numalloc = 0;
				}
				else
				{
					numalloc -= elen;
					if (*endnum > (i+1))
						memmove(&laarr[i], &laarr[i+1], 
							sizeof(long_ad) * (*endnum - (i+1)));
					i --;
					(*endnum) --;
				}
			}
			UDF_I_LENEXTENTS(inode) += numalloc << inode->i_sb->s_blocksize_bits;
		}
	}
}

static void udf_merge_extents(struct inode *inode,
	 kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
{
	int i;

	for (i=0; i<(*endnum-1); i++)
	{
		if ((laarr[i].extLength >> 30) == (laarr[i+1].extLength >> 30))
		{
			if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) ||
				((laarr[i+1].extLocation.logicalBlockNum - laarr[i].extLocation.logicalBlockNum) ==
				(((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits)))
			{
				if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
					(laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) +
					inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK)
				{
					laarr[i+1].extLength = (laarr[i+1].extLength -
						(laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
						UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1);
					laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) +
						(UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize;
					laarr[i+1].extLocation.logicalBlockNum =
						laarr[i].extLocation.logicalBlockNum +
						((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) >>
							inode->i_sb->s_blocksize_bits);
				}
				else
				{
					laarr[i].extLength = laarr[i+1].extLength +
						(((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
						inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1));
					if (*endnum > (i+2))
						memmove(&laarr[i+1], &laarr[i+2],
							sizeof(long_ad) * (*endnum - (i+2)));
					i --;
					(*endnum) --;
				}
			}
		}
		else if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) &&
			((laarr[i+1].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)))
		{
			udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0,
				((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
				inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
			laarr[i].extLocation.logicalBlockNum = 0;
			laarr[i].extLocation.partitionReferenceNum = 0;

			if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
				(laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) +
				inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK)
			{
				laarr[i+1].extLength = (laarr[i+1].extLength -
					(laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
					UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1);
				laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) +
					(UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize;
			}
			else
			{
				laarr[i].extLength = laarr[i+1].extLength +
					(((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
					inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1));
				if (*endnum > (i+2))
					memmove(&laarr[i+1], &laarr[i+2],
						sizeof(long_ad) * (*endnum - (i+2)));
				i --;
				(*endnum) --;
			}
		}
		else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
		{
			udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0,
				((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
			       inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
			laarr[i].extLocation.logicalBlockNum = 0;
			laarr[i].extLocation.partitionReferenceNum = 0;
			laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) |
				EXT_NOT_RECORDED_NOT_ALLOCATED;
		}
	}
}

static void udf_update_extents(struct inode *inode,
	kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum,
	kernel_lb_addr pbloc, uint32_t pextoffset, struct buffer_head **pbh)
{
	int start = 0, i;
	kernel_lb_addr tmploc;
	uint32_t tmplen;

	if (startnum > endnum)
	{
		for (i=0; i<(startnum-endnum); i++)
		{
			udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation,
				laarr[i].extLength, *pbh);
		}
	}
	else if (startnum < endnum)
	{
		for (i=0; i<(endnum-startnum); i++)
		{
			udf_insert_aext(inode, pbloc, pextoffset, laarr[i].extLocation,
				laarr[i].extLength, *pbh);
			udf_next_aext(inode, &pbloc, &pextoffset, &laarr[i].extLocation,
				&laarr[i].extLength, pbh, 1);
			start ++;
		}
	}

	for (i=start; i<endnum; i++)
	{
		udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0);
		udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation,
			laarr[i].extLength, *pbh, 1);
	}
}

struct buffer_head * udf_bread(struct inode * inode, int block,
	int create, int * err)
{
	struct buffer_head * bh = NULL;

	bh = udf_getblk(inode, block, create, err);
	if (!bh)
		return NULL;

	if (buffer_uptodate(bh))
		return bh;
	ll_rw_block(READ, 1, &bh);
	wait_on_buffer(bh);
	if (buffer_uptodate(bh))
		return bh;
	brelse(bh);
	*err = -EIO;
	return NULL;
}

void udf_truncate(struct inode * inode)
{
	int offset;
	int err;

	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
			S_ISLNK(inode->i_mode)))
		return;
	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
		return;

	lock_kernel();
	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
	{
		if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
			inode->i_size))
		{
			udf_expand_file_adinicb(inode, inode->i_size, &err);
			if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
			{
				inode->i_size = UDF_I_LENALLOC(inode);
				unlock_kernel();
				return;
			}
			else
				udf_truncate_extents(inode);
		}
		else
		{
			offset = inode->i_size & (inode->i_sb->s_blocksize - 1);
			memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset, 0x00, inode->i_sb->s_blocksize - offset - udf_file_entry_alloc_offset(inode));
			UDF_I_LENALLOC(inode) = inode->i_size;
		}
	}
	else
	{
		block_truncate_page(inode->i_mapping, inode->i_size, udf_get_block);
		udf_truncate_extents(inode);
	}	

	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
	if (IS_SYNC(inode))
		udf_sync_inode (inode);
	else
		mark_inode_dirty(inode);
	unlock_kernel();
}

static void
__udf_read_inode(struct inode *inode)
{
	struct buffer_head *bh = NULL;
	struct fileEntry *fe;
	uint16_t ident;

	/*
	 * Set defaults, but the inode is still incomplete!
	 * Note: get_new_inode() sets the following on a new inode:
	 *      i_sb = sb
	 *      i_no = ino
	 *      i_flags = sb->s_flags
	 *      i_state = 0
	 * clean_inode(): zero fills and sets
	 *      i_count = 1
	 *      i_nlink = 1
	 *      i_op = NULL;
	 */
	inode->i_blksize = PAGE_SIZE;

	bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident);

	if (!bh)
	{
		printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n",
			inode->i_ino);
		make_bad_inode(inode);
		return;
	}

	if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE &&
		ident != TAG_IDENT_USE)
	{
		printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n",
			inode->i_ino, ident);
		udf_release_data(bh);
		make_bad_inode(inode);
		return;
	}

	fe = (struct fileEntry *)bh->b_data;

	if (le16_to_cpu(fe->icbTag.strategyType) == 4096)
	{
		struct buffer_head *ibh = NULL, *nbh = NULL;
		struct indirectEntry *ie;

		ibh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 1, &ident);
		if (ident == TAG_IDENT_IE)
		{
			if (ibh)
			{
				kernel_lb_addr loc;
				ie = (struct indirectEntry *)ibh->b_data;
	
				loc = lelb_to_cpu(ie->indirectICB.extLocation);
	
				if (ie->indirectICB.extLength && 
					(nbh = udf_read_ptagged(inode->i_sb, loc, 0, &ident)))
				{
					if (ident == TAG_IDENT_FE ||
						ident == TAG_IDENT_EFE)
					{
						memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr));
						udf_release_data(bh);
						udf_release_data(ibh);
						udf_release_data(nbh);
						__udf_read_inode(inode);
						return;
					}
					else
					{
						udf_release_data(nbh);
						udf_release_data(ibh);
					}
				}
				else
					udf_release_data(ibh);
			}
		}
		else
			udf_release_data(ibh);
	}
	else if (le16_to_cpu(fe->icbTag.strategyType) != 4)
	{
		printk(KERN_ERR "udf: unsupported strategy type: %d\n",
			le16_to_cpu(fe->icbTag.strategyType));
		udf_release_data(bh);
		make_bad_inode(inode);
		return;
	}
	udf_fill_inode(inode, bh);
	udf_release_data(bh);
}

static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
{
	struct fileEntry *fe;
	struct extendedFileEntry *efe;
	time_t convtime;
	long convtime_usec;
	int offset;

	fe = (struct fileEntry *)bh->b_data;
	efe = (struct extendedFileEntry *)bh->b_data;

	if (le16_to_cpu(fe->icbTag.strategyType) == 4)
		UDF_I_STRAT4096(inode) = 0;
	else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */
		UDF_I_STRAT4096(inode) = 1;

	UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK;
	UDF_I_UNIQUE(inode) = 0;
	UDF_I_LENEATTR(inode) = 0;
	UDF_I_LENEXTENTS(inode) = 0;
	UDF_I_LENALLOC(inode) = 0;
	UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
	UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
	if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_EFE)
	{
		UDF_I_EFE(inode) = 1;
		UDF_I_USE(inode) = 0;
		UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry), GFP_KERNEL);
		memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct extendedFileEntry), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));
	}
	else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE)
	{
		UDF_I_EFE(inode) = 0;
		UDF_I_USE(inode) = 0;
		UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct fileEntry), GFP_KERNEL);
		memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct fileEntry), inode->i_sb->s_blocksize - sizeof(struct fileEntry));
	}
	else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE)
	{
		UDF_I_EFE(inode) = 0;
		UDF_I_USE(inode) = 1;
		UDF_I_LENALLOC(inode) =
			le32_to_cpu(
				((struct unallocSpaceEntry *)bh->b_data)->lengthAllocDescs);
		UDF_I_DATA(inode) = kmalloc(inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry), GFP_KERNEL);
		memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct unallocSpaceEntry), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry));
		return;
	}

	inode->i_uid = le32_to_cpu(fe->uid);
	if (inode->i_uid == -1 || UDF_QUERY_FLAG(inode->i_sb,
					UDF_FLAG_UID_IGNORE))
		inode->i_uid = UDF_SB(inode->i_sb)->s_uid;

	inode->i_gid = le32_to_cpu(fe->gid);
	if (inode->i_gid == -1 || UDF_QUERY_FLAG(inode->i_sb,
					UDF_FLAG_GID_IGNORE))
		inode->i_gid = UDF_SB(inode->i_sb)->s_gid;

	inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
	if (!inode->i_nlink)
		inode->i_nlink = 1;
	
	inode->i_size = le64_to_cpu(fe->informationLength);
	UDF_I_LENEXTENTS(inode) = inode->i_size;

	inode->i_mode = udf_convert_permissions(fe);
	inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;

	if (UDF_I_EFE(inode) == 0)
	{
		inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
			(inode->i_sb->s_blocksize_bits - 9);

		if ( udf_stamp_to_time(&convtime, &convtime_usec,
			lets_to_cpu(fe->accessTime)) )
		{
			inode->i_atime.tv_sec = convtime;
			inode->i_atime.tv_nsec = convtime_usec * 1000;
		}
		else
		{
			inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
		}

		if ( udf_stamp_to_time(&convtime, &convtime_usec,
			lets_to_cpu(fe->modificationTime)) )
		{
			inode->i_mtime.tv_sec = convtime;
			inode->i_mtime.tv_nsec = convtime_usec * 1000;
		}
		else
		{
			inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
		}

		if ( udf_stamp_to_time(&convtime, &convtime_usec,
			lets_to_cpu(fe->attrTime)) )
		{
			inode->i_ctime.tv_sec = convtime;
			inode->i_ctime.tv_nsec = convtime_usec * 1000;
		}
		else
		{
			inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
		}

		UDF_I_UNIQUE(inode) = le64_to_cpu(fe->uniqueID);
		UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr);
		UDF_I_LENALLOC(inode) = le32_to_cpu(fe->lengthAllocDescs);
		offset = sizeof(struct fileEntry) + UDF_I_LENEATTR(inode);
	}
	else
	{
		inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << 
			(inode->i_sb->s_blocksize_bits - 9);

		if ( udf_stamp_to_time(&convtime, &convtime_usec,
			lets_to_cpu(efe->accessTime)) )
		{
			inode->i_atime.tv_sec = convtime;
			inode->i_atime.tv_nsec = convtime_usec * 1000;
		}
		else
		{
			inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
		}

		if ( udf_stamp_to_time(&convtime, &convtime_usec,
			lets_to_cpu(efe->modificationTime)) )
		{
			inode->i_mtime.tv_sec = convtime;
			inode->i_mtime.tv_nsec = convtime_usec * 1000;
		}
		else
		{
			inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
		}

		if ( udf_stamp_to_time(&convtime, &convtime_usec,
			lets_to_cpu(efe->createTime)) )
		{
			UDF_I_CRTIME(inode).tv_sec = convtime;
			UDF_I_CRTIME(inode).tv_nsec = convtime_usec * 1000;
		}
		else
		{
			UDF_I_CRTIME(inode) = UDF_SB_RECORDTIME(inode->i_sb);
		}

		if ( udf_stamp_to_time(&convtime, &convtime_usec,
			lets_to_cpu(efe->attrTime)) )
		{
			inode->i_ctime.tv_sec = convtime;
			inode->i_ctime.tv_nsec = convtime_usec * 1000;
		}
		else
		{
			inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
		}

		UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID);
		UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr);
		UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs);
		offset = sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode);
	}

	switch (fe->icbTag.fileType)
	{
		case ICBTAG_FILE_TYPE_DIRECTORY:
		{
			inode->i_op = &udf_dir_inode_operations;
			inode->i_fop = &udf_dir_operations;
			inode->i_mode |= S_IFDIR;
			inode->i_nlink ++;
			break;
		}
		case ICBTAG_FILE_TYPE_REALTIME:
		case ICBTAG_FILE_TYPE_REGULAR:
		case ICBTAG_FILE_TYPE_UNDEF:
		{
			if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
				inode->i_data.a_ops = &udf_adinicb_aops;
			else
				inode->i_data.a_ops = &udf_aops;
			inode->i_op = &udf_file_inode_operations;
			inode->i_fop = &udf_file_operations;
			inode->i_mode |= S_IFREG;
			break;
		}
		case ICBTAG_FILE_TYPE_BLOCK:
		{
			inode->i_mode |= S_IFBLK;
			break;
		}
		case ICBTAG_FILE_TYPE_CHAR:
		{
			inode->i_mode |= S_IFCHR;
			break;
		}
		case ICBTAG_FILE_TYPE_FIFO:
		{
			init_special_inode(inode, inode->i_mode | S_IFIFO, 0);
			break;
		}
		case ICBTAG_FILE_TYPE_SOCKET:
		{
			init_special_inode(inode, inode->i_mode | S_IFSOCK, 0);
			break;
		}
		case ICBTAG_FILE_TYPE_SYMLINK:
		{
			inode->i_data.a_ops = &udf_symlink_aops;
			inode->i_op = &page_symlink_inode_operations;
			inode->i_mode = S_IFLNK|S_IRWXUGO;
			break;
		}
		default:
		{
			printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown file type=%d\n",
				inode->i_ino, fe->icbTag.fileType);
			make_bad_inode(inode);
			return;
		}
	}
	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
	{
		struct deviceSpec *dsea =
			(struct deviceSpec *)
				udf_get_extendedattr(inode, 12, 1);

		if (dsea)
		{
			init_special_inode(inode, inode->i_mode, MKDEV(
				le32_to_cpu(dsea->majorDeviceIdent),
				le32_to_cpu(dsea->minorDeviceIdent)));
			/* Developer ID ??? */
		}
		else
		{
			make_bad_inode(inode);
		}
	}
}

static mode_t
udf_convert_permissions(struct fileEntry *fe)
{
	mode_t mode;
	uint32_t permissions;
	uint32_t flags;

	permissions = le32_to_cpu(fe->permissions);
	flags = le16_to_cpu(fe->icbTag.flags);

	mode =	(( permissions      ) & S_IRWXO) |
		(( permissions >> 2 ) & S_IRWXG) |
		(( permissions >> 4 ) & S_IRWXU) |
		(( flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) |
		(( flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) |
		(( flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0);

	return mode;
}

/*
 * udf_write_inode
 *
 * PURPOSE
 *	Write out the specified inode.
 *
 * DESCRIPTION
 *	This routine is called whenever an inode is synced.
 *	Currently this routine is just a placeholder.
 *
 * HISTORY
 *	July 1, 1997 - Andrew E. Mileski
 *	Written, tested, and released.
 */

int udf_write_inode(struct inode * inode, int sync)
{
	int ret;
	lock_kernel();
	ret = udf_update_inode(inode, sync);
	unlock_kernel();
	return ret;
}

int udf_sync_inode(struct inode * inode)
{
	return udf_update_inode(inode, 1);
}

static int
udf_update_inode(struct inode *inode, int do_sync)
{
	struct buffer_head *bh = NULL;
	struct fileEntry *fe;
	struct extendedFileEntry *efe;
	uint32_t udfperms;
	uint16_t icbflags;
	uint16_t crclen;
	int i;
	kernel_timestamp cpu_time;
	int err = 0;

	bh = udf_tread(inode->i_sb,
		udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0));

	if (!bh)
	{
		udf_debug("bread failure\n");
		return -EIO;
	}

	memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);

	fe = (struct fileEntry *)bh->b_data;
	efe = (struct extendedFileEntry *)bh->b_data;

	if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE)
	{
		struct unallocSpaceEntry *use =
			(struct unallocSpaceEntry *)bh->b_data;

		use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
		memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry));
		crclen = sizeof(struct unallocSpaceEntry) + UDF_I_LENALLOC(inode) -
			sizeof(tag);
		use->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
		use->descTag.descCRCLength = cpu_to_le16(crclen);
		use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0));

		use->descTag.tagChecksum = 0;
		for (i=0; i<16; i++)
			if (i != 4)
				use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i];

		mark_buffer_dirty(bh);
		udf_release_data(bh);
		return err;
	}

	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
		fe->uid = cpu_to_le32(-1);
	else fe->uid = cpu_to_le32(inode->i_uid);

	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET))
		fe->gid = cpu_to_le32(-1);
	else fe->gid = cpu_to_le32(inode->i_gid);

	udfperms =	((inode->i_mode & S_IRWXO)     ) |
			((inode->i_mode & S_IRWXG) << 2) |
			((inode->i_mode & S_IRWXU) << 4);

	udfperms |=	(le32_to_cpu(fe->permissions) &
			(FE_PERM_O_DELETE | FE_PERM_O_CHATTR |
			 FE_PERM_G_DELETE | FE_PERM_G_CHATTR |
			 FE_PERM_U_DELETE | FE_PERM_U_CHATTR));
	fe->permissions = cpu_to_le32(udfperms);

	if (S_ISDIR(inode->i_mode))
		fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1);
	else
		fe->fileLinkCount = cpu_to_le16(inode->i_nlink);

	fe->informationLength = cpu_to_le64(inode->i_size);

	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
	{
		regid *eid;
		struct deviceSpec *dsea =
			(struct deviceSpec *)
				udf_get_extendedattr(inode, 12, 1);

		if (!dsea)
		{
			dsea = (struct deviceSpec *)
				udf_add_extendedattr(inode,
					sizeof(struct deviceSpec) +
					sizeof(regid), 12, 0x3);
			dsea->attrType = cpu_to_le32(12);
			dsea->attrSubtype = 1;
			dsea->attrLength = cpu_to_le32(sizeof(struct deviceSpec) +
				sizeof(regid));
			dsea->impUseLength = cpu_to_le32(sizeof(regid));
		}
		eid = (regid *)dsea->impUse;
		memset(eid, 0, sizeof(regid));
		strcpy(eid->ident, UDF_ID_DEVELOPER);
		eid->identSuffix[0] = UDF_OS_CLASS_UNIX;
		eid->identSuffix[1] = UDF_OS_ID_LINUX;
		dsea->majorDeviceIdent = cpu_to_le32(imajor(inode));
		dsea->minorDeviceIdent = cpu_to_le32(iminor(inode));
	}

	if (UDF_I_EFE(inode) == 0)
	{
		memcpy(bh->b_data + sizeof(struct fileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct fileEntry));
		fe->logicalBlocksRecorded = cpu_to_le64(
			(inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
			(inode->i_sb->s_blocksize_bits - 9));

		if (udf_time_to_stamp(&cpu_time, inode->i_atime))
			fe->accessTime = cpu_to_lets(cpu_time);
		if (udf_time_to_stamp(&cpu_time, inode->i_mtime))
			fe->modificationTime = cpu_to_lets(cpu_time);
		if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
			fe->attrTime = cpu_to_lets(cpu_time);
		memset(&(fe->impIdent), 0, sizeof(regid));
		strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
		fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
		fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
		fe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
		fe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
		fe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
		fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE);
		crclen = sizeof(struct fileEntry);
	}
	else
	{
		memcpy(bh->b_data + sizeof(struct extendedFileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));
		efe->objectSize = cpu_to_le64(inode->i_size);
		efe->logicalBlocksRecorded = cpu_to_le64(
			(inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
			(inode->i_sb->s_blocksize_bits - 9));

		if (UDF_I_CRTIME(inode).tv_sec > inode->i_atime.tv_sec ||
			(UDF_I_CRTIME(inode).tv_sec == inode->i_atime.tv_sec &&
			 UDF_I_CRTIME(inode).tv_nsec > inode->i_atime.tv_nsec))
		{
			UDF_I_CRTIME(inode) = inode->i_atime;
		}
		if (UDF_I_CRTIME(inode).tv_sec > inode->i_mtime.tv_sec ||
			(UDF_I_CRTIME(inode).tv_sec == inode->i_mtime.tv_sec &&
			 UDF_I_CRTIME(inode).tv_nsec > inode->i_mtime.tv_nsec))
		{
			UDF_I_CRTIME(inode) = inode->i_mtime;
		}
		if (UDF_I_CRTIME(inode).tv_sec > inode->i_ctime.tv_sec ||
			(UDF_I_CRTIME(inode).tv_sec == inode->i_ctime.tv_sec &&
			 UDF_I_CRTIME(inode).tv_nsec > inode->i_ctime.tv_nsec))
		{
			UDF_I_CRTIME(inode) = inode->i_ctime;
		}

		if (udf_time_to_stamp(&cpu_time, inode->i_atime))
			efe->accessTime = cpu_to_lets(cpu_time);
		if (udf_time_to_stamp(&cpu_time, inode->i_mtime))
			efe->modificationTime = cpu_to_lets(cpu_time);
		if (udf_time_to_stamp(&cpu_time, UDF_I_CRTIME(inode)))
			efe->createTime = cpu_to_lets(cpu_time);
		if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
			efe->attrTime = cpu_to_lets(cpu_time);

		memset(&(efe->impIdent), 0, sizeof(regid));
		strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
		efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
		efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
		efe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
		efe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
		efe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
		efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE);
		crclen = sizeof(struct extendedFileEntry);
	}
	if (UDF_I_STRAT4096(inode))
	{
		fe->icbTag.strategyType = cpu_to_le16(4096);
		fe->icbTag.strategyParameter = cpu_to_le16(1);
		fe->icbTag.numEntries = cpu_to_le16(2);
	}
	else
	{
		fe->icbTag.strategyType = cpu_to_le16(4);
		fe->icbTag.numEntries = cpu_to_le16(1);
	}

	if (S_ISDIR(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_DIRECTORY;
	else if (S_ISREG(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_REGULAR;
	else if (S_ISLNK(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_SYMLINK;
	else if (S_ISBLK(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_BLOCK;
	else if (S_ISCHR(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_CHAR;
	else if (S_ISFIFO(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_FIFO;
	else if (S_ISSOCK(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_SOCKET;

	icbflags =	UDF_I_ALLOCTYPE(inode) |
			((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) |
			((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) |
			((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) |
			(le16_to_cpu(fe->icbTag.flags) &
				~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID |
				ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY));

	fe->icbTag.flags = cpu_to_le16(icbflags);
	if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
		fe->descTag.descVersion = cpu_to_le16(3);
	else
		fe->descTag.descVersion = cpu_to_le16(2);
	fe->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
	fe->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
	crclen += UDF_I_LENEATTR(inode) + UDF_I_LENALLOC(inode) - sizeof(tag);
	fe->descTag.descCRCLength = cpu_to_le16(crclen);
	fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag), crclen, 0));

	fe->descTag.tagChecksum = 0;
	for (i=0; i<16; i++)
		if (i != 4)
			fe->descTag.tagChecksum += ((uint8_t *)&(fe->descTag))[i];

	/* write the data blocks */
	mark_buffer_dirty(bh);
	if (do_sync)
	{
		sync_dirty_buffer(bh);
		if (buffer_req(bh) && !buffer_uptodate(bh))
		{
			printk("IO error syncing udf inode [%s:%08lx]\n",
				inode->i_sb->s_id, inode->i_ino);
			err = -EIO;
		}
	}
	udf_release_data(bh);
	return err;
}

struct inode *
udf_iget(struct super_block *sb, kernel_lb_addr ino)
{
	unsigned long block = udf_get_lb_pblock(sb, ino, 0);
	struct inode *inode = iget_locked(sb, block);

	if (!inode)
		return NULL;

	if (inode->i_state & I_NEW) {
		memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(kernel_lb_addr));
		__udf_read_inode(inode);
		unlock_new_inode(inode);
	}

	if (is_bad_inode(inode))
		goto out_iput;

	if (ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) {
		udf_debug("block=%d, partition=%d out of range\n",
			ino.logicalBlockNum, ino.partitionReferenceNum);
		make_bad_inode(inode);
		goto out_iput;
	}

	return inode;

 out_iput:
	iput(inode);
	return NULL;
}

int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
	kernel_lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc)
{
	int adsize;
	short_ad *sad = NULL;
	long_ad *lad = NULL;
	struct allocExtDesc *aed;
	int8_t etype;
	uint8_t *ptr;

	if (!*bh)
		ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
	else
		ptr = (*bh)->b_data + *extoffset;

	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
		adsize = sizeof(short_ad);
	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
		adsize = sizeof(long_ad);
	else
		return -1;

	if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize)
	{
		char *sptr, *dptr;
		struct buffer_head *nbh;
		int err, loffset;
		kernel_lb_addr obloc = *bloc;

		if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, NULL,
			obloc.partitionReferenceNum, obloc.logicalBlockNum, &err)))
		{
			return -1;
		}
		if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
			*bloc, 0))))
		{
			return -1;
		}
		lock_buffer(nbh);
		memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize);
		set_buffer_uptodate(nbh);
		unlock_buffer(nbh);
		mark_buffer_dirty_inode(nbh, inode);

		aed = (struct allocExtDesc *)(nbh->b_data);
		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
			aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
		if (*extoffset + adsize > inode->i_sb->s_blocksize)
		{
			loffset = *extoffset;
			aed->lengthAllocDescs = cpu_to_le32(adsize);
			sptr = ptr - adsize;
			dptr = nbh->b_data + sizeof(struct allocExtDesc);
			memcpy(dptr, sptr, adsize);
			*extoffset = sizeof(struct allocExtDesc) + adsize;
		}
		else
		{
			loffset = *extoffset + adsize;
			aed->lengthAllocDescs = cpu_to_le32(0);
			sptr = ptr;
			*extoffset = sizeof(struct allocExtDesc);

			if (*bh)
			{
				aed = (struct allocExtDesc *)(*bh)->b_data;
				aed->lengthAllocDescs =
					cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
			}
			else
			{
				UDF_I_LENALLOC(inode) += adsize;
				mark_inode_dirty(inode);
			}
		}
		if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
				bloc->logicalBlockNum, sizeof(tag));
		else
			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
				bloc->logicalBlockNum, sizeof(tag));
		switch (UDF_I_ALLOCTYPE(inode))
		{
			case ICBTAG_FLAG_AD_SHORT:
			{
				sad = (short_ad *)sptr;
				sad->extLength = cpu_to_le32(
					EXT_NEXT_EXTENT_ALLOCDECS |
					inode->i_sb->s_blocksize);
				sad->extPosition = cpu_to_le32(bloc->logicalBlockNum);
				break;
			}
			case ICBTAG_FLAG_AD_LONG:
			{
				lad = (long_ad *)sptr;
				lad->extLength = cpu_to_le32(
					EXT_NEXT_EXTENT_ALLOCDECS |
					inode->i_sb->s_blocksize);
				lad->extLocation = cpu_to_lelb(*bloc);
				memset(lad->impUse, 0x00, sizeof(lad->impUse));
				break;
			}
		}
		if (*bh)
		{
			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
				udf_update_tag((*bh)->b_data, loffset);
			else
				udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
			mark_buffer_dirty_inode(*bh, inode);
			udf_release_data(*bh);
		}
		else
			mark_inode_dirty(inode);
		*bh = nbh;
	}

	etype = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc);

	if (!*bh)
	{
		UDF_I_LENALLOC(inode) += adsize;
		mark_inode_dirty(inode);
	}
	else
	{
		aed = (struct allocExtDesc *)(*bh)->b_data;
		aed->lengthAllocDescs =
			cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
			udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize));
		else
			udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
		mark_buffer_dirty_inode(*bh, inode);
	}

	return etype;
}

int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset,
    kernel_lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc)
{
	int adsize;
	uint8_t *ptr;

	if (!bh)
		ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
	else
	{
		ptr = bh->b_data + *extoffset;
		atomic_inc(&bh->b_count);
	}

	switch (UDF_I_ALLOCTYPE(inode))
	{
		case ICBTAG_FLAG_AD_SHORT:
		{
			short_ad *sad = (short_ad *)ptr;
			sad->extLength = cpu_to_le32(elen);
			sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);
			adsize = sizeof(short_ad);
			break;
		}
		case ICBTAG_FLAG_AD_LONG:
		{
			long_ad *lad = (long_ad *)ptr;
			lad->extLength = cpu_to_le32(elen);
			lad->extLocation = cpu_to_lelb(eloc);
			memset(lad->impUse, 0x00, sizeof(lad->impUse));
			adsize = sizeof(long_ad);
			break;
		}
		default:
			return -1;
	}

	if (bh)
	{
		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
		{
			struct allocExtDesc *aed = (struct allocExtDesc *)(bh)->b_data;
			udf_update_tag((bh)->b_data,
				le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc));
		}
		mark_buffer_dirty_inode(bh, inode);
		udf_release_data(bh);
	}
	else
		mark_inode_dirty(inode);

	if (inc)
		*extoffset += adsize;
	return (elen >> 30);
}

int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
	kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc)
{
	int8_t etype;

	while ((etype = udf_current_aext(inode, bloc, extoffset, eloc, elen, bh, inc)) ==
		(EXT_NEXT_EXTENT_ALLOCDECS >> 30))
	{
		*bloc = *eloc;
		*extoffset = sizeof(struct allocExtDesc);
		udf_release_data(*bh);
		if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0))))
		{
			udf_debug("reading block %d failed!\n",
				udf_get_lb_pblock(inode->i_sb, *bloc, 0));
			return -1;
		}
	}

	return etype;
}

int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
	kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc)
{
	int alen;
	int8_t etype;
	uint8_t *ptr;

	if (!*bh)
	{
		if (!(*extoffset))
			*extoffset = udf_file_entry_alloc_offset(inode);
		ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
		alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode);
	}
	else
	{
		if (!(*extoffset))
			*extoffset = sizeof(struct allocExtDesc);
		ptr = (*bh)->b_data + *extoffset;
		alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)(*bh)->b_data)->lengthAllocDescs);
	}

	switch (UDF_I_ALLOCTYPE(inode))
	{
		case ICBTAG_FLAG_AD_SHORT:
		{
			short_ad *sad;

			if (!(sad = udf_get_fileshortad(ptr, alen, extoffset, inc)))
				return -1;

			etype = le32_to_cpu(sad->extLength) >> 30;
			eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
			eloc->partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
			*elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK;
			break;
		}
		case ICBTAG_FLAG_AD_LONG:
		{
			long_ad *lad;

			if (!(lad = udf_get_filelongad(ptr, alen, extoffset, inc)))
				return -1;

			etype = le32_to_cpu(lad->extLength) >> 30;
			*eloc = lelb_to_cpu(lad->extLocation);
			*elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;
			break;
		}
		default:
		{
			udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode));
			return -1;
		}
	}

	return etype;
}

static int8_t
udf_insert_aext(struct inode *inode, kernel_lb_addr bloc, int extoffset,
		kernel_lb_addr neloc, uint32_t nelen, struct buffer_head *bh)
{
	kernel_lb_addr oeloc;
	uint32_t oelen;
	int8_t etype;

	if (bh)
		atomic_inc(&bh->b_count);

	while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
	{
		udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);

		neloc = oeloc;
		nelen = (etype << 30) | oelen;
	}
	udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1);
	udf_release_data(bh);
	return (nelen >> 30);
}

int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset,
	kernel_lb_addr eloc, uint32_t elen, struct buffer_head *nbh)
{
	struct buffer_head *obh;
	kernel_lb_addr obloc;
	int oextoffset, adsize;
	int8_t etype;
	struct allocExtDesc *aed;

	if (nbh)
	{
		atomic_inc(&nbh->b_count);
		atomic_inc(&nbh->b_count);
	}

	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
		adsize = sizeof(short_ad);
	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
		adsize = sizeof(long_ad);
	else
		adsize = 0;

	obh = nbh;
	obloc = nbloc;
	oextoffset = nextoffset;

	if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1)
		return -1;

	while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
	{
		udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1);
		if (obh != nbh)
		{
			obloc = nbloc;
			udf_release_data(obh);
			atomic_inc(&nbh->b_count);
			obh = nbh;
			oextoffset = nextoffset - adsize;
		}
	}
	memset(&eloc, 0x00, sizeof(kernel_lb_addr));
	elen = 0;

	if (nbh != obh)
	{
		udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1);
		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
		if (!obh)
		{
			UDF_I_LENALLOC(inode) -= (adsize * 2);
			mark_inode_dirty(inode);
		}
		else
		{
			aed = (struct allocExtDesc *)(obh)->b_data;
			aed->lengthAllocDescs =
				cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize));
			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
				udf_update_tag((obh)->b_data, oextoffset - (2*adsize));
			else
				udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
			mark_buffer_dirty_inode(obh, inode);
		}
	}
	else
	{
		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
		if (!obh)
		{
			UDF_I_LENALLOC(inode) -= adsize;
			mark_inode_dirty(inode);
		}
		else
		{
			aed = (struct allocExtDesc *)(obh)->b_data;
			aed->lengthAllocDescs =
				cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize);
			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
				udf_update_tag((obh)->b_data, oextoffset - adsize);
			else
				udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
			mark_buffer_dirty_inode(obh, inode);
		}
	}
	
	udf_release_data(nbh);
	udf_release_data(obh);
	return (elen >> 30);
}

int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t *extoffset,
	kernel_lb_addr *eloc, uint32_t *elen, uint32_t *offset, struct buffer_head **bh)
{
	uint64_t lbcount = 0, bcount = (uint64_t)block << inode->i_sb->s_blocksize_bits;
	int8_t etype;

	if (block < 0)
	{
		printk(KERN_ERR "udf: inode_bmap: block < 0\n");
		return -1;
	}

	*extoffset = 0;
	*elen = 0;
	*bloc = UDF_I_LOCATION(inode);

	do
	{
		if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1)
		{
			*offset = bcount - lbcount;
			UDF_I_LENEXTENTS(inode) = lbcount;
			return -1;
		}
		lbcount += *elen;
	} while (lbcount <= bcount);

	*offset = bcount + *elen - lbcount;

	return etype;
}

long udf_block_map(struct inode *inode, long block)
{
	kernel_lb_addr eloc, bloc;
	uint32_t offset, extoffset, elen;
	struct buffer_head *bh = NULL;
	int ret;

	lock_kernel();

	if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
		ret = udf_get_lb_pblock(inode->i_sb, eloc, offset >> inode->i_sb->s_blocksize_bits);
	else
		ret = 0;

	unlock_kernel();
	udf_release_data(bh);

	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
		return udf_fixed_to_variable(ret);
	else
		return ret;
}
