提交 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;
......
此差异已折叠。
...@@ -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.
先完成此消息的编辑!
想要评论请 注册