Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4651c590 authored by Jan Kara's avatar Jan Kara
Browse files

udf: Fix directory corruption after extent merging



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: default avatarJan Kara <jack@suse.cz>
parent 8754a3f7
Loading
Loading
Loading
Loading
+10 −6
Original line number Original line Diff line number Diff line
@@ -471,15 +471,19 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
				f_pos >> dir->i_sb->s_blocksize_bits, 1, err);
				f_pos >> dir->i_sb->s_blocksize_bits, 1, err);
		if (!fibh->ebh)
		if (!fibh->ebh)
			goto out_err;
			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 (!fibh->soffset) {
			if (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
			/* Find the freshly allocated block */
			    (EXT_RECORDED_ALLOCATED >> 30)) {
			while (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
				(EXT_RECORDED_ALLOCATED >> 30))
				;
			block = eloc.logicalBlockNum + ((elen - 1) >>
			block = eloc.logicalBlockNum + ((elen - 1) >>
					dir->i_sb->s_blocksize_bits);
					dir->i_sb->s_blocksize_bits);
			} else
				block++;

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