Whamcloud - gitweb
EX-2873 pcc: don't fallback sync attach for EINPROGRESS error
authorQian Yingjin <qian@ddn.com>
Wed, 31 Mar 2021 09:44:06 +0000 (17:44 +0800)
committerLi Xi <lixi@ddn.com>
Fri, 14 May 2021 07:59:57 +0000 (07:59 +0000)
When a file is read-only attaching into PCC backend in background
with asynchronous mode by a thread, other threads trying to open
attach the same file will get -EINPROGRESS error code. It should
tolerate this erorr instead of falling back to synchronous attach
mode.

For asynchronous open attach, it can not reuse the Lustre file
handle directly for data copy when the file is opening for read
as the file position in the file handle can not be shread by the
user thread and the asynchronous attach thread in kernel on the
background. It needs reopen the file without O_DIRECT flag and
use the new Lustre file handle to do data copy from Lustre OSTs
to the PCC copy.

As i_size_read(inode) without stat() call sometimes returns zero
value, not the actual file size value. This may result in wrong
open attach action. Also it does not know whether the lazysize is
always going to be set. Thus, in this patch it uses max(lazysize,
i_size_read(inode)) to determine whether do open attach in
background asynchronously.

Signed-off-by: Qian Yingjin <qian@ddn.com>
Change-Id: I80b88a8ba05af4af45433ba9be5b87854e116b10
Reviewed-on: https://review.whamcloud.com/43180
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Li Xi <lixi@ddn.com>
lustre/llite/pcc.c
lustre/tests/sanity-pcc.sh

index 893f1a5..8923f30 100644 (file)
@@ -1651,14 +1651,33 @@ static int pcc_readonly_attach(struct file *file, struct inode *inode,
 static int pcc_readonly_attach_thread(void *arg)
 {
        struct pcc_attach_context *pccx = (struct pcc_attach_context *)arg;
+       struct file *file = pccx->pccx_file;
        int rc;
 
        ENTRY;
 
-       rc = pcc_readonly_attach(pccx->pccx_file, pccx->pccx_inode,
-                                pccx->pccx_attach_id);
+       /*
+        * For asynchronous open attach, it can not reuse the Lustre file
+        * handle directly when the file is opening for read as the file
+        * position in the file handle can not be shared by both user thread
+        * and asynchronous attach thread in kenerl on the background.
+        * It must reopen the file without O_DIRECT flag and use this new
+        * file hanlde to do data copy from Lustre OSTs to the PCC copy.
+        */
+       file = dentry_open(&file->f_path, file->f_flags & ~O_DIRECT,
+                          pcc_super_cred(pccx->pccx_inode->i_sb));
+       if (IS_ERR_OR_NULL(file))
+               GOTO(out, rc = file == NULL ? -EINVAL : PTR_ERR(file));
+
+       rc = pcc_readonly_attach(file, pccx->pccx_inode, pccx->pccx_attach_id);
        pcc_readonly_attach_fini(pccx->pccx_inode);
        pcc_attach_context_free(pccx);
+       fput(file);
+out:
+       CDEBUG(D_CACHE, "PCC-RO attach in background for %pd "DFID" rc = %d\n",
+              file_dentry(pccx->pccx_file),
+              PFID(ll_inode2fid(pccx->pccx_inode)), rc);
+
        RETURN(rc);
 }
 
@@ -1706,11 +1725,16 @@ static int pcc_readonly_attach_sync(struct file *file,
 static inline int pcc_do_readonly_attach(struct file *file,
                                         struct inode *inode, __u32 roid)
 {
-       int rc = 0;
+       int rc;
+
+       if (max_t(__u64, ll_i2info(inode)->lli_lazysize, i_size_read(inode)) >=
+           ll_i2pccs(inode)->pccs_async_threshold) {
+               rc = pcc_readonly_attach_async(file, inode, roid);
+               if (!rc || rc == -EINPROGRESS)
+                       return rc;
+       }
 
-       if (i_size_read(inode) <= ll_i2pccs(inode)->pccs_async_threshold ||
-           pcc_readonly_attach_async(file, inode, roid))
-               rc = pcc_readonly_attach_sync(file, inode, roid);
+       rc = pcc_readonly_attach_sync(file, inode, roid);
 
        return rc;
 }
index f4f5933..8e0a4a5 100644 (file)
@@ -3066,14 +3066,14 @@ test_40() {
        local file=$dir/$tfile
        local id=100
 
-       setup_loopdev $SINGLEAGT $loopfile $mntpt 50
+       setup_loopdev $SINGLEAGT $loopfile $mntpt 200
        do_facet $SINGLEAGT mkdir $hsm_root || error "mkdir $hsm_root failed"
        setup_pcc_mapping $SINGLEAGT \
                "projid={$id}\ roid=$HSM_ARCHIVE_NUMBER\ ropcc=1"
        do_facet $SINGLEAGT $LCTL pcc list $MOUNT
 
        mkdir -p $dir || error "mkdir $dir failed"
-       do_facet $SINGLEAGT dd if=/dev/zero of=$file bs=1M count=30 ||
+       do_facet $SINGLEAGT dd if=/dev/zero of=$file bs=1M count=50 ||
                error "Write $file failed"
 
        $LFS project -p $id $file || error "failed to set project for $file"
@@ -3085,6 +3085,7 @@ test_40() {
        do_facet $SINGLEAGT $LCTL set_param osc.*.stats=clear
        #define OBD_FAIL_OST_BRW_PAUSE_BULK
        set_nodes_failloc "$(osts_nodes)" 0x214 1
+       echo 3 > /proc/sys/vm/drop_caches
 
        local stime
        local time1
@@ -3139,18 +3140,21 @@ test_40() {
        do_facet $SINGLEAGT $LCTL set_param llite.*.pcc_async_threshold=5MB
        do_facet $SINGLEAGT $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
 
+       echo "Read 1MB data with async_threshold=5MB"
        stime=$SECONDS
        do_facet $SINGLEAGT dd if=$file of=/dev/null bs=1M count=1 iflag=direct
        time1=$((SECONDS - stime))
+       wait_readonly_attach_fini $file
 
        do_facet $SINGLEAGT $LFS pcc detach $file
        do_facet $SINGLEAGT $LFS pcc state $file
        do_facet $SINGLEAGT $LCTL set_param llite.*.pcc_async_threshold=1G
        do_facet $SINGLEAGT $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
 
+       echo "Read 1MB data with async_threshold=1G"
        stime=$SECONDS
        do_facet $SINGLEAGT dd if=$file of=/dev/null bs=1M count=1 iflag=direct
-       time1=$((SECONDS - stime))
+       time2=$((SECONDS - stime))
 
        echo "Time1: $time1 Time2: $time2"
        [ $time1 -le $time2 ] ||