From 3ca3500252765e7afbfe99cbbb7a0e7eb9df01bc Mon Sep 17 00:00:00 2001 From: jcl Date: Fri, 2 Aug 2013 13:25:30 +0200 Subject: [PATCH] LU-3718 mdt: HSM EXIST event not triggered at last rm/mv After a rm or mv, if the target file is destroyed (last unlink) and if there is an archive in the backend a flags must be set in changelog event Signed-off-by: JC Lafoucriere Change-Id: I92f3ea91d377ba8b3724aef43d4e7ba8b0a6f681 Reviewed-on: http://review.whamcloud.com/7260 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Jinshan Xiong Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin --- lustre/include/lustre/lustre_user.h | 5 +- lustre/mdd/mdd_dir.c | 100 +++++++++++++++++++++++++----------- lustre/tests/sanity-hsm.sh | 6 +-- 3 files changed, 76 insertions(+), 35 deletions(-) diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index f058f6d..0c4fa6e 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -703,7 +703,10 @@ static inline const char *changelog_type2str(int type) { #define CLF_UNLINK_HSM_EXISTS 0x0002 /* File has something in HSM */ /* HSM cleaning needed */ /* Flags for rename */ -#define CLF_RENAME_LAST 0x0001 /* rename unlink last hardlink of target */ +#define CLF_RENAME_LAST 0x0001 /* rename unlink last hardlink + * of target */ +#define CLF_RENAME_LAST_EXISTS 0x0002 /* rename unlink last hardlink of target + * has an archive in backend */ /* Flags for HSM */ /* 12b used (from high weight to low weight): diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index b75ba34..71d7443 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -1385,6 +1385,39 @@ static int mdd_declare_unlink(const struct lu_env *env, struct mdd_device *mdd, return rc; } +/* + * test if a file has an HSM archive + * if HSM attributes are not found in ma update them from + * HSM xattr + */ +static bool mdd_hsm_archive_exists(const struct lu_env *env, + struct mdd_object *obj, + struct md_attr *ma) +{ + ENTRY; + + if (!(ma->ma_valid & MA_HSM)) { + /* no HSM MD provided, read xattr */ + struct lu_buf *hsm_buf; + const size_t buflen = sizeof(struct hsm_attrs); + int rc; + + hsm_buf = mdd_buf_get(env, NULL, 0); + lu_buf_alloc(hsm_buf, buflen); + rc = mdo_xattr_get(env, obj, hsm_buf, XATTR_NAME_HSM, + mdd_object_capa(env, obj)); + rc = lustre_buf2hsm(hsm_buf->lb_buf, rc, &ma->ma_hsm); + lu_buf_free(hsm_buf); + if (rc < 0) + RETURN(false); + + ma->ma_valid = MA_HSM; + } + if (ma->ma_hsm.mh_flags & HS_EXISTS) + RETURN(true); + RETURN(false); +} + /** * Delete name entry and the object. * Note: no_name == 1 means it only destory the object, i.e. name_entry @@ -1398,16 +1431,16 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, struct md_object *cobj, const struct lu_name *lname, struct md_attr *ma, int no_name) { - const char *name = lname->ln_name; + const char *name = lname->ln_name; struct lu_attr *cattr = &mdd_env_info(env)->mti_cattr; - struct lu_attr *la = &mdd_env_info(env)->mti_la_for_fix; - struct mdd_object *mdd_pobj = md2mdd_obj(pobj); + struct lu_attr *la = &mdd_env_info(env)->mti_la_for_fix; + struct mdd_object *mdd_pobj = md2mdd_obj(pobj); struct mdd_object *mdd_cobj = NULL; - struct mdd_device *mdd = mdo2mdd(pobj); - struct dynlock_handle *dlh; - struct thandle *handle; + struct mdd_device *mdd = mdo2mdd(pobj); + struct dynlock_handle *dlh; + struct thandle *handle; int rc, is_dir = 0; - ENTRY; + ENTRY; /* cobj == NULL means only delete name entry */ if (likely(cobj != NULL)) { @@ -1420,8 +1453,8 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, } handle = mdd_trans_create(env, mdd); - if (IS_ERR(handle)) - RETURN(PTR_ERR(handle)); + if (IS_ERR(handle)) + RETURN(PTR_ERR(handle)); rc = mdd_declare_unlink(env, mdd, mdd_pobj, mdd_cobj, lname, ma, handle, no_name); @@ -1496,25 +1529,25 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, } if (cattr->la_nlink > 0 || mdd_cobj->mod_count > 0) { - /* update ctime of an unlinked file only if it is still - * opened or a link still exists */ - la->la_valid = LA_CTIME; - rc = mdd_attr_check_set_internal(env, mdd_cobj, la, handle, 0); - if (rc) - GOTO(cleanup, rc); - } + /* update ctime of an unlinked file only if it is still + * opened or a link still exists */ + la->la_valid = LA_CTIME; + rc = mdd_attr_check_set_internal(env, mdd_cobj, la, handle, 0); + if (rc) + GOTO(cleanup, rc); + } /* XXX: this transfer to ma will be removed with LOD/OSP */ ma->ma_attr = *cattr; ma->ma_valid |= MA_INODE; - rc = mdd_finish_unlink(env, mdd_cobj, ma, handle); + rc = mdd_finish_unlink(env, mdd_cobj, ma, handle); /* fetch updated nlink */ if (rc == 0) rc = mdd_la_get(env, mdd_cobj, cattr, mdd_object_capa(env, mdd_cobj)); - if (!is_dir) + if (!is_dir) /* old files may not have link ea; ignore errors */ mdd_links_del(env, mdd_cobj, mdo2fid(mdd_pobj), lname, handle); @@ -1523,27 +1556,29 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, ma->ma_attr = *cattr; ma->ma_valid |= MA_INODE; } - EXIT; + EXIT; cleanup: - mdd_write_unlock(env, mdd_cobj); - mdd_pdo_write_unlock(env, mdd_pobj, dlh); - if (rc == 0) { - int cl_flags; + mdd_write_unlock(env, mdd_cobj); + mdd_pdo_write_unlock(env, mdd_pobj, dlh); + if (rc == 0) { + int cl_flags = 0; - cl_flags = (cattr->la_nlink == 0) ? CLF_UNLINK_LAST : 0; - if ((ma->ma_valid & MA_HSM) && - (ma->ma_hsm.mh_flags & HS_EXISTS)) - cl_flags |= CLF_UNLINK_HSM_EXISTS; + if (cattr->la_nlink == 0) { + cl_flags |= CLF_UNLINK_LAST; + /* search for an existing archive */ + if (mdd_hsm_archive_exists(env, mdd_cobj, ma)) + cl_flags |= CLF_UNLINK_HSM_EXISTS; + } rc = mdd_changelog_ns_store(env, mdd, is_dir ? CL_RMDIR : CL_UNLINK, cl_flags, mdd_cobj, mdd_pobj, lname, handle); - } + } stop: - mdd_trans_stop(env, mdd, rc, handle); + mdd_trans_stop(env, mdd, rc, handle); - return rc; + return rc; } /* @@ -2663,8 +2698,11 @@ static int mdd_rename(const struct lu_env *env, ma->ma_attr = *tg_attr; ma->ma_valid |= MA_INODE; - if (tg_attr->la_nlink == 0) + if (tg_attr->la_nlink == 0) { cl_flags |= CLF_RENAME_LAST; + if (mdd_hsm_archive_exists(env, mdd_tobj, ma)) + cl_flags |= CLF_RENAME_LAST_EXISTS; + } } la->la_valid = LA_CTIME | LA_MTIME; diff --git a/lustre/tests/sanity-hsm.sh b/lustre/tests/sanity-hsm.sh index 49b5ec3..62164fb 100644 --- a/lustre/tests/sanity-hsm.sh +++ b/lustre/tests/sanity-hsm.sh @@ -14,8 +14,8 @@ ONLY=${ONLY:-"$*"} # bug number for skipped test: # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT! # skip test cases failed before landing - Jinshan -ALWAYS_EXCEPT="$SANITY_HSM_EXCEPT 12a 12b 12n 13 24 30a 31a 34 35 36 52 58 59" -ALWAYS_EXCEPT="$ALWAYS_EXCEPT 110a 200 201 221 222a 223a 223b 225 226" +ALWAYS_EXCEPT="$SANITY_HSM_EXCEPT 12a 12b 12n 13 24 30a 31a 34 35 36 58 59" +ALWAYS_EXCEPT="$ALWAYS_EXCEPT 110a 200 201 221 222a 223a 223b 225" LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)} @@ -36,7 +36,7 @@ fi check_and_setup_lustre -if [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.53) ]; then +if [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.53) ]]; then skip_env "Need MDS version at least 2.4.53" && exit fi -- 1.8.3.1