From: Qian Yingjin Date: Wed, 31 Mar 2021 09:44:06 +0000 (+0800) Subject: EX-2873 pcc: don't fallback sync attach for EINPROGRESS error X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=403952b901e9c4d26283b982041a3efa0a250262;p=fs%2Flustre-release.git EX-2873 pcc: don't fallback sync attach for EINPROGRESS error 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 Change-Id: I80b88a8ba05af4af45433ba9be5b87854e116b10 Reviewed-on: https://review.whamcloud.com/43180 Tested-by: jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Li Xi --- diff --git a/lustre/llite/pcc.c b/lustre/llite/pcc.c index 893f1a5..8923f30 100644 --- a/lustre/llite/pcc.c +++ b/lustre/llite/pcc.c @@ -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; } diff --git a/lustre/tests/sanity-pcc.sh b/lustre/tests/sanity-pcc.sh index f4f5933..8e0a4a5 100644 --- a/lustre/tests/sanity-pcc.sh +++ b/lustre/tests/sanity-pcc.sh @@ -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 ] ||