Whamcloud - gitweb
LU-13805 llite: add flag to disable unaligned DIO 25/51125/39
authorPatrick Farrell <pfarrell@whamcloud.com>
Sun, 21 May 2023 16:48:25 +0000 (12:48 -0400)
committerOleg Drokin <green@whamcloud.com>
Fri, 3 Nov 2023 04:01:53 +0000 (04:01 +0000)
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 <pfarrell@whamcloud.com>
Change-Id: Ibc86d84704151a7f30afcc538d9c03e3fdf1c38a
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51125
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/lproc_llite.c
lustre/llite/rw26.c
lustre/tests/sanity.sh

index 60887a7..4d96376 100644 (file)
@@ -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 */
index db455fe..1baa507 100644 (file)
@@ -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)
index bd4708b..5f55b07 100644 (file)
@@ -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,
index 8f9511d..791feb0 100644 (file)
@@ -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
index bbe83c9..0fda525 100755 (executable)
@@ -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