Whamcloud - gitweb
LU-13802 llite: trivial bio_dio switch check 86/52586/13
authorQian Yingjin <qian@ddn.com>
Fri, 6 Oct 2023 19:33:32 +0000 (15:33 -0400)
committerOleg Drokin <green@whamcloud.com>
Fri, 23 Feb 2024 07:01:05 +0000 (07:01 +0000)
This adds a trivial version of the DIO BIO switch checking
function which doesn't ever switch.  This creates the basic
check function which we'll add to in future patches.

Test-Parameters: trivial
Signed-off-by: Patrick Farrell <pfarrell@whamcloud.com>
Signed-off-by: Qian Yingjin <qian@ddn.com>
Change-Id: Ia01df8d0f33246d3833c5327bcb1a07ac305492b
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52586
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/llite/file.c

index 0116127..e2cf516 100644 (file)
@@ -1703,6 +1703,31 @@ static void ll_heat_add(struct inode *inode, enum cl_io_type iot,
        spin_unlock(&lli->lli_heat_lock);
 }
 
+static bool
+ll_hybrid_bio_dio_switch_check(struct file *file, struct kiocb *iocb,
+                              enum cl_io_type iot, size_t count)
+{
+       /* we can only do this with IOCB_FLAGS, since we can't modify f_flags
+        * because they're visible in userspace.  so we check for IOCB_DIRECT
+        */
+#ifdef IOCB_DIRECT
+       ENTRY;
+
+       /* it doesn't make sense to switch unless it's READ or WRITE */
+       if (iot != CIT_WRITE && iot != CIT_READ)
+               RETURN(false);
+
+       if (!iocb)
+               RETURN(false);
+
+       /* Already using direct I/O, no need to switch. */
+       if (iocb->ki_flags & IOCB_DIRECT)
+               RETURN(false);
+
+#endif
+       RETURN(false);
+}
+
 static ssize_t
 ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,
                   struct file *file, enum cl_io_type iot,
@@ -2150,14 +2175,22 @@ static ssize_t ll_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 
        ll_ras_enter(file, iocb->ki_pos, iov_iter_count(to));
 
-       result = ll_do_fast_read(iocb, to);
-       if (result < 0 || iov_iter_count(to) == 0)
-               GOTO(out, result);
+       if (ll_hybrid_bio_dio_switch_check(file, iocb, CIT_READ,
+                                          iov_iter_count(to))) {
+#ifdef IOCB_DIRECT
+               iocb->ki_flags |= IOCB_DIRECT;
+               CDEBUG(D_VFSTRACE, "switching to DIO\n");
+#endif
+       }
 
        args = ll_env_args(env);
        args->u.normal.via_iter = to;
        args->u.normal.via_iocb = iocb;
 
+       result = ll_do_fast_read(iocb, to);
+       if (result < 0 || iov_iter_count(to) == 0)
+               GOTO(out, result);
+
        rc2 = ll_file_io_generic(env, args, file, CIT_READ,
                                 &iocb->ki_pos, iov_iter_count(to));
        if (rc2 > 0)
@@ -2291,6 +2324,14 @@ static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        if (cached && result != -ENOSPC && result != -EDQUOT)
                GOTO(out, rc_normal = result);
 
+       if (ll_hybrid_bio_dio_switch_check(file, iocb, CIT_WRITE,
+                                          iov_iter_count(from))) {
+#ifdef IOCB_DIRECT
+               iocb->ki_flags |= IOCB_DIRECT;
+               CDEBUG(D_VFSTRACE, "switching to DIO\n");
+#endif
+       }
+
        /* NB: we can't do direct IO for tiny writes because they use the page
         * cache, we can't do sync writes because tiny writes can't flush
         * pages, and we can't do append writes because we can't guarantee the