Skip to content

Commit

Permalink
udf: Fix directory corruption after extent merging
Browse files Browse the repository at this point in the history
If udf_bread() called from udf_add_entry() managed to merge created extent to
an already existing one (or if previous extents could be merged), the code
truncating the last extent to proper size would just overwrite the freshly
allocated extent with an extent that used to be in that place.  This obviously
results in a directory corruption. Fix the problem by properly reloading the
last extent.

Signed-off-by: Jan Kara <jack@suse.cz>
  • Loading branch information
Jan Kara committed Jan 6, 2011
1 parent 8754a3f commit 4651c59
Showing 1 changed file with 10 additions and 6 deletions.
16 changes: 10 additions & 6 deletions fs/udf/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,15 +471,19 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
f_pos >> dir->i_sb->s_blocksize_bits, 1, err);
if (!fibh->ebh)
goto out_err;
/* Extents could have been merged, invalidate our position */
brelse(epos.bh);
epos.bh = NULL;
epos.block = dinfo->i_location;
epos.offset = udf_file_entry_alloc_offset(dir);

if (!fibh->soffset) {
if (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
(EXT_RECORDED_ALLOCATED >> 30)) {
block = eloc.logicalBlockNum + ((elen - 1) >>
/* Find the freshly allocated block */
while (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
(EXT_RECORDED_ALLOCATED >> 30))
;
block = eloc.logicalBlockNum + ((elen - 1) >>
dir->i_sb->s_blocksize_bits);
} else
block++;

brelse(fibh->sbh);
fibh->sbh = fibh->ebh;
fi = (struct fileIdentDesc *)(fibh->sbh->b_data);
Expand Down

0 comments on commit 4651c59

Please sign in to comment.