Whamcloud - gitweb
LU-15748 ofd: fix fallocate interop for older clients 48/47548/17
authorAndreas Dilger <adilger@whamcloud.com>
Mon, 6 Jun 2022 23:14:32 +0000 (17:14 -0600)
committerOleg Drokin <green@whamcloud.com>
Tue, 29 Nov 2022 07:06:14 +0000 (07:06 +0000)
The logic for detecting older client fallocate was backward, and
should be checking if the OBD_CONNECT_OLD_FALLOC patch was *not*
present to detect old clients.

Since the new server does not have OLD_FALLOC in the SUPPORTED flags,
it will clear the flag from the export at connect time, so it needs
to be saved in the export early on.

Test-Parameters: testlist=sanityn env=ONLY=16,HONOR_EXCEPT=y
Test-Parameters: serverversion=2.14 testlist=sanityn env=ONLY=16,HONOR_EXCEPT=y
Fixes: 7905359296 ("LU-15748 osc: fallocate interop for 2.14 clients")
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Change-Id: I327183025a8de6fd814a7c2929365497153ebbe5
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/47548
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Arshad Hussain <arshad.hussain@aeoncomputing.com>
Reviewed-by: Jian Yu <yujian@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lustre_export.h
lustre/ldlm/ldlm_lib.c
lustre/mdt/mdt_io.c
lustre/ofd/ofd_dev.c
lustre/tests/sanityn.sh

index 3137ccf..7a658d1 100644 (file)
@@ -279,6 +279,11 @@ struct obd_export {
                                exp_replay_done:1,
                                /* local client with recovery disabled */
                                exp_no_recovery:1,
+                               /* old client will set this to 1 (true).
+                                * Newer clients 2.15 and beyond will have this
+                                * set as 0 (false)
+                                */
+                               exp_old_falloc:1,
                                exp_hashed:1;
        /* also protected by exp_lock */
        enum lustre_sec_part    exp_sp_peer;
index dadb8bd..9eea19a 100644 (file)
@@ -1107,6 +1107,9 @@ int target_handle_connect(struct ptlrpc_request *req)
        struct obd_connect_data *data, *tmpdata;
        int size, tmpsize;
        lnet_nid_t client_nid;
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
+       int tmp_exp_old_falloc;
+#endif
        struct ptlrpc_connection *pcon = NULL;
 
        ENTRY;
@@ -1195,6 +1198,15 @@ int target_handle_connect(struct ptlrpc_request *req)
        if (!(data->ocd_connect_flags & OBD_CONNECT_FULL20))
                GOTO(out, rc = -EPROTO);
 
+       /* Old clients will have 'tmp_exp_old_falloc' as 1.
+        * Newer clients (2.15) and beyond will have it set as 0
+        */
+       tmp_exp_old_falloc =
+               !!(data->ocd_connect_flags & OBD_CONNECT_OLD_FALLOC);
+
+       CDEBUG(D_INFO, "%s: ocd_connect_flags: %#llx tmp_exp_old_falloc: %d\n",
+              target->obd_name, data->ocd_connect_flags, tmp_exp_old_falloc);
+
        /*
         * Don't allow liblustre clients to connect.
         * - testing was disabled in v2_2_50_0-61-g6a75d65
@@ -1514,6 +1526,13 @@ dont_check_exports:
        LASSERT(lustre_msg_get_conn_cnt(req->rq_reqmsg) > 0);
        export->exp_conn_cnt = lustre_msg_get_conn_cnt(req->rq_reqmsg);
 
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
+       /* make 'tmp_exp_old_falloc' persistent by saving it into
+        * server side export object(obd_export)
+        */
+       export->exp_old_falloc = tmp_exp_old_falloc;
+#endif
+
        /* Check to see if connection came from another NID. */
        if (export->exp_connection != NULL &&
            !nid_same(&export->exp_connection->c_peer.nid,
index 3a9ec7e..f766315 100644 (file)
@@ -971,13 +971,26 @@ int mdt_fallocate_hdl(struct tgt_session_info *tsi)
        if ((oa->o_valid & (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) !=
            (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)
 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 21, 53, 0)
-           && (tgt_conn_flags(tsi) & OBD_CONNECT_OLD_FALLOC)
+           && !tsi->tsi_exp->exp_old_falloc
 #endif
            )
                RETURN(-EOPNOTSUPP);
 
        start = oa->o_size;
        end = oa->o_blocks;
+       CDEBUG(D_INFO, "%s: start: %llu end: %llu\n",
+              mdt->mdt_child_exp->exp_obd->obd_name, start, end);
+
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 21, 53, 0)
+       /*
+        * For inter-op case with older clients (where exp_old_falloc is true)
+        * fallocate() start and end are passed in as 0 (For interior case
+        * where end offset less than file size) This is fixed later.
+        * For such cases we return -EOPNOTSUPP
+        */
+       if (tsi->tsi_exp->exp_old_falloc && start >= end)
+               RETURN(-EOPNOTSUPP);
+#endif
        /* client should already limit len >= 0 */
        if (start >= end)
                RETURN(-EINVAL);
index 811a1e7..535196a 100644 (file)
@@ -1991,9 +1991,10 @@ static int ofd_fallocate_hdl(struct tgt_session_info *tsi)
         * fallocate() start and end are passed in o_size and o_blocks
         * on the wire.  Clients 2.15.0 and newer should always set
         * the OBD_MD_FLSIZE and OBD_MD_FLBLOCKS valid flags, but some
-        * older client versions did not.  We permit older clients to
-        * not set these flags, checking their version by proxy using
-        * the lack of OBD_CONNECT_TRUNCLOCK to imply 2.14.0 and older.
+        * older client (exp_old_falloc is true) versions did not.
+        * We permit older clients to not set these flags, checking their
+        * version by proxy using the lack of OBD_CONNECT_TRUNCLOCK to
+        * imply 2.14.0 and older.
         *
         * Return -EOPNOTSUPP to also work with older clients not
         * supporting newer server modes.
@@ -2001,13 +2002,25 @@ static int ofd_fallocate_hdl(struct tgt_session_info *tsi)
        if ((oa->o_valid & (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) !=
            (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)
 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 21, 53, 0)
-           && (tgt_conn_flags(tsi) & OBD_CONNECT_OLD_FALLOC)
+           && !tsi->tsi_exp->exp_old_falloc
 #endif
            )
                RETURN(-EOPNOTSUPP);
 
        start = oa->o_size;
        end = oa->o_blocks;
+       CDEBUG(D_INFO, "%s: start: %llu end: %llu\n", tgt_name(tsi->tsi_tgt),
+              start, end);
+
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 21, 53, 0)
+       /* For inter-op case with older clients (where exp_old_falloc is true)
+        * fallocate() start and end are passed in as 0 (For interior case
+        * where end offset less than file size) This is fixed later.
+        * For such cases we return -EOPNOTSUPP
+        */
+       if (tsi->tsi_exp->exp_old_falloc && start >= end)
+               RETURN(-EOPNOTSUPP);
+#endif
        /* client should already limit len >= 0 */
        if (start >= end)
                RETURN(-EINVAL);
index 25158d0..ce4968e 100755 (executable)
@@ -563,6 +563,9 @@ test_16f() { # LU-14541
        local duration=20
        local status
 
+       (( $MDS1_VERSION > $(version_code 2.15.51) )) ||
+               skip "Need MDS version at least 2.15.51"
+
        timeout --preserve-status --signal=USR1 $duration \
                rw_seq_cst_vs_drop_caches $file1 $file2
        status=$?