Whamcloud - gitweb
EX-7601 tgt: objcount in RPC must be 1
authorPatrick Farrell <pfarrell@whamcloud.com>
Fri, 29 Dec 2023 19:49:55 +0000 (14:49 -0500)
committerAndreas Dilger <adilger@whamcloud.com>
Tue, 2 Jan 2024 08:24:16 +0000 (08:24 +0000)
Much of the BRW write code assumes objcount is one, but
there is some provision for multiple objects.

Since the code will break if we send it multiple objects,
add errors to make sure anyone changing it will notice.

This isn't strictly compression related, but compression
adds even more code which assumes this, so this protection
will be useful.

Signed-off-by: Patrick Farrell <pfarrell@whamcloud.com>
Change-Id: Idcbf33fd14d4b1bd179c9516bed07cca907008bc
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/52990
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/ofd/ofd_io.c
lustre/target/tgt_handler.c

index ad62c8b..4b33142 100644 (file)
@@ -778,7 +778,11 @@ static int ofd_preprw_write(const struct lu_env *env, struct obd_export *exp,
 
        ENTRY;
        LASSERT(env != NULL);
-       LASSERT(objcount == 1);
+       if (objcount != 1) {
+               CERROR("%s: this server only supports 1 object per RPC\n",
+                      ofd_name(ofd));
+               GOTO(out, rc = -EPROTO);
+       }
 
        if (unlikely(exp->exp_obd->obd_recovering)) {
                u64 seq = ostid_seq(&oa->o_oi);
@@ -1341,7 +1345,11 @@ int ofd_preprw(const struct lu_env *env, int cmd, struct obd_export *exp,
                ofd_seq_put(env, oseq);
        }
 
-       LASSERT(objcount == 1);
+       if (objcount != 1) {
+               CERROR("%s: this server only supports 1 object per RPC\n",
+                      ofd_name(ofd));
+               RETURN(rc = -EPROTO);
+       }
        LASSERT(obj->ioo_bufcnt > 0);
 
        if (cmd == OBD_BRW_WRITE) {
@@ -1648,14 +1656,17 @@ ofd_commitrw_write(const struct lu_env *env, struct obd_export *exp,
 
        ENTRY;
 
-       LASSERT(objcount == 1);
-
        fo = ofd_info(env)->fti_obj;
        LASSERT(fo != NULL);
 
        o = ofd_object_child(fo);
        LASSERT(o != NULL);
 
+       if (objcount != 1) {
+               CERROR("%s: this server only supports 1 object per RPC\n",
+                      ofd_name(ofd));
+               GOTO(out, rc = -EPROTO);
+       }
        if (old_rc)
                GOTO(out, rc = old_rc);
        if (!ofd_object_exists(fo))
index eb588df..2559fad 100644 (file)
@@ -2907,6 +2907,17 @@ int tgt_brw_write(struct tgt_session_info *tsi)
        objcount = req_capsule_get_size(&req->rq_pill, &RMF_OBD_IOOBJ,
                                        RCL_CLIENT) / sizeof(*ioo);
 
+       /* there are currently never multiple objects in one RPC, and parts of
+        * this code assume one object, so assert it for now (the loop after
+        * this is part of the incomplete handling for multiple objects in an
+        * RPC, so it is left here to help if we add multi-object RPCs in
+        * future)
+        */
+       if (objcount != 1) {
+               CERROR("%s: this server only supports 1 object per RPC\n",
+                      tgt_name(tsi->tsi_tgt));
+               GOTO(out, rc = -EPROTO);
+       }
        for (niocount = i = 0; i < objcount; i++)
                niocount += ioo[i].ioo_bufcnt;