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>
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)
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
*/
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,
$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"
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"
$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"