aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2021-02-28 09:12:47 -0500
committerTheodore Ts'o <tytso@mit.edu>2021-02-28 09:27:27 -0500
commite1af249abafbf4b08c5b55cab6a0564170ce0f7d (patch)
treea459791a919b5d09ea928d2427ccd1ca13afa29a
parent8895443d2556c504753ca4d2c58386b55392dc7b (diff)
downloade2fsprogs-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.c18
-rw-r--r--tests/u_bounce_io/expect.1106
-rw-r--r--tests/u_bounce_io/script9
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