From 96dbac2eaef7a5d1090807bedc9951279c06d037 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Thu, 12 Feb 2015 13:53:18 -0600 Subject: [PATCH] LU-4727 hsm: use IOC_MDC_GETFILEINFO in restore Use IOC_MDC_GETFILEINFO rather than fstatat() to get the original file attributes during restore. Add test_12p to sanity-hsm to check that triggering an implicit restore from the copytool's own mount point does not wedge the copytool. Signed-off-by: John L. Hammond Change-Id: I1b1eeb703c60907a2759fdb6d8fb8728a13f8918 Reviewed-on: http://review.whamcloud.com/13750 Tested-by: Jenkins Reviewed-by: Jinshan Xiong Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Henri Doreau Reviewed-by: Oleg Drokin --- lustre/tests/sanity-hsm.sh | 20 ++++++++++++++++ lustre/utils/liblustreapi_hsm.c | 53 ++++++++++++++++++++++++++++++++++------- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/lustre/tests/sanity-hsm.sh b/lustre/tests/sanity-hsm.sh index 53f7f59..76a88ef 100755 --- a/lustre/tests/sanity-hsm.sh +++ b/lustre/tests/sanity-hsm.sh @@ -1385,6 +1385,26 @@ test_12o() { } run_test 12o "Layout-swap failure during Restore leaves file released" +test_12p() { + # test needs a running copytool + copytool_setup + + mkdir $DIR/$tdir + local f=$DIR/$tdir/$tfile + local fid=$(copy_file /etc/hosts $f) + + $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f + wait_request_state $fid ARCHIVE SUCCEED + do_facet $SINGLEAGT cat $f > /dev/null || error "cannot cat $f" + $LFS hsm_release $f || error "cannot release $f" + do_facet $SINGLEAGT cat $f > /dev/null || error "cannot cat $f" + $LFS hsm_release $f || error "cannot release $f" + do_facet $SINGLEAGT cat $f > /dev/null || error "cannot cat $f" + + copytool_cleanup +} +run_test 12p "implicit restore of a file on copytool mount point" + test_13() { # test needs a running copytool copytool_setup diff --git a/lustre/utils/liblustreapi_hsm.c b/lustre/utils/liblustreapi_hsm.c index 835bed4..ebc9183 100644 --- a/lustre/utils/liblustreapi_hsm.c +++ b/lustre/utils/liblustreapi_hsm.c @@ -81,7 +81,7 @@ struct hsm_copyaction_private { __s32 data_fd; const struct hsm_copytool_private *ct_priv; struct hsm_copy copy; - struct stat stat; + lstat_t stat; }; #include @@ -962,17 +962,52 @@ static int ct_open_by_fid(const struct hsm_copytool_private *ct, return fd < 0 ? -errno : fd; } -static int ct_stat_by_fid(const struct hsm_copytool_private *ct, - const struct lu_fid *fid, - struct stat *buf) +/** + * Get metadata attributes of file by FID. + * + * Use the IOC_MDC_GETFILEINFO ioctl (to send a MDS_GETATTR_NAME RPC) + * to get the attributes of the file identified by \a fid. This + * returns only the attributes stored on the MDT and avoids taking + * layout locks or accessing OST objects. It also bypasses the inode + * cache. Attributes are returned in \a st. + */ +static int ct_md_getattr(const struct hsm_copytool_private *ct, + const struct lu_fid *fid, + lstat_t *st) { - char fid_name[FID_NOBRACE_LEN + 1]; + struct lov_user_mds_data *lmd; + size_t lmd_size; int rc; - snprintf(fid_name, sizeof(fid_name), DFID_NOBRACE, PFID(fid)); + lmd_size = sizeof(lmd->lmd_st) + + lov_user_md_size(LOV_MAX_STRIPE_COUNT, LOV_USER_MAGIC_V3); + + if (lmd_size < sizeof(lmd->lmd_st) + XATTR_SIZE_MAX) + lmd_size = sizeof(lmd->lmd_st) + XATTR_SIZE_MAX; + + if (lmd_size < FID_NOBRACE_LEN + 1) + lmd_size = FID_NOBRACE_LEN + 1; + + lmd = malloc(lmd_size); + if (lmd == NULL) + return -ENOMEM; - rc = fstatat(ct->open_by_fid_fd, fid_name, buf, 0); - return rc ? -errno : 0; + snprintf((char *)lmd, lmd_size, DFID_NOBRACE, PFID(fid)); + + rc = ioctl(ct->open_by_fid_fd, IOC_MDC_GETFILEINFO, lmd); + if (rc != 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, + "cannot get metadata attributes of "DFID" in '%s'", + PFID(fid), ct->mnt); + goto out; + } + + *st = lmd->lmd_st; +out: + free(lmd); + + return rc; } /** Create the destination volatile file for a restore operation. @@ -1063,7 +1098,7 @@ int llapi_hsm_action_begin(struct hsm_copyaction_private **phcp, goto ok_out; if (hai->hai_action == HSMA_RESTORE) { - rc = ct_stat_by_fid(hcp->ct_priv, &hai->hai_fid, &hcp->stat); + rc = ct_md_getattr(hcp->ct_priv, &hai->hai_fid, &hcp->stat); if (rc < 0) goto err_out; -- 1.8.3.1