Whamcloud - gitweb
LU-17550 lov: check for empty layout on DIO 77/54077/7
authorPatrick Farrell <paf0187@gmail.com>
Mon, 1 Apr 2024 15:28:49 +0000 (11:28 -0400)
committerOleg Drokin <green@whamcloud.com>
Tue, 23 Apr 2024 19:47:24 +0000 (19:47 +0000)
When a write crosses from an area of a file with a layout to
one without, the write should return ENODATA.  Due to layout
caching in the direct IO path, we need an extra check for
this to work correctly for DIO.

Fixes: 14db1faa0f ("LU-13799 lov: Cache stripe offset calculation")
Signed-off-by: Patrick Farrell <patrick.farrell@oracle.com>
Change-Id: Ib9a40dab7939d9420144ecaa7460625d6184aa0b
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/54077
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/lov/lov_cl_internal.h
lustre/lov/lov_io.c
lustre/lov/lov_page.c
lustre/tests/sanity-pfl.sh

index eabe028..9bccabc 100644 (file)
@@ -596,6 +596,7 @@ struct lu_object *lovsub_object_alloc(const struct lu_env *env,
                                      struct lu_device *dev);
 
 int lov_io_layout_at(struct lov_io *lio, __u64 offset);
+bool lov_io_layout_at_confirm(struct lov_io *lio, int entry, __u64 offset);
 
 #define lov_foreach_target(lov, var)                    \
        for (var = 0; var < lov_targets_nr(lov); ++var)
index aa3c71a..bd235b8 100644 (file)
@@ -1999,6 +1999,19 @@ int lov_io_init_released(const struct lu_env *env, struct cl_object *obj,
        RETURN(result);
 }
 
+/* confirm this offset is in the given layout entry */
+bool lov_io_layout_at_confirm(struct lov_io *lio, int entry, __u64 offset)
+{
+       struct lov_object *lov = lio->lis_object;
+       struct lov_layout_entry *lle = lov_entry(lov, entry);
+
+       if ((offset >= lle->lle_extent->e_start &&
+            offset < lle->lle_extent->e_end) ||
+           (offset == OBD_OBJECT_EOF &&
+            lle->lle_extent->e_end == OBD_OBJECT_EOF))
+               return true;
+       return false;
+}
 /**
  * Return the index in composite:lo_entries by the file offset
  */
index 3bf4721..db0c852 100644 (file)
@@ -77,13 +77,19 @@ int lov_page_init_composite(const struct lu_env *env, struct cl_object *obj,
 
        if (stripe_cached) {
                entry = lio->lis_cached_entry;
+               /* if there's no layout at this offset, we'll end up here with
+                * a cached layout entry, so we must verify the layout includes
+                * this offset
+                */
+               if (!lov_io_layout_at_confirm(lio, entry, offset))
+                       return -ENODATA;
                stripe = lio->lis_cached_stripe;
                /* Offset can never go backwards in an i/o, so this is valid */
                suboff = lio->lis_cached_suboff + offset - lio->lis_cached_off;
        } else {
                entry = lov_io_layout_at(lio, offset);
                if (entry < 0)
-                       return(-ENODATA);
+                       return -ENODATA;
 
                stripe = lov_stripe_number(loo->lo_lsm, entry, offset);
                rc = lov_stripe_offset(loo->lo_lsm, entry, offset, stripe,
index cc78292..7544f3e 100755 (executable)
@@ -2565,6 +2565,8 @@ test_26a() {
        $LFS setstripe -E 1m -S 1M -c 1 $DIR/$tfile
        dd if=/dev/urandom bs=1M count=10 >> $DIR/$tfile
        [ $? != 0 ] || error "append must return an error"
+       dd if=/dev/urandom bs=1M count=10 oflag=direct >> $DIR/$tfile
+       [ $? != 0 ] || error "append must return an error"
 }
 run_test 26a "Append to not-existent component"
 
@@ -2573,6 +2575,8 @@ test_26b() {
        dd if=/dev/urandom bs=1M count=1 > $DIR/$tfile
        dd if=/dev/urandom bs=1M count=1 >> $DIR/$tfile
        [ $? != 0 ] || error "append must return an error"
+       dd if=/dev/urandom bs=1M count=1 oflag=direct >> $DIR/$tfile
+       [ $? != 0 ] || error "append must return an error"
 }
 run_test 26b "Append to not-existend component, file size is unknown"
 
@@ -2580,6 +2584,8 @@ test_26c() {
        $LFS setstripe -E 1m -S 1M -c 1 $DIR/$tfile
        dd if=/dev/urandom bs=2M count=1 >> $DIR/$tfile
        [ $? != 0 ] || error "append must return an error"
+       dd if=/dev/urandom bs=2M count=1 oflag=direct >> $DIR/$tfile
+       [ $? != 0 ] || error "append must return an error"
 }
 run_test 26c "Append to not-existend component, crossing the component border"