Whamcloud - gitweb
LU-9727 lustre: add CL_GETXATTR for Changelogs 51/28251/22
authorSebastien Buisson <sbuisson@ddn.com>
Thu, 6 Jul 2017 12:50:14 +0000 (21:50 +0900)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 14 Feb 2018 00:51:35 +0000 (00:51 +0000)
Record GETXATTR events in Changelogs, and add a new changelog
extension named changelog_ext_xattr to hold xattr name.
A GETXATTR changlog entry is in the following form:
8 23GXATR 09:22:55.886793012 2017.07.27 0x0
t=[0x200000402:0x1:0x0] ef=0xf u=500:500 nid=10.128.11.159@tcp
x=user.name0
Also, rename CL_XATTR type to CL_SETXATTR.
By default, disable recording of GETXATTR events in Changelogs.

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: Ia02e870ca162c7d2b97eb0ce80e99fe7145b7601
Reviewed-on: https://review.whamcloud.com/28251
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Li Xi <lixi@ddn.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/mdc/mdc_changelog.c
lustre/mdd/mdd_dir.c
lustre/mdd/mdd_internal.h
lustre/mdd/mdd_object.c
lustre/obdclass/llog_osd.c
lustre/utils/lfs.c
lustre/utils/liblustreapi_chlg.c
lustre/utils/lustre_rsync.c

index 5bfe219..b4ee226 100644 (file)
@@ -2702,10 +2702,11 @@ struct llog_size_change_rec {
 /** default \a changelog_rec_type mask. Allow all of them, except
  * CL_ATIME since it can really be time consuming, and not necessary
  * under normal use.
- * Remove also CL_OPEN from default list as it can be costly and only necessary
- * for audit purpose.
+ * Remove also CL_OPEN and CL_GETXATTR from default list as it can be costly and
+ * only necessary for audit purpose.
  */
-#define CHANGELOG_DEFMASK (CHANGELOG_ALLMASK & ~(1 << CL_ATIME | 1 << CL_OPEN))
+#define CHANGELOG_DEFMASK (CHANGELOG_ALLMASK & \
+                          ~(1 << CL_ATIME | 1 << CL_OPEN | 1 << CL_GETXATTR))
 
 /* changelog llog name, needed by client replicators */
 #define CHANGELOG_CATALOG "changelog_catalog"
@@ -2800,6 +2801,7 @@ enum llog_flag {
        LLOG_F_EXT_X_UIDGID     = 0x40,
        LLOG_F_EXT_X_NID        = 0x80,
        LLOG_F_EXT_X_OMODE      = 0x100,
+       LLOG_F_EXT_X_XATTR      = 0x200,
 
        /* Note: Flags covered by LLOG_F_EXT_MASK will be inherited from
         * catlog to plain log, so do not add LLOG_F_IS_FIXSIZE here,
@@ -2807,7 +2809,7 @@ enum llog_flag {
         * log record can be variable */
        LLOG_F_EXT_MASK = LLOG_F_EXT_JOBID | LLOG_F_EXT_EXTRA_FLAGS |
                          LLOG_F_EXT_X_UIDGID | LLOG_F_EXT_X_NID |
-                         LLOG_F_EXT_X_OMODE,
+                         LLOG_F_EXT_X_OMODE | LLOG_F_EXT_X_XATTR,
 };
 
 /* On-disk header structure of each log object, stored in little endian order */
index 8479c11..fabf9db 100644 (file)
@@ -1055,7 +1055,8 @@ enum changelog_rec_type {
        CL_LAYOUT   = 12, /* file layout/striping modified */
        CL_TRUNC    = 13,
        CL_SETATTR  = 14,
-       CL_XATTR    = 15,
+       CL_SETXATTR = 15,
+       CL_XATTR    = CL_SETXATTR, /* Deprecated name */
        CL_HSM      = 16, /* HSM specific events, see flags */
        CL_MTIME    = 17, /* Precedence: setattr > mtime > ctime > atime */
        CL_CTIME    = 18,
@@ -1063,6 +1064,7 @@ enum changelog_rec_type {
        CL_MIGRATE  = 20,
        CL_FLRW     = 21, /* FLR: file was firstly written */
        CL_RESYNC   = 22, /* FLR: file was resync-ed */
+       CL_GETXATTR = 23,
        CL_LAST
 };
 
@@ -1071,7 +1073,7 @@ static inline const char *changelog_type2str(int type) {
                "MARK",  "CREAT", "MKDIR", "HLINK", "SLINK", "MKNOD", "UNLNK",
                "RMDIR", "RENME", "RNMTO", "OPEN",  "CLOSE", "LYOUT", "TRUNC",
                "SATTR", "XATTR", "HSM",   "MTIME", "CTIME", "ATIME", "MIGRT",
-               "FLRW",  "RESYNC",
+               "FLRW",  "RESYNC","GXATR",
        };
 
        if (type >= 0 && type < CL_LAST)
@@ -1178,7 +1180,8 @@ enum changelog_rec_extra_flags {
        CLFE_UIDGID     = 0x0001,
        CLFE_NID        = 0x0002,
        CLFE_OPEN       = 0x0004,
-       CLFE_SUPPORTED  = CLFE_UIDGID | CLFE_NID | CLFE_OPEN
+       CLFE_XATTR      = 0x0008,
+       CLFE_SUPPORTED  = CLFE_UIDGID | CLFE_NID | CLFE_OPEN | CLFE_XATTR
 };
 
 enum changelog_send_flag {
@@ -1201,6 +1204,8 @@ enum changelog_send_extra_flag {
        CHANGELOG_EXTRA_FLAG_NID    = 0x02,
        /* Pack open mode into the changelog record */
        CHANGELOG_EXTRA_FLAG_OMODE  = 0x04,
+       /* Pack xattr name into the changelog record */
+       CHANGELOG_EXTRA_FLAG_XATTR  = 0x08,
 };
 
 #define CR_MAXSIZE cfs_size_round(2 * NAME_MAX + 2 + \
@@ -1267,6 +1272,11 @@ struct changelog_ext_openmode {
        __u32 cr_openflags;
 };
 
+/* Changelog extra extension to include xattr */
+struct changelog_ext_xattr {
+       char cr_xattr[XATTR_NAME_MAX + 1]; /**< zero-terminated string. */
+};
+
 static inline struct changelog_ext_extra_flags *changelog_rec_extra_flags(
        const struct changelog_rec *rec);
 
@@ -1289,6 +1299,8 @@ static inline size_t changelog_rec_offset(enum changelog_rec_flags crf,
                        size += sizeof(struct changelog_ext_nid);
                if (cref & CLFE_OPEN)
                        size += sizeof(struct changelog_ext_openmode);
+               if (cref & CLFE_XATTR)
+                       size += sizeof(struct changelog_ext_xattr);
        }
 
        return size;
@@ -1390,6 +1402,23 @@ struct changelog_ext_openmode *changelog_rec_openmode(
                                               changelog_rec_offset(crf, cref));
 }
 
+/* The xattr name is the fourth extra extension */
+static inline
+struct changelog_ext_xattr *changelog_rec_xattr(
+       const struct changelog_rec *rec)
+{
+       enum changelog_rec_flags crf = rec->cr_flags &
+               (CLF_VERSION | CLF_RENAME | CLF_JOBID | CLF_EXTRA_FLAGS);
+       enum changelog_rec_extra_flags cref = CLFE_INVALID;
+
+       if (rec->cr_flags & CLF_EXTRA_FLAGS)
+               cref = changelog_rec_extra_flags(rec)->cr_extra_flags &
+                       (CLFE_UIDGID | CLFE_NID | CLFE_OPEN);
+
+       return (struct changelog_ext_xattr *)((char *)rec +
+                                             changelog_rec_offset(crf, cref));
+}
+
 /* The name follows the rename, jobid  and extra flags extns, if present */
 static inline char *changelog_rec_name(const struct changelog_rec *rec)
 {
@@ -1439,6 +1468,7 @@ static inline void changelog_remap_rec(struct changelog_rec *rec,
                                       enum changelog_rec_flags crf_wanted,
                                       enum changelog_rec_extra_flags cref_want)
 {
+       char *xattr_mov = NULL;
        char *omd_mov = NULL;
        char *nid_mov = NULL;
        char *uidgid_mov = NULL;
@@ -1465,18 +1495,24 @@ static inline void changelog_remap_rec(struct changelog_rec *rec,
 
        /* Locations of extensions in the remapped record */
        if (rec->cr_flags & CLF_EXTRA_FLAGS) {
+               xattr_mov = (char *)rec +
+                       changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
+                                            cref_want & ~CLFE_XATTR);
                omd_mov = (char *)rec +
                        changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
-                                            cref_want & ~CLFE_OPEN);
+                                            cref_want & ~(CLFE_OPEN |
+                                                          CLFE_XATTR));
                nid_mov = (char *)rec +
                        changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
                                             cref_want & ~(CLFE_NID |
-                                                          CLFE_OPEN));
+                                                          CLFE_OPEN |
+                                                          CLFE_XATTR));
                uidgid_mov = (char *)rec +
                        changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
                                             cref_want & ~(CLFE_UIDGID |
                                                           CLFE_NID |
-                                                          CLFE_OPEN));
+                                                          CLFE_OPEN |
+                                                          CLFE_XATTR));
                cref = changelog_rec_extra_flags(rec)->cr_extra_flags;
        }
 
@@ -1497,6 +1533,10 @@ static inline void changelog_remap_rec(struct changelog_rec *rec,
        /* Move the extension fields to the desired positions */
        if ((crf_wanted & CLF_EXTRA_FLAGS) &&
            (rec->cr_flags & CLF_EXTRA_FLAGS)) {
+               if ((cref_want & CLFE_XATTR) && (cref & CLFE_XATTR))
+                       memmove(xattr_mov, changelog_rec_xattr(rec),
+                               sizeof(struct changelog_ext_xattr));
+
                if ((cref_want & CLFE_OPEN) && (cref & CLFE_OPEN))
                        memmove(omd_mov, changelog_rec_openmode(rec),
                                sizeof(struct changelog_ext_openmode));
@@ -1522,6 +1562,10 @@ static inline void changelog_remap_rec(struct changelog_rec *rec,
                        sizeof(struct changelog_ext_rename));
 
        /* Clear newly added fields */
+       if (xattr_mov && (cref_want & CLFE_XATTR) &&
+           !(cref & CLFE_XATTR))
+               memset(xattr_mov, 0, sizeof(struct changelog_ext_xattr));
+
        if (omd_mov && (cref_want & CLFE_OPEN) &&
            !(cref & CLFE_OPEN))
                memset(omd_mov, 0, sizeof(struct changelog_ext_openmode));
index 96b9dee..e29e705 100644 (file)
@@ -222,7 +222,8 @@ static int chlg_load(void *args)
                              LLOG_F_EXT_EXTRA_FLAGS |
                              LLOG_F_EXT_X_UIDGID |
                              LLOG_F_EXT_X_NID |
-                             LLOG_F_EXT_X_OMODE,
+                             LLOG_F_EXT_X_OMODE |
+                             LLOG_F_EXT_X_XATTR,
                              NULL);
        if (rc) {
                CERROR("%s: fail to init llog handle: rc = %d\n",
index 88ee6a0..2df81f2 100644 (file)
@@ -1069,6 +1069,14 @@ void mdd_changelog_rec_extra_omode(struct changelog_rec *rec, int flags)
        omd->cr_openflags = (__u32)flags;
 }
 
+void mdd_changelog_rec_extra_xattr(struct changelog_rec *rec,
+                                  const char *xattr_name)
+{
+       struct changelog_ext_xattr    *xattr = changelog_rec_xattr(rec);
+
+       strlcpy(xattr->cr_xattr, xattr_name, sizeof(xattr->cr_xattr));
+}
+
 /** Store a namespace change changelog record
  * If this fails, we must fail the whole transaction; we don't
  * want the change to commit without the log entry.
index d704d2f..b93753d 100644 (file)
@@ -311,6 +311,8 @@ void mdd_changelog_rec_extra_uidgid(struct changelog_rec *rec,
 void mdd_changelog_rec_extra_nid(struct changelog_rec *rec,
                                 lnet_nid_t nid);
 void mdd_changelog_rec_extra_omode(struct changelog_rec *rec, int flags);
+void mdd_changelog_rec_extra_xattr(struct changelog_rec *rec,
+                                  const char *xattr_name);
 int mdd_changelog_store(const struct lu_env *env, struct mdd_device *mdd,
                        struct llog_changelog_rec *rec, struct thandle *th);
 int mdd_changelog_data_store(const struct lu_env *env, struct mdd_device *mdd,
index 2e9bf89..5894d79 100644 (file)
@@ -57,6 +57,15 @@ static int mdd_xattr_get(const struct lu_env *env,
                          struct md_object *obj, struct lu_buf *buf,
                          const char *name);
 
+static int mdd_changelog_data_store_by_fid(const struct lu_env *env,
+                                          struct mdd_device *mdd,
+                                          enum changelog_rec_type type,
+                                          int flags, const struct lu_fid *fid,
+                                          const char *xattr_name,
+                                          struct thandle *handle);
+
+static inline bool has_prefix(const char *str, const char *prefix);
+
 int mdd_la_get(const struct lu_env *env, struct mdd_object *obj,
               struct lu_attr *la)
 {
@@ -224,16 +233,18 @@ static int mdd_xattr_get(const struct lu_env *env,
                          struct md_object *obj, struct lu_buf *buf,
                          const char *name)
 {
-        struct mdd_object *mdd_obj = md2mdd_obj(obj);
-        int rc;
+       struct mdd_object *mdd_obj = md2mdd_obj(obj);
+       struct md_device *md_dev = lu2md_dev(mdd2lu_dev(mdo2mdd(obj)));
+       int rc;
 
-        ENTRY;
+       ENTRY;
 
-        if (mdd_object_exists(mdd_obj) == 0) {
-                CERROR("%s: object "DFID" not found: rc = -2\n",
-                       mdd_obj_dev_name(mdd_obj),PFID(mdd_object_fid(mdd_obj)));
-                return -ENOENT;
-        }
+       if (mdd_object_exists(mdd_obj) == 0) {
+               CERROR("%s: object "DFID" not found: rc = -2\n",
+                      mdd_obj_dev_name(mdd_obj),
+                      PFID(mdd_object_fid(mdd_obj)));
+               return -ENOENT;
+       }
 
        /* If the object has been destroyed, then do not get LMVEA, because
         * it needs to load stripes from the iteration of the master object,
@@ -250,11 +261,50 @@ static int mdd_xattr_get(const struct lu_env *env,
                      strcmp(name, XATTR_NAME_LINK) == 0))
                RETURN(-ENOENT);
 
-        mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
+       mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
        rc = mdo_xattr_get(env, mdd_obj, buf, name);
-        mdd_read_unlock(env, mdd_obj);
+       mdd_read_unlock(env, mdd_obj);
+
+       /* record only getting user xattrs and acls */
+       if (rc >= 0 &&
+           (has_prefix(name, XATTR_USER_PREFIX) ||
+            has_prefix(name, XATTR_NAME_POSIX_ACL_ACCESS) ||
+            has_prefix(name, XATTR_NAME_POSIX_ACL_DEFAULT))) {
+               struct thandle *handle;
+               struct mdd_device *mdd = lu2mdd_dev(&md_dev->md_lu_dev);
+               int rc2;
+
+               /* Not recording */
+               if (!(mdd->mdd_cl.mc_flags & CLM_ON))
+                       RETURN(rc);
+               if (!(mdd->mdd_cl.mc_mask & (1 << CL_GETXATTR)))
+                       RETURN(rc);
 
-        RETURN(rc);
+               LASSERT(mdo2fid(mdd_obj) != NULL);
+
+               handle = mdd_trans_create(env, mdd);
+               if (IS_ERR(handle))
+                       RETURN(PTR_ERR(handle));
+
+               rc2 = mdd_declare_changelog_store(env, mdd, NULL, NULL, handle);
+               if (rc2)
+                       GOTO(stop, rc2);
+
+               rc2 = mdd_trans_start(env, mdd, handle);
+               if (rc2)
+                       GOTO(stop, rc2);
+
+               rc2 = mdd_changelog_data_store_by_fid(env, mdd, CL_GETXATTR, 0,
+                                                     mdo2fid(mdd_obj), name,
+                                                     handle);
+
+stop:
+               rc2 = mdd_trans_stop(env, mdd, rc2, handle);
+               if (rc2)
+                       rc = rc2;
+       }
+
+       RETURN(rc);
 }
 
 /*
@@ -634,10 +684,11 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj,
 }
 
 static int mdd_changelog_data_store_by_fid(const struct lu_env *env,
-                                   struct mdd_device *mdd,
-                                   enum changelog_rec_type type, int flags,
-                                   const struct lu_fid *fid,
-                                   struct thandle *handle)
+                                          struct mdd_device *mdd,
+                                          enum changelog_rec_type type,
+                                          int flags, const struct lu_fid *fid,
+                                          const char *xattr_name,
+                                          struct thandle *handle)
 {
        const struct lu_ucred *uc = lu_ucred(env);
        struct llog_changelog_rec *rec;
@@ -656,6 +707,8 @@ static int mdd_changelog_data_store_by_fid(const struct lu_env *env,
        }
        if (type == CL_OPEN)
                xflags |= CLFE_OPEN;
+       if (type == CL_SETXATTR || type == CL_GETXATTR)
+               xflags |= CLFE_XATTR;
 
        reclen = llog_data_len(LLOG_CHANGELOG_HDR_SZ +
                               changelog_rec_offset(flags & CLF_SUPPORTED,
@@ -683,6 +736,11 @@ static int mdd_changelog_data_store_by_fid(const struct lu_env *env,
                        mdd_changelog_rec_extra_nid(&rec->cr, uc->uc_nid);
                if (xflags & CLFE_OPEN)
                        mdd_changelog_rec_extra_omode(&rec->cr, flags);
+               if (xflags & CLFE_XATTR) {
+                       if (xattr_name == NULL)
+                               RETURN(-EINVAL);
+                       mdd_changelog_rec_extra_xattr(&rec->cr, xattr_name);
+               }
        }
 
        rc = mdd_changelog_store(env, mdd, rec, handle);
@@ -723,7 +781,46 @@ int mdd_changelog_data_store(const struct lu_env *env, struct mdd_device *mdd,
        }
 
        rc = mdd_changelog_data_store_by_fid(env, mdd, type, flags,
-                                            mdo2fid(mdd_obj), handle);
+                                            mdo2fid(mdd_obj), NULL, handle);
+       if (rc == 0)
+               mdd_obj->mod_cltime = ktime_get();
+
+       RETURN(rc);
+}
+
+static int mdd_changelog_data_store_xattr(const struct lu_env *env,
+                                         struct mdd_device *mdd,
+                                         enum changelog_rec_type type,
+                                         int flags, struct mdd_object *mdd_obj,
+                                         const char *xattr_name,
+                                         struct thandle *handle)
+{
+       int                              rc;
+
+       LASSERT(mdd_obj != NULL);
+       LASSERT(handle != NULL);
+
+       /* Not recording */
+       if (!(mdd->mdd_cl.mc_flags & CLM_ON))
+               RETURN(0);
+       if ((mdd->mdd_cl.mc_mask & (1 << type)) == 0)
+               RETURN(0);
+
+       if (mdd_is_volatile_obj(mdd_obj))
+               RETURN(0);
+
+       if ((type >= CL_MTIME) && (type <= CL_ATIME) &&
+           ktime_before(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
+                * entry
+                */
+               RETURN(0);
+       }
+
+       rc = mdd_changelog_data_store_by_fid(env, mdd, type, flags,
+                                            mdo2fid(mdd_obj), xattr_name,
+                                            handle);
        if (rc == 0)
                mdd_obj->mod_cltime = ktime_get();
 
@@ -759,7 +856,7 @@ static int mdd_changelog(const struct lu_env *env, enum changelog_rec_type type,
                GOTO(stop, rc);
 
        rc = mdd_changelog_data_store_by_fid(env, mdd, type, flags,
-                                                    fid, handle);
+                                            fid, NULL, handle);
 
 stop:
        rc = mdd_trans_stop(env, mdd, rc, handle);
@@ -1036,8 +1133,10 @@ mdd_xattr_changelog_type(const struct lu_env *env, struct mdd_device *mdd,
 
        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;
+           has_prefix(xattr_name, XATTR_NAME_POSIX_ACL_DEFAULT) ||
+           has_prefix(xattr_name, XATTR_TRUSTED_PREFIX) ||
+           has_prefix(xattr_name, XATTR_SECURITY_PREFIX))
+               return CL_SETXATTR;
 
        return -1;
 }
@@ -1607,8 +1706,8 @@ static int mdd_xattr_set(const struct lu_env *env, struct md_object *obj,
        if (cl_type < 0)
                GOTO(stop, rc = 0);
 
-       rc = mdd_changelog_data_store(env, mdd, cl_type, cl_flags, mdd_obj,
-                                     handle);
+       rc = mdd_changelog_data_store_xattr(env, mdd, cl_type, cl_flags,
+                                           mdd_obj, name, handle);
 
        EXIT;
 stop:
@@ -1676,7 +1775,8 @@ static int mdd_xattr_del(const struct lu_env *env, struct md_object *obj,
        if (mdd_xattr_changelog_type(env, mdd, name) < 0)
                GOTO(stop, rc = 0);
 
-       rc = mdd_changelog_data_store(env, mdd, CL_XATTR, 0, mdd_obj, handle);
+       rc = mdd_changelog_data_store_xattr(env, mdd, CL_SETXATTR, 0, mdd_obj,
+                                           name, handle);
 
        EXIT;
 stop:
index a374221..2fee9d8 100644 (file)
@@ -793,6 +793,8 @@ static void changelog_block_trim_ext(struct llog_rec_hdr *hdr,
        enum changelog_rec_flags flags = CLF_SUPPORTED;
        enum changelog_rec_extra_flags extra_flags = CLFE_SUPPORTED;
 
+       if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_XATTR))
+               extra_flags &= ~CLFE_XATTR;
        if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_OMODE))
                extra_flags &= ~CLFE_OPEN;
        if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_NID))
index 4d2cc6e..1e45c0e 100644 (file)
@@ -5808,7 +5808,8 @@ static int lfs_changelog(int argc, char **argv)
        rc = llapi_changelog_set_xflags(changelog_priv,
                                        CHANGELOG_EXTRA_FLAG_UIDGID |
                                        CHANGELOG_EXTRA_FLAG_NID |
-                                       CHANGELOG_EXTRA_FLAG_OMODE);
+                                       CHANGELOG_EXTRA_FLAG_OMODE |
+                                       CHANGELOG_EXTRA_FLAG_XATTR);
        if (rc < 0) {
                fprintf(stderr, "Can't set xflags for changelog: %s\n",
                        strerror(errno = -rc));
@@ -5889,6 +5890,14 @@ static int lfs_changelog(int argc, char **argv)
                                        printf(" m=%s", mode);
 
                        }
+
+                       if (ef->cr_extra_flags & CLFE_XATTR) {
+                               struct changelog_ext_xattr *xattr =
+                                       changelog_rec_xattr(rec);
+
+                               if (xattr->cr_xattr[0] != '\0')
+                                       printf(" x=%s", xattr->cr_xattr);
+                       }
                }
 
                if (rec->cr_namelen)
index 9ff2c8b..5735fc1 100644 (file)
@@ -251,6 +251,8 @@ int llapi_changelog_recv(void *priv, struct changelog_rec **rech)
                        rec_extra_fmt |= CLFE_NID;
                if (cp->clp_send_extra_flags & CHANGELOG_EXTRA_FLAG_OMODE)
                        rec_extra_fmt |= CLFE_OPEN;
+               if (cp->clp_send_extra_flags & CHANGELOG_EXTRA_FLAG_XATTR)
+                       rec_extra_fmt |= CLFE_XATTR;
        }
 
        if (cp->clp_buf + cp->clp_buf_len <= cp->clp_buf_pos) {
index ed906ac..fe8406a 100644 (file)
@@ -1576,7 +1576,8 @@ int lr_replicate()
        rc = llapi_changelog_set_xflags(changelog_priv,
                                        CHANGELOG_EXTRA_FLAG_UIDGID |
                                        CHANGELOG_EXTRA_FLAG_NID |
-                                       CHANGELOG_EXTRA_FLAG_OMODE);
+                                       CHANGELOG_EXTRA_FLAG_OMODE |
+                                       CHANGELOG_EXTRA_FLAG_XATTR);
        if (rc < 0) {
                fprintf(stderr, "Error setting xflag in changelog for fs %s.\n",
                        status->ls_source_fs);
@@ -1629,12 +1630,13 @@ int lr_replicate()
                 case CL_SETATTR:
                         rc = lr_setattr(info);
                         break;
-                case CL_XATTR:
+               case CL_SETXATTR:
                         rc = lr_setxattr(info);
                         break;
                case CL_CLOSE:
                case CL_EXT:
                case CL_OPEN:
+               case CL_GETXATTR:
                case CL_LAYOUT:
                case CL_MARK:
                        /* Nothing needs to be done for these entries */