Whamcloud - gitweb
EX-7601 ofd: add chunk rounding to read
authorPatrick Farrell <pfarrell@whamcloud.com>
Fri, 27 Oct 2023 20:24:33 +0000 (16:24 -0400)
committerAndreas Dilger <adilger@whamcloud.com>
Tue, 12 Dec 2023 04:02:22 +0000 (04:02 +0000)
We need to round all niobufs to chunk size in the read
process, so we read in the full chunk.

dt_bufs_get sets up the local niobuf for the read, so we
round before calling it.

This patch is a partial implementation of unaligned read
support, and breaks compression testing until the next few
patches are landed.  So this patch temporarily adds the
compression tests to ALWAYS_EXCEPT.

Signed-off-by: Patrick Farrell <pfarrell@whamcloud.com>
Change-Id: I587a519db4dae983db5db1d690e63e15bc010b7e
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/52867
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Artem Blagodarenko <ablagodarenko@ddn.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/include/obd.h
lustre/obdclass/lustre_compr.c
lustre/ofd/ofd_io.c
lustre/target/tgt_handler.c
lustre/tests/sanity-compr.sh
lustre/tests/sanity-pfl.sh
lustre/tests/sanity.sh

index eb1d232..27d1846 100644 (file)
@@ -475,6 +475,7 @@ struct niobuf_local {
        __u16           lnb_locked:1;
 };
 
+void chunk_round(__u64 *buf_start, __u64 *buf_end, int chunk_size);
 void merge_chunk(struct brw_page **pga, struct niobuf_local *lnb,
                 int first, int count, char *merged, unsigned int *size);
 void unmerge_chunk(struct brw_page **pga, struct niobuf_local *lnb, int first,
index 3b85182..bab0322 100644 (file)
 static bool tried_llz4_load = false;
 static bool tried_lgzip_load = false;
 
+/* rounds buf_start and buf_end to chunk size */
+void chunk_round(__u64 *buf_start, __u64 *buf_end, int chunk_size)
+{
+       __u64 orig_start = *buf_start;
+       __u64 orig_end = *buf_end;
+
+       *buf_start = round_down(*buf_start, chunk_size);
+       *buf_end = round_up(*buf_end, chunk_size);
+
+       if (*buf_start != orig_start || *buf_end != orig_end) {
+               CDEBUG(D_SEC, "ROUNDED: buf_start %llu, buf_end %llu\n",
+                      *buf_start, *buf_end);
+       }
+}
+EXPORT_SYMBOL(chunk_round);
+
 static inline const char *crypto_name_from_type(enum ll_compr_type type,
                                                unsigned int level)
 {
index 379ca9a..a11ba66 100644 (file)
@@ -593,6 +593,7 @@ static int ofd_preprw_read(const struct lu_env *env, struct obd_export *exp,
        enum dt_bufs_type dbt = DT_BUFS_TYPE_READ;
        int maxlnb = *nr_local;
        __u64 begin, end;
+       __u64 prev_buf_end = 0;
 
        ENTRY;
        LASSERT(env != NULL);
@@ -623,15 +624,56 @@ static int ofd_preprw_read(const struct lu_env *env, struct obd_export *exp,
        end = 0;
 
        for (*nr_local = 0, i = 0, j = 0; i < niocount; i++) {
+               __u64 buf_start;
+               __u64 buf_end;
+               int buf_len;
+
                begin = min_t(__u64, begin, rnb[i].rnb_offset);
                end = max_t(__u64, end, rnb[i].rnb_offset + rnb[i].rnb_len);
+               CDEBUG(D_SEC, "begin %llu, end %llu\n", begin, end);
 
                if (OBD_FAIL_CHECK(OBD_FAIL_OST_2BIG_NIOBUF))
                        rnb[i].rnb_len = 100 * 1024 * 1024;
 
-               rc = dt_bufs_get(env, ofd_object_child(fo), lnb + j,
-                                rnb[i].rnb_offset, rnb[i].rnb_len, maxlnb,
-                                dbt);
+               buf_start = rnb[i].rnb_offset;
+               buf_end = rnb[i].rnb_offset + rnb[i].rnb_len;
+
+               CDEBUG(D_SEC, "buf_start %llu, buf_end %llu\n", buf_start,
+                      buf_end);
+
+               /* compressd reads must be rounded to cover whole chunks */
+               if (chunk_size) {
+                       chunk_round(&buf_start, &buf_end, chunk_size);
+                       /* unaligned reads on compressed files are not supported
+                        * yet
+                        */
+                       if (buf_start != rnb[i].rnb_offset ||
+                           buf_end != rnb[i].rnb_offset + rnb[i].rnb_len)
+                               GOTO(buf_put, rc = -EINVAL);
+
+                       /* rounded rnbs can overlap at the chunk level, but it's
+                        * important we don't allocate multiple buffers for the
+                        * same page, so move the start of this buffer to the
+                        * end of the previous one
+                        */
+                       if (buf_start < prev_buf_end) {
+                               buf_start = prev_buf_end;
+                               /* two rnbs may be entirely inside the same
+                                * chunk, in which case we're already doing IO
+                                * for that chunk, so skip it
+                                */
+                               if (buf_start == buf_end) {
+                                       prev_buf_end = buf_end;
+                                       continue;
+                               }
+                       }
+                       prev_buf_end = buf_end;
+               }
+
+               buf_len = buf_end - buf_start;
+
+               rc = dt_bufs_get(env, ofd_object_child(fo), lnb + j, buf_start,
+                                buf_len, maxlnb, dbt);
                if (unlikely(rc < 0))
                        GOTO(buf_put, rc);
                LASSERT(rc <= PTLRPC_MAX_BRW_PAGES);
index 136e78c..35bf91e 100644 (file)
@@ -2478,9 +2478,10 @@ int tgt_brw_read(struct tgt_session_info *tsi)
                io_start = remote_nb[0].rnb_offset;
                io_end = remote_nb[niocount - 1].rnb_offset +
                         remote_nb[niocount - 1].rnb_len;
+               chunk_start = io_start;
+               chunk_end = io_end;
 
-               chunk_start = round_down(io_start, chunk_size);
-               chunk_end = round_up(io_end, chunk_size);
+               chunk_round(&chunk_start, &chunk_end, chunk_size);
 
                CDEBUG(D_SEC,
                       "io_start: %llu io_end: %llu, chunk_start %llu, chunk_end %llu\n",
index ec9f8ac..8850095 100644 (file)
@@ -14,7 +14,9 @@ init_test_env "$@"
 init_logging
 
 # bug number for skipped test:
-ALWAYS_EXCEPT="$SANITY_COMPR_EXCEPT"
+ALWAYS_EXCEPT="$SANITY_COMPR_EXCEPT "
+### TEMPORARY, will be removed shortly ###
+always_except EX-7601 test_sanity test_sanityn test_1000
 
 build_test_filter
 
index 33d3c2c..e65d3a7 100644 (file)
@@ -28,6 +28,8 @@ fi
 
 # until data compression on MDT works
 always_except EX-7806  100k
+# Temporary for EX-7601, will be removed
+always_except EX-7601  100l
 
 build_test_filter
 
index b066f1a..68ee2ba 100755 (executable)
@@ -46,6 +46,8 @@ always_except LU-16515 118c 118d
 always_except LU-9054  312
 always_except LU-8411  407
 always_except EX-4334  428
+### TEMPORARY, will be removed shortly ###
+always_except EX-7601  460a 460b 460c 460d 460e 460f
 
 if $SHARED_KEY; then
        always_except LU-14181 64e 64f