From 3fcc8bc896c548e7651bf279041b5fd6234c4989 Mon Sep 17 00:00:00 2001 From: Qian Yingjin Date: Wed, 29 Sep 2021 11:35:30 +0800 Subject: [PATCH] LU-10499 pcc: Check if PCC copy is unlinked for state output In this patch, it adds support for the command "lfs pcc state" to check whether the PCC copy is in the local client cache or unlinked improperly. Do not print an error message if "lfs pcc detach" tries to detach a file that is already removed from the cache. This might happen for a wide variety of reasons (external cache cleanup process, etc). EX-bug-id: EX-3825 Test-Parameters: testlist=sanity-pcc env=ONLY=48 Signed-off-by: Qian Yingjin Change-Id: Ic50c901df78adfaf5b56990120f832e5d74a117c Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/54451 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin Reviewed-by: Andreas Dilger Reviewed-by: Li Xi Reviewed-by: James Simmons --- lustre/llite/pcc.c | 22 ++++++++++++++++------ lustre/tests/sanity-pcc.sh | 32 ++++++++++++++++++++++++++++++-- lustre/utils/lfs.c | 7 ++++--- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/lustre/llite/pcc.c b/lustre/llite/pcc.c index 64e47e8..308256e 100644 --- a/lustre/llite/pcc.c +++ b/lustre/llite/pcc.c @@ -2401,10 +2401,14 @@ void pcc_file_release(struct inode *inode, struct file *file) goto out; pcci = ll_i2pcci(inode); - LASSERT(pcci); - path = &pcci->pcci_path; - CDEBUG(D_CACHE, "releasing pcc file \"%pd\"\n", path->dentry); - pcc_inode_put(pcci); + if (pcci) { + path = &pcci->pcci_path; + CDEBUG(D_CACHE, "releasing pcc file \"%pd\"\n", path->dentry); + pcc_inode_put(pcci); + } else { + CDEBUG(D_CACHE, "PCC copy "DFID" was unlinked?\n", + PFID(ll_inode2fid(inode))); + } LASSERT(file_count(pccf->pccf_file) > 0); fput(pccf->pccf_file); @@ -3235,8 +3239,8 @@ static int pcc_inode_remove(struct inode *inode, struct dentry *pcc_dentry) int rc; rc = vfs_unlink(&nop_mnt_idmap, d_inode(parent), pcc_dentry); - if (rc) - CWARN("%s: failed to unlink PCC file %pd, rc = %d\n", + if (rc && rc != -ENOENT) + CWARN("%s: failed to unlink PCC file %pd: rc = %d\n", ll_i2sbi(inode)->ll_fsname, pcc_dentry, rc); dput(parent); @@ -4208,6 +4212,12 @@ int pcc_ioctl_state(struct file *file, struct inode *inode, if (IS_ERR(path)) GOTO(out_unlock, rc = PTR_ERR(path)); + if (!pcci->pcci_path.dentry->d_inode || + pcci->pcci_path.dentry->d_inode->i_nlink == 0) { + state->pccs_flags |= PCC_STATE_FL_UNLINKED; + pcc_inode_detach_put(inode); + } + if (strscpy(state->pccs_path, path, buf_len) < 0) GOTO(out_unlock, rc = -ENAMETOOLONG); diff --git a/lustre/tests/sanity-pcc.sh b/lustre/tests/sanity-pcc.sh index 28870a6..ef66f74 100755 --- a/lustre/tests/sanity-pcc.sh +++ b/lustre/tests/sanity-pcc.sh @@ -2807,11 +2807,13 @@ test_32() { sleep 3 do_facet $SINGLEAGT rm $lpcc_path || error "rm $lpcc_path failed" rmultiop_stop $agt_host || error "multiop $file read failed" + + # file will be detached in @pcc_ioctl_state() check_lpcc_state $file "readonly" local content=$(do_facet $SINGLEAGT cat $file) [[ $content == "roattach_removed" ]] || error "data mismatch: $content" - check_lpcc_state $file "readonly" + check_lpcc_state $file "none" do_facet $SINGLEAGT $LFS pcc detach -k $file || error "RO-PCC detach $file failed" check_lpcc_state $file "none" @@ -2819,10 +2821,11 @@ test_32() { do_facet $SINGLEAGT $LFS pcc attach -r -i $HSM_ARCHIVE_NUMBER $file || error "RO-PCC attach $file failed" do_facet $SINGLEAGT rm $lpcc_path || error "rm $lpcc_path failed" + # file will be detached in @pcc_ioctl_state() check_lpcc_state $file "readonly" content=$(do_facet $SINGLEAGT cat $file) [[ $content == "roattach_removed" ]] || error "data mismatch: $content" - check_lpcc_state $file "readonly" + check_lpcc_state $file "none" do_facet $SINGLEAGT $LFS pcc detach -k $file || error "RO-PCC detach $file failed" check_lpcc_state $file "none" @@ -3653,6 +3656,31 @@ test_47() { } run_test 47 "mtime should be kept once file attached into PCC" +test_48() { + local loopfile="$TMP/$tfile" + local mntpt="/mnt/pcc.$tdir" + local hsm_root="$mntpt/$tdir" + local file=$DIR/$tfile + local -a lpcc_path + + setup_loopdev client $loopfile $mntpt 60 + mkdir $hsm_root || error "mkdir $hsm_root failed" + setup_pcc_mapping client \ + "projid={0}\ roid=$HSM_ARCHIVE_NUMBER\ ropcc=1" + + echo "QQQQQ" > $file || error "echo $file failed" + lpcc_path=$(lpcc_fid2path $hsm_root $file) + cat $file || error "cat $file failed" + check_lpcc_state $file "readonly" client + + rm $lpcc_path || error "rm $lpcc_path failed" + $LFS pcc state $file | grep "(unlinked)" || error "$file not unlinked" + [[ "$(cat $file)" =~ "QQQQQ" ]] || error "read $file content failed" + check_lpcc_state $file "readonly" client + $LFS pcc detach $file || error "detach '$file' failed" +} +run_test 48 "PCC state should check whether the file in local PCC cache" + test_96() { local loopfile="$TMP/$tfile" local mntpt="/mnt/pcc.$tdir" diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 0843b0f..054ad65 100755 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -14154,10 +14154,9 @@ static int lfs_pcc_detach(int argc, char **argv) } rc2 = llapi_pcc_detach_file(fullpath, detach_flags); - if (rc2 < 0) { + if (rc2 < 0 && rc2 != -ENOENT) { rc2 = -errno; - fprintf(stderr, - "%s: cannot detach '%s' from PCC: %s\n", + fprintf(stderr, "%s: cannot detach '%s' from PCC: %s\n", argv[0], path, strerror(errno)); if (rc == 0) rc = rc2; @@ -14293,6 +14292,8 @@ static int lfs_pcc_state(int argc, char **argv) } printf(", PCC_file: %s", state.pccs_path); + if (state.pccs_flags & PCC_STATE_FL_UNLINKED) + printf(" (unlinked)"); printf(", open_count: %u", state.pccs_open_count); printf(", flags: %x", state.pccs_flags); printf("\n"); -- 1.8.3.1