udf: Do not bother merging very long extents
authorJan Kara <jack@suse.cz>
Fri, 16 Dec 2022 11:37:51 +0000 (12:37 +0100)
committerJan Kara <jack@suse.cz>
Mon, 9 Jan 2023 09:39:52 +0000 (10:39 +0100)
When merging very long extents we try to push as much length as possible
to the first extent. However this is unnecessarily complicated and not
really worth the trouble. Furthermore there was a bug in the logic
resulting in corrupting extents in the file as syzbot reproducer shows.
So just don't bother with the merging of extents that are too long
together.

CC: stable@vger.kernel.org
Reported-by: syzbot+60f291a24acecb3c2bd5@syzkaller.appspotmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
fs/udf/inode.c

index e077183e2ee3eeee824f9da472063595b450511d..5498365669eb639be6a44e149f40a51d6f70b7ae 100644 (file)
@@ -997,23 +997,8 @@ static void udf_merge_extents(struct inode *inode, struct kernel_long_ad *laarr,
                        blocksize - 1) >> blocksize_bits)))) {
 
                        if (((li->extLength & UDF_EXTENT_LENGTH_MASK) +
-                               (lip1->extLength & UDF_EXTENT_LENGTH_MASK) +
-                               blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) {
-                               lip1->extLength = (lip1->extLength -
-                                                 (li->extLength &
-                                                  UDF_EXTENT_LENGTH_MASK) +
-                                                  UDF_EXTENT_LENGTH_MASK) &
-                                                       ~(blocksize - 1);
-                               li->extLength = (li->extLength &
-                                                UDF_EXTENT_FLAG_MASK) +
-                                               (UDF_EXTENT_LENGTH_MASK + 1) -
-                                               blocksize;
-                               lip1->extLocation.logicalBlockNum =
-                                       li->extLocation.logicalBlockNum +
-                                       ((li->extLength &
-                                               UDF_EXTENT_LENGTH_MASK) >>
-                                               blocksize_bits);
-                       } else {
+                            (lip1->extLength & UDF_EXTENT_LENGTH_MASK) +
+                            blocksize - 1) <= UDF_EXTENT_LENGTH_MASK) {
                                li->extLength = lip1->extLength +
                                        (((li->extLength &
                                                UDF_EXTENT_LENGTH_MASK) +