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

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: NJan Kara <jack@suse.cz>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 32a8f24d
...@@ -95,7 +95,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos, ...@@ -95,7 +95,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
if (!fi) if (!fi)
return NULL; return NULL;
*nf_pos += ((fibh->eoffset - fibh->soffset) >> 2); *nf_pos += fibh->eoffset - fibh->soffset;
memcpy((uint8_t *)cfi, (uint8_t *)fi, memcpy((uint8_t *)cfi, (uint8_t *)fi,
sizeof(struct fileIdentDesc)); sizeof(struct fileIdentDesc));
...@@ -157,7 +157,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos, ...@@ -157,7 +157,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
if (!fi) if (!fi)
return NULL; return NULL;
*nf_pos += ((fibh->eoffset - fibh->soffset) >> 2); *nf_pos += fibh->eoffset - fibh->soffset;
if (fibh->eoffset <= dir->i_sb->s_blocksize) { if (fibh->eoffset <= dir->i_sb->s_blocksize) {
memcpy((uint8_t *)cfi, (uint8_t *)fi, memcpy((uint8_t *)cfi, (uint8_t *)fi,
...@@ -197,8 +197,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos, ...@@ -197,8 +197,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
cfi->lengthFileIdent + cfi->lengthFileIdent +
le16_to_cpu(cfi->lengthOfImpUse) + 3) & ~3; le16_to_cpu(cfi->lengthOfImpUse) + 3) & ~3;
*nf_pos += (fi_len - (fibh->eoffset - fibh->soffset)) *nf_pos += fi_len - (fibh->eoffset - fibh->soffset);
>> 2;
fibh->eoffset = fibh->soffset + fi_len; fibh->eoffset = fibh->soffset + fi_len;
} else { } else {
memcpy((uint8_t *)cfi, (uint8_t *)fi, memcpy((uint8_t *)cfi, (uint8_t *)fi,
......
...@@ -219,8 +219,8 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block, ...@@ -219,8 +219,8 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
struct extent_position epos; 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);
int size = (udf_ext0_offset(inode) + inode->i_size) >> 2; int size = udf_ext0_offset(inode) + inode->i_size;
struct fileIdentDesc cfi, *sfi, *dfi; struct fileIdentDesc cfi, *sfi, *dfi;
struct udf_inode_info *iinfo = UDF_I(inode); struct udf_inode_info *iinfo = UDF_I(inode);
...@@ -256,11 +256,11 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block, ...@@ -256,11 +256,11 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
mark_buffer_dirty_inode(dbh, inode); mark_buffer_dirty_inode(dbh, inode);
sfibh.soffset = sfibh.eoffset = 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; 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) {
iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL,
NULL, NULL, NULL); NULL, NULL, NULL);
......
...@@ -160,14 +160,13 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, ...@@ -160,14 +160,13 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
struct extent_position epos = {}; struct extent_position epos = {};
struct udf_inode_info *dinfo = UDF_I(dir); struct udf_inode_info *dinfo = UDF_I(dir);
size = (udf_ext0_offset(dir) + dir->i_size) >> 2; size = udf_ext0_offset(dir) + dir->i_size;
f_pos = (udf_ext0_offset(dir) >> 2); f_pos = udf_ext0_offset(dir);
fibh->soffset = fibh->eoffset = fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1);
(f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) if (dinfo->i_alloc_type == 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,
&epos, &eloc, &elen, &offset) == &epos, &eloc, &elen, &offset) ==
(EXT_RECORDED_ALLOCATED >> 30)) { (EXT_RECORDED_ALLOCATED >> 30)) {
block = udf_get_lb_pblock(dir->i_sb, eloc, offset); block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
...@@ -189,7 +188,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, ...@@ -189,7 +188,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
return NULL; return NULL;
} }
while ((f_pos < size)) { while (f_pos < size) {
fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc,
&elen, &offset); &elen, &offset);
if (!fi) { if (!fi) {
...@@ -342,7 +341,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, ...@@ -342,7 +341,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
loff_t f_pos; loff_t f_pos;
int flen; int flen;
char *nameptr; 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; int nfidlen;
uint8_t lfi; uint8_t lfi;
uint16_t liu; uint16_t liu;
...@@ -370,14 +369,13 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, ...@@ -370,14 +369,13 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
nfidlen = (sizeof(struct fileIdentDesc) + namelen + 3) & ~3; nfidlen = (sizeof(struct fileIdentDesc) + namelen + 3) & ~3;
f_pos = (udf_ext0_offset(dir) >> 2); f_pos = udf_ext0_offset(dir);
fibh->soffset = fibh->eoffset = fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1);
(f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
dinfo = UDF_I(dir); dinfo = UDF_I(dir);
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) if (dinfo->i_alloc_type == 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,
&epos, &eloc, &elen, &offset) == &epos, &eloc, &elen, &offset) ==
(EXT_RECORDED_ALLOCATED >> 30)) { (EXT_RECORDED_ALLOCATED >> 30)) {
block = udf_get_lb_pblock(dir->i_sb, eloc, offset); block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
...@@ -405,7 +403,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, ...@@ -405,7 +403,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
goto add; goto add;
} }
while ((f_pos < size)) { while (f_pos < size) {
fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc,
&elen, &offset); &elen, &offset);
...@@ -484,7 +482,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, ...@@ -484,7 +482,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
epos.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);
if (fibh->sbh != fibh->ebh) if (fibh->sbh != fibh->ebh)
brelse(fibh->ebh); brelse(fibh->ebh);
brelse(fibh->sbh); brelse(fibh->sbh);
...@@ -537,8 +535,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, ...@@ -537,8 +535,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
block = eloc.logicalBlockNum + ((elen - 1) >> block = eloc.logicalBlockNum + ((elen - 1) >>
dir->i_sb->s_blocksize_bits); dir->i_sb->s_blocksize_bits);
fibh->ebh = udf_bread(dir, fibh->ebh = udf_bread(dir,
f_pos >> (dir->i_sb->s_blocksize_bits - 2), f_pos >> dir->i_sb->s_blocksize_bits, 1, err);
1, err);
if (!fibh->ebh) { if (!fibh->ebh) {
brelse(epos.bh); brelse(epos.bh);
brelse(fibh->sbh); brelse(fibh->sbh);
...@@ -775,7 +772,7 @@ static int empty_dir(struct inode *dir) ...@@ -775,7 +772,7 @@ static int empty_dir(struct inode *dir)
struct fileIdentDesc *fi, cfi; struct fileIdentDesc *fi, cfi;
struct udf_fileident_bh fibh; struct udf_fileident_bh fibh;
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;
int block; int block;
kernel_lb_addr eloc; kernel_lb_addr eloc;
uint32_t elen; uint32_t elen;
...@@ -783,14 +780,12 @@ static int empty_dir(struct inode *dir) ...@@ -783,14 +780,12 @@ static int empty_dir(struct inode *dir)
struct extent_position epos = {}; struct extent_position epos = {};
struct udf_inode_info *dinfo = UDF_I(dir); struct udf_inode_info *dinfo = UDF_I(dir);
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);
fibh.soffset = fibh.eoffset =
(f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) if (dinfo->i_alloc_type == 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,
&epos, &eloc, &elen, &offset) == &epos, &eloc, &elen, &offset) ==
(EXT_RECORDED_ALLOCATED >> 30)) { (EXT_RECORDED_ALLOCATED >> 30)) {
block = udf_get_lb_pblock(dir->i_sb, eloc, offset); block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
...@@ -812,7 +807,7 @@ static int empty_dir(struct inode *dir) ...@@ -812,7 +807,7 @@ static int empty_dir(struct inode *dir)
return 0; return 0;
} }
while ((f_pos < size)) { while (f_pos < size) {
fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc, fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc,
&elen, &offset); &elen, &offset);
if (!fi) { if (!fi) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册