UDF: introduce struct extent_position

Introduce a structure extent_position to store a position of an extent and
the corresponding buffer_head in one place.

Signed-off-by: Jan Kara <jack@suse.cz>
Acked-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 6b09425..a106acb 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -51,8 +51,8 @@
 static void udf_fill_inode(struct inode *, struct buffer_head *);
 static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
 	long *, int *);
-static int8_t udf_insert_aext(struct inode *, kernel_lb_addr, int,
-	kernel_lb_addr, uint32_t, struct buffer_head *);
+static int8_t udf_insert_aext(struct inode *, struct extent_position,
+	kernel_lb_addr, uint32_t);
 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,
@@ -61,7 +61,7 @@
 	 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 **);
+	struct extent_position *);
 static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
 
 /*
@@ -194,10 +194,11 @@
 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;
+	struct buffer_head *dbh = NULL;
+	kernel_lb_addr eloc;
+	uint32_t elen;
 	uint8_t alloctype;
+	struct extent_position epos;
 
 	struct udf_fileident_bh sfibh, dfibh;
 	loff_t f_pos = udf_ext0_offset(inode) >> 2;
@@ -237,13 +238,13 @@
 	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;
+	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);
+		sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL);
 		if (!sfi)
 		{
 			udf_release_data(dbh);
@@ -266,16 +267,17 @@
 
 	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);
+	epos.bh = NULL;
+	epos.block = UDF_I_LOCATION(inode);
+	epos.offset = udf_file_entry_alloc_offset(inode);
+	udf_add_aext(inode, &epos, eloc, elen, 0);
 	/* UniqueID stuff */
 
-	udf_release_data(sbh);
+	udf_release_data(epos.bh);
 	mark_inode_dirty(inode);
 	return dbh;
 }
@@ -357,12 +359,12 @@
 static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
 	int *err, long *phys, int *new)
 {
-	struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL;
+	struct buffer_head *result = NULL;
 	kernel_long_ad laarr[EXTENT_MERGE_SIZE];
-	uint32_t pextoffset = 0, cextoffset = 0, nextoffset = 0;
+	struct extent_position prev_epos, cur_epos, next_epos;
 	int count = 0, startnum = 0, endnum = 0;
 	uint32_t elen = 0;
-	kernel_lb_addr eloc, pbloc, cbloc, nbloc;
+	kernel_lb_addr eloc;
 	int c = 1;
 	loff_t lbcount = 0, b_off = 0;
 	uint32_t newblocknum, newblock;
@@ -371,37 +373,39 @@
 	int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
 	char lastblock = 0;
 
-	pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode);
+	prev_epos.offset = udf_file_entry_alloc_offset(inode);
+	prev_epos.block = UDF_I_LOCATION(inode);
+	prev_epos.bh = NULL;
+	cur_epos = next_epos = prev_epos;
 	b_off = (loff_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)
+		if (prev_epos.bh != cur_epos.bh)
 		{
-			udf_release_data(pbh);
-			atomic_inc(&cbh->b_count);
-			pbh = cbh;
+			udf_release_data(prev_epos.bh);
+			atomic_inc(&cur_epos.bh->b_count);
+			prev_epos.bh = cur_epos.bh;
 		}
-		if (cbh != nbh)
+		if (cur_epos.bh != next_epos.bh)
 		{
-			udf_release_data(cbh);
-			atomic_inc(&nbh->b_count);
-			cbh = nbh;
+			udf_release_data(cur_epos.bh);
+			atomic_inc(&next_epos.bh->b_count);
+			cur_epos.bh = next_epos.bh;
 		}
 
 		lbcount += elen;
 
-		pbloc = cbloc;
-		cbloc = nbloc;
+		prev_epos.block = cur_epos.block;
+		cur_epos.block = next_epos.block;
 
-		pextoffset = cextoffset;
-		cextoffset = nextoffset;
+		prev_epos.offset = cur_epos.offset;
+		cur_epos.offset = next_epos.offset;
 
-		if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) == -1)
+		if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1)) == -1)
 			break;
 
 		c = !c;
@@ -430,11 +434,11 @@
 			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);
+			etype = udf_write_aext(inode, &cur_epos, eloc, elen, 1);
 		}
-		udf_release_data(pbh);
-		udf_release_data(cbh);
-		udf_release_data(nbh);
+		udf_release_data(prev_epos.bh);
+		udf_release_data(cur_epos.bh);
+		udf_release_data(next_epos.bh);
 		newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset);
 		*phys = newblock;
 		return NULL;
@@ -477,7 +481,7 @@
 	/* 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)
+		if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0)) != -1)
 		{
 			laarr[c+1].extLength = (etype << 30) | elen;
 			laarr[c+1].extLocation = eloc;
@@ -488,8 +492,8 @@
 		else
 			lastblock = 1;
 	}
-	udf_release_data(cbh);
-	udf_release_data(nbh);
+	udf_release_data(cur_epos.bh);
+	udf_release_data(next_epos.bh);
 
 	/* if the current extent is not recorded but allocated, get the
 		block in the extent corresponding to the requested block */
@@ -509,7 +513,7 @@
 		if (!(newblocknum = udf_new_block(inode->i_sb, inode,
 			UDF_I_LOCATION(inode).partitionReferenceNum, goal, err)))
 		{
-			udf_release_data(pbh);
+			udf_release_data(prev_epos.bh);
 			*err = -ENOSPC;
 			return NULL;
 		}
@@ -532,9 +536,9 @@
 	/* 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_update_extents(inode, laarr, startnum, endnum, &prev_epos);
 
-	udf_release_data(pbh);
+	udf_release_data(prev_epos.bh);
 
 	if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,
 		UDF_I_LOCATION(inode).partitionReferenceNum, 0)))
@@ -796,7 +800,7 @@
 
 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)
+	struct extent_position *epos)
 {
 	int start = 0, i;
 	kernel_lb_addr tmploc;
@@ -805,28 +809,26 @@
 	if (startnum > endnum)
 	{
 		for (i=0; i<(startnum-endnum); i++)
-		{
-			udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation,
-				laarr[i].extLength, *pbh);
-		}
+			udf_delete_aext(inode, *epos, laarr[i].extLocation,
+				laarr[i].extLength);
 	}
 	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);
+			udf_insert_aext(inode, *epos, laarr[i].extLocation,
+				laarr[i].extLength);
+			udf_next_aext(inode, epos, &laarr[i].extLocation,
+				&laarr[i].extLength, 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);
+		udf_next_aext(inode, epos, &tmploc, &tmplen, 0);
+		udf_write_aext(inode, epos, laarr[i].extLocation,
+			laarr[i].extLength, 1);
 	}
 }
 
@@ -1557,8 +1559,8 @@
 	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)
+int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
+	kernel_lb_addr eloc, uint32_t elen, int inc)
 {
 	int adsize;
 	short_ad *sad = NULL;
@@ -1567,10 +1569,10 @@
 	int8_t etype;
 	uint8_t *ptr;
 
-	if (!*bh)
-		ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
+	if (!epos->bh)
+		ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
 	else
-		ptr = (*bh)->b_data + *extoffset;
+		ptr = epos->bh->b_data + epos->offset;
 
 	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
 		adsize = sizeof(short_ad);
@@ -1579,20 +1581,20 @@
 	else
 		return -1;
 
-	if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize)
+	if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize)
 	{
 		char *sptr, *dptr;
 		struct buffer_head *nbh;
 		int err, loffset;
-		kernel_lb_addr obloc = *bloc;
+		kernel_lb_addr obloc = epos->block;
 
-		if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, NULL,
+		if (!(epos->block.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))))
+			epos->block, 0))))
 		{
 			return -1;
 		}
@@ -1605,25 +1607,25 @@
 		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)
+		if (epos->offset + adsize > inode->i_sb->s_blocksize)
 		{
-			loffset = *extoffset;
+			loffset = epos->offset;
 			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;
+			epos->offset = sizeof(struct allocExtDesc) + adsize;
 		}
 		else
 		{
-			loffset = *extoffset + adsize;
+			loffset = epos->offset + adsize;
 			aed->lengthAllocDescs = cpu_to_le32(0);
 			sptr = ptr;
-			*extoffset = sizeof(struct allocExtDesc);
+			epos->offset = sizeof(struct allocExtDesc);
 
-			if (*bh)
+			if (epos->bh)
 			{
-				aed = (struct allocExtDesc *)(*bh)->b_data;
+				aed = (struct allocExtDesc *)epos->bh->b_data;
 				aed->lengthAllocDescs =
 					cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
 			}
@@ -1635,10 +1637,10 @@
 		}
 		if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
 			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
-				bloc->logicalBlockNum, sizeof(tag));
+				epos->block.logicalBlockNum, sizeof(tag));
 		else
 			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
-				bloc->logicalBlockNum, sizeof(tag));
+				epos->block.logicalBlockNum, sizeof(tag));
 		switch (UDF_I_ALLOCTYPE(inode))
 		{
 			case ICBTAG_FLAG_AD_SHORT:
@@ -1647,7 +1649,7 @@
 				sad->extLength = cpu_to_le32(
 					EXT_NEXT_EXTENT_ALLOCDECS |
 					inode->i_sb->s_blocksize);
-				sad->extPosition = cpu_to_le32(bloc->logicalBlockNum);
+				sad->extPosition = cpu_to_le32(epos->block.logicalBlockNum);
 				break;
 			}
 			case ICBTAG_FLAG_AD_LONG:
@@ -1656,60 +1658,57 @@
 				lad->extLength = cpu_to_le32(
 					EXT_NEXT_EXTENT_ALLOCDECS |
 					inode->i_sb->s_blocksize);
-				lad->extLocation = cpu_to_lelb(*bloc);
+				lad->extLocation = cpu_to_lelb(epos->block);
 				memset(lad->impUse, 0x00, sizeof(lad->impUse));
 				break;
 			}
 		}
-		if (*bh)
+		if (epos->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);
+				udf_update_tag(epos->bh->b_data, loffset);
 			else
-				udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
-			mark_buffer_dirty_inode(*bh, inode);
-			udf_release_data(*bh);
+				udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc));
+			mark_buffer_dirty_inode(epos->bh, inode);
+			udf_release_data(epos->bh);
 		}
 		else
 			mark_inode_dirty(inode);
-		*bh = nbh;
+		epos->bh = nbh;
 	}
 
-	etype = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc);
+	etype = udf_write_aext(inode, epos, eloc, elen, inc);
 
-	if (!*bh)
+	if (!epos->bh)
 	{
 		UDF_I_LENALLOC(inode) += adsize;
 		mark_inode_dirty(inode);
 	}
 	else
 	{
-		aed = (struct allocExtDesc *)(*bh)->b_data;
+		aed = (struct allocExtDesc *)epos->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));
+			udf_update_tag(epos->bh->b_data, epos->offset + (inc ? 0 : adsize));
 		else
-			udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
-		mark_buffer_dirty_inode(*bh, inode);
+			udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc));
+		mark_buffer_dirty_inode(epos->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)
+int8_t udf_write_aext(struct inode *inode, struct extent_position *epos,
+    kernel_lb_addr eloc, uint32_t elen, 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);
+	if (!epos->bh)
+		ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
 	else
-	{
-		ptr = bh->b_data + *extoffset;
-		atomic_inc(&bh->b_count);
-	}
+		ptr = epos->bh->b_data + epos->offset;
 
 	switch (UDF_I_ALLOCTYPE(inode))
 	{
@@ -1734,40 +1733,39 @@
 			return -1;
 	}
 
-	if (bh)
+	if (epos->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,
+			struct allocExtDesc *aed = (struct allocExtDesc *)epos->bh->b_data;
+			udf_update_tag(epos->bh->b_data,
 				le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc));
 		}
-		mark_buffer_dirty_inode(bh, inode);
-		udf_release_data(bh);
+		mark_buffer_dirty_inode(epos->bh, inode);
 	}
 	else
 		mark_inode_dirty(inode);
 
 	if (inc)
-		*extoffset += adsize;
+		epos->offset += 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 udf_next_aext(struct inode *inode, struct extent_position *epos,
+	kernel_lb_addr *eloc, uint32_t *elen, int inc)
 {
 	int8_t etype;
 
-	while ((etype = udf_current_aext(inode, bloc, extoffset, eloc, elen, bh, inc)) ==
+	while ((etype = udf_current_aext(inode, epos, eloc, elen, 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))))
+		epos->block = *eloc;
+		epos->offset = sizeof(struct allocExtDesc);
+		udf_release_data(epos->bh);
+		if (!(epos->bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, epos->block, 0))))
 		{
 			udf_debug("reading block %d failed!\n",
-				udf_get_lb_pblock(inode->i_sb, *bloc, 0));
+				udf_get_lb_pblock(inode->i_sb, epos->block, 0));
 			return -1;
 		}
 	}
@@ -1775,26 +1773,26 @@
 	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)
+int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
+	kernel_lb_addr *eloc, uint32_t *elen, int inc)
 {
 	int alen;
 	int8_t etype;
 	uint8_t *ptr;
 
-	if (!*bh)
+	if (!epos->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);
+		if (!epos->offset)
+			epos->offset = udf_file_entry_alloc_offset(inode);
+		ptr = UDF_I_DATA(inode) + epos->offset - 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);
+		if (!epos->offset)
+			epos->offset = sizeof(struct allocExtDesc);
+		ptr = epos->bh->b_data + epos->offset;
+		alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->lengthAllocDescs);
 	}
 
 	switch (UDF_I_ALLOCTYPE(inode))
@@ -1803,7 +1801,7 @@
 		{
 			short_ad *sad;
 
-			if (!(sad = udf_get_fileshortad(ptr, alen, extoffset, inc)))
+			if (!(sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc)))
 				return -1;
 
 			etype = le32_to_cpu(sad->extLength) >> 30;
@@ -1816,7 +1814,7 @@
 		{
 			long_ad *lad;
 
-			if (!(lad = udf_get_filelongad(ptr, alen, extoffset, inc)))
+			if (!(lad = udf_get_filelongad(ptr, alen, &epos->offset, inc)))
 				return -1;
 
 			etype = le32_to_cpu(lad->extLength) >> 30;
@@ -1835,41 +1833,40 @@
 }
 
 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)
+udf_insert_aext(struct inode *inode, struct extent_position epos,
+		kernel_lb_addr neloc, uint32_t nelen)
 {
 	kernel_lb_addr oeloc;
 	uint32_t oelen;
 	int8_t etype;
 
-	if (bh)
-		atomic_inc(&bh->b_count);
+	if (epos.bh)
+		atomic_inc(&epos.bh->b_count);
 
-	while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
+	while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1)
 	{
-		udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
+		udf_write_aext(inode, &epos, neloc, nelen, 1);
 
 		neloc = oeloc;
 		nelen = (etype << 30) | oelen;
 	}
-	udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1);
-	udf_release_data(bh);
+	udf_add_aext(inode, &epos, neloc, nelen, 1);
+	udf_release_data(epos.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)
+int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
+	kernel_lb_addr eloc, uint32_t elen)
 {
-	struct buffer_head *obh;
-	kernel_lb_addr obloc;
-	int oextoffset, adsize;
+	struct extent_position oepos;
+	int adsize;
 	int8_t etype;
 	struct allocExtDesc *aed;
 
-	if (nbh)
+	if (epos.bh)
 	{
-		atomic_inc(&nbh->b_count);
-		atomic_inc(&nbh->b_count);
+		atomic_inc(&epos.bh->b_count);
+		atomic_inc(&epos.bh->b_count);
 	}
 
 	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
@@ -1879,78 +1876,75 @@
 	else
 		adsize = 0;
 
-	obh = nbh;
-	obloc = nbloc;
-	oextoffset = nextoffset;
-
-	if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1)
+	oepos = epos;
+	if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1)
 		return -1;
 
-	while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
+	while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1)
 	{
-		udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1);
-		if (obh != nbh)
+		udf_write_aext(inode, &oepos, eloc, (etype << 30) | elen, 1);
+		if (oepos.bh != epos.bh)
 		{
-			obloc = nbloc;
-			udf_release_data(obh);
-			atomic_inc(&nbh->b_count);
-			obh = nbh;
-			oextoffset = nextoffset - adsize;
+			oepos.block = epos.block;
+			udf_release_data(oepos.bh);
+			atomic_inc(&epos.bh->b_count);
+			oepos.bh = epos.bh;
+			oepos.offset = epos.offset - adsize;
 		}
 	}
 	memset(&eloc, 0x00, sizeof(kernel_lb_addr));
 	elen = 0;
 
-	if (nbh != obh)
+	if (epos.bh != oepos.bh)
 	{
-		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_free_blocks(inode->i_sb, inode, epos.block, 0, 1);
+		udf_write_aext(inode, &oepos, eloc, elen, 1);
+		udf_write_aext(inode, &oepos, eloc, elen, 1);
+		if (!oepos.bh)
 		{
 			UDF_I_LENALLOC(inode) -= (adsize * 2);
 			mark_inode_dirty(inode);
 		}
 		else
 		{
-			aed = (struct allocExtDesc *)(obh)->b_data;
+			aed = (struct allocExtDesc *)oepos.bh->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));
+				udf_update_tag(oepos.bh->b_data, oepos.offset - (2*adsize));
 			else
-				udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
-			mark_buffer_dirty_inode(obh, inode);
+				udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc));
+			mark_buffer_dirty_inode(oepos.bh, inode);
 		}
 	}
 	else
 	{
-		udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
-		if (!obh)
+		udf_write_aext(inode, &oepos, eloc, elen, 1);
+		if (!oepos.bh)
 		{
 			UDF_I_LENALLOC(inode) -= adsize;
 			mark_inode_dirty(inode);
 		}
 		else
 		{
-			aed = (struct allocExtDesc *)(obh)->b_data;
+			aed = (struct allocExtDesc *)oepos.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((obh)->b_data, oextoffset - adsize);
+				udf_update_tag(oepos.bh->b_data, epos.offset - adsize);
 			else
-				udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
-			mark_buffer_dirty_inode(obh, inode);
+				udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc));
+			mark_buffer_dirty_inode(oepos.bh, inode);
 		}
 	}
 	
-	udf_release_data(nbh);
-	udf_release_data(obh);
+	udf_release_data(epos.bh);
+	udf_release_data(oepos.bh);
 	return (elen >> 30);
 }
 
-int8_t inode_bmap(struct inode *inode, sector_t block, kernel_lb_addr *bloc, uint32_t *extoffset,
-	kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset, struct buffer_head **bh)
+int8_t inode_bmap(struct inode *inode, sector_t block, struct extent_position *pos,
+	kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset)
 {
 	loff_t lbcount = 0, bcount = (loff_t)block << inode->i_sb->s_blocksize_bits;
 	int8_t etype;
@@ -1961,13 +1955,14 @@
 		return -1;
 	}
 
-	*extoffset = 0;
+	pos->offset = 0;
+	pos->block = UDF_I_LOCATION(inode);
+	pos->bh = NULL;
 	*elen = 0;
-	*bloc = UDF_I_LOCATION(inode);
 
 	do
 	{
-		if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1)
+		if ((etype = udf_next_aext(inode, pos, eloc, elen, 1)) == -1)
 		{
 			*offset = (bcount - lbcount) >> inode->i_sb->s_blocksize_bits;
 			UDF_I_LENEXTENTS(inode) = lbcount;
@@ -1983,21 +1978,21 @@
 
 long udf_block_map(struct inode *inode, sector_t block)
 {
-	kernel_lb_addr eloc, bloc;
-	uint32_t extoffset, elen;
+	kernel_lb_addr eloc;
+	uint32_t elen;
 	sector_t offset;
-	struct buffer_head *bh = NULL;
+	struct extent_position epos = { NULL, 0, { 0, 0}};
 	int ret;
 
 	lock_kernel();
 
-	if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
+	if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
 		ret = udf_get_lb_pblock(inode->i_sb, eloc, offset);
 	else
 		ret = 0;
 
 	unlock_kernel();
-	udf_release_data(bh);
+	udf_release_data(epos.bh);
 
 	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
 		return udf_fixed_to_variable(ret);