diff mbox series

[26/39] lustre: lov: fix SEEK_HOLE calcs at component end

Message ID 1611249422-556-27-git-send-email-jsimmons@infradead.org (mailing list archive)
State New
Headers show
Series lustre: update to latest OpenSFS version as of Jan 21 2021 | expand

Commit Message

James Simmons Jan. 21, 2021, 5:16 p.m. UTC
From: Mikhail Pershin <mpershin@whamcloud.com>

If data ends exactly at component end then LOV assumed that
is not yet hole in file and the next component will take care.
Meanwhile there can be no next component initialized yet if file
ends exactly at component boundary, so no hole offset is returned
but error

Patch fixes that issue. If component reports hole offset at
component end then it is saved to be used as result when no
other components report valid hole offset.

WC-bug-id: https://jira.whamcloud.com/browse/LU-14143
Lustre-commit: dbb6b493ad9f98 ("LU-14143 lov: fix SEEK_HOLE calcs at component end")
Signed-off-by: Mikhail Pershin <mpershin@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/40713
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: John L. Hammond <jhammond@whamcloud.com>
Signed-off-by: James Simmons <jsimmons@infradead.org>
---
 fs/lustre/lov/lov_io.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/fs/lustre/lov/lov_io.c b/fs/lustre/lov/lov_io.c
index 7f0e945..ac88a55 100644
--- a/fs/lustre/lov/lov_io.c
+++ b/fs/lustre/lov/lov_io.c
@@ -1295,6 +1295,7 @@  static void lov_io_lseek_end(const struct lu_env *env,
 	struct lov_stripe_md *lsm = lio->lis_object->lo_lsm;
 	struct lov_io_sub *sub;
 	loff_t offset = -ENXIO;
+	u64 hole_off = 0;
 	bool seek_hole = io->u.ci_lseek.ls_whence == SEEK_HOLE;
 
 	list_for_each_entry(sub, &lio->lis_active, sub_linkage) {
@@ -1302,6 +1303,7 @@  static void lov_io_lseek_end(const struct lu_env *env,
 		int index = lov_comp_entry(sub->sub_subio_index);
 		int stripe = lov_comp_stripe(sub->sub_subio_index);
 		loff_t sub_off, lov_off;
+		u64 comp_end = lsm->lsm_entries[index]->lsme_extent.e_end;
 
 		lov_io_end_wrapper(sub->sub_env, subio);
 
@@ -1347,10 +1349,22 @@  static void lov_io_lseek_end(const struct lu_env *env,
 		/* resulting offset can be out of component range if stripe
 		 * object is full and its file size was returned as virtual
 		 * hole start. Skip this result, the next component will give
-		 * us correct lseek result.
+		 * us correct lseek result but keep possible hole offset in
+		 * case there is no more components ahead
 		 */
-		if (lov_off >= lsm->lsm_entries[index]->lsme_extent.e_end)
+		if (lov_off >= comp_end) {
+			/* must be SEEK_HOLE case */
+			if (likely(seek_hole)) {
+				/* save comp end as potential hole offset */
+				hole_off = max_t(u64, comp_end, hole_off);
+			} else {
+				io->ci_result = -EINVAL;
+				CDEBUG(D_INFO,
+				       "off %lld >= comp_end %llu: rc = %d\n",
+				       lov_off, comp_end, io->ci_result);
+			}
 			continue;
+		}
 
 		CDEBUG(D_INFO, "SEEK_%s: %lld->%lld/%lld: rc = %d\n",
 		       seek_hole ? "HOLE" : "DATA",
@@ -1358,6 +1372,10 @@  static void lov_io_lseek_end(const struct lu_env *env,
 		       sub->sub_io.ci_result);
 		offset = min_t(u64, offset, lov_off);
 	}
+	/* no result but some component returns hole as component end */
+	if (seek_hole && offset == -ENXIO && hole_off > 0)
+		offset = hole_off;
+
 	io->u.ci_lseek.ls_result = offset;
 }