From 11eef3f7353313b573f00cae924a9cfaecf7de3d Mon Sep 17 00:00:00 2001 From: Qian Yingjin Date: Thu, 25 Feb 2021 20:43:58 +0800 Subject: [PATCH] LU-10499 pcc: get PCC state for a file without opening itself Originally to get PCC state for a given file, the user needs to open the file and then get the current PCC state of the file via the file handle. After that, close the file. If the file is met the predefined condition of auto prefetching into PCC at the open time, "lfs pcc state" command on the file will attach the file into PCC cache. This may be not the intention of the user. In this patch, we rework the "lfs pcc state" command. It always open the parent directory, and then do the lookup by name/FID without open the file itself to get the PCC state. EX-5358 pcc: remove realpath() from lfs_pcc_state() Before Ubuntu 20.04, realpath() executes lstat() for each component of the path. If the file is still valid cached on PCC device with the layout generation unchanged, the Lustre file will be auto re-attach during the stat() call in the Lustre kernel. This may result in misunderstanding for the operation "lfs pcc state" on a file that has already detached but still valid cached on PCC according to the unchanged layout generation. This problem exposes on the newer Ubuntu 22.04 in which realpath() executes readlink() for each component of the path instead of lstat(): readlink("/mnt", 0x7fffd5760800, 1023) = -1 readlink("/mnt/lustre", 0x7fffd5760800, 1023) = -1 readlink("/mnt/lustre/sanity-pcc.f15", 0x7fffd5760800, 1023) = -1 Was-Change-Id: I50ae46a1e952a3faaf0d7a7293579e239156d6d3 LU-16030 pcc: enlarge PCC backend size for sanity-pcc script In this patch, it removes realpath() from lfs_pcc_state() to avoid this misunderstanding behavior for the command: $LFS pcc state. And it also fixes the test scripts sanity-pcc: test_15, test_16, test_27, test_39. Was-Change-Id: Ib19f01ed054cb6c9eecceabea1f1da72dea0b113 EX-bug-id: EX-2455 EX-5358 LU-16030 Test-Parameters: clientcount=3 testlist=sanity-pcc,sanity-pcc,sanity-pcc Signed-off-by: Qian Yingjin Change-Id: I310a7e73dc6c0f4318dc27df2e02ecf6559ee5b4 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/54372 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Li Xi Reviewed-by: Oleg Drokin Reviewed-by: Andreas Dilger --- lustre/include/uapi/linux/lustre/lustre_user.h | 10 +-- lustre/llite/dir.c | 75 ++++++++++++++++++ lustre/llite/file.c | 2 + lustre/llite/pcc.c | 13 +++- lustre/ptlrpc/wiretest.c | 8 +- lustre/tests/sanity-pcc.sh | 103 ++++++++++++++++++++++--- lustre/utils/lfs.c | 11 +-- lustre/utils/liblustreapi.c | 2 +- lustre/utils/liblustreapi_pcc.c | 30 ++++++- lustre/utils/lustreapi_internal.h | 3 + lustre/utils/wirecheck.c | 2 +- lustre/utils/wiretest.c | 8 +- 12 files changed, 225 insertions(+), 42 deletions(-) diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index 2aa68cb..3904e44 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -3027,11 +3027,11 @@ enum lu_pcc_state_flags { }; struct lu_pcc_state { - __u32 pccs_type; /* enum lu_pcc_type */ - __u32 pccs_open_count; - __u32 pccs_flags; /* enum lu_pcc_state_flags */ - __u32 pccs_padding; - char pccs_path[PATH_MAX]; + __u32 pccs_type; /* OUT: enum lu_pcc_type */ + __u32 pccs_open_count; /* OUT: user count */ + __u32 pccs_flags; /* OUT: enum lu_pcc_state_flags */ + __u32 pccs_namelen; /* IN: file name len */ + char pccs_path[PATH_MAX]; /* IN|OUT: file name or path buffer */ }; enum lu_pcc_cleanup_flags { diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index bff67ce..3c68ef5 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -2767,6 +2767,81 @@ out_ladvise: OBD_FREE_PTR(ladvise); RETURN(rc); } + case LL_IOC_PCC_STATE: { + struct lu_pcc_state __user *ustate = + (struct lu_pcc_state __user *)arg; + struct lu_pcc_state *state; + struct dentry *parent = file_dentry(file); + struct dentry *dchild = NULL; + struct inode *child_inode = NULL; + struct qstr qstr; + int namelen = 0; + char *name; + + OBD_ALLOC_PTR(state); + if (state == NULL) + RETURN(-ENOMEM); + + if (copy_from_user(state, ustate, sizeof(*state))) + GOTO(out_free, rc = -EFAULT); + + name = state->pccs_path; + namelen = strlen(name); + if (namelen < 0 || state->pccs_namelen != namelen + 1) { + CDEBUG(D_INFO, "IOC_PCC_STATE missing filename\n"); + GOTO(out_state_free, rc = -EINVAL); + } + + /* Get Child from dcache first. */ + qstr.hash = ll_full_name_hash(parent, name, namelen); + qstr.name = name; + qstr.len = namelen; + dchild = d_lookup(parent, &qstr); + if (dchild) { + if (dchild->d_inode) + child_inode = igrab(dchild->d_inode); + dput(dchild); + } + + if (!child_inode) { + unsigned long ino; + struct lu_fid fid; + + rc = ll_get_fid_by_name(parent->d_inode, name, namelen, + &fid, NULL); + if (rc) + GOTO(out_state_free, rc); + + ino = cl_fid_build_ino(&fid, ll_need_32bit_api(sbi)); + child_inode = ilookup5(inode->i_sb, ino, + ll_test_inode_by_fid, &fid); + } + + if (!child_inode) { + /* + * Target inode is not in inode cache, the + * corresponding PCC file may be already released, + * return immediately. + */ + state->pccs_type = LU_PCC_NONE; + GOTO(out_copy_to, rc = 0); + } + + if (!S_ISREG(child_inode->i_mode)) + GOTO(out_child_iput, rc = -EINVAL); + + rc = pcc_ioctl_state(NULL, child_inode, state); + if (rc) + GOTO(out_child_iput, rc); +out_copy_to: + if (copy_to_user(ustate, state, sizeof(*state))) + GOTO(out_child_iput, rc = -EFAULT); +out_child_iput: + iput(child_inode); +out_state_free: + OBD_FREE_PTR(state); + RETURN(rc); + } case LL_IOC_PCC_DETACH_BY_FID: { struct lu_pcc_detach_fid *detach; struct lu_fid *fid; diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 91aa134..162099b 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -4911,6 +4911,7 @@ out_detach_free: OBD_FREE_PTR(detach); RETURN(rc); } +#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 18, 53, 0) case LL_IOC_PCC_STATE: { struct lu_pcc_state __user *ustate = uarg; struct lu_pcc_state *state; @@ -4933,6 +4934,7 @@ out_state: OBD_FREE_PTR(state); RETURN(rc); } +#endif default: rc = ll_iocontrol(inode, file, cmd, uarg); if (rc != -ENOTTY) diff --git a/lustre/llite/pcc.c b/lustre/llite/pcc.c index 3ddb2a5..5f4cf07 100644 --- a/lustre/llite/pcc.c +++ b/lustre/llite/pcc.c @@ -3730,8 +3730,6 @@ int pcc_ioctl_state(struct file *file, struct inode *inode, char *buf; char *path; int buf_len = sizeof(state->pccs_path); - struct ll_file_data *fd = file->private_data; - struct pcc_file *pccf = &fd->fd_pcc_file; struct pcc_inode *pcci; ENTRY; @@ -3759,8 +3757,15 @@ int pcc_ioctl_state(struct file *file, struct inode *inode, if (pcc_inode_has_layout(pcci)) count--; - if (pccf->pccf_file != NULL) - count--; + + if (file) { + struct ll_file_data *fd = file->private_data; + struct pcc_file *pccf = &fd->fd_pcc_file; + + if (pccf->pccf_file != NULL) + count--; + } + state->pccs_type = pcci->pcci_type; state->pccs_open_count = count; state->pccs_flags = ll_i2info(inode)->lli_pcc_state; diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 8f76dc8..4292383 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -7067,10 +7067,10 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct lu_pcc_state, pccs_flags)); LASSERTF((int)sizeof(((struct lu_pcc_state *)0)->pccs_flags) == 4, "found %lld\n", (long long)(int)sizeof(((struct lu_pcc_state *)0)->pccs_flags)); - LASSERTF((int)offsetof(struct lu_pcc_state, pccs_padding) == 12, "found %lld\n", - (long long)(int)offsetof(struct lu_pcc_state, pccs_padding)); - LASSERTF((int)sizeof(((struct lu_pcc_state *)0)->pccs_padding) == 4, "found %lld\n", - (long long)(int)sizeof(((struct lu_pcc_state *)0)->pccs_padding)); + LASSERTF((int)offsetof(struct lu_pcc_state, pccs_namelen) == 12, "found %lld\n", + (long long)(int)offsetof(struct lu_pcc_state, pccs_namelen)); + LASSERTF((int)sizeof(((struct lu_pcc_state *)0)->pccs_namelen) == 4, "found %lld\n", + (long long)(int)sizeof(((struct lu_pcc_state *)0)->pccs_namelen)); LASSERTF((int)offsetof(struct lu_pcc_state, pccs_path) == 16, "found %lld\n", (long long)(int)offsetof(struct lu_pcc_state, pccs_path)); LASSERTF((int)sizeof(((struct lu_pcc_state *)0)->pccs_path) == 4096, "found %lld\n", diff --git a/lustre/tests/sanity-pcc.sh b/lustre/tests/sanity-pcc.sh index 820b10a..65d412a 100755 --- a/lustre/tests/sanity-pcc.sh +++ b/lustre/tests/sanity-pcc.sh @@ -1441,12 +1441,18 @@ test_15() { # detached automatically. do_facet $SINGLEAGT $LCTL \ set_param ldlm.namespaces.*mdc*.lru_size=clear + check_lpcc_state $file "none" $SINGLEAGT "$RUNAS" + do_facet $SINGLEAGT $RUNAS $MULTIOP $file oc || + error "failed to open $file" check_lpcc_state $file "readwrite" $SINGLEAGT "$RUNAS" # Detach the file but keep the cache , as the file layout generation # is not changed, so the file is still valid cached in PCC, and can # be reused from PCC cache directly. do_facet $SINGLEAGT $RUNAS $LFS pcc detach -k $file || error "PCC detach $file failed" + check_lpcc_state $file "none" $SINGLEAGT "$RUNAS" + do_facet $SINGLEAGT $RUNAS $MULTIOP $file oc || + error "failed to open $file" check_lpcc_state $file "readwrite" $SINGLEAGT "$RUNAS" do_facet $SINGLEAGT $RUNAS $LFS pcc detach $file || error "PCC detach $file failed" @@ -1470,6 +1476,8 @@ test_15() { # and can be reused from PCC cache directly. do_facet $SINGLEAGT $LFS pcc detach -k $file || error "RW-PCC detach $file failed" + check_lpcc_state $file "none" + do_facet $SINGLEAGT $MULTIOP $file oc || error "failed to open $file" check_lpcc_state $file "readwrite" # HSM released exists archived status check_hsm_flags $file "0x0000000d" @@ -1500,6 +1508,8 @@ test_15() { # and can be reused from PCC cache directly. do_facet $SINGLEAGT $LFS pcc detach -k $file || error "RO-PCC detach $file failed" + check_lpcc_state $file "none" + do_facet $SINGLEAGT $MULTIOP $file oc || error "failed to open $file" check_lpcc_state $file "readonly" check_file_data $SINGLEAGT $file "autoattach_data" do_facet $SINGLEAGT $LFS pcc detach $file || @@ -1534,7 +1544,7 @@ test_16() { # Valid PCC cache can be reused do_facet $SINGLEAGT $LFS pcc detach -k $file || error "PCC detach $file failed" - check_lpcc_state $file "readwrite" + check_lpcc_state $file "none" # HSM released exists archived status check_hsm_flags $file "0x0000000d" @@ -1556,6 +1566,9 @@ test_16() { do_facet $SINGLEAGT $LFS pcc detach -k $file || error "RO-PCC detach $file failed" + check_lpcc_state $file "none" + # Reading the file will re-attach the file in readonly mode + do_facet $SINGLEAGT cat $file || error "cat $file failed" check_lpcc_state $file "readonly" do_facet $SINGLEAGT $LFS pcc detach $file || @@ -1696,7 +1709,7 @@ test_20() { local hsm_root="$mntpt/$tdir" local file=$DIR/$tfile - setup_loopdev $SINGLEAGT $loopfile $mntpt 50 + setup_loopdev $SINGLEAGT $loopfile $mntpt 120 copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER" setup_pcc_mapping $SINGLEAGT \ "projid={100}\ rwid=$HSM_ARCHIVE_NUMBER\ pccrw=1" @@ -2473,7 +2486,7 @@ test_27() { rmultiop_start $agt_host $file O_c || error "multiop $file failed" do_facet $SINGLEAGT $LFS pcc detach -k $file || error "detach $file failed" - check_lpcc_state $file "readwrite" + check_lpcc_state $file "none" check_file_data $SINGLEAGT $file "auto_attach_multi_open" check_lpcc_state $file "readwrite" do_facet $SINGLEAGT $LFS pcc detach $file || @@ -2490,7 +2503,7 @@ test_27() { rmultiop_start $agt_host $file O_c || error "multiop $file failed" do_facet $SINGLEAGT $LCTL \ set_param ldlm.namespaces.*mdc*.lru_size=clear - check_lpcc_state $file "readwrite" + check_lpcc_state $file "none" check_file_data $SINGLEAGT $file "auto_attach_multi_open" check_lpcc_state $file "readwrite" do_facet $SINGLEAGT $LFS pcc detach $file || @@ -2505,7 +2518,7 @@ test_27() { rmultiop_start $agt_host $file O_c || error "multiop $file failed" do_facet $SINGLEAGT $LFS pcc detach -k $file || error "detach $file failed" - check_lpcc_state $file "readonly" + check_lpcc_state $file "none" check_file_data $SINGLEAGT $file "auto_attach_multi_open" check_lpcc_state $file "readonly" do_facet $SINGLEAGT $LFS pcc detach $file || @@ -2519,7 +2532,7 @@ test_27() { rmultiop_start $agt_host $file O_c || error "multiop $file failed" do_facet $SINGLEAGT $LCTL \ set_param ldlm.namespaces.*mdc*.lru_size=clear - check_lpcc_state $file "readonly" + check_lpcc_state $file "none" check_file_data $SINGLEAGT $file "auto_attach_multi_open" check_lpcc_state $file "readonly" do_facet $SINGLEAGT $LFS pcc detach $file || @@ -2599,12 +2612,14 @@ test_29a() { $LFS project -sp $project_id $file || error "failed to set project for $file" $LFS project -d $file + check_file_data $SINGLEAGT $file "ro_uptodate" check_lpcc_state $file "readonly" check_file_data $SINGLEAGT $file "ro_uptodate" echo -n Update_ro_data > $file2 - check_lpcc_state $file "readonly" + check_lpcc_state $file "none" check_file_data $SINGLEAGT $file "Update_ro_data" + check_lpcc_state $file "readonly" do_facet $SINGLEAGT $LFS pcc detach $file || error "failed to detach $file" @@ -2811,20 +2826,30 @@ test_33() { do_facet $SINGLEAGT $LCTL pcc list $MOUNT touch $file || error "touch $file failed" $TRUNCATE $file $((1048576 * 2)) || error "Truncate $file failed" + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "none" do_facet $SINGLEAGT $LFS pcc state $file $TRUNCATE $file $((1048576 / 2)) || error "Truncate $file failed" do_facet $SINGLEAGT $LFS pcc state $file + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "readonly" cleanup_pcc_mapping setup_pcc_mapping $SINGLEAGT \ "fname={*.doc}\&size\<{5M}\&size\>{3M}\ roid=5\ pccro=1" do_facet $SINGLEAGT $LCTL pcc list $MOUNT + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "none" $TRUNCATE $file2 $((1048576 * 6)) || error "Truncate $file2 failed" + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "none" $TRUNCATE $file2 $((1048576 * 4)) || error "Truncate $file2 failed" + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "readonly" cleanup_pcc_mapping @@ -2873,39 +2898,59 @@ test_34() { do_facet $SINGLEAGT $LCTL pcc list $MOUNT do_facet $SINGLEAGT "echo -n QQQQQ > $file" || error "failed to write $file" + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "none" $LFS project -p 99 $file || error "failed to set project for $file" $LFS project -d $file + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "none" $LFS project -p 101 $file || error "failed to set project for $file" $LFS project -d $file + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "readonly" cleanup_pcc_mapping setup_pcc_mapping $SINGLEAGT \ "projid\<{100}\ roid=5\ ropcc=1" do_facet $SINGLEAGT $LCTL pcc list $MOUNT + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "none" $LFS project -p 102 $file || error "failed to set project for $file" $LFS project -d $file + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "none" $LFS project -p 99 $file || error "failed to set project for $file" $LFS project -d $file + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "readonly" cleanup_pcc_mapping setup_pcc_mapping $SINGLEAGT \ "projid\<{120}\&projid\>{110}\ roid=5\ ropcc=1" do_facet $SINGLEAGT $LCTL pcc list $MOUNT + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "none" $LFS project -p 105 $file || error "failed to set project for $file" $LFS project -d $file + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "none" $LFS project -p 121 $file || error "failed to set project for $file" $LFS project -d $file + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "none" $LFS project -p 115 $file || error "failed to set project for $file" $LFS project -d $file + do_facet $SINGLEAGT $MULTIOP $file oc || + error "failed to readonly open $file" check_lpcc_state $file "readonly" cleanup_pcc_mapping } @@ -3030,6 +3075,40 @@ test_37() { } run_test 37 "Multiple readers on a shared file with PCC-RO mode" +test_38() { + local loopfile="$TMP/$tfile" + local mntpt="/mnt/pcc.$tdir" + local hsm_root="$mntpt/$tdir" + local dir=$DIR/$tdir + local file=$dir/$tfile + + $LCTL get_param -n mdc.*.connect_flags | grep -q pcc_ro || + skip "Server does not support PCC-RO" + + is_project_quota_supported || skip "project quota is not supported" + + enable_project_quota + mkdir $dir || error "mkdir $dir failed" + $LFS project -sp 100 $dir || + error "failed to set project for $dir" + echo "QQQQQ" > $file + + setup_loopdev $SINGLEAGT $loopfile $mntpt 50 + do_facet $SINGLEAGT mkdir $hsm_root || error "mkdir $hsm_root failed" + setup_pcc_mapping $SINGLEAGT \ + "projid={100}\ roid=$HSM_ARCHIVE_NUMBER\ pccro=1" + + do_facet $SINGLEAGT $LFS pcc state $file || + error "failed to get PCC state for $file" + check_lpcc_state $file "none" + do_facet $SINGLEAGT cat $file || error "cat $file failed" + check_lpcc_state $file "readonly" + do_facet $SINGLEAGT $LFS pcc detach $file || + error "failed to detach $file" + check_lpcc_state $file "none" +} +run_test 38 "Verify LFS pcc state does not trigger prefetch for auto PCC-RO" + test_41() { local loopfile="$TMP/$tfile" local mntpt="/mnt/pcc.$tdir" @@ -3042,7 +3121,7 @@ test_41() { setup_loopdev $SINGLEAGT $loopfile $mntpt 50 do_facet $SINGLEAGT mkdir $hsm_root || error "mkdir $hsm_root failed" setup_pcc_mapping $SINGLEAGT \ - "mtime\>{1m}\ roid=$HSM_ARCHIVE_NUMBER\ ropcc=1" + "mtime\>{1m}\ roid=$HSM_ARCHIVE_NUMBER\ pccro=1" do_facet $SINGLEAGT $LCTL pcc list $MOUNT echo "pcc_ro_data" > $file || error "echo $file failed" @@ -3129,12 +3208,18 @@ test_101a() { # Revoke the layout lock, the PCC-cached file will be # detached automatically. do_facet $SINGLEAGT $LCTL set_param ldlm.namespaces.*mdc*.lru_size=clear + check_lpcc_state $file "none" $SINGLEAGT "$RUNAS" + do_facet $SINGLEAGT $RUNAS $MULTIOP $file oc || + error "failed to open $file" check_lpcc_state $file "readwrite" $SINGLEAGT "$RUNAS" # Detach the file but keep the cache, as the file layout generation # is not changed, so the file is still valid cached in PCC, and can # be reused from PCC cache directly. do_facet $SINGLEAGT nsenter -t $PID -U -m $LFS pcc detach -k $file || error "PCC detach $file failed" + check_lpcc_state $file "none" $SINGLEAGT "$RUNAS" + do_facet $SINGLEAGT nsenter -t $PID -U -m $MULTIOP $file oc || + error "failed to open $file" check_lpcc_state $file "readwrite" $SINGLEAGT "$RUNAS" do_facet $SINGLEAGT nsenter -t $PID -U -m $LFS pcc detach $file || error "PCC detach $file failed" @@ -3167,10 +3252,10 @@ test_101a() { # and can be reused from PCC cache directly. do_facet $SINGLEAGT $LFS pcc detach -k $file || error "RW-PCC detach $file failed" - check_lpcc_state $file "readwrite" # HSM released exists archived status check_hsm_flags $file "0x0000000d" check_file_data $SINGLEAGT $file "autoattach_data" $PID + check_lpcc_state $file "readwrite" # HSM restore the PCC cached file, the layout generation # was changed, so the file can not be auto attached. diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index cf38041..002acdf 100755 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -13868,7 +13868,6 @@ static int lfs_pcc_state(int argc, char **argv) { int rc = 0; const char *path; - char fullpath[PATH_MAX]; struct lu_pcc_state state; optind = 1; @@ -13883,15 +13882,7 @@ static int lfs_pcc_state(int argc, char **argv) int rc2; path = argv[optind++]; - if (!realpath(path, fullpath)) { - fprintf(stderr, "%s: could not find path '%s': %s\n", - argv[0], path, strerror(errno)); - if (rc == 0) - rc = -EINVAL; - continue; - } - - rc2 = llapi_pcc_state_get(fullpath, &state); + rc2 = llapi_pcc_state_get(path, &state); if (rc2 < 0) { if (rc == 0) rc = rc2; diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 5231561..2693b3e 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -1567,7 +1567,7 @@ static int cb_common_fini(char *path, int p, int *dp, void *data, } /* set errno upon failure */ -static int open_parent(const char *path) +int open_parent(const char *path) { char *path_copy; char *parent_path; diff --git a/lustre/utils/liblustreapi_pcc.c b/lustre/utils/liblustreapi_pcc.c index cb1e312..2e6a2ec 100644 --- a/lustre/utils/liblustreapi_pcc.c +++ b/lustre/utils/liblustreapi_pcc.c @@ -373,7 +373,7 @@ int llapi_pcc_detach_file(const char *path, __u32 flags) /** * Return the current PCC state related to a file. * - * \param fd File handle. + * \param fd File handle for the parent directory. * \param state PCC state info. * * \return 0 on success, an error code otherwise. @@ -396,16 +396,38 @@ int llapi_pcc_state_get_fd(int fd, struct lu_pcc_state *state) */ int llapi_pcc_state_get(const char *path, struct lu_pcc_state *state) { + char *path_copy; + char *filename; int fd; int rc; - fd = open(path, O_RDONLY | O_NONBLOCK); - if (fd < 0) - return -errno; + fd = open_parent(path); + if (fd == -1) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, "can not open %s", path); + return rc; + } + + path_copy = strdup(path); + if (path_copy == NULL) { + close(fd); + return -ENOMEM; + } + + filename = basename(path_copy); + state->pccs_namelen = strlen(filename) + 1; + strncpy(state->pccs_path, filename, sizeof(state->pccs_path) - 1); rc = llapi_pcc_state_get_fd(fd, state); + if (rc != 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, "Get PCC state on %s failed", + path); + } close(fd); + free(path_copy); + return rc; } diff --git a/lustre/utils/lustreapi_internal.h b/lustre/utils/lustreapi_internal.h index 0cea0d5..7e1dd40 100644 --- a/lustre/utils/lustreapi_internal.h +++ b/lustre/utils/lustreapi_internal.h @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -204,4 +205,6 @@ int get_lmd_info_fd(const char *path, int parentfd, int dirfd, void *lmd_buf, int lmd_len, enum get_lmd_info_type type); int lov_comp_md_size(struct lov_comp_md_v1 *lcm); + +int open_parent(const char *path); #endif /* _LUSTREAPI_INTERNAL_H_ */ diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 09729de..0799f77 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -3320,7 +3320,7 @@ static void check_lu_pcc_state(void) CHECK_MEMBER(lu_pcc_state, pccs_type); CHECK_MEMBER(lu_pcc_state, pccs_open_count); CHECK_MEMBER(lu_pcc_state, pccs_flags); - CHECK_MEMBER(lu_pcc_state, pccs_padding); + CHECK_MEMBER(lu_pcc_state, pccs_namelen); CHECK_MEMBER(lu_pcc_state, pccs_path); } diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 8b2660e..0876eda 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -7092,10 +7092,10 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct lu_pcc_state, pccs_flags)); LASSERTF((int)sizeof(((struct lu_pcc_state *)0)->pccs_flags) == 4, "found %lld\n", (long long)(int)sizeof(((struct lu_pcc_state *)0)->pccs_flags)); - LASSERTF((int)offsetof(struct lu_pcc_state, pccs_padding) == 12, "found %lld\n", - (long long)(int)offsetof(struct lu_pcc_state, pccs_padding)); - LASSERTF((int)sizeof(((struct lu_pcc_state *)0)->pccs_padding) == 4, "found %lld\n", - (long long)(int)sizeof(((struct lu_pcc_state *)0)->pccs_padding)); + LASSERTF((int)offsetof(struct lu_pcc_state, pccs_namelen) == 12, "found %lld\n", + (long long)(int)offsetof(struct lu_pcc_state, pccs_namelen)); + LASSERTF((int)sizeof(((struct lu_pcc_state *)0)->pccs_namelen) == 4, "found %lld\n", + (long long)(int)sizeof(((struct lu_pcc_state *)0)->pccs_namelen)); LASSERTF((int)offsetof(struct lu_pcc_state, pccs_path) == 16, "found %lld\n", (long long)(int)offsetof(struct lu_pcc_state, pccs_path)); LASSERTF((int)sizeof(((struct lu_pcc_state *)0)->pccs_path) == 4096, "found %lld\n", -- 1.8.3.1