]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
libext2s: fix unix_io with IO_FLAG_FORCE_BOUNCE flag set
authorTheodore Ts'o <tytso@mit.edu>
Sun, 28 Feb 2021 14:12:47 +0000 (09:12 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 28 Feb 2021 14:27:27 +0000 (09:27 -0500)
The bounce read/write code would crash with a floating point exception
if alignment is set to 0.

Fixes: c001596110e8 ("libext2fs: fix unix_io's Direct I/O support")
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
lib/ext2fs/unix_io.c
tests/u_bounce_io/expect.1 [new file with mode: 0644]
tests/u_bounce_io/script [new file with mode: 0644]

index 8965535c35babbe5a5602288127e27e10a7348f7..9fd95aaa8f891480b4aff1e247733894853ca697 100644 (file)
@@ -227,13 +227,8 @@ static errcode_t raw_read_blk(io_channel channel,
        mutex_unlock(data, STATS_MTX);
        location = ((ext2_loff_t) block * channel->block_size) + data->offset;
 
-       if (data->flags & IO_FLAG_FORCE_BOUNCE) {
-               if (ext2fs_llseek(data->dev, location, SEEK_SET) < 0) {
-                       retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
-                       goto error_out;
-               }
+       if (data->flags & IO_FLAG_FORCE_BOUNCE)
                goto bounce_read;
-       }
 
 #ifdef HAVE_PREAD64
        /* Try an aligned pread */
@@ -291,6 +286,8 @@ static errcode_t raw_read_blk(io_channel channel,
         * to the O_DIRECT rules, so we need to do this the hard way...
         */
 bounce_read:
+       if (channel->align == 0)
+               channel->align = 1;
        if ((channel->block_size > channel->align) &&
            (channel->block_size % channel->align) == 0)
                align_size = channel->block_size;
@@ -364,13 +361,8 @@ static errcode_t raw_write_blk(io_channel channel,
 
        location = ((ext2_loff_t) block * channel->block_size) + data->offset;
 
-       if (data->flags & IO_FLAG_FORCE_BOUNCE) {
-               if (ext2fs_llseek(data->dev, location, SEEK_SET) < 0) {
-                       retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
-                       goto error_out;
-               }
+       if (data->flags & IO_FLAG_FORCE_BOUNCE)
                goto bounce_write;
-       }
 
 #ifdef HAVE_PWRITE64
        /* Try an aligned pwrite */
@@ -426,6 +418,8 @@ static errcode_t raw_write_blk(io_channel channel,
         * to the O_DIRECT rules, so we need to do this the hard way...
         */
 bounce_write:
+       if (channel->align == 0)
+               channel->align = 1;
        if ((channel->block_size > channel->align) &&
            (channel->block_size % channel->align) == 0)
                align_size = channel->block_size;
diff --git a/tests/u_bounce_io/expect.1 b/tests/u_bounce_io/expect.1
new file mode 100644 (file)
index 0000000..a11cb9b
--- /dev/null
@@ -0,0 +1,106 @@
+Creating filesystem with 65536 1k blocks and 16384 inodes
+Superblock backups stored on blocks: 
+       8193, 24577, 40961, 57345
+
+Allocating group tables:    \b\b\bdone                            
+Writing inode tables:    \b\b\bdone                            
+Writing superblocks and filesystem accounting information:    \b\b\bdone
+
+Filesystem features: ext_attr resize_inode dir_index filetype sparse_super
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 11/16384 files (0.0% non-contiguous), 3364/65536 blocks
+Exit status is 0
+Filesystem volume name:   <none>
+Last mounted on:          <not available>
+Filesystem magic number:  0xEF53
+Filesystem revision #:    1 (dynamic)
+Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super
+Default mount options:    (none)
+Filesystem state:         clean
+Errors behavior:          Continue
+Filesystem OS type:       Linux
+Inode count:              16384
+Block count:              65536
+Reserved block count:     3276
+Overhead clusters:        3350
+Free blocks:              62172
+Free inodes:              16373
+First block:              1
+Block size:               1024
+Fragment size:            1024
+Reserved GDT blocks:      255
+Blocks per group:         8192
+Fragments per group:      8192
+Inodes per group:         2048
+Inode blocks per group:   256
+Mount count:              0
+Check interval:           15552000 (6 months)
+Reserved blocks uid:      0
+Reserved blocks gid:      0
+First inode:              11
+Inode size:              128
+Default directory hash:   half_md4
+
+
+Group 0: (Blocks 1-8192)
+  Primary superblock at 1, Group descriptors at 2-2
+  Reserved GDT blocks at 3-257
+  Block bitmap at 258 (+257), Inode bitmap at 259 (+258)
+  Inode table at 260-515 (+259)
+  7663 free blocks, 2037 free inodes, 2 directories
+  Free blocks: 530-8192
+  Free inodes: 12-2048
+Group 1: (Blocks 8193-16384)
+  Backup superblock at 8193, Group descriptors at 8194-8194
+  Reserved GDT blocks at 8195-8449
+  Block bitmap at 8450 (+257), Inode bitmap at 8451 (+258)
+  Inode table at 8452-8707 (+259)
+  7677 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 8708-16384
+  Free inodes: 2049-4096
+Group 2: (Blocks 16385-24576)
+  Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
+  Inode table at 16387-16642 (+2)
+  7934 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 16643-24576
+  Free inodes: 4097-6144
+Group 3: (Blocks 24577-32768)
+  Backup superblock at 24577, Group descriptors at 24578-24578
+  Reserved GDT blocks at 24579-24833
+  Block bitmap at 24834 (+257), Inode bitmap at 24835 (+258)
+  Inode table at 24836-25091 (+259)
+  7677 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 25092-32768
+  Free inodes: 6145-8192
+Group 4: (Blocks 32769-40960)
+  Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
+  Inode table at 32771-33026 (+2)
+  7934 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 33027-40960
+  Free inodes: 8193-10240
+Group 5: (Blocks 40961-49152)
+  Backup superblock at 40961, Group descriptors at 40962-40962
+  Reserved GDT blocks at 40963-41217
+  Block bitmap at 41218 (+257), Inode bitmap at 41219 (+258)
+  Inode table at 41220-41475 (+259)
+  7677 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 41476-49152
+  Free inodes: 10241-12288
+Group 6: (Blocks 49153-57344)
+  Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
+  Inode table at 49155-49410 (+2)
+  7934 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 49411-57344
+  Free inodes: 12289-14336
+Group 7: (Blocks 57345-65535)
+  Backup superblock at 57345, Group descriptors at 57346-57346
+  Reserved GDT blocks at 57347-57601
+  Block bitmap at 57602 (+257), Inode bitmap at 57603 (+258)
+  Inode table at 57604-57859 (+259)
+  7676 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 57860-65535
+  Free inodes: 14337-16384
diff --git a/tests/u_bounce_io/script b/tests/u_bounce_io/script
new file mode 100644 (file)
index 0000000..5dd6329
--- /dev/null
@@ -0,0 +1,9 @@
+DESCRIPTION="bounce I/O in unix_io"
+DUMPE2FS_IGNORE_80COL=1
+export DUMPE2FS_IGNORE_80COL
+UNIX_IO_FORCE_BOUNCE=yes
+export UNIX_IO_FORCE_BOUNCE
+FS_SIZE=65536
+. $cmd_dir/run_mke2fs
+unset DUMPE2FS_IGNORE_80COL
+unset UNIX_IO_FORCE_BOUNCE