Whamcloud - gitweb
b=23035 split changelog time record into ctime,mtime,atime
authorNathan Rutman <nathan.rutman@oracle.com>
Fri, 13 Aug 2010 17:36:41 +0000 (21:36 +0400)
committerMikhail Pershin <tappro@sun.com>
Thu, 26 Aug 2010 12:22:03 +0000 (16:22 +0400)
lustre/include/lustre/lustre_idl.h
lustre/include/lustre/lustre_user.h
lustre/mdd/mdd_device.c
lustre/mdd/mdd_dir.c
lustre/mdd/mdd_object.c

index 28cfc2d..f56d210 100644 (file)
@@ -2476,7 +2476,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
+#define CHANGELOG_DEFMASK CHANGELOG_ALLMASK & ~(1 << CL_ATIME)
 
 /* changelog llog name, needed by client replicators */
 #define CHANGELOG_CATALOG "changelog_catalog"
index 3731b65..e275262 100644 (file)
@@ -478,7 +478,9 @@ enum changelog_rec_type {
         CL_SETATTR  = 14,
         CL_XATTR    = 15,
         CL_HSM      = 16, /* HSM specific events, see flags */
-        CL_TIME     = 17, /* mtime, atime, ctime change only */
+        CL_MTIME    = 17, /* Precedence: setattr > mtime > ctime > atime */
+        CL_CTIME    = 18,
+        CL_ATIME    = 19,
         CL_LAST
 };
 
@@ -486,7 +488,7 @@ static inline const char *changelog_type2str(int type) {
         static const char *changelog_str[] = {
                 "MARK",  "CREAT", "MKDIR", "HLINK", "SLINK", "MKNOD", "UNLNK",
                 "RMDIR", "RNMFM", "RNMTO", "OPEN",  "CLOSE", "IOCTL", "TRUNC",
-                "SATTR", "XATTR", "HSM",   "TIME"  };
+                "SATTR", "XATTR", "HSM",   "MTIME", "CTIME", "ATIME"  };
         if (type >= 0 && type < CL_LAST)
                 return changelog_str[type];
         return NULL;
index 8b665d5..28d129c 100644 (file)
@@ -312,9 +312,6 @@ int mdd_changelog_llog_write(struct mdd_device         *mdd,
         struct llog_ctxt *ctxt;
         int rc;
 
-        if ((mdd->mdd_cl.mc_mask & (1 << rec->cr.cr_type)) == 0)
-                return 0;
-
         rec->cr_hdr.lrh_len = llog_data_len(sizeof(*rec) + rec->cr.cr_namelen);
         /* llog_lvfs_write_rec sets the llog tail len */
         rec->cr_hdr.lrh_type = CHANGELOG_REC;
@@ -412,7 +409,8 @@ int mdd_changelog_write_header(struct mdd_device *mdd, int markerflags)
         /* Status and action flags */
         rec->cr.cr_markerflags = mdd->mdd_cl.mc_flags | markerflags;
 
-        rc = mdd_changelog_llog_write(mdd, rec, NULL);
+        rc = (mdd->mdd_cl.mc_mask & (1 << CL_MARK)) ?
+                mdd_changelog_llog_write(mdd, rec, NULL) : 0;
 
         /* assume on or off event; reset repeat-access time */
         mdd->mdd_cl.mc_starttime = cfs_time_current_64();
index 97fef89..2ee1985 100644 (file)
@@ -633,8 +633,11 @@ static int mdd_changelog_ns_store(const struct lu_env  *env,
         int rc;
         ENTRY;
 
+        /* Not recording */
         if (!(mdd->mdd_cl.mc_flags & CLM_ON))
                 RETURN(0);
+        if ((mdd->mdd_cl.mc_mask & (1 << type)) == 0)
+                RETURN(0);
 
         LASSERT(parent != NULL);
         LASSERT(tname != NULL);
index a735f7f..1f8f83e 100644 (file)
@@ -1231,6 +1231,7 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj,
 static int mdd_changelog_data_store(const struct lu_env     *env,
                                     struct mdd_device       *mdd,
                                     enum changelog_rec_type type,
+                                    int                     flags,
                                     struct mdd_object       *mdd_obj,
                                     struct thandle          *handle)
 {
@@ -1240,13 +1241,16 @@ static int mdd_changelog_data_store(const struct lu_env     *env,
         int reclen;
         int rc;
 
+        /* Not recording */
         if (!(mdd->mdd_cl.mc_flags & CLM_ON))
                 RETURN(0);
+        if ((mdd->mdd_cl.mc_mask & (1 << type)) == 0)
+                RETURN(0);
 
         LASSERT(handle != NULL);
         LASSERT(mdd_obj != NULL);
 
-        if ((type == CL_TIME) &&
+        if ((type >= CL_MTIME) && (type <= CL_ATIME) &&
             cfs_time_before_64(mdd->mdd_cl.mc_starttime, mdd_obj->mod_cltime)) {
                 /* Don't need multiple updates in this log */
                 /* Don't check under lock - no big deal if we get an extra
@@ -1260,7 +1264,7 @@ static int mdd_changelog_data_store(const struct lu_env     *env,
                 RETURN(-ENOMEM);
         rec = (struct llog_changelog_rec *)buf->lb_buf;
 
-        rec->cr.cr_flags = CLF_VERSION;
+        rec->cr.cr_flags = CLF_VERSION | (CLF_FLAGMASK & flags);
         rec->cr.cr_type = (__u32)type;
         rec->cr.cr_tfid = *tfid;
         rec->cr.cr_namelen = 0;
@@ -1353,6 +1357,36 @@ static int mdd_lma_set_locked(const struct lu_env *env,
         return rc;
 }
 
+/* Precedence for choosing record type when multiple
+ * attributes change: setattr > mtime > ctime > atime
+ * (ctime changes when mtime does, plus chmod/chown.
+ * atime and ctime are independent.) */
+static int mdd_attr_set_changelog(const struct lu_env *env,
+                                  struct md_object *obj, struct thandle *handle,
+                                  __u64 valid)
+{
+        struct mdd_device *mdd = mdo2mdd(obj);
+        int bits, type = 0;
+
+        bits = (valid & ~(LA_CTIME|LA_MTIME|LA_ATIME)) ? 1 << CL_SETATTR : 0;
+        bits |= (valid & LA_MTIME) ? 1 << CL_MTIME : 0;
+        bits |= (valid & LA_CTIME) ? 1 << CL_CTIME : 0;
+        bits |= (valid & LA_ATIME) ? 1 << CL_ATIME : 0;
+        bits = bits & mdd->mdd_cl.mc_mask;
+        if (bits == 0)
+                return 0;
+
+        /* The record type is the lowest non-masked set bit */
+        while (bits && ((bits & 1) == 0)) {
+                bits = bits >> 1;
+                type++;
+        }
+
+        /* FYI we only store the first CLF_FLAGMASK bits of la_valid */
+        return mdd_changelog_data_store(env, mdd, type, (int)valid,
+                                        md2mdd_obj(obj), handle);
+}
+
 /* set attr and LOV EA at once, return updated attr */
 static int mdd_attr_set(const struct lu_env *env, struct md_object *obj,
                         const struct md_attr *ma)
@@ -1478,11 +1512,8 @@ static int mdd_attr_set(const struct lu_env *env, struct md_object *obj,
         }
 cleanup:
         if (rc == 0)
-                rc = mdd_changelog_data_store(env, mdd,
-                                              (ma->ma_attr.la_valid &
-                                               ~(LA_MTIME|LA_CTIME|LA_ATIME)) ?
-                                              CL_SETATTR : CL_TIME,
-                                              mdd_obj, handle);
+                rc = mdd_attr_set_changelog(env, obj, handle,
+                                            ma->ma_attr.la_valid);
         mdd_trans_stop(env, mdd, rc, handle);
         if (rc == 0 && (lmm != NULL && lmm_size > 0 )) {
                 /*set obd attr, if needed*/
@@ -1572,9 +1603,8 @@ static int mdd_xattr_set(const struct lu_env *env, struct md_object *obj,
         rc = mdd_xattr_set_txn(env, mdd_obj, buf, name, fl, handle);
 
         /* Only record user xattr changes */
-        if ((rc == 0) && (mdd->mdd_cl.mc_flags & CLM_ON) &&
-            (strncmp("user.", name, 5) == 0))
-                rc = mdd_changelog_data_store(env, mdd, CL_XATTR, mdd_obj,
+        if ((rc == 0) && (strncmp("user.", name, 5) == 0))
+                rc = mdd_changelog_data_store(env, mdd, CL_XATTR, 0, mdd_obj,
                                               handle);
         mdd_trans_stop(env, mdd, rc, handle);
 
@@ -1609,9 +1639,8 @@ int mdd_xattr_del(const struct lu_env *env, struct md_object *obj,
         mdd_write_unlock(env, mdd_obj);
 
         /* Only record user xattr changes */
-        if ((rc == 0) && (mdd->mdd_cl.mc_flags & CLM_ON) &&
-            (strncmp("user.", name, 5) != 0))
-                rc = mdd_changelog_data_store(env, mdd, CL_XATTR, mdd_obj,
+        if ((rc == 0) && (strncmp("user.", name, 5) != 0))
+                rc = mdd_changelog_data_store(env, mdd, CL_XATTR, 0, mdd_obj,
                                               handle);
 
         mdd_trans_stop(env, mdd, rc, handle);