From: Vitaly Fertman Date: Wed, 29 Jun 2011 10:49:07 +0000 (+0400) Subject: LU-579 MRP-120 changelog CLOSE event. X-Git-Tag: 2.1.53~14 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=c958412e42d3e1529a40b78e96f36e6d15608517 LU-579 MRP-120 changelog CLOSE event. add CLOSE event into changelog, but not into the default mask. do not create close changelog record sometimes, if a dup mfd handler appeared: - open replay (1st mfd appears) - re-connect - open replay (2nd mfd appears) Reviewed-by: Nathan Rutman Reviewed-by: Alexey Lyashkov Change-Id: I8e5ff99905b84ee58416406ca7b690c86db60c62 Signed-off-by: Vitaly Fertman Reviewed-on: http://review.whamcloud.com/1197 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Mikhail Pershin Reviewed-by: Oleg Drokin --- diff --git a/lustre/cmm/cmm_object.c b/lustre/cmm/cmm_object.c index 5fdcf9a..df839c9 100644 --- a/lustre/cmm/cmm_object.c +++ b/lustre/cmm/cmm_object.c @@ -349,11 +349,11 @@ static int cml_open(const struct lu_env *env, struct md_object *mo, } static int cml_close(const struct lu_env *env, struct md_object *mo, - struct md_attr *ma) + struct md_attr *ma, int mode) { int rc; ENTRY; - rc = mo_close(env, md_object_next(mo), ma); + rc = mo_close(env, md_object_next(mo), ma, mode); RETURN(rc); } @@ -1099,7 +1099,7 @@ static int cmr_open(const struct lu_env *env, struct md_object *mo, } static int cmr_close(const struct lu_env *env, struct md_object *mo, - struct md_attr *ma) + struct md_attr *ma, int mode) { return -EFAULT; } diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index d8a4550..45d8270 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -1877,7 +1877,8 @@ enum { MDS_SOM = 1 << 4, MDS_QUOTA_IGNORE = 1 << 5, MDS_CLOSE_CLEANUP = 1 << 6, - MDS_KEEP_ORPHAN = 1 << 7 + MDS_KEEP_ORPHAN = 1 << 7, + MDS_RECOV_OPEN = 1 << 8, }; /* instance of mdt_reint_rec */ @@ -2545,7 +2546,7 @@ struct llog_size_change_rec { /** bits covering all \a changelog_rec_type's */ #define CHANGELOG_ALLMASK 0XFFFFFFFF /** default \a changelog_rec_type mask */ -#define CHANGELOG_DEFMASK CHANGELOG_ALLMASK & ~(1 << CL_ATIME) +#define CHANGELOG_DEFMASK CHANGELOG_ALLMASK & ~(1 << CL_ATIME | 1 << CL_CLOSE) /* changelog llog name, needed by client replicators */ #define CHANGELOG_CATALOG "changelog_catalog" diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index d4c5b66..0346116 100644 --- a/lustre/include/md_object.h +++ b/lustre/include/md_object.h @@ -272,7 +272,7 @@ struct md_object_operations { struct md_object *obj, int flag); int (*moo_close)(const struct lu_env *env, struct md_object *obj, - struct md_attr *ma); + struct md_attr *ma, int mode); int (*moo_capa_get)(const struct lu_env *, struct md_object *, struct lustre_capa *, int renewal); @@ -693,10 +693,11 @@ static inline int mo_open(const struct lu_env *env, static inline int mo_close(const struct lu_env *env, struct md_object *m, - struct md_attr *ma) + struct md_attr *ma, + int mode) { LASSERT(m->mo_ops->moo_close); - return m->mo_ops->moo_close(env, m, ma); + return m->mo_ops->moo_close(env, m, ma, mode); } static inline int mo_readpage(const struct lu_env *env, diff --git a/lustre/mdd/mdd_device.c b/lustre/mdd/mdd_device.c index 876a51a..d69839b 100644 --- a/lustre/mdd/mdd_device.c +++ b/lustre/mdd/mdd_device.c @@ -542,7 +542,7 @@ static int dot_lustre_mdd_open(const struct lu_env *env, struct md_object *obj, } static int dot_lustre_mdd_close(const struct lu_env *env, struct md_object *obj, - struct md_attr *ma) + struct md_attr *ma, int mode) { struct mdd_object *mdd_obj = md2mdd_obj(obj); @@ -794,7 +794,7 @@ static int obf_mdd_open(const struct lu_env *env, struct md_object *obj, } static int obf_mdd_close(const struct lu_env *env, struct md_object *obj, - struct md_attr *ma) + struct md_attr *ma, int mode) { struct mdd_object *mdd_obj = md2mdd_obj(obj); diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index 5088814..1a525a3 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -84,6 +84,7 @@ enum mdd_txn_op { MDD_TXN_RENAME_TGT_OP, MDD_TXN_CREATE_DATA_OP, MDD_TXN_MKDIR_OP, + MDD_TXN_CLOSE_OP, MDD_TXN_LAST_OP }; diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 5320344..fa25ba2 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -1267,6 +1267,7 @@ static int mdd_changelog_data_store(const struct lu_env *env, { const struct lu_fid *tfid = mdo2fid(mdd_obj); struct llog_changelog_rec *rec; + struct thandle *th = NULL; struct lu_buf *buf; int reclen; int rc; @@ -1277,7 +1278,6 @@ static int mdd_changelog_data_store(const struct lu_env *env, if ((mdd->mdd_cl.mc_mask & (1 << type)) == 0) RETURN(0); - LASSERT(handle != NULL); LASSERT(mdd_obj != NULL); if ((type >= CL_MTIME) && (type <= CL_ATIME) && @@ -1300,7 +1300,20 @@ static int mdd_changelog_data_store(const struct lu_env *env, rec->cr.cr_namelen = 0; mdd_obj->mod_cltime = cfs_time_current_64(); - rc = mdd_changelog_llog_write(mdd, rec, handle); + if (handle == NULL) { + /* Used for the close event only for now. */ + LASSERT(type == CL_CLOSE); + LASSERT(mdd_env_info(env)->mti_param.tp_credits != 0); + th = mdd_trans_start(env, mdd); + if (IS_ERR(th)) + GOTO(err, rc = PTR_ERR(th)); + } + + rc = mdd_changelog_llog_write(mdd, rec, handle ? : th); + + if (th) + mdd_trans_stop(env, mdd, rc, th); +err: if (rc < 0) { CERROR("changelog failed: rc=%d op%d t"DFID"\n", rc, type, PFID(tfid)); @@ -2115,7 +2128,7 @@ int mdd_object_kill(const struct lu_env *env, struct mdd_object *obj, * No permission check is needed. */ static int mdd_close(const struct lu_env *env, struct md_object *obj, - struct md_attr *ma) + struct md_attr *ma, int mode) { struct mdd_object *mdd_obj = md2mdd_obj(obj); struct mdd_device *mdd = mdo2mdd(obj); @@ -2144,7 +2157,8 @@ static int mdd_close(const struct lu_env *env, struct md_object *obj, if (mdd_obj->mod_count == 1 && (mdd_obj->mod_flags & (ORPHAN_OBJ | DEAD_OBJ)) != 0) { again: - rc = mdd_log_txn_param_build(env, obj, ma, MDD_TXN_UNLINK_OP, 0); + rc = mdd_log_txn_param_build(env, obj, ma, + MDD_TXN_UNLINK_OP, 1); if (rc) RETURN(rc); handle = mdd_trans_start(env, mdo2mdd(obj)); @@ -2213,8 +2227,18 @@ out: ma->ma_valid &= ~(MA_LOV | MA_COOKIE); mdd_write_unlock(env, mdd_obj); + + if (rc == 0 && + (mode & (FMODE_WRITE | MDS_OPEN_APPEND | MDS_OPEN_TRUNC)) && + !(ma->ma_valid & MA_FLAGS && ma->ma_attr_flags & MDS_RECOV_OPEN)) { + if (handle == 0) + mdd_txn_param_build(env, mdd, MDD_TXN_CLOSE_OP, 1); + mdd_changelog_data_store(env, mdd, CL_CLOSE, mode, + mdd_obj, handle); + } + if (handle != NULL) - mdd_trans_stop(env, mdo2mdd(obj), rc, handle); + mdd_trans_stop(env, mdd, rc, handle); #ifdef HAVE_QUOTA_SUPPORT if (quota_opc) /* Trigger dqrel on the owner of child. If failed, diff --git a/lustre/mdd/mdd_trans.c b/lustre/mdd/mdd_trans.c index 9519e38..c31ede1 100644 --- a/lustre/mdd/mdd_trans.c +++ b/lustre/mdd/mdd_trans.c @@ -277,6 +277,9 @@ int mdd_txn_init_credits(const struct lu_env *env, struct mdd_device *mdd) *c = 2 * dt[DTO_INDEX_INSERT] + dt[DTO_OBJECT_CREATE]; break; + case MDD_TXN_CLOSE_OP: + *c = 0; + break; default: CERROR("Invalid op %d init its credit\n", op); LBUG(); diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c index 20281b8..0292633 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -693,7 +693,11 @@ static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p, cfs_spin_unlock(&med->med_open_lock); /* no attr update for that close */ la->la_valid = 0; + ma->ma_valid |= MA_FLAGS; + ma->ma_attr_flags |= MDS_RECOV_OPEN; mdt_mfd_close(info, old_mfd); + ma->ma_attr_flags &= ~MDS_RECOV_OPEN; + ma->ma_valid &= ~MA_FLAGS; } CDEBUG(D_HA, "Store old cookie "LPX64" in new mfd\n", info->mti_rr.rr_handle->cookie); @@ -1517,7 +1521,7 @@ int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd) ma->ma_valid &= ~MA_INODE; if (!MFD_CLOSED(mode)) - rc = mo_close(info->mti_env, next, ma); + rc = mo_close(info->mti_env, next, ma, mode); if (ret == MDT_IOEPOCH_GETATTR || ret == MDT_IOEPOCH_OPENED) { struct mdt_export_data *med; diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 9aa27b2..23e4f8f 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -7336,11 +7336,24 @@ err17935 () { error $* fi } + +changelog_chmask() +{ + MASK=$(do_facet $SINGLEMDS $LCTL get_param mdd.$MDT0.changelog_mask |\ + grep -c $1) + + if [ $MASK -eq 1 ]; then + do_facet $SINGLEMDS $LCTL set_param mdd.$MDT0.changelog_mask="-$1" + else + do_facet $SINGLEMDS $LCTL set_param mdd.$MDT0.changelog_mask="+$1" + fi +} + test_160() { remote_mds_nodsh && skip "remote MDS with nodsh" && return - USER=$(do_facet $SINGLEMDS lctl --device $MDT0 changelog_register -n) + USER=$(do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_register -n) echo "Registered as changelog user $USER" - do_facet $SINGLEMDS lctl get_param -n mdd.$MDT0.changelog_users | \ + do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_users | \ grep -q $USER || error "User $USER not found in changelog_users" # change something @@ -7355,12 +7368,23 @@ test_160() { $LFS changelog $MDT0 | tail -5 echo "verifying changelog mask" - do_facet $SINGLEMDS lctl set_param mdd.$MDT0.changelog_mask="-mkdir" - mkdir -p $DIR/$tdir/pics/2009/sofia - do_facet $SINGLEMDS lctl set_param mdd.$MDT0.changelog_mask="+mkdir" - mkdir $DIR/$tdir/pics/2009/zachary - DIRS=$($LFS changelog $MDT0 | tail -5 | grep -c MKDIR) - [ $DIRS -eq 1 ] || err17935 "changelog mask count $DIRS != 1" + changelog_chmask "MKDIR" + changelog_chmask "CLOSE" + + mkdir -p $DIR/$tdir/pics/zach/sofia + echo "zzzzzz" > $DIR/$tdir/pics/zach/file + + changelog_chmask "MKDIR" + changelog_chmask "CLOSE" + + mkdir -p $DIR/$tdir/pics/2008/sofia + echo "zzzzzz" > $DIR/$tdir/pics/zach/file + + $LFS changelog $MDT0 + MKDIRS=$($LFS changelog $MDT0 | tail -5 | grep -c "MKDIR") + CLOSES=$($LFS changelog $MDT0 | tail -5 | grep -c "CLOSE") + [ $MKDIRS -eq 1 ] || err17935 "MKDIR changelog mask count $DIRS != 1" + [ $CLOSES -eq 1 ] || err17935 "CLOSE changelog mask count $DIRS != 1" # verify contents echo "verifying target fid" @@ -7376,16 +7400,16 @@ test_160() { [ "$fidc" == "p=$fidf" ] || \ err17935 "pfid in changelog $fidc != dir fid $fidf" - USER_REC1=$(do_facet $SINGLEMDS lctl get_param -n \ + USER_REC1=$(do_facet $SINGLEMDS $LCTL get_param -n \ mdd.$MDT0.changelog_users | grep $USER | awk '{print $2}') $LFS changelog_clear $MDT0 $USER $(($USER_REC1 + 5)) - USER_REC2=$(do_facet $SINGLEMDS lctl get_param -n \ + USER_REC2=$(do_facet $SINGLEMDS $LCTL get_param -n \ mdd.$MDT0.changelog_users | grep $USER | awk '{print $2}') echo "verifying user clear: $(( $USER_REC1 + 5 )) == $USER_REC2" [ $USER_REC2 == $(($USER_REC1 + 5)) ] || \ err17935 "user index should be $(($USER_REC1 + 5)); is $USER_REC2" - MIN_REC=$(do_facet $SINGLEMDS lctl get_param mdd.$MDT0.changelog_users | \ + MIN_REC=$(do_facet $SINGLEMDS $LCTL get_param mdd.$MDT0.changelog_users | \ awk 'min == "" || $2 < min {min = $2}; END {print min}') FIRST_REC=$($LFS changelog $MDT0 | head -1 | awk '{print $1}') echo "verifying min purge: $(( $MIN_REC + 1 )) == $FIRST_REC" @@ -7393,17 +7417,17 @@ test_160() { err17935 "first index should be $(($MIN_REC + 1)); is $FIRST_REC" echo "verifying user deregister" - do_facet $SINGLEMDS lctl --device $MDT0 changelog_deregister $USER - do_facet $SINGLEMDS lctl get_param -n mdd.$MDT0.changelog_users | \ + do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister $USER + do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_users | \ grep -q $USER && error "User $USER still found in changelog_users" - USERS=$(( $(do_facet $SINGLEMDS lctl get_param -n \ + USERS=$(( $(do_facet $SINGLEMDS $LCTL get_param -n \ mdd.$MDT0.changelog_users | wc -l) - 2 )) if [ $USERS -eq 0 ]; then - LAST_REC1=$(do_facet $SINGLEMDS lctl get_param -n \ + LAST_REC1=$(do_facet $SINGLEMDS $LCTL get_param -n \ mdd.$MDT0.changelog_users | head -1 | awk '{print $3}') touch $DIR/$tdir/chloe - LAST_REC2=$(do_facet $SINGLEMDS lctl get_param -n \ + LAST_REC2=$(do_facet $SINGLEMDS $LCTL get_param -n \ mdd.$MDT0.changelog_users | head -1 | awk '{print $3}') echo "verify changelogs are off if we were the only user: $LAST_REC1 == $LAST_REC2" [ $LAST_REC1 == $LAST_REC2 ] || error "changelogs not off"