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

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: 16d0556568 ("udf: Discard preallocation before extending file with a hole")
Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
Jan Kara 2023-01-23 14:18:47 +01:00
parent 36580ed087
commit 36ec52ea03

View File

@ -742,19 +742,17 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map)
c = 0; c = 0;
offset = 0; offset = 0;
count += ret; count += ret;
/* We are not covered by a preallocated extent? */ /*
if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) != * Is there any real extent? - otherwise we overwrite the fake
EXT_NOT_RECORDED_ALLOCATED) { * one...
/* Is there any real extent? - otherwise we overwrite */
* the fake one... */ if (count)
if (count) c = !c;
c = !c; laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | inode->i_sb->s_blocksize;
inode->i_sb->s_blocksize; memset(&laarr[c].extLocation, 0x00,
memset(&laarr[c].extLocation, 0x00, sizeof(struct kernel_lb_addr));
sizeof(struct kernel_lb_addr)); count++;
count++;
}
endnum = c + 1; endnum = c + 1;
lastblock = 1; lastblock = 1;
} else { } else {