diff options
author | Theodore Ts'o <tytso@mit.edu> | 2021-02-28 09:12:47 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2021-02-28 09:27:27 -0500 |
commit | e1af249abafbf4b08c5b55cab6a0564170ce0f7d (patch) | |
tree | a459791a919b5d09ea928d2427ccd1ca13afa29a | |
parent | 8895443d2556c504753ca4d2c58386b55392dc7b (diff) | |
download | e2fsprogs-e1af249abafbf4b08c5b55cab6a0564170ce0f7d.tar.gz |
libext2s: fix unix_io with IO_FLAG_FORCE_BOUNCE flag set
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>
-rw-r--r-- | lib/ext2fs/unix_io.c | 18 | ||||
-rw-r--r-- | tests/u_bounce_io/expect.1 | 106 | ||||
-rw-r--r-- | tests/u_bounce_io/script | 9 |
3 files changed, 121 insertions, 12 deletions
diff --git a/lib/ext2fs/unix_io.c b/lib/ext2fs/unix_io.c index 8965535c3..9fd95aaa8 100644 --- a/lib/ext2fs/unix_io.c +++ b/lib/ext2fs/unix_io.c @@ -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 index 000000000..a11cb9bc7 --- /dev/null +++ b/tests/u_bounce_io/expect.1 @@ -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: done +Writing inode tables: done +Writing superblocks and filesystem accounting information: done + +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 index 000000000..5dd632999 --- /dev/null +++ b/tests/u_bounce_io/script @@ -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 |