Whamcloud - gitweb
libext2fs: fix Direct I/O support in the Unix I/O manager
authorAlexander Kanavin <alex.kanavin@gmail.com>
Sat, 1 May 2021 11:06:12 +0000 (13:06 +0200)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 7 May 2021 20:29:41 +0000 (16:29 -0400)
Commit d557b9659ba9 ("libext2fs: fix potential races in unix_io")
contained some additional changes that were supposed to clarify the
management of the length calculations when reading and writing
non-page aligned data using Direct I/O; unfortunately, those changes
were incorrect, and actually broke the Direct I/O support.

Fix these problems by reverting those portions of that commit.

[ commit description rewritten by tytso ]

Originally from https://github.com/tytso/e2fsprogs/pull/68

Fixes: d557b9659ba9 ("libext2fs: fix potential races in unix_io")
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
lib/ext2fs/unix_io.c

index 528c2fb..f4916b2 100644 (file)
@@ -311,10 +311,10 @@ bounce_read:
                        size += really_read;
                        goto short_read;
                }
-               actual = size;
-               if (actual > align_size)
-                       actual = align_size;
-               actual -= offset;
+               if ((actual + offset) > align_size)
+                       actual = align_size - offset;
+               if (actual > size)
+                       actual = size;
                memcpy(buf, data->bounce + offset, actual);
 
                really_read += actual;
@@ -455,9 +455,10 @@ bounce_write:
                        }
                }
                actual = size;
-               if (actual > align_size)
-                       actual = align_size;
-               actual -= offset;
+               if ((actual + offset) > align_size)
+                       actual = align_size - offset;
+               if (actual > size)
+                       actual = size;
                memcpy(((char *)data->bounce) + offset, buf, actual);
                if (ext2fs_llseek(data->dev, aligned_blk * align_size, SEEK_SET) < 0) {
                        retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;