From 9ef9c5f9f0ceeaaaac018702286c0c23a8eb5d4b Mon Sep 17 00:00:00 2001 From: Henri Doreau Date: Fri, 23 Sep 2016 10:07:40 +0200 Subject: [PATCH] LU-7264 mdd: refactor changelog handling for XATTR ops Add a helper function mdd_xattr_changelog_type() to determine the changelog type to store when setting/deleting an xattr, if applicable. Change-Id: I2a0d1d524c3a7c33da96ee470fe14ad13fd8638c Signed-off-by: Henri Doreau Reviewed-on: https://review.whamcloud.com/22697 Reviewed-by: John L. Hammond Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger --- lustre/mdd/mdd_object.c | 154 +++++++++++++++++++++++++----------------------- 1 file changed, 80 insertions(+), 74 deletions(-) diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 42c7cec..c3a6eb3 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -930,6 +930,45 @@ static int mdd_xattr_sanity_check(const struct lu_env *env, RETURN(0); } +/** + * Check if a string begins with a given prefix. + * + * \param str String to check + * \param prefix Substring to check at the beginning of \a str + * \return true/false whether the condition is verified. + */ +static inline bool has_prefix(const char *str, const char *prefix) +{ + return strncmp(prefix, str, strlen(prefix)) == 0; +} + +/** + * Indicate the kind of changelog to store (if any) for a xattr set/del. + * + * \param[in] xattr_name Full extended attribute name. + * + * \return The type of changelog to use, or -1 if no changelog is to be emitted. + */ +static enum changelog_rec_type +mdd_xattr_changelog_type(const struct lu_env *env, struct mdd_device *mdd, + const char *xattr_name) +{ + /* Layout changes systematically recorded */ + if (strcmp(XATTR_NAME_LOV, xattr_name) == 0) + return CL_LAYOUT; + + /* HSM information changes systematically recorded */ + if (strcmp(XATTR_NAME_HSM, xattr_name) == 0) + return CL_HSM; + + if (has_prefix(xattr_name, XATTR_USER_PREFIX) || + has_prefix(xattr_name, XATTR_NAME_POSIX_ACL_ACCESS) || + has_prefix(xattr_name, XATTR_NAME_POSIX_ACL_DEFAULT)) + return CL_XATTR; + + return -1; +} + static int mdd_declare_xattr_set(const struct lu_env *env, struct mdd_device *mdd, struct mdd_object *obj, @@ -943,24 +982,10 @@ static int mdd_declare_xattr_set(const struct lu_env *env, if (rc) return rc; - /* Only record user and layout xattr changes */ - if (strncmp(XATTR_USER_PREFIX, name, - sizeof(XATTR_USER_PREFIX) - 1) == 0 || - strcmp(XATTR_NAME_LOV, name) == 0) { - rc = mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); - if (rc) - return rc; - } + if (mdd_xattr_changelog_type(env, mdd, name) < 0) + return 0; /* no changelog to store */ - /* If HSM data is modified, this could add a changelog */ - if (strcmp(XATTR_NAME_HSM, name) == 0) { - rc = mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); - if (rc) - return rc; - } - - rc = mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); - return rc; + return mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); } /* @@ -975,10 +1000,9 @@ static int mdd_declare_xattr_set(const struct lu_env *env, static int mdd_hsm_update_locked(const struct lu_env *env, struct md_object *obj, const struct lu_buf *buf, - struct thandle *handle) + struct thandle *handle, int *cl_flags) { struct mdd_thread_info *info = mdd_env_info(env); - struct mdd_device *mdd = mdo2mdd(obj); struct mdd_object *mdd_obj = md2mdd_obj(obj); struct lu_buf *current_buf; struct md_hsm *current_mh; @@ -1007,22 +1031,20 @@ static int mdd_hsm_update_locked(const struct lu_env *env, GOTO(free, rc = -ENOMEM); lustre_buf2hsm(buf->lb_buf, buf->lb_len, new_mh); - /* If HSM flags are different, add a changelog */ rc = 0; + + /* Flags differ, set flags for the changelog that will be added */ if (current_mh->mh_flags != new_mh->mh_flags) { - int flags = 0; - hsm_set_cl_event(&flags, HE_STATE); + hsm_set_cl_event(cl_flags, HE_STATE); if (new_mh->mh_flags & HS_DIRTY) - hsm_set_cl_flags(&flags, CLF_HSM_DIRTY); - - rc = mdd_changelog_data_store(env, mdd, CL_HSM, flags, mdd_obj, - handle); + hsm_set_cl_flags(cl_flags, CLF_HSM_DIRTY); } OBD_FREE_PTR(new_mh); + EXIT; free: OBD_FREE_PTR(current_mh); - return(rc); + return rc; } static int mdd_xattr_del(const struct lu_env *env, struct md_object *obj, @@ -1040,6 +1062,8 @@ static int mdd_xattr_set(const struct lu_env *env, struct md_object *obj, struct lu_attr *attr = MDD_ENV_VAR(env, cattr); struct mdd_device *mdd = mdo2mdd(obj); struct thandle *handle; + enum changelog_rec_type cl_type; + int cl_flags = 0; int rc; ENTRY; @@ -1088,7 +1112,7 @@ static int mdd_xattr_set(const struct lu_env *env, struct md_object *obj, mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD); if (strcmp(XATTR_NAME_HSM, name) == 0) { - rc = mdd_hsm_update_locked(env, obj, buf, handle); + rc = mdd_hsm_update_locked(env, obj, buf, handle, &cl_flags); if (rc) { mdd_write_unlock(env, mdd_obj); GOTO(stop, rc); @@ -1100,22 +1124,16 @@ static int mdd_xattr_set(const struct lu_env *env, struct md_object *obj, if (rc) GOTO(stop, rc); - if (strcmp(XATTR_NAME_LOV, name) == 0) - rc = mdd_changelog_data_store(env, mdd, CL_LAYOUT, 0, mdd_obj, - handle); - else if (strncmp(XATTR_USER_PREFIX, name, - sizeof(XATTR_USER_PREFIX) - 1) == 0 || - strncmp(XATTR_NAME_POSIX_ACL_ACCESS, name, - sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1) == 0 || - strncmp(XATTR_NAME_POSIX_ACL_DEFAULT, name, - sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1) == 0) - rc = mdd_changelog_data_store(env, mdd, CL_XATTR, 0, mdd_obj, - handle); + cl_type = mdd_xattr_changelog_type(env, mdd, name); + if (cl_type < 0) + GOTO(stop, rc = 0); -stop: - rc = mdd_trans_stop(env, mdd, rc, handle); + rc = mdd_changelog_data_store(env, mdd, cl_type, cl_flags, mdd_obj, + handle); - RETURN(rc); + EXIT; +stop: + return mdd_trans_stop(env, mdd, rc, handle); } static int mdd_declare_xattr_del(const struct lu_env *env, @@ -1130,16 +1148,10 @@ static int mdd_declare_xattr_del(const struct lu_env *env, if (rc) return rc; - /* Only record system & user xattr changes */ - if (strncmp(XATTR_USER_PREFIX, name, - sizeof(XATTR_USER_PREFIX) - 1) == 0 || - strncmp(XATTR_NAME_POSIX_ACL_ACCESS, name, - sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1) == 0 || - strncmp(XATTR_NAME_POSIX_ACL_DEFAULT, name, - sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1) == 0) - rc = mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); + if (mdd_xattr_changelog_type(env, mdd, name) < 0) + return 0; /* no changelog to store */ - return rc; + return mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); } /** @@ -1164,38 +1176,32 @@ static int mdd_xattr_del(const struct lu_env *env, struct md_object *obj, if (rc) RETURN(rc); - handle = mdd_trans_create(env, mdd); - if (IS_ERR(handle)) - RETURN(PTR_ERR(handle)); + handle = mdd_trans_create(env, mdd); + if (IS_ERR(handle)) + RETURN(PTR_ERR(handle)); - rc = mdd_declare_xattr_del(env, mdd, mdd_obj, name, handle); - if (rc) - GOTO(stop, rc); + rc = mdd_declare_xattr_del(env, mdd, mdd_obj, name, handle); + if (rc) + GOTO(stop, rc); - rc = mdd_trans_start(env, mdd, handle); - if (rc) - GOTO(stop, rc); + rc = mdd_trans_start(env, mdd, handle); + if (rc) + GOTO(stop, rc); - mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD); + mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD); rc = mdo_xattr_del(env, mdd_obj, name, handle); - mdd_write_unlock(env, mdd_obj); + mdd_write_unlock(env, mdd_obj); if (rc) GOTO(stop, rc); - /* Only record system & user xattr changes */ - if (strncmp(XATTR_USER_PREFIX, name, - sizeof(XATTR_USER_PREFIX) - 1) == 0 || - strncmp(XATTR_NAME_POSIX_ACL_ACCESS, name, - sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1) == 0 || - strncmp(XATTR_NAME_POSIX_ACL_DEFAULT, name, - sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1) == 0) - rc = mdd_changelog_data_store(env, mdd, CL_XATTR, 0, mdd_obj, - handle); + if (mdd_xattr_changelog_type(env, mdd, name) < 0) + GOTO(stop, rc = 0); -stop: - rc = mdd_trans_stop(env, mdd, rc, handle); + rc = mdd_changelog_data_store(env, mdd, CL_XATTR, 0, mdd_obj, handle); - RETURN(rc); + EXIT; +stop: + return mdd_trans_stop(env, mdd, rc, handle); } /* -- 1.8.3.1