forked from Minki/linux
udf: cleanup directory offset handling
Position in directory returned by readdir is offset of directory entry divided by four (don't ask me why). Make this conversion only when reading f_pos from userspace / writing it there and internally work in bytes. It makes things more easily readable and also fixes a bug (we forgot to divide length of the entry by 4 when advancing f_pos in udf_add_entry()). Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
32a8f24dd7
commit
af793295bf
@ -95,7 +95,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
|
||||
if (!fi)
|
||||
return NULL;
|
||||
|
||||
*nf_pos += ((fibh->eoffset - fibh->soffset) >> 2);
|
||||
*nf_pos += fibh->eoffset - fibh->soffset;
|
||||
|
||||
memcpy((uint8_t *)cfi, (uint8_t *)fi,
|
||||
sizeof(struct fileIdentDesc));
|
||||
@ -157,7 +157,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
|
||||
if (!fi)
|
||||
return NULL;
|
||||
|
||||
*nf_pos += ((fibh->eoffset - fibh->soffset) >> 2);
|
||||
*nf_pos += fibh->eoffset - fibh->soffset;
|
||||
|
||||
if (fibh->eoffset <= dir->i_sb->s_blocksize) {
|
||||
memcpy((uint8_t *)cfi, (uint8_t *)fi,
|
||||
@ -197,8 +197,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
|
||||
cfi->lengthFileIdent +
|
||||
le16_to_cpu(cfi->lengthOfImpUse) + 3) & ~3;
|
||||
|
||||
*nf_pos += (fi_len - (fibh->eoffset - fibh->soffset))
|
||||
>> 2;
|
||||
*nf_pos += fi_len - (fibh->eoffset - fibh->soffset);
|
||||
fibh->eoffset = fibh->soffset + fi_len;
|
||||
} else {
|
||||
memcpy((uint8_t *)cfi, (uint8_t *)fi,
|
||||
|
@ -219,8 +219,8 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
|
||||
struct extent_position epos;
|
||||
|
||||
struct udf_fileident_bh sfibh, dfibh;
|
||||
loff_t f_pos = udf_ext0_offset(inode) >> 2;
|
||||
int size = (udf_ext0_offset(inode) + inode->i_size) >> 2;
|
||||
loff_t f_pos = udf_ext0_offset(inode);
|
||||
int size = udf_ext0_offset(inode) + inode->i_size;
|
||||
struct fileIdentDesc cfi, *sfi, *dfi;
|
||||
struct udf_inode_info *iinfo = UDF_I(inode);
|
||||
|
||||
@ -256,11 +256,11 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
|
||||
mark_buffer_dirty_inode(dbh, inode);
|
||||
|
||||
sfibh.soffset = sfibh.eoffset =
|
||||
(f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
|
||||
f_pos & (inode->i_sb->s_blocksize - 1);
|
||||
sfibh.sbh = sfibh.ebh = NULL;
|
||||
dfibh.soffset = dfibh.eoffset = 0;
|
||||
dfibh.sbh = dfibh.ebh = dbh;
|
||||
while ((f_pos < size)) {
|
||||
while (f_pos < size) {
|
||||
iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
|
||||
sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL,
|
||||
NULL, NULL, NULL);
|
||||
|
@ -160,14 +160,13 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
|
||||
struct extent_position epos = {};
|
||||
struct udf_inode_info *dinfo = UDF_I(dir);
|
||||
|
||||
size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
|
||||
f_pos = (udf_ext0_offset(dir) >> 2);
|
||||
size = udf_ext0_offset(dir) + dir->i_size;
|
||||
f_pos = udf_ext0_offset(dir);
|
||||
|
||||
fibh->soffset = fibh->eoffset =
|
||||
(f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
|
||||
fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1);
|
||||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
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,
|
||||
&epos, &eloc, &elen, &offset) ==
|
||||
(EXT_RECORDED_ALLOCATED >> 30)) {
|
||||
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
|
||||
@ -189,7 +188,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while ((f_pos < size)) {
|
||||
while (f_pos < size) {
|
||||
fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc,
|
||||
&elen, &offset);
|
||||
if (!fi) {
|
||||
@ -342,7 +341,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
|
||||
loff_t f_pos;
|
||||
int flen;
|
||||
char *nameptr;
|
||||
loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
|
||||
loff_t size = udf_ext0_offset(dir) + dir->i_size;
|
||||
int nfidlen;
|
||||
uint8_t lfi;
|
||||
uint16_t liu;
|
||||
@ -370,14 +369,13 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
|
||||
|
||||
nfidlen = (sizeof(struct fileIdentDesc) + namelen + 3) & ~3;
|
||||
|
||||
f_pos = (udf_ext0_offset(dir) >> 2);
|
||||
f_pos = udf_ext0_offset(dir);
|
||||
|
||||
fibh->soffset = fibh->eoffset =
|
||||
(f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
|
||||
fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1);
|
||||
dinfo = UDF_I(dir);
|
||||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
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,
|
||||
&epos, &eloc, &elen, &offset) ==
|
||||
(EXT_RECORDED_ALLOCATED >> 30)) {
|
||||
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
|
||||
@ -405,7 +403,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
|
||||
goto add;
|
||||
}
|
||||
|
||||
while ((f_pos < size)) {
|
||||
while (f_pos < size) {
|
||||
fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc,
|
||||
&elen, &offset);
|
||||
|
||||
@ -484,7 +482,7 @@ add:
|
||||
epos.bh = NULL;
|
||||
fibh->soffset -= udf_ext0_offset(dir);
|
||||
fibh->eoffset -= udf_ext0_offset(dir);
|
||||
f_pos -= (udf_ext0_offset(dir) >> 2);
|
||||
f_pos -= udf_ext0_offset(dir);
|
||||
if (fibh->sbh != fibh->ebh)
|
||||
brelse(fibh->ebh);
|
||||
brelse(fibh->sbh);
|
||||
@ -537,8 +535,7 @@ add:
|
||||
block = eloc.logicalBlockNum + ((elen - 1) >>
|
||||
dir->i_sb->s_blocksize_bits);
|
||||
fibh->ebh = udf_bread(dir,
|
||||
f_pos >> (dir->i_sb->s_blocksize_bits - 2),
|
||||
1, err);
|
||||
f_pos >> dir->i_sb->s_blocksize_bits, 1, err);
|
||||
if (!fibh->ebh) {
|
||||
brelse(epos.bh);
|
||||
brelse(fibh->sbh);
|
||||
@ -775,7 +772,7 @@ static int empty_dir(struct inode *dir)
|
||||
struct fileIdentDesc *fi, cfi;
|
||||
struct udf_fileident_bh fibh;
|
||||
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;
|
||||
int block;
|
||||
kernel_lb_addr eloc;
|
||||
uint32_t elen;
|
||||
@ -783,14 +780,12 @@ static int empty_dir(struct inode *dir)
|
||||
struct extent_position epos = {};
|
||||
struct udf_inode_info *dinfo = UDF_I(dir);
|
||||
|
||||
f_pos = (udf_ext0_offset(dir) >> 2);
|
||||
|
||||
fibh.soffset = fibh.eoffset =
|
||||
(f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
|
||||
f_pos = udf_ext0_offset(dir);
|
||||
fibh.soffset = fibh.eoffset = f_pos & (dir->i_sb->s_blocksize - 1);
|
||||
|
||||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
|
||||
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,
|
||||
&epos, &eloc, &elen, &offset) ==
|
||||
(EXT_RECORDED_ALLOCATED >> 30)) {
|
||||
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
|
||||
@ -812,7 +807,7 @@ static int empty_dir(struct inode *dir)
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((f_pos < size)) {
|
||||
while (f_pos < size) {
|
||||
fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc,
|
||||
&elen, &offset);
|
||||
if (!fi) {
|
||||
|
Loading…
Reference in New Issue
Block a user