Whamcloud - gitweb
LU-579 MRP-120 changelog CLOSE event.
authorVitaly Fertman <vitaly_fertman@xyratex.com>
Wed, 29 Jun 2011 10:49:07 +0000 (14:49 +0400)
committerOleg Drokin <green@whamcloud.com>
Wed, 14 Dec 2011 12:58:40 +0000 (07:58 -0500)
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 <Nathan_Rutman@xyratex.com>
Reviewed-by: Alexey Lyashkov <alexey_lyashkov@xyratex.com>
Change-Id: I8e5ff99905b84ee58416406ca7b690c86db60c62
Signed-off-by: Vitaly Fertman <vitaly_fertman@xyratex.com>
Reviewed-on: http://review.whamcloud.com/1197
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Mikhail Pershin <tappro@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/cmm/cmm_object.c
lustre/include/lustre/lustre_idl.h
lustre/include/md_object.h
lustre/mdd/mdd_device.c
lustre/mdd/mdd_internal.h
lustre/mdd/mdd_object.c
lustre/mdd/mdd_trans.c
lustre/mdt/mdt_open.c
lustre/tests/sanity.sh

index 5fdcf9a..df839c9 100644 (file)
@@ -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;
 }
index d8a4550..45d8270 100644 (file)
@@ -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"
index d4c5b66..0346116 100644 (file)
@@ -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,
index 876a51a..d69839b 100644 (file)
@@ -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);
 
index 5088814..1a525a3 100644 (file)
@@ -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
 };
 
index 5320344..fa25ba2 100644 (file)
@@ -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,
index 9519e38..c31ede1 100644 (file)
@@ -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();
index 20281b8..0292633 100644 (file)
@@ -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;
index 9aa27b2..23e4f8f 100644 (file)
@@ -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"