Whamcloud - gitweb
LU-16612 llite: protect cp_state with vmpage lock
authorBobi Jam <bobijam@whamcloud.com>
Thu, 2 Mar 2023 09:45:14 +0000 (17:45 +0800)
committerAndreas Dilger <adilger@whamcloud.com>
Tue, 25 Apr 2023 03:35:34 +0000 (03:35 +0000)
cl_page_make_ready() calls cl_page_io_start() without vmpage lock
protection, and that could mess up cl_page's cp_state/cp_owner.

Lustre-change: https://review.whamcloud.com/50180
Lustre-commit: d03b038d0dd8360dc896ceb7f3cee99245551cb8

Signed-off-by: Bobi Jam <bobijam@whamcloud.com>
Change-Id: Id0df7e14246aa561494a9b6e581cebc55241c4b9
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/50182
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Patrick Farrell <pfarrell@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lustre/llite/vvp_page.c
lustre/obdclass/cl_page.c

index 59388b3..9316add 100644 (file)
@@ -350,7 +350,6 @@ static int vvp_page_make_ready(const struct lu_env *env,
        struct cl_page *pg = slice->cpl_page;
        int result = 0;
 
-       lock_page(vmpage);
        if (clear_page_dirty_for_io(vmpage)) {
                LASSERT(pg->cp_state == CPS_CACHED);
                /* This actually clears the dirty bit in the radix
@@ -368,7 +367,6 @@ static int vvp_page_make_ready(const struct lu_env *env,
                              pg->cp_state);
                LBUG();
        }
-       unlock_page(vmpage);
        RETURN(result);
 }
 
index 86c9f6d..af52311 100644 (file)
@@ -1074,14 +1074,16 @@ int cl_page_make_ready(const struct lu_env *env, struct cl_page *cl_page,
                        enum cl_req_type crt)
 {
        const struct cl_page_slice *slice;
+       struct page *vmpage = cl_page->cp_vmpage;
        int result = 0;
        int i;
 
-        ENTRY;
+       ENTRY;
        PINVRNT(env, cl_page, crt < CRT_NR);
        if (crt >= CRT_NR)
                RETURN(-EINVAL);
 
+       lock_page(vmpage);
        cl_page_slice_for_each(cl_page, slice, i) {
                if (slice->cpl_ops->io[crt].cpo_make_ready != NULL)
                        result = (*slice->cpl_ops->io[crt].cpo_make_ready)(env, slice);
@@ -1094,6 +1096,7 @@ int cl_page_make_ready(const struct lu_env *env, struct cl_page *cl_page,
                PASSERT(env, cl_page, cl_page->cp_state == CPS_CACHED);
                cl_page_io_start(env, cl_page, crt);
         }
+       unlock_page(vmpage);
        CL_PAGE_HEADER(D_TRACE, env, cl_page, "%d %d\n", crt, result);
 
        RETURN(result);