From 33ed79ba61a3275519c897557407619d576a9dc2 Mon Sep 17 00:00:00 2001 From: Patrick Farrell Date: Sun, 21 May 2023 12:48:25 -0400 Subject: [PATCH] LU-13805 llite: add flag to disable unaligned DIO As with any new IO feature, it's a good idea to have the option to turn off unaligned DIO support if needed. It would be reasonable to merge this patch with the core patch implementing the feature; I have kept it separate for ease of review. Signed-off-by: Patrick Farrell Change-Id: Ibc86d84704151a7f30afcc538d9c03e3fdf1c38a Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51125 Reviewed-by: Oleg Drokin Reviewed-by: Andreas Dilger Reviewed-by: Sebastien Buisson Tested-by: jenkins Tested-by: Maloo --- lustre/llite/llite_internal.h | 6 ++++++ lustre/llite/llite_lib.c | 2 ++ lustre/llite/lproc_llite.c | 37 +++++++++++++++++++++++++++++++++++++ lustre/llite/rw26.c | 12 ++++++++---- lustre/tests/sanity.sh | 9 +++++++++ 5 files changed, 62 insertions(+), 4 deletions(-) diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 60887a7..4d96376 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -779,6 +779,7 @@ enum ll_sbi_flags { LL_SBI_FILE_HEAT, /* file heat support */ LL_SBI_PARALLEL_DIO, /* parallel (async) O_DIRECT RPCs */ LL_SBI_ENCRYPT_NAME, /* name encryption */ + LL_SBI_UNALIGNED_DIO, /* unaligned DIO */ LL_SBI_NUM_FLAGS }; @@ -1123,6 +1124,11 @@ static inline bool ll_sbi_has_parallel_dio(struct ll_sb_info *sbi) return test_bit(LL_SBI_PARALLEL_DIO, sbi->ll_flags); } +static inline bool ll_sbi_has_unaligned_dio(struct ll_sb_info *sbi) +{ + return test_bit(LL_SBI_UNALIGNED_DIO, sbi->ll_flags); +} + void ll_ras_enter(struct file *f, loff_t pos, size_t bytes); /* llite/lcommon_misc.c */ diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index db455fe..1baa507 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -194,6 +194,7 @@ static struct ll_sb_info *ll_init_sbi(struct lustre_sb_info *lsi) set_bit(LL_SBI_FAST_READ, sbi->ll_flags); set_bit(LL_SBI_TINY_WRITE, sbi->ll_flags); set_bit(LL_SBI_PARALLEL_DIO, sbi->ll_flags); + set_bit(LL_SBI_UNALIGNED_DIO, sbi->ll_flags); ll_sbi_set_encrypt(sbi, true); ll_sbi_set_name_encrypt(sbi, true); @@ -1010,6 +1011,7 @@ static const match_table_t ll_sbi_flags_name = { {LL_SBI_FILE_HEAT, "file_heat"}, {LL_SBI_PARALLEL_DIO, "parallel_dio"}, {LL_SBI_ENCRYPT_NAME, "name_encrypt"}, + {LL_SBI_UNALIGNED_DIO, "unaligned_dio"}, }; int ll_sbi_flags_seq_show(struct seq_file *m, void *v) diff --git a/lustre/llite/lproc_llite.c b/lustre/llite/lproc_llite.c index bd4708b..5f55b07 100644 --- a/lustre/llite/lproc_llite.c +++ b/lustre/llite/lproc_llite.c @@ -1140,6 +1140,42 @@ static ssize_t tiny_write_store(struct kobject *kobj, } LUSTRE_RW_ATTR(tiny_write); +static ssize_t unaligned_dio_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kset.kobj); + + return scnprintf(buf, PAGE_SIZE, "%u\n", + test_bit(LL_SBI_UNALIGNED_DIO, sbi->ll_flags)); +} + +static ssize_t unaligned_dio_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) +{ + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kset.kobj); + bool val; + int rc; + + rc = kstrtobool(buffer, &val); + if (rc) + return rc; + + spin_lock(&sbi->ll_lock); + if (val) + set_bit(LL_SBI_UNALIGNED_DIO, sbi->ll_flags); + else + clear_bit(LL_SBI_UNALIGNED_DIO, sbi->ll_flags); + spin_unlock(&sbi->ll_lock); + + return count; +} +LUSTRE_RW_ATTR(unaligned_dio); + static ssize_t parallel_dio_show(struct kobject *kobj, struct attribute *attr, char *buf) @@ -1892,6 +1928,7 @@ static struct attribute *llite_attrs[] = { &lustre_attr_fast_read.attr, &lustre_attr_tiny_write.attr, &lustre_attr_parallel_dio.attr, + &lustre_attr_unaligned_dio.attr, &lustre_attr_file_heat.attr, &lustre_attr_heat_decay_percentage.attr, &lustre_attr_heat_period_second.attr, diff --git a/lustre/llite/rw26.c b/lustre/llite/rw26.c index 8f9511d..791feb0 100644 --- a/lustre/llite/rw26.c +++ b/lustre/llite/rw26.c @@ -498,10 +498,6 @@ ll_direct_IO_impl(struct kiocb *iocb, struct iov_iter *iter, int rw) ENTRY; - /* Check EOF by ourselves */ - if (rw == READ && file_offset >= i_size_read(inode)) - RETURN(0); - if (file_offset & ~PAGE_MASK) unaligned = true; @@ -519,6 +515,14 @@ ll_direct_IO_impl(struct kiocb *iocb, struct iov_iter *iter, int rw) (count >> PAGE_SHIFT) + !!(count & ~PAGE_MASK), MAX_DIO_SIZE >> PAGE_SHIFT, unaligned ? ", unaligned" : ""); + /* Check EOF by ourselves */ + if (rw == READ && file_offset >= i_size_read(inode)) + RETURN(0); + + /* unaligned DIO support can be turned off, so is it on? */ + if (unaligned && !ll_sbi_has_unaligned_dio(ll_i2sbi(inode))) + RETURN(-EINVAL); + /* the requirement to not return EIOCBQUEUED for pipes (see bottom of * this function) plays havoc with the unaligned I/O lifecycle, so * don't allow unaligned I/O on pipes diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index bbe83c9..0fda525 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -13565,6 +13565,15 @@ test_119e() iflag=direct oflag=direct || error "trivial unaligned dio failed" + # Test of disabling unaligned DIO support + $LCTL set_param llite.*.unaligned_dio=0 + stack_trap "$LCTL set_param llite.*.unaligned_dio=1" + echo "testing disabling unaligned DIO - 'invalid argument' expected:" + dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \ + iflag=direct oflag=direct && + error "unaligned dio succeeded when disabled" + $LCTL set_param llite.*.unaligned_dio=1 + # Clean up before next part of test rm -f $DIR/$tfile.2 -- 1.8.3.1