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

Commit 38a1f5e9 authored by Jan Kara's avatar Jan Kara Committed by Greg Kroah-Hartman
Browse files

udf: Fix file corruption when appending just after end of preallocated extent



commit 36ec52ea038b18a53e198116ef7d7e70c87db046 upstream.

When we append new block just after the end of preallocated extent, the
code in inode_getblk() wrongly determined we're going to use the
preallocated extent which resulted in adding block into a wrong logical
offset in the file. Sequence like this manifests it:

xfs_io -f -c "pwrite 0x2cacf 0xd122" -c "truncate 0x2dd6f" \
  -c "pwrite 0x27fd9 0x69a9" -c "pwrite 0x32981 0x7244" <file>

The code that determined the use of preallocated extent is actually
stale because udf_do_extend_file() does not create preallocation anymore
so after calling that function we are sure there's no usable
preallocation. Just remove the faulty condition.

CC: stable@vger.kernel.org
Fixes: 16d055656814 ("udf: Discard preallocation before extending file with a hole")
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d747b31e
Loading
Loading
Loading
Loading
+11 −13
Original line number Diff line number Diff line
@@ -807,11 +807,10 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
		c = 0;
		offset = 0;
		count += ret;
		/* We are not covered by a preallocated extent? */
		if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) !=
						EXT_NOT_RECORDED_ALLOCATED) {
			/* Is there any real extent? - otherwise we overwrite
			 * the fake one... */
		/*
		 * Is there any real extent? - otherwise we overwrite the fake
		 * one...
		 */
		if (count)
			c = !c;
		laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
@@ -819,7 +818,6 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
		memset(&laarr[c].extLocation, 0x00,
			sizeof(struct kernel_lb_addr));
		count++;
		}
		endnum = c + 1;
		lastblock = 1;
	} else {