From 61b4a00ea826cf5215925673d7ea0e2d082b1c66 Mon Sep 17 00:00:00 2001 From: Patrick Farrell Date: Thu, 1 Jun 2023 22:24:15 -0400 Subject: [PATCH] EX-6127 llite: DIO fallback on compressed files 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 Change-Id: I8224ef9b8ad1d912d8a11eccad37d3dff8dd8498 Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/51200 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Sebastien Buisson Reviewed-by: Andreas Dilger --- lustre/include/cl_object.h | 6 +++++- lustre/llite/rw26.c | 6 ++++++ lustre/lov/lov_object.c | 16 ++++++++++++++-- lustre/tests/sanity.sh | 20 ++++++++++---------- 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index 000235d..26587ac 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -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 */ diff --git a/lustre/llite/rw26.c b/lustre/llite/rw26.c index 0b4c263..dd5d28d 100644 --- a/lustre/llite/rw26.c +++ b/lustre/llite/rw26.c @@ -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); diff --git a/lustre/lov/lov_object.c b/lustre/lov/lov_object.c index 86f5a2b..50dd1c8 100644 --- a/lustre/lov/lov_object.c +++ b/lustre/lov/lov_object.c @@ -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, diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 65a576c..a88546a 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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() { -- 1.8.3.1