Whamcloud - gitweb
LU-17653 sec: avoid unlocking unlocked page 34/54734/6
authorShaun Tancheff <shaun.tancheff@hpe.com>
Thu, 11 Apr 2024 14:03:30 +0000 (22:03 +0800)
committerOleg Drokin <green@whamcloud.com>
Wed, 5 Jun 2024 04:44:30 +0000 (04:44 +0000)
If a page is unlocked by @cl_2queue_disown after explictly write the
newly modified page, the following page_unlock must not be performed.

Track the page locked state and do not unlock pages which
are not locked in ll_io_zero_page()

Fixes: adf46db962 ("LU-12275 sec: support truncate for encrypted file")
Test-Parameters: testlist=sanity-sec clientdistro=el9.3 env=ONLY=48a,ONLY_REPEAT=10
Test-Parameters: testlist=sanity-sec clientdistro=el9.3
Signed-off-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Signed-off-by: Qian Yingjin <qian@ddn.com>
Change-Id: I6e121920c7e86e4d0004def77b0ce066ae2ba81a
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/54734
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Reviewed-by: Patrick Farrell <patrick.farrell@oracle.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/llite_lib.c

index a99cd35..5a196d3 100644 (file)
@@ -2079,6 +2079,7 @@ static int ll_io_zero_page(struct inode *inode, pgoff_t index, pgoff_t offset,
        struct cl_2queue *queue = NULL;
        struct cl_sync_io *anchor = NULL;
        bool holdinglock = false;
+       bool page_locked = false;
        int rc;
 
        ENTRY;
@@ -2120,6 +2121,7 @@ static int ll_io_zero_page(struct inode *inode, pgoff_t index, pgoff_t offset,
        if (vmpage == NULL)
                GOTO(rellock, rc = -EOPNOTSUPP);
 
+       page_locked = true;
        if (!PageDirty(vmpage)) {
                /* associate cl_page */
                clpage = cl_page_find(env, clob, vmpage->index,
@@ -2181,13 +2183,17 @@ queuefini2:
 queuefini1:
                cl_2queue_disown(env, queue);
                cl_2queue_fini(env, queue);
+               /* The page was unlocked by queue disown. */
+               page_locked = false;
        }
 
 clpfini:
        if (clpage)
                cl_page_put(env, clpage);
 pagefini:
-       unlock_page(vmpage);
+       if (page_locked)
+               unlock_page(vmpage);
+       page_locked = false;
        put_page(vmpage);
 rellock:
        if (holdinglock)