Whamcloud - gitweb
EX-6127 llite: DIO fallback on compressed files
authorPatrick Farrell <pfarrell@whamcloud.com>
Fri, 2 Jun 2023 02:24:15 +0000 (22:24 -0400)
committerAndreas Dilger <adilger@whamcloud.com>
Fri, 23 Jun 2023 23:36:05 +0000 (23:36 +0000)
Fully supporting direct I/O on compressed files is tricky
because we cannot pull the full chunk in to the page cache
(because there is no page cache for DIO).

So instead we fall back to buffered I/O for DIO on
compressed files.

This patch adds the check and a test for this.

Signed-off-by: Patrick Farrell <pfarrell@whamcloud.com>
Change-Id: I8224ef9b8ad1d912d8a11eccad37d3dff8dd8498
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/51200
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/include/cl_object.h
lustre/llite/rw26.c
lustre/lov/lov_object.c
lustre/tests/sanity.sh

index 000235d..26587ac 100644 (file)
@@ -2010,7 +2010,11 @@ struct cl_io {
         * to userspace, only the RPCs are submitted async, then waited for at
         * the llite layer before returning.
         */
-                            ci_parallel_dio:1;
+                            ci_parallel_dio:1,
+       /**
+        * This IO is on a compressed file
+        */
+                            ci_compressed_io:1;
        /**
         * Bypass quota check
         */
index 0b4c263..dd5d28d 100644 (file)
@@ -516,6 +516,12 @@ ll_direct_IO_impl(struct kiocb *iocb, struct iov_iter *iter, int rw)
        io = lcc->lcc_io;
        LASSERT(io != NULL);
 
+       /* compression is not supported with direct I/O yet, so we fall back to
+        * buffered I/O by returning 0 to the kernel
+        */
+       if (io->ci_compressed_io)
+               RETURN(0);
+
        ll_dio_aio = io->ci_dio_aio;
        LASSERT(ll_dio_aio);
        LASSERT(ll_dio_aio->cda_iocb == iocb);
index 86f5a2b..50dd1c8 100644 (file)
@@ -1505,11 +1505,23 @@ static int lov_page_init(const struct lu_env *env, struct cl_object *obj,
 static int lov_io_init(const struct lu_env *env, struct cl_object *obj,
                       struct cl_io *io)
 {
+       struct lov_object *lov = cl2lov(obj);
+       struct lov_layout_entry *lle;
+
        CL_IO_SLICE_CLEAN(lov_env_io(env), lis_preserved);
 
-       CDEBUG(D_INODE, DFID "io %p type %d ignore/verify layout %d/%d\n",
+       lov_foreach_layout_entry(lov, lle) {
+               if (lle->lle_lsme->lsme_pattern & LOV_PATTERN_COMPRESS) {
+                       io->ci_compressed_io = true;
+                       break;
+               }
+       }
+
+       CDEBUG(D_INODE,
+              DFID "io %p type %d ignore/verify layout %d/%d, compressed %d\n",
               PFID(lu_object_fid(&obj->co_lu)), io, io->ci_type,
-              io->ci_ignore_layout, io->ci_verify_layout);
+              io->ci_ignore_layout, io->ci_verify_layout,
+              io->ci_compressed_io);
 
        /* IO type CIT_MISC with ci_ignore_layout set are usually invoked from
         * the OSC layer. It shouldn't take lov layout conf lock in that case,
index 65a576c..a88546a 100755 (executable)
@@ -27520,10 +27520,10 @@ compress_type() {
        local stored_dir=$DIR/$tdir/
        local stored=$stored_dir/$orig_short.$t1$l1$c1
        local stored2=$TMP/$tdir/$tfile.dec_$orig_short.$t1$l1$c1cpy
+       local stored3=$stored_dir/$orig_short.$t1$l1$c1.direct
        local decomp1=$TMP/$tdir/$tfile.dec_$orig_short.$t1$l1$c1
        local decomp2=$TMP/$tdir/$tfile.dec_$orig_short.$t1$l1$c1.cp
        local decomp3=$TMP/$tdir/$tfile.dec_$orig_short.$t1$l1$c1.32.1.5
-       local decomp4=$TMP/$tdir/$tfile.dec_$orig_short.$t1$l1$c1.32.1.5.orig
 
        $LFS setstripe -E 512K -Z $t1:$l1 -E 768K -Z none -E -1 -Z $t1:$l1 \
                --compress-chunk=$c1 $stored_dir ||
@@ -27567,17 +27567,17 @@ compress_type() {
        diff $orig $decomp2 ||
                error "decompression failed"
 
-       # Reading starting the 480K offset
-       # on compressed/plain data board
-       dd if=$stored of=$decomp3 \
-               bs=32k count=2 skip=15 &>/dev/null ||
-               error "dd to $decomp3 failed"
+       # Copy file with direct I/O (falls back to buffered I/O)
+       dd if=$orig of=$stored3 bs=$PAGE_SIZE oflag=direct ||
+               error "dd to $stored3 failed"
 
-       dd if=$orig of=$decomp4 \
-               bs=32k count=2 skip=15 &>/dev/null ||
-               error "dd to $decomp4 failed"
+       cmp --verbose $orig $stored3 || error "decompression failed"
 
-       cmp --verbose $decomp3 $decomp4 || error "decompression failed"
+       # Flush cache and verify contents on disk are correct as well
+       sync
+       echo 3 > /proc/sys/vm/drop_caches
+
+       cmp --verbose $orig $stored3 || error "decompression failed"
 }
 
 compress_content() {