Whamcloud - gitweb
LU-15117 ofd: no lock for dt_bufs_get() in read path 09/48209/5
authorAlex Zhuravlev <bzzz@whamcloud.com>
Fri, 12 Aug 2022 11:24:17 +0000 (14:24 +0300)
committerOleg Drokin <green@whamcloud.com>
Tue, 8 Nov 2022 08:49:43 +0000 (08:49 +0000)
osd_bufs_get() allocates the pages and can cause new transactions
as part of memory release procedure. this would break Lustre's
"start a transaction, then do locking" rule.

Signed-off-by: Alex Zhuravlev <bzzz@whamcloud.com>
Change-Id: I782f0cc6c96251ad88d5fb8d15c9ac91d382bf7e
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/48209
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Yang Sheng <ys@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/ofd/ofd_io.c

index 1ff552e..27da3ed 100644 (file)
@@ -580,15 +580,8 @@ static int ofd_preprw_read(const struct lu_env *env, struct obd_export *exp,
        if (oa->o_valid & OBD_MD_FLATIME)
                ofd_handle_atime(env, ofd, fo, oa->o_atime);
 
-       ofd_read_lock(env, fo);
        if (!ofd_object_exists(fo))
-               GOTO(unlock, rc = -ENOENT);
-
-       if (ofd->ofd_lfsck_verify_pfid && oa->o_valid & OBD_MD_FLFID) {
-               rc = ofd_verify_ff(env, fo, oa);
-               if (rc != 0)
-                       GOTO(unlock, rc);
-       }
+               GOTO(obj_put, rc = -ENOENT);
 
        if (ptlrpc_connection_is_local(exp->exp_connection))
                dbt |= DT_BUFS_TYPE_LOCAL;
@@ -616,10 +609,20 @@ static int ofd_preprw_read(const struct lu_env *env, struct obd_export *exp,
                tot_bytes += rnb[i].rnb_len;
        }
 
+       ofd_read_lock(env, fo);
+       if (!ofd_object_exists(fo))
+               GOTO(unlock, rc = -ENOENT);
+
+       if (ofd->ofd_lfsck_verify_pfid && oa->o_valid & OBD_MD_FLFID) {
+               rc = ofd_verify_ff(env, fo, oa);
+               if (rc != 0)
+                       GOTO(unlock, rc);
+       }
+
        LASSERT(*nr_local > 0 && *nr_local <= PTLRPC_MAX_BRW_PAGES);
        rc = dt_read_prep(env, ofd_object_child(fo), lnb, *nr_local);
        if (unlikely(rc))
-               GOTO(buf_put, rc);
+               GOTO(unlock, rc);
        ofd_read_unlock(env, fo);
 
        ofd_access(env, ofd,
@@ -635,10 +638,11 @@ static int ofd_preprw_read(const struct lu_env *env, struct obd_export *exp,
 
        RETURN(0);
 
-buf_put:
-       dt_bufs_put(env, ofd_object_child(fo), lnb, *nr_local);
 unlock:
        ofd_read_unlock(env, fo);
+buf_put:
+       dt_bufs_put(env, ofd_object_child(fo), lnb, *nr_local);
+obj_put:
        ofd_object_put(env, fo);
        return rc;
 }