提交 ff116fc8 编写于 作者: J Jan Kara 提交者: Linus Torvalds

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: NJan Kara <jack@suse.cz>
Acked-by: NChristoph Hellwig <hch@infradead.org>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 60448b1d
...@@ -427,9 +427,9 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -427,9 +427,9 @@ static void udf_table_free_blocks(struct super_block * sb,
{ {
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
uint32_t start, end; uint32_t start, end;
uint32_t nextoffset, oextoffset, elen; uint32_t elen;
kernel_lb_addr nbloc, obloc, eloc; kernel_lb_addr eloc;
struct buffer_head *obh, *nbh; struct extent_position oepos, epos;
int8_t etype; int8_t etype;
int i; int i;
...@@ -457,14 +457,13 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -457,14 +457,13 @@ static void udf_table_free_blocks(struct super_block * sb,
start = bloc.logicalBlockNum + offset; start = bloc.logicalBlockNum + offset;
end = bloc.logicalBlockNum + offset + count - 1; end = bloc.logicalBlockNum + offset + count - 1;
oextoffset = nextoffset = sizeof(struct unallocSpaceEntry); epos.offset = oepos.offset = sizeof(struct unallocSpaceEntry);
elen = 0; elen = 0;
obloc = nbloc = UDF_I_LOCATION(table); epos.block = oepos.block = UDF_I_LOCATION(table);
epos.bh = oepos.bh = NULL;
obh = nbh = NULL;
while (count && (etype = while (count && (etype =
udf_next_aext(table, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1) udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
{ {
if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) == if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) ==
start)) start))
...@@ -482,7 +481,7 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -482,7 +481,7 @@ static void udf_table_free_blocks(struct super_block * sb,
start += count; start += count;
count = 0; count = 0;
} }
udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1); udf_write_aext(table, &oepos, eloc, elen, 1);
} }
else if (eloc.logicalBlockNum == (end + 1)) else if (eloc.logicalBlockNum == (end + 1))
{ {
...@@ -502,20 +501,20 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -502,20 +501,20 @@ static void udf_table_free_blocks(struct super_block * sb,
end -= count; end -= count;
count = 0; count = 0;
} }
udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1); udf_write_aext(table, &oepos, eloc, elen, 1);
} }
if (nbh != obh) if (epos.bh != oepos.bh)
{ {
i = -1; i = -1;
obloc = nbloc; oepos.block = epos.block;
udf_release_data(obh); udf_release_data(oepos.bh);
atomic_inc(&nbh->b_count); atomic_inc(&epos.bh->b_count);
obh = nbh; oepos.bh = epos.bh;
oextoffset = 0; oepos.offset = 0;
} }
else else
oextoffset = nextoffset; oepos.offset = epos.offset;
} }
if (count) if (count)
...@@ -547,55 +546,53 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -547,55 +546,53 @@ static void udf_table_free_blocks(struct super_block * sb,
adsize = sizeof(long_ad); adsize = sizeof(long_ad);
else else
{ {
udf_release_data(obh); udf_release_data(oepos.bh);
udf_release_data(nbh); udf_release_data(epos.bh);
goto error_return; goto error_return;
} }
if (nextoffset + (2 * adsize) > sb->s_blocksize) if (epos.offset + (2 * adsize) > sb->s_blocksize)
{ {
char *sptr, *dptr; char *sptr, *dptr;
int loffset; int loffset;
udf_release_data(obh); udf_release_data(oepos.bh);
obh = nbh; oepos = epos;
obloc = nbloc;
oextoffset = nextoffset;
/* Steal a block from the extent being free'd */ /* Steal a block from the extent being free'd */
nbloc.logicalBlockNum = eloc.logicalBlockNum; epos.block.logicalBlockNum = eloc.logicalBlockNum;
eloc.logicalBlockNum ++; eloc.logicalBlockNum ++;
elen -= sb->s_blocksize; elen -= sb->s_blocksize;
if (!(nbh = udf_tread(sb, if (!(epos.bh = udf_tread(sb,
udf_get_lb_pblock(sb, nbloc, 0)))) udf_get_lb_pblock(sb, epos.block, 0))))
{ {
udf_release_data(obh); udf_release_data(oepos.bh);
goto error_return; goto error_return;
} }
aed = (struct allocExtDesc *)(nbh->b_data); aed = (struct allocExtDesc *)(epos.bh->b_data);
aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); aed->previousAllocExtLocation = cpu_to_le32(oepos.block.logicalBlockNum);
if (nextoffset + adsize > sb->s_blocksize) if (epos.offset + adsize > sb->s_blocksize)
{ {
loffset = nextoffset; loffset = epos.offset;
aed->lengthAllocDescs = cpu_to_le32(adsize); aed->lengthAllocDescs = cpu_to_le32(adsize);
sptr = UDF_I_DATA(inode) + nextoffset - sptr = UDF_I_DATA(inode) + epos.offset -
udf_file_entry_alloc_offset(inode) + udf_file_entry_alloc_offset(inode) +
UDF_I_LENEATTR(inode) - adsize; UDF_I_LENEATTR(inode) - adsize;
dptr = nbh->b_data + sizeof(struct allocExtDesc); dptr = epos.bh->b_data + sizeof(struct allocExtDesc);
memcpy(dptr, sptr, adsize); memcpy(dptr, sptr, adsize);
nextoffset = sizeof(struct allocExtDesc) + adsize; epos.offset = sizeof(struct allocExtDesc) + adsize;
} }
else else
{ {
loffset = nextoffset + adsize; loffset = epos.offset + adsize;
aed->lengthAllocDescs = cpu_to_le32(0); aed->lengthAllocDescs = cpu_to_le32(0);
sptr = (obh)->b_data + nextoffset; sptr = oepos.bh->b_data + epos.offset;
nextoffset = sizeof(struct allocExtDesc); epos.offset = sizeof(struct allocExtDesc);
if (obh) if (oepos.bh)
{ {
aed = (struct allocExtDesc *)(obh)->b_data; aed = (struct allocExtDesc *)oepos.bh->b_data;
aed->lengthAllocDescs = aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
} }
...@@ -606,11 +603,11 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -606,11 +603,11 @@ static void udf_table_free_blocks(struct super_block * sb,
} }
} }
if (UDF_SB_UDFREV(sb) >= 0x0200) if (UDF_SB_UDFREV(sb) >= 0x0200)
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3, 1,
nbloc.logicalBlockNum, sizeof(tag)); epos.block.logicalBlockNum, sizeof(tag));
else else
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 2, 1,
nbloc.logicalBlockNum, sizeof(tag)); epos.block.logicalBlockNum, sizeof(tag));
switch (UDF_I_ALLOCTYPE(table)) switch (UDF_I_ALLOCTYPE(table))
{ {
case ICBTAG_FLAG_AD_SHORT: case ICBTAG_FLAG_AD_SHORT:
...@@ -619,7 +616,7 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -619,7 +616,7 @@ static void udf_table_free_blocks(struct super_block * sb,
sad->extLength = cpu_to_le32( sad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS | EXT_NEXT_EXTENT_ALLOCDECS |
sb->s_blocksize); sb->s_blocksize);
sad->extPosition = cpu_to_le32(nbloc.logicalBlockNum); sad->extPosition = cpu_to_le32(epos.block.logicalBlockNum);
break; break;
} }
case ICBTAG_FLAG_AD_LONG: case ICBTAG_FLAG_AD_LONG:
...@@ -628,14 +625,14 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -628,14 +625,14 @@ static void udf_table_free_blocks(struct super_block * sb,
lad->extLength = cpu_to_le32( lad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS | EXT_NEXT_EXTENT_ALLOCDECS |
sb->s_blocksize); sb->s_blocksize);
lad->extLocation = cpu_to_lelb(nbloc); lad->extLocation = cpu_to_lelb(epos.block);
break; break;
} }
} }
if (obh) if (oepos.bh)
{ {
udf_update_tag(obh->b_data, loffset); udf_update_tag(oepos.bh->b_data, loffset);
mark_buffer_dirty(obh); mark_buffer_dirty(oepos.bh);
} }
else else
mark_inode_dirty(table); mark_inode_dirty(table);
...@@ -643,26 +640,26 @@ static void udf_table_free_blocks(struct super_block * sb, ...@@ -643,26 +640,26 @@ static void udf_table_free_blocks(struct super_block * sb,
if (elen) /* It's possible that stealing the block emptied the extent */ if (elen) /* It's possible that stealing the block emptied the extent */
{ {
udf_write_aext(table, nbloc, &nextoffset, eloc, elen, nbh, 1); udf_write_aext(table, &epos, eloc, elen, 1);
if (!nbh) if (!epos.bh)
{ {
UDF_I_LENALLOC(table) += adsize; UDF_I_LENALLOC(table) += adsize;
mark_inode_dirty(table); mark_inode_dirty(table);
} }
else else
{ {
aed = (struct allocExtDesc *)nbh->b_data; aed = (struct allocExtDesc *)epos.bh->b_data;
aed->lengthAllocDescs = aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
udf_update_tag(nbh->b_data, nextoffset); udf_update_tag(epos.bh->b_data, epos.offset);
mark_buffer_dirty(nbh); mark_buffer_dirty(epos.bh);
} }
} }
} }
udf_release_data(nbh); udf_release_data(epos.bh);
udf_release_data(obh); udf_release_data(oepos.bh);
error_return: error_return:
sb->s_dirt = 1; sb->s_dirt = 1;
...@@ -677,9 +674,9 @@ static int udf_table_prealloc_blocks(struct super_block * sb, ...@@ -677,9 +674,9 @@ static int udf_table_prealloc_blocks(struct super_block * sb,
{ {
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
int alloc_count = 0; int alloc_count = 0;
uint32_t extoffset, elen, adsize; uint32_t elen, adsize;
kernel_lb_addr bloc, eloc; kernel_lb_addr eloc;
struct buffer_head *bh; struct extent_position epos;
int8_t etype = -1; int8_t etype = -1;
if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition)) if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
...@@ -693,14 +690,13 @@ static int udf_table_prealloc_blocks(struct super_block * sb, ...@@ -693,14 +690,13 @@ static int udf_table_prealloc_blocks(struct super_block * sb,
return 0; return 0;
mutex_lock(&sbi->s_alloc_mutex); mutex_lock(&sbi->s_alloc_mutex);
extoffset = sizeof(struct unallocSpaceEntry); epos.offset = sizeof(struct unallocSpaceEntry);
bloc = UDF_I_LOCATION(table); epos.block = UDF_I_LOCATION(table);
epos.bh = NULL;
bh = NULL;
eloc.logicalBlockNum = 0xFFFFFFFF; eloc.logicalBlockNum = 0xFFFFFFFF;
while (first_block != eloc.logicalBlockNum && (etype = while (first_block != eloc.logicalBlockNum && (etype =
udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
{ {
udf_debug("eloc=%d, elen=%d, first_block=%d\n", udf_debug("eloc=%d, elen=%d, first_block=%d\n",
eloc.logicalBlockNum, elen, first_block); eloc.logicalBlockNum, elen, first_block);
...@@ -709,7 +705,7 @@ static int udf_table_prealloc_blocks(struct super_block * sb, ...@@ -709,7 +705,7 @@ static int udf_table_prealloc_blocks(struct super_block * sb,
if (first_block == eloc.logicalBlockNum) if (first_block == eloc.logicalBlockNum)
{ {
extoffset -= adsize; epos.offset -= adsize;
alloc_count = (elen >> sb->s_blocksize_bits); alloc_count = (elen >> sb->s_blocksize_bits);
if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count)) if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count))
...@@ -719,15 +715,15 @@ static int udf_table_prealloc_blocks(struct super_block * sb, ...@@ -719,15 +715,15 @@ static int udf_table_prealloc_blocks(struct super_block * sb,
alloc_count = block_count; alloc_count = block_count;
eloc.logicalBlockNum += alloc_count; eloc.logicalBlockNum += alloc_count;
elen -= (alloc_count << sb->s_blocksize_bits); elen -= (alloc_count << sb->s_blocksize_bits);
udf_write_aext(table, bloc, &extoffset, eloc, (etype << 30) | elen, bh, 1); udf_write_aext(table, &epos, eloc, (etype << 30) | elen, 1);
} }
else else
udf_delete_aext(table, bloc, extoffset, eloc, (etype << 30) | elen, bh); udf_delete_aext(table, epos, eloc, (etype << 30) | elen);
} }
else else
alloc_count = 0; alloc_count = 0;
udf_release_data(bh); udf_release_data(epos.bh);
if (alloc_count && UDF_SB_LVIDBH(sb)) if (alloc_count && UDF_SB_LVIDBH(sb))
{ {
...@@ -747,9 +743,9 @@ static int udf_table_new_block(struct super_block * sb, ...@@ -747,9 +743,9 @@ static int udf_table_new_block(struct super_block * sb,
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF; uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF;
uint32_t newblock = 0, adsize; uint32_t newblock = 0, adsize;
uint32_t extoffset, goal_extoffset, elen, goal_elen = 0; uint32_t elen, goal_elen = 0;
kernel_lb_addr bloc, goal_bloc, eloc, goal_eloc; kernel_lb_addr eloc, goal_eloc;
struct buffer_head *bh, *goal_bh; struct extent_position epos, goal_epos;
int8_t etype; int8_t etype;
*err = -ENOSPC; *err = -ENOSPC;
...@@ -770,14 +766,12 @@ static int udf_table_new_block(struct super_block * sb, ...@@ -770,14 +766,12 @@ static int udf_table_new_block(struct super_block * sb,
We store the buffer_head, bloc, and extoffset of the current closest We store the buffer_head, bloc, and extoffset of the current closest
match and use that when we are done. match and use that when we are done.
*/ */
epos.offset = sizeof(struct unallocSpaceEntry);
extoffset = sizeof(struct unallocSpaceEntry); epos.block = UDF_I_LOCATION(table);
bloc = UDF_I_LOCATION(table); epos.bh = goal_epos.bh = NULL;
goal_bh = bh = NULL;
while (spread && (etype = while (spread && (etype =
udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
{ {
if (goal >= eloc.logicalBlockNum) if (goal >= eloc.logicalBlockNum)
{ {
...@@ -793,24 +787,24 @@ static int udf_table_new_block(struct super_block * sb, ...@@ -793,24 +787,24 @@ static int udf_table_new_block(struct super_block * sb,
if (nspread < spread) if (nspread < spread)
{ {
spread = nspread; spread = nspread;
if (goal_bh != bh) if (goal_epos.bh != epos.bh)
{ {
udf_release_data(goal_bh); udf_release_data(goal_epos.bh);
goal_bh = bh; goal_epos.bh = epos.bh;
atomic_inc(&goal_bh->b_count); atomic_inc(&goal_epos.bh->b_count);
} }
goal_bloc = bloc; goal_epos.block = epos.block;
goal_extoffset = extoffset - adsize; goal_epos.offset = epos.offset - adsize;
goal_eloc = eloc; goal_eloc = eloc;
goal_elen = (etype << 30) | elen; goal_elen = (etype << 30) | elen;
} }
} }
udf_release_data(bh); udf_release_data(epos.bh);
if (spread == 0xFFFFFFFF) if (spread == 0xFFFFFFFF)
{ {
udf_release_data(goal_bh); udf_release_data(goal_epos.bh);
mutex_unlock(&sbi->s_alloc_mutex); mutex_unlock(&sbi->s_alloc_mutex);
return 0; return 0;
} }
...@@ -826,17 +820,17 @@ static int udf_table_new_block(struct super_block * sb, ...@@ -826,17 +820,17 @@ static int udf_table_new_block(struct super_block * sb,
if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
{ {
udf_release_data(goal_bh); udf_release_data(goal_epos.bh);
mutex_unlock(&sbi->s_alloc_mutex); mutex_unlock(&sbi->s_alloc_mutex);
*err = -EDQUOT; *err = -EDQUOT;
return 0; return 0;
} }
if (goal_elen) if (goal_elen)
udf_write_aext(table, goal_bloc, &goal_extoffset, goal_eloc, goal_elen, goal_bh, 1); udf_write_aext(table, &goal_epos, goal_eloc, goal_elen, 1);
else else
udf_delete_aext(table, goal_bloc, goal_extoffset, goal_eloc, goal_elen, goal_bh); udf_delete_aext(table, goal_epos, goal_eloc, goal_elen);
udf_release_data(goal_bh); udf_release_data(goal_epos.bh);
if (UDF_SB_LVIDBH(sb)) if (UDF_SB_LVIDBH(sb))
{ {
......
...@@ -111,12 +111,13 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d ...@@ -111,12 +111,13 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
uint16_t liu; uint16_t liu;
uint8_t lfi; uint8_t lfi;
loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
struct buffer_head * bh = NULL, * tmp, * bha[16]; struct buffer_head *tmp, *bha[16];
kernel_lb_addr bloc, eloc; kernel_lb_addr eloc;
uint32_t extoffset, elen; uint32_t elen;
sector_t offset; sector_t offset;
int i, num; int i, num;
unsigned int dt_type; unsigned int dt_type;
struct extent_position epos = { NULL, 0, {0, 0}};
if (nf_pos >= size) if (nf_pos >= size)
return 0; return 0;
...@@ -128,22 +129,22 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d ...@@ -128,22 +129,22 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh.sbh = fibh.ebh = NULL; fibh.sbh = fibh.ebh = NULL;
else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2), else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
&bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
{ {
block = udf_get_lb_pblock(dir->i_sb, eloc, offset); block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen) if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{ {
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
extoffset -= sizeof(short_ad); epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
extoffset -= sizeof(long_ad); epos.offset -= sizeof(long_ad);
} }
else else
offset = 0; offset = 0;
if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block)))
{ {
udf_release_data(bh); udf_release_data(epos.bh);
return -EIO; return -EIO;
} }
...@@ -171,7 +172,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d ...@@ -171,7 +172,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
} }
else else
{ {
udf_release_data(bh); udf_release_data(epos.bh);
return -ENOENT; return -ENOENT;
} }
...@@ -179,14 +180,14 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d ...@@ -179,14 +180,14 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
{ {
filp->f_pos = nf_pos + 1; filp->f_pos = nf_pos + 1;
fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset);
if (!fi) if (!fi)
{ {
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh); udf_release_data(fibh.ebh);
udf_release_data(fibh.sbh); udf_release_data(fibh.sbh);
udf_release_data(bh); udf_release_data(epos.bh);
return 0; return 0;
} }
...@@ -246,7 +247,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d ...@@ -246,7 +247,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh); udf_release_data(fibh.ebh);
udf_release_data(fibh.sbh); udf_release_data(fibh.sbh);
udf_release_data(bh); udf_release_data(epos.bh);
return 0; return 0;
} }
} }
...@@ -257,7 +258,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d ...@@ -257,7 +258,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh); udf_release_data(fibh.ebh);
udf_release_data(fibh.sbh); udf_release_data(fibh.sbh);
udf_release_data(bh); udf_release_data(epos.bh);
return 0; return 0;
} }
...@@ -75,9 +75,9 @@ struct fileIdentDesc * ...@@ -75,9 +75,9 @@ struct fileIdentDesc *
udf_fileident_read(struct inode *dir, loff_t *nf_pos, udf_fileident_read(struct inode *dir, loff_t *nf_pos,
struct udf_fileident_bh *fibh, struct udf_fileident_bh *fibh,
struct fileIdentDesc *cfi, struct fileIdentDesc *cfi,
kernel_lb_addr *bloc, uint32_t *extoffset, struct extent_position *epos,
kernel_lb_addr *eloc, uint32_t *elen, kernel_lb_addr *eloc, uint32_t *elen,
sector_t *offset, struct buffer_head **bh) sector_t *offset)
{ {
struct fileIdentDesc *fi; struct fileIdentDesc *fi;
int i, num, block; int i, num, block;
...@@ -105,13 +105,11 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, ...@@ -105,13 +105,11 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
if (fibh->eoffset == dir->i_sb->s_blocksize) if (fibh->eoffset == dir->i_sb->s_blocksize)
{ {
int lextoffset = *extoffset; int lextoffset = epos->offset;
if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) != if (udf_next_aext(dir, epos, eloc, elen, 1) !=
(EXT_RECORDED_ALLOCATED >> 30)) (EXT_RECORDED_ALLOCATED >> 30))
{
return NULL; return NULL;
}
block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
...@@ -120,7 +118,7 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, ...@@ -120,7 +118,7 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
*offset = 0; *offset = 0;
else else
*extoffset = lextoffset; epos->offset = lextoffset;
udf_release_data(fibh->sbh); udf_release_data(fibh->sbh);
if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block)))
...@@ -169,13 +167,11 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, ...@@ -169,13 +167,11 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
} }
else if (fibh->eoffset > dir->i_sb->s_blocksize) else if (fibh->eoffset > dir->i_sb->s_blocksize)
{ {
int lextoffset = *extoffset; int lextoffset = epos->offset;
if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) != if (udf_next_aext(dir, epos, eloc, elen, 1) !=
(EXT_RECORDED_ALLOCATED >> 30)) (EXT_RECORDED_ALLOCATED >> 30))
{
return NULL; return NULL;
}
block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset); block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
...@@ -184,7 +180,7 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos, ...@@ -184,7 +180,7 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen) if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
*offset = 0; *offset = 0;
else else
*extoffset = lextoffset; epos->offset = lextoffset;
fibh->soffset -= dir->i_sb->s_blocksize; fibh->soffset -= dir->i_sb->s_blocksize;
fibh->eoffset -= dir->i_sb->s_blocksize; fibh->eoffset -= dir->i_sb->s_blocksize;
......
...@@ -51,8 +51,8 @@ static int udf_update_inode(struct inode *, int); ...@@ -51,8 +51,8 @@ static int udf_update_inode(struct inode *, int);
static void udf_fill_inode(struct inode *, struct buffer_head *); static void udf_fill_inode(struct inode *, struct buffer_head *);
static struct buffer_head *inode_getblk(struct inode *, sector_t, int *, static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
long *, int *); long *, int *);
static int8_t udf_insert_aext(struct inode *, kernel_lb_addr, int, static int8_t udf_insert_aext(struct inode *, struct extent_position,
kernel_lb_addr, uint32_t, struct buffer_head *); kernel_lb_addr, uint32_t);
static void udf_split_extents(struct inode *, int *, int, int, static void udf_split_extents(struct inode *, int *, int, int,
kernel_long_ad [EXTENT_MERGE_SIZE], int *); kernel_long_ad [EXTENT_MERGE_SIZE], int *);
static void udf_prealloc_extents(struct inode *, int, int, static void udf_prealloc_extents(struct inode *, int, int,
...@@ -61,7 +61,7 @@ static void udf_merge_extents(struct inode *, ...@@ -61,7 +61,7 @@ static void udf_merge_extents(struct inode *,
kernel_long_ad [EXTENT_MERGE_SIZE], int *); kernel_long_ad [EXTENT_MERGE_SIZE], int *);
static void udf_update_extents(struct inode *, static void udf_update_extents(struct inode *,
kernel_long_ad [EXTENT_MERGE_SIZE], int, int, 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); static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
/* /*
...@@ -194,10 +194,11 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err) ...@@ -194,10 +194,11 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err) struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err)
{ {
int newblock; int newblock;
struct buffer_head *sbh = NULL, *dbh = NULL; struct buffer_head *dbh = NULL;
kernel_lb_addr bloc, eloc; kernel_lb_addr eloc;
uint32_t elen, extoffset; uint32_t elen;
uint8_t alloctype; uint8_t alloctype;
struct extent_position epos;
struct udf_fileident_bh sfibh, dfibh; struct udf_fileident_bh sfibh, dfibh;
loff_t f_pos = udf_ext0_offset(inode) >> 2; loff_t f_pos = udf_ext0_offset(inode) >> 2;
...@@ -237,13 +238,13 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int ...@@ -237,13 +238,13 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
mark_buffer_dirty_inode(dbh, inode); mark_buffer_dirty_inode(dbh, inode);
sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2; 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.soffset = dfibh.eoffset = 0;
dfibh.sbh = dfibh.ebh = dbh; dfibh.sbh = dfibh.ebh = dbh;
while ( (f_pos < size) ) while ( (f_pos < size) )
{ {
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB; 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) if (!sfi)
{ {
udf_release_data(dbh); udf_release_data(dbh);
...@@ -266,16 +267,17 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int ...@@ -266,16 +267,17 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode)); memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode));
UDF_I_LENALLOC(inode) = 0; UDF_I_LENALLOC(inode) = 0;
bloc = UDF_I_LOCATION(inode);
eloc.logicalBlockNum = *block; eloc.logicalBlockNum = *block;
eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
elen = inode->i_size; elen = inode->i_size;
UDF_I_LENEXTENTS(inode) = elen; UDF_I_LENEXTENTS(inode) = elen;
extoffset = udf_file_entry_alloc_offset(inode); epos.bh = NULL;
udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0); epos.block = UDF_I_LOCATION(inode);
epos.offset = udf_file_entry_alloc_offset(inode);
udf_add_aext(inode, &epos, eloc, elen, 0);
/* UniqueID stuff */ /* UniqueID stuff */
udf_release_data(sbh); udf_release_data(epos.bh);
mark_inode_dirty(inode); mark_inode_dirty(inode);
return dbh; return dbh;
} }
...@@ -357,12 +359,12 @@ udf_getblk(struct inode *inode, long block, int create, int *err) ...@@ -357,12 +359,12 @@ udf_getblk(struct inode *inode, long block, int create, int *err)
static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
int *err, long *phys, int *new) 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]; 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; int count = 0, startnum = 0, endnum = 0;
uint32_t elen = 0; uint32_t elen = 0;
kernel_lb_addr eloc, pbloc, cbloc, nbloc; kernel_lb_addr eloc;
int c = 1; int c = 1;
loff_t lbcount = 0, b_off = 0; loff_t lbcount = 0, b_off = 0;
uint32_t newblocknum, newblock; uint32_t newblocknum, newblock;
...@@ -371,37 +373,39 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -371,37 +373,39 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum; int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
char lastblock = 0; 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; 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. /* find the extent which contains the block we are looking for.
alternate between laarr[0] and laarr[1] for locations of the alternate between laarr[0] and laarr[1] for locations of the
current extent, and the previous extent */ current extent, and the previous extent */
do do
{ {
if (pbh != cbh) if (prev_epos.bh != cur_epos.bh)
{ {
udf_release_data(pbh); udf_release_data(prev_epos.bh);
atomic_inc(&cbh->b_count); atomic_inc(&cur_epos.bh->b_count);
pbh = cbh; prev_epos.bh = cur_epos.bh;
} }
if (cbh != nbh) if (cur_epos.bh != next_epos.bh)
{ {
udf_release_data(cbh); udf_release_data(cur_epos.bh);
atomic_inc(&nbh->b_count); atomic_inc(&next_epos.bh->b_count);
cbh = nbh; cur_epos.bh = next_epos.bh;
} }
lbcount += elen; lbcount += elen;
pbloc = cbloc; prev_epos.block = cur_epos.block;
cbloc = nbloc; cur_epos.block = next_epos.block;
pextoffset = cextoffset; prev_epos.offset = cur_epos.offset;
cextoffset = nextoffset; 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; break;
c = !c; c = !c;
...@@ -430,11 +434,11 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -430,11 +434,11 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
elen = EXT_RECORDED_ALLOCATED | elen = EXT_RECORDED_ALLOCATED |
((elen + inode->i_sb->s_blocksize - 1) & ((elen + inode->i_sb->s_blocksize - 1) &
~(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(prev_epos.bh);
udf_release_data(cbh); udf_release_data(cur_epos.bh);
udf_release_data(nbh); udf_release_data(next_epos.bh);
newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset); newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset);
*phys = newblock; *phys = newblock;
return NULL; return NULL;
...@@ -477,7 +481,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -477,7 +481,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
/* if the current block is located in a extent, read the next extent */ /* if the current block is located in a extent, read the next extent */
if (etype != -1) 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].extLength = (etype << 30) | elen;
laarr[c+1].extLocation = eloc; laarr[c+1].extLocation = eloc;
...@@ -488,8 +492,8 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -488,8 +492,8 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
else else
lastblock = 1; lastblock = 1;
} }
udf_release_data(cbh); udf_release_data(cur_epos.bh);
udf_release_data(nbh); udf_release_data(next_epos.bh);
/* if the current extent is not recorded but allocated, get the /* if the current extent is not recorded but allocated, get the
block in the extent corresponding to the requested block */ block in the extent corresponding to the requested block */
...@@ -509,7 +513,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -509,7 +513,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
if (!(newblocknum = udf_new_block(inode->i_sb, inode, if (!(newblocknum = udf_new_block(inode->i_sb, inode,
UDF_I_LOCATION(inode).partitionReferenceNum, goal, err))) UDF_I_LOCATION(inode).partitionReferenceNum, goal, err)))
{ {
udf_release_data(pbh); udf_release_data(prev_epos.bh);
*err = -ENOSPC; *err = -ENOSPC;
return NULL; return NULL;
} }
...@@ -532,9 +536,9 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block, ...@@ -532,9 +536,9 @@ static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
/* write back the new extents, inserting new extents if the new number /* write back the new extents, inserting new extents if the new number
of extents is greater than the old number, and deleting extents if of extents is greater than the old number, and deleting extents if
the new number of extents is less than the old number */ 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, if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,
UDF_I_LOCATION(inode).partitionReferenceNum, 0))) UDF_I_LOCATION(inode).partitionReferenceNum, 0)))
...@@ -796,7 +800,7 @@ static void udf_merge_extents(struct inode *inode, ...@@ -796,7 +800,7 @@ static void udf_merge_extents(struct inode *inode,
static void udf_update_extents(struct inode *inode, static void udf_update_extents(struct inode *inode,
kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum, 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; int start = 0, i;
kernel_lb_addr tmploc; kernel_lb_addr tmploc;
...@@ -805,28 +809,26 @@ static void udf_update_extents(struct inode *inode, ...@@ -805,28 +809,26 @@ static void udf_update_extents(struct inode *inode,
if (startnum > endnum) if (startnum > endnum)
{ {
for (i=0; i<(startnum-endnum); i++) for (i=0; i<(startnum-endnum); i++)
{ udf_delete_aext(inode, *epos, laarr[i].extLocation,
udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation, laarr[i].extLength);
laarr[i].extLength, *pbh);
}
} }
else if (startnum < endnum) else if (startnum < endnum)
{ {
for (i=0; i<(endnum-startnum); i++) for (i=0; i<(endnum-startnum); i++)
{ {
udf_insert_aext(inode, pbloc, pextoffset, laarr[i].extLocation, udf_insert_aext(inode, *epos, laarr[i].extLocation,
laarr[i].extLength, *pbh); laarr[i].extLength);
udf_next_aext(inode, &pbloc, &pextoffset, &laarr[i].extLocation, udf_next_aext(inode, epos, &laarr[i].extLocation,
&laarr[i].extLength, pbh, 1); &laarr[i].extLength, 1);
start ++; start ++;
} }
} }
for (i=start; i<endnum; i++) for (i=start; i<endnum; i++)
{ {
udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0); udf_next_aext(inode, epos, &tmploc, &tmplen, 0);
udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation, udf_write_aext(inode, epos, laarr[i].extLocation,
laarr[i].extLength, *pbh, 1); laarr[i].extLength, 1);
} }
} }
...@@ -1557,8 +1559,8 @@ udf_iget(struct super_block *sb, kernel_lb_addr ino) ...@@ -1557,8 +1559,8 @@ udf_iget(struct super_block *sb, kernel_lb_addr ino)
return NULL; return NULL;
} }
int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
kernel_lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc) kernel_lb_addr eloc, uint32_t elen, int inc)
{ {
int adsize; int adsize;
short_ad *sad = NULL; short_ad *sad = NULL;
...@@ -1567,10 +1569,10 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, ...@@ -1567,10 +1569,10 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
int8_t etype; int8_t etype;
uint8_t *ptr; uint8_t *ptr;
if (!*bh) if (!epos->bh)
ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
else else
ptr = (*bh)->b_data + *extoffset; ptr = epos->bh->b_data + epos->offset;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
adsize = sizeof(short_ad); adsize = sizeof(short_ad);
...@@ -1579,20 +1581,20 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, ...@@ -1579,20 +1581,20 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
else else
return -1; return -1;
if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize) if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize)
{ {
char *sptr, *dptr; char *sptr, *dptr;
struct buffer_head *nbh; struct buffer_head *nbh;
int err, loffset; 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))) obloc.partitionReferenceNum, obloc.logicalBlockNum, &err)))
{ {
return -1; return -1;
} }
if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb, if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
*bloc, 0)))) epos->block, 0))))
{ {
return -1; return -1;
} }
...@@ -1605,25 +1607,25 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, ...@@ -1605,25 +1607,25 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
aed = (struct allocExtDesc *)(nbh->b_data); aed = (struct allocExtDesc *)(nbh->b_data);
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum); 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); aed->lengthAllocDescs = cpu_to_le32(adsize);
sptr = ptr - adsize; sptr = ptr - adsize;
dptr = nbh->b_data + sizeof(struct allocExtDesc); dptr = nbh->b_data + sizeof(struct allocExtDesc);
memcpy(dptr, sptr, adsize); memcpy(dptr, sptr, adsize);
*extoffset = sizeof(struct allocExtDesc) + adsize; epos->offset = sizeof(struct allocExtDesc) + adsize;
} }
else else
{ {
loffset = *extoffset + adsize; loffset = epos->offset + adsize;
aed->lengthAllocDescs = cpu_to_le32(0); aed->lengthAllocDescs = cpu_to_le32(0);
sptr = ptr; 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 = aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
} }
...@@ -1635,10 +1637,10 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, ...@@ -1635,10 +1637,10 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
} }
if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1, udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
bloc->logicalBlockNum, sizeof(tag)); epos->block.logicalBlockNum, sizeof(tag));
else else
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1, 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)) switch (UDF_I_ALLOCTYPE(inode))
{ {
case ICBTAG_FLAG_AD_SHORT: case ICBTAG_FLAG_AD_SHORT:
...@@ -1647,7 +1649,7 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, ...@@ -1647,7 +1649,7 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
sad->extLength = cpu_to_le32( sad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS | EXT_NEXT_EXTENT_ALLOCDECS |
inode->i_sb->s_blocksize); inode->i_sb->s_blocksize);
sad->extPosition = cpu_to_le32(bloc->logicalBlockNum); sad->extPosition = cpu_to_le32(epos->block.logicalBlockNum);
break; break;
} }
case ICBTAG_FLAG_AD_LONG: case ICBTAG_FLAG_AD_LONG:
...@@ -1656,60 +1658,57 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, ...@@ -1656,60 +1658,57 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
lad->extLength = cpu_to_le32( lad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS | EXT_NEXT_EXTENT_ALLOCDECS |
inode->i_sb->s_blocksize); 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)); memset(lad->impUse, 0x00, sizeof(lad->impUse));
break; break;
} }
} }
if (*bh) if (epos->bh)
{ {
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) 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 else
udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc)); udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc));
mark_buffer_dirty_inode(*bh, inode); mark_buffer_dirty_inode(epos->bh, inode);
udf_release_data(*bh); udf_release_data(epos->bh);
} }
else else
mark_inode_dirty(inode); 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; UDF_I_LENALLOC(inode) += adsize;
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
else else
{ {
aed = (struct allocExtDesc *)(*bh)->b_data; aed = (struct allocExtDesc *)epos->bh->b_data;
aed->lengthAllocDescs = aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); 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) 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 else
udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc)); udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc));
mark_buffer_dirty_inode(*bh, inode); mark_buffer_dirty_inode(epos->bh, inode);
} }
return etype; return etype;
} }
int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset, int8_t udf_write_aext(struct inode *inode, struct extent_position *epos,
kernel_lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc) kernel_lb_addr eloc, uint32_t elen, int inc)
{ {
int adsize; int adsize;
uint8_t *ptr; uint8_t *ptr;
if (!bh) if (!epos->bh)
ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode); ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
else else
{ ptr = epos->bh->b_data + epos->offset;
ptr = bh->b_data + *extoffset;
atomic_inc(&bh->b_count);
}
switch (UDF_I_ALLOCTYPE(inode)) switch (UDF_I_ALLOCTYPE(inode))
{ {
...@@ -1734,40 +1733,39 @@ int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset, ...@@ -1734,40 +1733,39 @@ int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset,
return -1; return -1;
} }
if (bh) if (epos->bh)
{ {
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) 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; struct allocExtDesc *aed = (struct allocExtDesc *)epos->bh->b_data;
udf_update_tag((bh)->b_data, udf_update_tag(epos->bh->b_data,
le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc)); le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc));
} }
mark_buffer_dirty_inode(bh, inode); mark_buffer_dirty_inode(epos->bh, inode);
udf_release_data(bh);
} }
else else
mark_inode_dirty(inode); mark_inode_dirty(inode);
if (inc) if (inc)
*extoffset += adsize; epos->offset += adsize;
return (elen >> 30); return (elen >> 30);
} }
int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) kernel_lb_addr *eloc, uint32_t *elen, int inc)
{ {
int8_t etype; 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)) (EXT_NEXT_EXTENT_ALLOCDECS >> 30))
{ {
*bloc = *eloc; epos->block = *eloc;
*extoffset = sizeof(struct allocExtDesc); epos->offset = sizeof(struct allocExtDesc);
udf_release_data(*bh); udf_release_data(epos->bh);
if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0)))) 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_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; return -1;
} }
} }
...@@ -1775,26 +1773,26 @@ int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, ...@@ -1775,26 +1773,26 @@ int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
return etype; return etype;
} }
int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset, int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc) kernel_lb_addr *eloc, uint32_t *elen, int inc)
{ {
int alen; int alen;
int8_t etype; int8_t etype;
uint8_t *ptr; uint8_t *ptr;
if (!*bh) if (!epos->bh)
{ {
if (!(*extoffset)) if (!epos->offset)
*extoffset = udf_file_entry_alloc_offset(inode); epos->offset = udf_file_entry_alloc_offset(inode);
ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(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); alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode);
} }
else else
{ {
if (!(*extoffset)) if (!epos->offset)
*extoffset = sizeof(struct allocExtDesc); epos->offset = sizeof(struct allocExtDesc);
ptr = (*bh)->b_data + *extoffset; ptr = epos->bh->b_data + epos->offset;
alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)(*bh)->b_data)->lengthAllocDescs); alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->lengthAllocDescs);
} }
switch (UDF_I_ALLOCTYPE(inode)) switch (UDF_I_ALLOCTYPE(inode))
...@@ -1803,7 +1801,7 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse ...@@ -1803,7 +1801,7 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse
{ {
short_ad *sad; short_ad *sad;
if (!(sad = udf_get_fileshortad(ptr, alen, extoffset, inc))) if (!(sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc)))
return -1; return -1;
etype = le32_to_cpu(sad->extLength) >> 30; etype = le32_to_cpu(sad->extLength) >> 30;
...@@ -1816,7 +1814,7 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse ...@@ -1816,7 +1814,7 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse
{ {
long_ad *lad; long_ad *lad;
if (!(lad = udf_get_filelongad(ptr, alen, extoffset, inc))) if (!(lad = udf_get_filelongad(ptr, alen, &epos->offset, inc)))
return -1; return -1;
etype = le32_to_cpu(lad->extLength) >> 30; etype = le32_to_cpu(lad->extLength) >> 30;
...@@ -1835,41 +1833,40 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse ...@@ -1835,41 +1833,40 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse
} }
static int8_t static int8_t
udf_insert_aext(struct inode *inode, kernel_lb_addr bloc, int extoffset, udf_insert_aext(struct inode *inode, struct extent_position epos,
kernel_lb_addr neloc, uint32_t nelen, struct buffer_head *bh) kernel_lb_addr neloc, uint32_t nelen)
{ {
kernel_lb_addr oeloc; kernel_lb_addr oeloc;
uint32_t oelen; uint32_t oelen;
int8_t etype; int8_t etype;
if (bh) if (epos.bh)
atomic_inc(&bh->b_count); 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; neloc = oeloc;
nelen = (etype << 30) | oelen; nelen = (etype << 30) | oelen;
} }
udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1); udf_add_aext(inode, &epos, neloc, nelen, 1);
udf_release_data(bh); udf_release_data(epos.bh);
return (nelen >> 30); return (nelen >> 30);
} }
int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset, int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
kernel_lb_addr eloc, uint32_t elen, struct buffer_head *nbh) kernel_lb_addr eloc, uint32_t elen)
{ {
struct buffer_head *obh; struct extent_position oepos;
kernel_lb_addr obloc; int adsize;
int oextoffset, adsize;
int8_t etype; int8_t etype;
struct allocExtDesc *aed; struct allocExtDesc *aed;
if (nbh) if (epos.bh)
{ {
atomic_inc(&nbh->b_count); atomic_inc(&epos.bh->b_count);
atomic_inc(&nbh->b_count); atomic_inc(&epos.bh->b_count);
} }
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
...@@ -1879,78 +1876,75 @@ int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset ...@@ -1879,78 +1876,75 @@ int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset
else else
adsize = 0; adsize = 0;
obh = nbh; oepos = epos;
obloc = nbloc; if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1)
oextoffset = nextoffset;
if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1)
return -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); udf_write_aext(inode, &oepos, eloc, (etype << 30) | elen, 1);
if (obh != nbh) if (oepos.bh != epos.bh)
{ {
obloc = nbloc; oepos.block = epos.block;
udf_release_data(obh); udf_release_data(oepos.bh);
atomic_inc(&nbh->b_count); atomic_inc(&epos.bh->b_count);
obh = nbh; oepos.bh = epos.bh;
oextoffset = nextoffset - adsize; oepos.offset = epos.offset - adsize;
} }
} }
memset(&eloc, 0x00, sizeof(kernel_lb_addr)); memset(&eloc, 0x00, sizeof(kernel_lb_addr));
elen = 0; elen = 0;
if (nbh != obh) if (epos.bh != oepos.bh)
{ {
udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1); udf_free_blocks(inode->i_sb, inode, epos.block, 0, 1);
udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); udf_write_aext(inode, &oepos, eloc, elen, 1);
udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); udf_write_aext(inode, &oepos, eloc, elen, 1);
if (!obh) if (!oepos.bh)
{ {
UDF_I_LENALLOC(inode) -= (adsize * 2); UDF_I_LENALLOC(inode) -= (adsize * 2);
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
else else
{ {
aed = (struct allocExtDesc *)(obh)->b_data; aed = (struct allocExtDesc *)oepos.bh->b_data;
aed->lengthAllocDescs = aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize)); 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) 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 else
udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc)); udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc));
mark_buffer_dirty_inode(obh, inode); mark_buffer_dirty_inode(oepos.bh, inode);
} }
} }
else else
{ {
udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1); udf_write_aext(inode, &oepos, eloc, elen, 1);
if (!obh) if (!oepos.bh)
{ {
UDF_I_LENALLOC(inode) -= adsize; UDF_I_LENALLOC(inode) -= adsize;
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
else else
{ {
aed = (struct allocExtDesc *)(obh)->b_data; aed = (struct allocExtDesc *)oepos.bh->b_data;
aed->lengthAllocDescs = aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize); 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) 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 else
udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc)); udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc));
mark_buffer_dirty_inode(obh, inode); mark_buffer_dirty_inode(oepos.bh, inode);
} }
} }
udf_release_data(nbh); udf_release_data(epos.bh);
udf_release_data(obh); udf_release_data(oepos.bh);
return (elen >> 30); return (elen >> 30);
} }
int8_t inode_bmap(struct inode *inode, sector_t block, kernel_lb_addr *bloc, uint32_t *extoffset, int8_t inode_bmap(struct inode *inode, sector_t block, struct extent_position *pos,
kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset, struct buffer_head **bh) kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset)
{ {
loff_t lbcount = 0, bcount = (loff_t)block << inode->i_sb->s_blocksize_bits; loff_t lbcount = 0, bcount = (loff_t)block << inode->i_sb->s_blocksize_bits;
int8_t etype; int8_t etype;
...@@ -1961,13 +1955,14 @@ int8_t inode_bmap(struct inode *inode, sector_t block, kernel_lb_addr *bloc, uin ...@@ -1961,13 +1955,14 @@ int8_t inode_bmap(struct inode *inode, sector_t block, kernel_lb_addr *bloc, uin
return -1; return -1;
} }
*extoffset = 0; pos->offset = 0;
pos->block = UDF_I_LOCATION(inode);
pos->bh = NULL;
*elen = 0; *elen = 0;
*bloc = UDF_I_LOCATION(inode);
do 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; *offset = (bcount - lbcount) >> inode->i_sb->s_blocksize_bits;
UDF_I_LENEXTENTS(inode) = lbcount; UDF_I_LENEXTENTS(inode) = lbcount;
...@@ -1983,21 +1978,21 @@ int8_t inode_bmap(struct inode *inode, sector_t block, kernel_lb_addr *bloc, uin ...@@ -1983,21 +1978,21 @@ int8_t inode_bmap(struct inode *inode, sector_t block, kernel_lb_addr *bloc, uin
long udf_block_map(struct inode *inode, sector_t block) long udf_block_map(struct inode *inode, sector_t block)
{ {
kernel_lb_addr eloc, bloc; kernel_lb_addr eloc;
uint32_t extoffset, elen; uint32_t elen;
sector_t offset; sector_t offset;
struct buffer_head *bh = NULL; struct extent_position epos = { NULL, 0, { 0, 0}};
int ret; int ret;
lock_kernel(); 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); ret = udf_get_lb_pblock(inode->i_sb, eloc, offset);
else else
ret = 0; ret = 0;
unlock_kernel(); unlock_kernel();
udf_release_data(bh); udf_release_data(epos.bh);
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
return udf_fixed_to_variable(ret); return udf_fixed_to_variable(ret);
......
...@@ -155,10 +155,10 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, ...@@ -155,10 +155,10 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
uint8_t lfi; uint8_t lfi;
uint16_t liu; uint16_t liu;
loff_t size; loff_t size;
kernel_lb_addr bloc, eloc; kernel_lb_addr eloc;
uint32_t extoffset, elen; uint32_t elen;
sector_t offset; sector_t offset;
struct buffer_head *bh = NULL; struct extent_position epos = { NULL, 0, { 0, 0}};
size = (udf_ext0_offset(dir) + dir->i_size) >> 2; size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
f_pos = (udf_ext0_offset(dir) >> 2); f_pos = (udf_ext0_offset(dir) >> 2);
...@@ -167,41 +167,41 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, ...@@ -167,41 +167,41 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh->sbh = fibh->ebh = NULL; fibh->sbh = fibh->ebh = NULL;
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
&bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
{ {
block = udf_get_lb_pblock(dir->i_sb, eloc, offset); block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen) if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{ {
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
extoffset -= sizeof(short_ad); epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
extoffset -= sizeof(long_ad); epos.offset -= sizeof(long_ad);
} }
else else
offset = 0; offset = 0;
if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block)))
{ {
udf_release_data(bh); udf_release_data(epos.bh);
return NULL; return NULL;
} }
} }
else else
{ {
udf_release_data(bh); udf_release_data(epos.bh);
return NULL; return NULL;
} }
while ( (f_pos < size) ) while ( (f_pos < size) )
{ {
fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, &elen, &offset);
if (!fi) if (!fi)
{ {
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh)
udf_release_data(fibh->ebh); udf_release_data(fibh->ebh);
udf_release_data(fibh->sbh); udf_release_data(fibh->sbh);
udf_release_data(bh); udf_release_data(epos.bh);
return NULL; return NULL;
} }
...@@ -247,7 +247,7 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, ...@@ -247,7 +247,7 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
{ {
if (udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) if (udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name))
{ {
udf_release_data(bh); udf_release_data(epos.bh);
return fi; return fi;
} }
} }
...@@ -255,7 +255,7 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, ...@@ -255,7 +255,7 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh)
udf_release_data(fibh->ebh); udf_release_data(fibh->ebh);
udf_release_data(fibh->sbh); udf_release_data(fibh->sbh);
udf_release_data(bh); udf_release_data(epos.bh);
return NULL; return NULL;
} }
...@@ -353,10 +353,10 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -353,10 +353,10 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
uint8_t lfi; uint8_t lfi;
uint16_t liu; uint16_t liu;
int block; int block;
kernel_lb_addr bloc, eloc; kernel_lb_addr eloc;
uint32_t extoffset, elen; uint32_t elen;
sector_t offset; sector_t offset;
struct buffer_head *bh = NULL; struct extent_position epos = { NULL, 0, { 0, 0 }};
sb = dir->i_sb; sb = dir->i_sb;
...@@ -385,22 +385,22 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -385,22 +385,22 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh->sbh = fibh->ebh = NULL; fibh->sbh = fibh->ebh = NULL;
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
&bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
{ {
block = udf_get_lb_pblock(dir->i_sb, eloc, offset); block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen) if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{ {
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
extoffset -= sizeof(short_ad); epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
extoffset -= sizeof(long_ad); epos.offset -= sizeof(long_ad);
} }
else else
offset = 0; offset = 0;
if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block)))
{ {
udf_release_data(bh); udf_release_data(epos.bh);
*err = -EIO; *err = -EIO;
return NULL; return NULL;
} }
...@@ -418,14 +418,14 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -418,14 +418,14 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
while ( (f_pos < size) ) while ( (f_pos < size) )
{ {
fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, &elen, &offset);
if (!fi) if (!fi)
{ {
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh)
udf_release_data(fibh->ebh); udf_release_data(fibh->ebh);
udf_release_data(fibh->sbh); udf_release_data(fibh->sbh);
udf_release_data(bh); udf_release_data(epos.bh);
*err = -EIO; *err = -EIO;
return NULL; return NULL;
} }
...@@ -455,7 +455,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -455,7 +455,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
{ {
if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen) if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen)
{ {
udf_release_data(bh); udf_release_data(epos.bh);
cfi->descTag.tagSerialNum = cpu_to_le16(1); cfi->descTag.tagSerialNum = cpu_to_le16(1);
cfi->fileVersionNum = cpu_to_le16(1); cfi->fileVersionNum = cpu_to_le16(1);
cfi->fileCharacteristics = 0; cfi->fileCharacteristics = 0;
...@@ -480,7 +480,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -480,7 +480,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh)
udf_release_data(fibh->ebh); udf_release_data(fibh->ebh);
udf_release_data(fibh->sbh); udf_release_data(fibh->sbh);
udf_release_data(bh); udf_release_data(epos.bh);
*err = -EEXIST; *err = -EEXIST;
return NULL; return NULL;
} }
...@@ -492,8 +492,8 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -492,8 +492,8 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB && if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB &&
sb->s_blocksize - fibh->eoffset < nfidlen) sb->s_blocksize - fibh->eoffset < nfidlen)
{ {
udf_release_data(bh); udf_release_data(epos.bh);
bh = NULL; epos.bh = NULL;
fibh->soffset -= udf_ext0_offset(dir); fibh->soffset -= udf_ext0_offset(dir);
fibh->eoffset -= udf_ext0_offset(dir); fibh->eoffset -= udf_ext0_offset(dir);
f_pos -= (udf_ext0_offset(dir) >> 2); f_pos -= (udf_ext0_offset(dir) >> 2);
...@@ -502,15 +502,15 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -502,15 +502,15 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
udf_release_data(fibh->sbh); udf_release_data(fibh->sbh);
if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err))) if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err)))
return NULL; return NULL;
bloc = UDF_I_LOCATION(dir); epos.block = UDF_I_LOCATION(dir);
eloc.logicalBlockNum = block; eloc.logicalBlockNum = block;
eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum; eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
elen = dir->i_sb->s_blocksize; elen = dir->i_sb->s_blocksize;
extoffset = udf_file_entry_alloc_offset(dir); epos.offset = udf_file_entry_alloc_offset(dir);
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
extoffset += sizeof(short_ad); epos.offset += sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
extoffset += sizeof(long_ad); epos.offset += sizeof(long_ad);
} }
if (sb->s_blocksize - fibh->eoffset >= nfidlen) if (sb->s_blocksize - fibh->eoffset >= nfidlen)
...@@ -550,14 +550,14 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -550,14 +550,14 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
if (!(fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err))) if (!(fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err)))
{ {
udf_release_data(bh); udf_release_data(epos.bh);
udf_release_data(fibh->sbh); udf_release_data(fibh->sbh);
return NULL; return NULL;
} }
if (!(fibh->soffset)) if (!(fibh->soffset))
{ {
if (udf_next_aext(dir, &bloc, &extoffset, &eloc, &elen, &bh, 1) == if (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
(EXT_RECORDED_ALLOCATED >> 30)) (EXT_RECORDED_ALLOCATED >> 30))
{ {
block = eloc.logicalBlockNum + ((elen - 1) >> block = eloc.logicalBlockNum + ((elen - 1) >>
...@@ -587,7 +587,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -587,7 +587,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
cfi->lengthOfImpUse = cpu_to_le16(0); cfi->lengthOfImpUse = cpu_to_le16(0);
if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name))
{ {
udf_release_data(bh); udf_release_data(epos.bh);
dir->i_size += nfidlen; dir->i_size += nfidlen;
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
UDF_I_LENALLOC(dir) += nfidlen; UDF_I_LENALLOC(dir) += nfidlen;
...@@ -596,7 +596,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry, ...@@ -596,7 +596,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
} }
else else
{ {
udf_release_data(bh); udf_release_data(epos.bh);
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh)
udf_release_data(fibh->ebh); udf_release_data(fibh->ebh);
udf_release_data(fibh->sbh); udf_release_data(fibh->sbh);
...@@ -781,10 +781,10 @@ static int empty_dir(struct inode *dir) ...@@ -781,10 +781,10 @@ static int empty_dir(struct inode *dir)
loff_t f_pos; loff_t f_pos;
loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
int block; int block;
kernel_lb_addr bloc, eloc; kernel_lb_addr eloc;
uint32_t extoffset, elen; uint32_t elen;
sector_t offset; sector_t offset;
struct buffer_head *bh = NULL; struct extent_position epos = { NULL, 0, { 0, 0}};
f_pos = (udf_ext0_offset(dir) >> 2); f_pos = (udf_ext0_offset(dir) >> 2);
...@@ -793,42 +793,42 @@ static int empty_dir(struct inode *dir) ...@@ -793,42 +793,42 @@ static int empty_dir(struct inode *dir)
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh.sbh = fibh.ebh = NULL; fibh.sbh = fibh.ebh = NULL;
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
&bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
{ {
block = udf_get_lb_pblock(dir->i_sb, eloc, offset); block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen) if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{ {
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
extoffset -= sizeof(short_ad); epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
extoffset -= sizeof(long_ad); epos.offset -= sizeof(long_ad);
} }
else else
offset = 0; offset = 0;
if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block)))
{ {
udf_release_data(bh); udf_release_data(epos.bh);
return 0; return 0;
} }
} }
else else
{ {
udf_release_data(bh); udf_release_data(epos.bh);
return 0; return 0;
} }
while ( (f_pos < size) ) while ( (f_pos < size) )
{ {
fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset);
if (!fi) if (!fi)
{ {
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh); udf_release_data(fibh.ebh);
udf_release_data(fibh.sbh); udf_release_data(fibh.sbh);
udf_release_data(bh); udf_release_data(epos.bh);
return 0; return 0;
} }
...@@ -837,14 +837,14 @@ static int empty_dir(struct inode *dir) ...@@ -837,14 +837,14 @@ static int empty_dir(struct inode *dir)
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh); udf_release_data(fibh.ebh);
udf_release_data(fibh.sbh); udf_release_data(fibh.sbh);
udf_release_data(bh); udf_release_data(epos.bh);
return 0; return 0;
} }
} }
if (fibh.sbh != fibh.ebh) if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh); udf_release_data(fibh.ebh);
udf_release_data(fibh.sbh); udf_release_data(fibh.sbh);
udf_release_data(bh); udf_release_data(epos.bh);
return 1; return 1;
} }
...@@ -941,7 +941,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * ...@@ -941,7 +941,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
struct pathComponent *pc; struct pathComponent *pc;
char *compstart; char *compstart;
struct udf_fileident_bh fibh; struct udf_fileident_bh fibh;
struct buffer_head *bh = NULL; struct extent_position epos = { NULL, 0, {0, 0}};
int eoffset, elen = 0; int eoffset, elen = 0;
struct fileIdentDesc *fi; struct fileIdentDesc *fi;
struct fileIdentDesc cfi; struct fileIdentDesc cfi;
...@@ -961,33 +961,33 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * ...@@ -961,33 +961,33 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB)
{ {
struct buffer_head *bh = NULL; kernel_lb_addr eloc;
kernel_lb_addr bloc, eloc; uint32_t elen;
uint32_t elen, extoffset;
block = udf_new_block(inode->i_sb, inode, block = udf_new_block(inode->i_sb, inode,
UDF_I_LOCATION(inode).partitionReferenceNum, UDF_I_LOCATION(inode).partitionReferenceNum,
UDF_I_LOCATION(inode).logicalBlockNum, &err); UDF_I_LOCATION(inode).logicalBlockNum, &err);
if (!block) if (!block)
goto out_no_entry; goto out_no_entry;
bloc = UDF_I_LOCATION(inode); epos.block = UDF_I_LOCATION(inode);
epos.offset = udf_file_entry_alloc_offset(inode);
epos.bh = NULL;
eloc.logicalBlockNum = block; eloc.logicalBlockNum = block;
eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
elen = inode->i_sb->s_blocksize; elen = inode->i_sb->s_blocksize;
UDF_I_LENEXTENTS(inode) = elen; UDF_I_LENEXTENTS(inode) = elen;
extoffset = udf_file_entry_alloc_offset(inode); udf_add_aext(inode, &epos, eloc, elen, 0);
udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 0); udf_release_data(epos.bh);
udf_release_data(bh);
block = udf_get_pblock(inode->i_sb, block, block = udf_get_pblock(inode->i_sb, block,
UDF_I_LOCATION(inode).partitionReferenceNum, 0); UDF_I_LOCATION(inode).partitionReferenceNum, 0);
bh = udf_tread(inode->i_sb, block); epos.bh = udf_tread(inode->i_sb, block);
lock_buffer(bh); lock_buffer(epos.bh);
memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize);
set_buffer_uptodate(bh); set_buffer_uptodate(epos.bh);
unlock_buffer(bh); unlock_buffer(epos.bh);
mark_buffer_dirty_inode(bh, inode); mark_buffer_dirty_inode(epos.bh, inode);
ea = bh->b_data + udf_ext0_offset(inode); ea = epos.bh->b_data + udf_ext0_offset(inode);
} }
else else
ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
...@@ -1060,7 +1060,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * ...@@ -1060,7 +1060,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
} }
} }
udf_release_data(bh); udf_release_data(epos.bh);
inode->i_size = elen; inode->i_size = elen;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
UDF_I_LENALLOC(inode) = inode->i_size; UDF_I_LENALLOC(inode) = inode->i_size;
......
...@@ -1883,21 +1883,20 @@ static unsigned int ...@@ -1883,21 +1883,20 @@ static unsigned int
udf_count_free_table(struct super_block *sb, struct inode * table) udf_count_free_table(struct super_block *sb, struct inode * table)
{ {
unsigned int accum = 0; unsigned int accum = 0;
uint32_t extoffset, elen; uint32_t elen;
kernel_lb_addr bloc, eloc; kernel_lb_addr eloc;
int8_t etype; int8_t etype;
struct buffer_head *bh = NULL; struct extent_position epos;
lock_kernel(); lock_kernel();
bloc = UDF_I_LOCATION(table); epos.block = UDF_I_LOCATION(table);
extoffset = sizeof(struct unallocSpaceEntry); epos.offset = sizeof(struct unallocSpaceEntry);
epos.bh = NULL;
while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
{
accum += (elen >> table->i_sb->s_blocksize_bits); accum += (elen >> table->i_sb->s_blocksize_bits);
} udf_release_data(epos.bh);
udf_release_data(bh);
unlock_kernel(); unlock_kernel();
......
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
#include "udf_i.h" #include "udf_i.h"
#include "udf_sb.h" #include "udf_sb.h"
static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffset, static void extent_trunc(struct inode * inode, struct extent_position *epos,
kernel_lb_addr eloc, int8_t etype, uint32_t elen, struct buffer_head *bh, uint32_t nelen) kernel_lb_addr eloc, int8_t etype, uint32_t elen, uint32_t nelen)
{ {
kernel_lb_addr neloc = { 0, 0 }; kernel_lb_addr neloc = { 0, 0 };
int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits; int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
...@@ -49,7 +49,7 @@ static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffse ...@@ -49,7 +49,7 @@ static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffse
if (elen != nelen) if (elen != nelen)
{ {
udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0); udf_write_aext(inode, epos, neloc, nelen, 0);
if (last_block - first_block > 0) if (last_block - first_block > 0)
{ {
if (etype == (EXT_RECORDED_ALLOCATED >> 30)) if (etype == (EXT_RECORDED_ALLOCATED >> 30))
...@@ -63,18 +63,16 @@ static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffse ...@@ -63,18 +63,16 @@ static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffse
void udf_discard_prealloc(struct inode * inode) void udf_discard_prealloc(struct inode * inode)
{ {
kernel_lb_addr bloc, eloc; struct extent_position epos = { NULL, 0, {0, 0}};
uint32_t extoffset = 0, elen, nelen; kernel_lb_addr eloc;
uint32_t elen, nelen;
uint64_t lbcount = 0; uint64_t lbcount = 0;
int8_t etype = -1, netype; int8_t etype = -1, netype;
struct buffer_head *bh = NULL;
int adsize; int adsize;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB || if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB ||
inode->i_size == UDF_I_LENEXTENTS(inode)) inode->i_size == UDF_I_LENEXTENTS(inode))
{
return; return;
}
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
adsize = sizeof(short_ad); adsize = sizeof(short_ad);
...@@ -83,53 +81,55 @@ void udf_discard_prealloc(struct inode * inode) ...@@ -83,53 +81,55 @@ void udf_discard_prealloc(struct inode * inode)
else else
adsize = 0; adsize = 0;
bloc = UDF_I_LOCATION(inode); epos.block = UDF_I_LOCATION(inode);
while ((netype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1) /* Find the last extent in the file */
while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1)
{ {
etype = netype; etype = netype;
lbcount += elen; lbcount += elen;
if (lbcount > inode->i_size && lbcount - inode->i_size < inode->i_sb->s_blocksize) if (lbcount > inode->i_size && lbcount - inode->i_size < inode->i_sb->s_blocksize)
{ {
nelen = elen - (lbcount - inode->i_size); nelen = elen - (lbcount - inode->i_size);
extent_trunc(inode, bloc, extoffset-adsize, eloc, etype, elen, bh, nelen); epos.offset -= adsize;
extent_trunc(inode, &epos, eloc, etype, elen, nelen);
epos.offset += adsize;
lbcount = inode->i_size; lbcount = inode->i_size;
} }
} }
if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
{ epos.offset -= adsize;
extoffset -= adsize;
lbcount -= elen; lbcount -= elen;
extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0); extent_trunc(inode, &epos, eloc, etype, elen, 0);
if (!bh) if (!epos.bh)
{ {
UDF_I_LENALLOC(inode) = extoffset - udf_file_entry_alloc_offset(inode); UDF_I_LENALLOC(inode) = epos.offset - udf_file_entry_alloc_offset(inode);
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
else else
{ {
struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data); struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data);
aed->lengthAllocDescs = cpu_to_le32(extoffset - sizeof(struct allocExtDesc)); aed->lengthAllocDescs = cpu_to_le32(epos.offset - sizeof(struct allocExtDesc));
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
udf_update_tag(bh->b_data, extoffset); udf_update_tag(epos.bh->b_data, epos.offset);
else else
udf_update_tag(bh->b_data, sizeof(struct allocExtDesc)); udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc));
mark_buffer_dirty_inode(bh, inode); mark_buffer_dirty_inode(epos.bh, inode);
} }
} }
UDF_I_LENEXTENTS(inode) = lbcount; UDF_I_LENEXTENTS(inode) = lbcount;
udf_release_data(bh); udf_release_data(epos.bh);
} }
void udf_truncate_extents(struct inode * inode) void udf_truncate_extents(struct inode * inode)
{ {
kernel_lb_addr bloc, eloc, neloc = { 0, 0 }; struct extent_position epos;
uint32_t extoffset, elen, nelen = 0, lelen = 0, lenalloc; kernel_lb_addr eloc, neloc = { 0, 0 };
uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc;
int8_t etype; int8_t etype;
sector_t first_block = inode->i_size >> inode->i_sb->s_blocksize_bits, offset; sector_t first_block = inode->i_size >> inode->i_sb->s_blocksize_bits, offset;
loff_t byte_offset; loff_t byte_offset;
struct buffer_head *bh = NULL;
int adsize; int adsize;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
...@@ -137,102 +137,98 @@ void udf_truncate_extents(struct inode * inode) ...@@ -137,102 +137,98 @@ void udf_truncate_extents(struct inode * inode)
else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
adsize = sizeof(long_ad); adsize = sizeof(long_ad);
else else
adsize = 0; BUG();
etype = inode_bmap(inode, first_block, &bloc, &extoffset, &eloc, &elen, &offset, &bh); etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
byte_offset = (offset << inode->i_sb->s_blocksize_bits) + (inode->i_size & (inode->i_sb->s_blocksize-1)); byte_offset = (offset << inode->i_sb->s_blocksize_bits) + (inode->i_size & (inode->i_sb->s_blocksize-1));
if (etype != -1) if (etype != -1)
{ {
extoffset -= adsize; epos.offset -= adsize;
extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, byte_offset); extent_trunc(inode, &epos, eloc, etype, elen, byte_offset);
extoffset += adsize; epos.offset += adsize;
if (byte_offset) if (byte_offset)
lenalloc = extoffset; lenalloc = epos.offset;
else else
lenalloc = extoffset - adsize; lenalloc = epos.offset - adsize;
if (!bh) if (!epos.bh)
lenalloc -= udf_file_entry_alloc_offset(inode); lenalloc -= udf_file_entry_alloc_offset(inode);
else else
lenalloc -= sizeof(struct allocExtDesc); lenalloc -= sizeof(struct allocExtDesc);
while ((etype = udf_current_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 0)) != -1) while ((etype = udf_current_aext(inode, &epos, &eloc, &elen, 0)) != -1)
{ {
if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30))
{ {
udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0); udf_write_aext(inode, &epos, neloc, nelen, 0);
extoffset = 0; if (indirect_ext_len)
if (lelen)
{ {
if (!bh) /* We managed to free all extents in the
* indirect extent - free it too */
if (!epos.bh)
BUG(); BUG();
else udf_free_blocks(inode->i_sb, inode, epos.block, 0, indirect_ext_len);
memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
} }
else else
{ {
if (!bh) if (!epos.bh)
{ {
UDF_I_LENALLOC(inode) = lenalloc; UDF_I_LENALLOC(inode) = lenalloc;
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
else else
{ {
struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data); struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data);
aed->lengthAllocDescs = cpu_to_le32(lenalloc); aed->lengthAllocDescs = cpu_to_le32(lenalloc);
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
udf_update_tag(bh->b_data, lenalloc + udf_update_tag(epos.bh->b_data, lenalloc +
sizeof(struct allocExtDesc)); sizeof(struct allocExtDesc));
else else
udf_update_tag(bh->b_data, sizeof(struct allocExtDesc)); udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc));
mark_buffer_dirty_inode(bh, inode); mark_buffer_dirty_inode(epos.bh, inode);
} }
} }
brelse(epos.bh);
udf_release_data(bh); epos.offset = sizeof(struct allocExtDesc);
extoffset = sizeof(struct allocExtDesc); epos.block = eloc;
bloc = eloc; epos.bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, eloc, 0));
bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, bloc, 0));
if (elen) if (elen)
lelen = (elen + inode->i_sb->s_blocksize - 1) >> indirect_ext_len = (elen +
inode->i_sb->s_blocksize - 1) >>
inode->i_sb->s_blocksize_bits; inode->i_sb->s_blocksize_bits;
else else
lelen = 1; indirect_ext_len = 1;
} }
else else
{ {
extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0); extent_trunc(inode, &epos, eloc, etype, elen, 0);
extoffset += adsize; epos.offset += adsize;
} }
} }
if (lelen) if (indirect_ext_len)
{ {
if (!bh) if (!epos.bh)
BUG(); BUG();
else udf_free_blocks(inode->i_sb, inode, epos.block, 0, indirect_ext_len);
memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
} }
else else
{ {
if (!bh) if (!epos.bh)
{ {
UDF_I_LENALLOC(inode) = lenalloc; UDF_I_LENALLOC(inode) = lenalloc;
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
else else
{ {
struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data); struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data);
aed->lengthAllocDescs = cpu_to_le32(lenalloc); aed->lengthAllocDescs = cpu_to_le32(lenalloc);
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
udf_update_tag(bh->b_data, lenalloc + udf_update_tag(epos.bh->b_data, lenalloc +
sizeof(struct allocExtDesc)); sizeof(struct allocExtDesc));
else else
udf_update_tag(bh->b_data, sizeof(struct allocExtDesc)); udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc));
mark_buffer_dirty_inode(bh, inode); mark_buffer_dirty_inode(epos.bh, inode);
} }
} }
} }
...@@ -245,50 +241,51 @@ void udf_truncate_extents(struct inode * inode) ...@@ -245,50 +241,51 @@ void udf_truncate_extents(struct inode * inode)
* no extent above inode->i_size => truncate is * no extent above inode->i_size => truncate is
* extending the file by 'offset'. * extending the file by 'offset'.
*/ */
if ((!bh && extoffset == udf_file_entry_alloc_offset(inode)) || if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) ||
(bh && extoffset == sizeof(struct allocExtDesc))) { (epos.bh && epos.offset == sizeof(struct allocExtDesc))) {
/* File has no extents at all! */ /* File has no extents at all! */
memset(&eloc, 0x00, sizeof(kernel_lb_addr)); memset(&eloc, 0x00, sizeof(kernel_lb_addr));
elen = EXT_NOT_RECORDED_NOT_ALLOCATED | byte_offset; elen = EXT_NOT_RECORDED_NOT_ALLOCATED | byte_offset;
udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); udf_add_aext(inode, &epos, eloc, elen, 1);
} }
else { else {
extoffset -= adsize; epos.offset -= adsize;
etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1); etype = udf_next_aext(inode, &epos, &eloc, &elen, 1);
if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
{ {
extoffset -= adsize; epos.offset -= adsize;
elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + byte_offset); elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + byte_offset);
udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0); udf_write_aext(inode, &epos, eloc, elen, 0);
} }
else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
{ {
kernel_lb_addr neloc = { 0, 0 }; kernel_lb_addr neloc = { 0, 0 };
extoffset -= adsize; epos.offset -= adsize;
nelen = EXT_NOT_RECORDED_NOT_ALLOCATED | nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
((elen + byte_offset + inode->i_sb->s_blocksize - 1) & ((elen + byte_offset + inode->i_sb->s_blocksize - 1) &
~(inode->i_sb->s_blocksize - 1)); ~(inode->i_sb->s_blocksize - 1));
udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1); udf_write_aext(inode, &epos, neloc, nelen, 1);
udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1); udf_add_aext(inode, &epos, eloc, (etype << 30) | elen, 1);
} }
else else
{ {
if (elen & (inode->i_sb->s_blocksize - 1)) if (elen & (inode->i_sb->s_blocksize - 1))
{ {
extoffset -= adsize; epos.offset -= adsize;
elen = EXT_RECORDED_ALLOCATED | elen = EXT_RECORDED_ALLOCATED |
((elen + inode->i_sb->s_blocksize - 1) & ((elen + inode->i_sb->s_blocksize - 1) &
~(inode->i_sb->s_blocksize - 1)); ~(inode->i_sb->s_blocksize - 1));
udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1); udf_write_aext(inode, &epos, eloc, elen, 1);
} }
memset(&eloc, 0x00, sizeof(kernel_lb_addr)); memset(&eloc, 0x00, sizeof(kernel_lb_addr));
elen = EXT_NOT_RECORDED_NOT_ALLOCATED | byte_offset; elen = EXT_NOT_RECORDED_NOT_ALLOCATED | byte_offset;
udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); udf_add_aext(inode, &epos, eloc, elen, 1);
} }
} }
} }
} }
UDF_I_LENEXTENTS(inode) = inode->i_size; UDF_I_LENEXTENTS(inode) = inode->i_size;
udf_release_data(bh); udf_release_data(epos.bh);
} }
...@@ -77,6 +77,13 @@ struct ustr ...@@ -77,6 +77,13 @@ struct ustr
uint8_t u_len; uint8_t u_len;
}; };
struct extent_position {
struct buffer_head *bh;
uint32_t offset;
kernel_lb_addr block;
};
/* super.c */ /* super.c */
extern void udf_error(struct super_block *, const char *, const char *, ...); extern void udf_error(struct super_block *, const char *, const char *, ...);
extern void udf_warning(struct super_block *, const char *, const char *, ...); extern void udf_warning(struct super_block *, const char *, const char *, ...);
...@@ -99,12 +106,12 @@ extern void udf_delete_inode(struct inode *); ...@@ -99,12 +106,12 @@ extern void udf_delete_inode(struct inode *);
extern void udf_clear_inode(struct inode *); extern void udf_clear_inode(struct inode *);
extern int udf_write_inode(struct inode *, int); extern int udf_write_inode(struct inode *, int);
extern long udf_block_map(struct inode *, sector_t); extern long udf_block_map(struct inode *, sector_t);
extern int8_t inode_bmap(struct inode *, sector_t, kernel_lb_addr *, uint32_t *, kernel_lb_addr *, uint32_t *, sector_t *, struct buffer_head **); extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, kernel_lb_addr *, uint32_t *, sector_t *);
extern int8_t udf_add_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr, uint32_t, struct buffer_head **, int); extern int8_t udf_add_aext(struct inode *, struct extent_position *, kernel_lb_addr, uint32_t, int);
extern int8_t udf_write_aext(struct inode *, kernel_lb_addr, int *, kernel_lb_addr, uint32_t, struct buffer_head *, int); extern int8_t udf_write_aext(struct inode *, struct extent_position *, kernel_lb_addr, uint32_t, int);
extern int8_t udf_delete_aext(struct inode *, kernel_lb_addr, int, kernel_lb_addr, uint32_t, struct buffer_head *); extern int8_t udf_delete_aext(struct inode *, struct extent_position, kernel_lb_addr, uint32_t);
extern int8_t udf_next_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr *, uint32_t *, struct buffer_head **, int); extern int8_t udf_next_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int);
extern int8_t udf_current_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr *, uint32_t *, struct buffer_head **, int); extern int8_t udf_current_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int);
/* misc.c */ /* misc.c */
extern struct buffer_head *udf_tgetblk(struct super_block *, int); extern struct buffer_head *udf_tgetblk(struct super_block *, int);
...@@ -151,7 +158,7 @@ extern int udf_new_block(struct super_block *, struct inode *, uint16_t, uint32_ ...@@ -151,7 +158,7 @@ extern int udf_new_block(struct super_block *, struct inode *, uint16_t, uint32_
extern int udf_fsync_file(struct file *, struct dentry *, int); extern int udf_fsync_file(struct file *, struct dentry *, int);
/* directory.c */ /* directory.c */
extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, kernel_lb_addr *, uint32_t *, kernel_lb_addr *, uint32_t *, sector_t *, struct buffer_head **); extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, struct extent_position *, kernel_lb_addr *, uint32_t *, sector_t *);
extern struct fileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset); extern struct fileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset);
extern long_ad * udf_get_filelongad(uint8_t *, int, int *, int); extern long_ad * udf_get_filelongad(uint8_t *, int, int *, int);
extern short_ad * udf_get_fileshortad(uint8_t *, int, int *, int); extern short_ad * udf_get_fileshortad(uint8_t *, int, int *, int);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册