@@ -231,7 +231,10 @@ static int chlg_load(void *args)
goto err_out;
}
- rc = llog_init_handle(NULL, llh, LLOG_F_IS_CAT | LLOG_F_EXT_JOBID,
+ rc = llog_init_handle(NULL, llh,
+ LLOG_F_IS_CAT |
+ LLOG_F_EXT_JOBID |
+ LLOG_F_EXT_EXTRA_FLAGS,
NULL);
if (rc) {
CERROR("%s: fail to init llog handle: rc = %d\n",
@@ -2577,6 +2577,7 @@ enum llog_flag {
LLOG_F_IS_PLAIN = 0x4,
LLOG_F_EXT_JOBID = 0x8,
LLOG_F_IS_FIXSIZE = 0x10,
+ LLOG_F_EXT_EXTRA_FLAGS = 0x20,
/*
* Note: Flags covered by LLOG_F_EXT_MASK will be inherited from
@@ -2584,7 +2585,7 @@ enum llog_flag {
* because the catlog record is usually fixed size, but its plain
* log record can be variable
*/
- LLOG_F_EXT_MASK = LLOG_F_EXT_JOBID,
+ LLOG_F_EXT_MASK = LLOG_F_EXT_JOBID | LLOG_F_EXT_EXTRA_FLAGS,
};
/* On-disk header structure of each log object, stored in little endian order */
@@ -885,7 +885,8 @@ enum changelog_rec_flags {
CLF_VERSION = 0x1000,
CLF_RENAME = 0x2000,
CLF_JOBID = 0x4000,
- CLF_SUPPORTED = CLF_VERSION | CLF_RENAME | CLF_JOBID
+ CLF_EXTRA_FLAGS = 0x8000,
+ CLF_SUPPORTED = CLF_VERSION | CLF_RENAME | CLF_JOBID | CLF_EXTRA_FLAGS
};
/* Anything under the flagmask may be per-type (if desired) */
@@ -971,6 +972,11 @@ static inline void hsm_set_cl_error(int *flags, int error)
*flags |= (error << CLF_HSM_ERR_L);
}
+enum changelog_rec_extra_flags {
+ CLFE_INVALID = 0, /* No additional flags currently implemented */
+ CLFE_SUPPORTED = CLFE_INVALID
+};
+
enum changelog_send_flag {
/* Not yet implemented */
CHANGELOG_FLAG_FOLLOW = 0x01,
@@ -982,10 +988,13 @@ enum changelog_send_flag {
CHANGELOG_FLAG_BLOCK = 0x02,
/* Pack jobid into the changelog records if available. */
CHANGELOG_FLAG_JOBID = 0x04,
+ /* Pack additional flag bits into the changelog record */
+ CHANGELOG_FLAG_EXTRA_FLAGS = 0x08,
};
#define CR_MAXSIZE __ALIGN_KERNEL(2 * NAME_MAX + 2 + \
- changelog_rec_offset(CLF_SUPPORTED), 8)
+ changelog_rec_offset(CLF_SUPPORTED, \
+ CLFE_SUPPORTED), 8)
/* 31 usable bytes string + null terminator. */
#define LUSTRE_JOBID_SIZE 32
@@ -993,9 +1002,10 @@ enum changelog_send_flag {
/*
* This is the minimal changelog record. It can contain extensions
* such as rename fields or process jobid. Its exact content is described
- * by the cr_flags.
+ * by the cr_flags and cr_extra_flags.
*
- * Extensions are packed in the same order as their corresponding flags.
+ * Extensions are packed in the same order as their corresponding flags,
+ * then in the same order as their corresponding extra flags.
*/
struct changelog_rec {
__u16 cr_namelen;
@@ -1022,7 +1032,16 @@ struct changelog_ext_jobid {
char cr_jobid[LUSTRE_JOBID_SIZE]; /**< zero-terminated string. */
};
-static inline size_t changelog_rec_offset(enum changelog_rec_flags crf)
+/* Changelog extension to include additional flags. */
+struct changelog_ext_extra_flags {
+ __u64 cr_extra_flags; /* Additional CLFE_* flags */
+};
+
+static inline struct changelog_ext_extra_flags *changelog_rec_extra_flags(
+ const struct changelog_rec *rec);
+
+static inline size_t changelog_rec_offset(enum changelog_rec_flags crf,
+ enum changelog_rec_extra_flags cref)
{
size_t size = sizeof(struct changelog_rec);
@@ -1032,12 +1051,20 @@ static inline size_t changelog_rec_offset(enum changelog_rec_flags crf)
if (crf & CLF_JOBID)
size += sizeof(struct changelog_ext_jobid);
+ if (crf & CLF_EXTRA_FLAGS)
+ size += sizeof(struct changelog_ext_extra_flags);
+
return size;
}
static inline size_t changelog_rec_size(struct changelog_rec *rec)
{
- return changelog_rec_offset(rec->cr_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;
+
+ return changelog_rec_offset(rec->cr_flags, cref);
}
static inline size_t changelog_rec_varsize(struct changelog_rec *rec)
@@ -1051,7 +1078,8 @@ struct changelog_ext_rename *changelog_rec_rename(struct changelog_rec *rec)
enum changelog_rec_flags crf = rec->cr_flags & CLF_VERSION;
return (struct changelog_ext_rename *)((char *)rec +
- changelog_rec_offset(crf));
+ changelog_rec_offset(crf,
+ CLFE_INVALID));
}
/* The jobid follows the rename extension, if present */
@@ -1062,14 +1090,33 @@ struct changelog_ext_jobid *changelog_rec_jobid(struct changelog_rec *rec)
(CLF_VERSION | CLF_RENAME);
return (struct changelog_ext_jobid *)((char *)rec +
- changelog_rec_offset(crf));
+ changelog_rec_offset(crf,
+ CLFE_INVALID));
}
-/* The name follows the rename and jobid extensions, if present */
+/* The additional flags follow the rename and jobid extensions, if present */
+static inline
+struct changelog_ext_extra_flags *changelog_rec_extra_flags(
+ const struct changelog_rec *rec)
+{
+ enum changelog_rec_flags crf = rec->cr_flags &
+ (CLF_VERSION | CLF_RENAME | CLF_JOBID);
+
+ return (struct changelog_ext_extra_flags *)((char *)rec +
+ changelog_rec_offset(crf,
+ CLFE_INVALID));
+}
+
+/* The name follows the rename, jobid and extra flags extns, if present */
static inline char *changelog_rec_name(struct changelog_rec *rec)
{
- return (char *)rec + changelog_rec_offset(rec->cr_flags &
- CLF_SUPPORTED);
+ enum changelog_rec_extra_flags cref = CLFE_INVALID;
+
+ if (rec->cr_flags & CLF_EXTRA_FLAGS)
+ cref = changelog_rec_extra_flags(rec)->cr_extra_flags;
+
+ return (char *)rec + changelog_rec_offset(rec->cr_flags & CLF_SUPPORTED,
+ cref & CLFE_SUPPORTED);
}
static inline size_t changelog_rec_snamelen(struct changelog_rec *rec)
@@ -1099,31 +1146,57 @@ static inline char *changelog_rec_sname(struct changelog_rec *rec)
* The following assumptions are being made:
* - CLF_RENAME will not be removed
* - CLF_JOBID will not be added without CLF_RENAME being added too
+ * - CLF_EXTRA_FLAGS will not be added without CLF_JOBID being added too
*
* @rec The record to remap.
* @crf_wanted Flags describing the desired extensions.
+ * @cref_want Flags describing the desired extra extensions.
*/
static inline void changelog_remap_rec(struct changelog_rec *rec,
- enum changelog_rec_flags crf_wanted)
+ enum changelog_rec_flags crf_wanted,
+ enum changelog_rec_extra_flags cref_want)
{
+ char *ef_mov;
char *jid_mov, *rnm_mov;
crf_wanted &= CLF_SUPPORTED;
-
- if ((rec->cr_flags & CLF_SUPPORTED) == crf_wanted)
- return;
+ cref_want &= CLFE_SUPPORTED;
+
+ if ((rec->cr_flags & CLF_SUPPORTED) == crf_wanted) {
+ if (!(rec->cr_flags & CLF_EXTRA_FLAGS) ||
+ (rec->cr_flags & CLF_EXTRA_FLAGS &&
+ (changelog_rec_extra_flags(rec)->cr_extra_flags &
+ CLFE_SUPPORTED) ==
+ cref_want))
+ return;
+ }
/* First move the variable-length name field */
- memmove((char *)rec + changelog_rec_offset(crf_wanted),
+ memmove((char *)rec + changelog_rec_offset(crf_wanted, cref_want),
changelog_rec_name(rec), rec->cr_namelen);
- /* Locations of jobid and rename extensions in the remapped record */
+ /* Locations of extensions in the remapped record */
+ ef_mov = (char *)rec +
+ changelog_rec_offset(crf_wanted & ~CLF_EXTRA_FLAGS,
+ CLFE_INVALID);
jid_mov = (char *)rec +
- changelog_rec_offset(crf_wanted & ~CLF_JOBID);
+ changelog_rec_offset(crf_wanted &
+ ~(CLF_EXTRA_FLAGS | CLF_JOBID),
+ CLFE_INVALID);
rnm_mov = (char *)rec +
- changelog_rec_offset(crf_wanted & ~(CLF_JOBID | CLF_RENAME));
+ changelog_rec_offset(crf_wanted &
+ ~(CLF_EXTRA_FLAGS |
+ CLF_JOBID |
+ CLF_RENAME),
+ CLFE_INVALID);
/* Move the extension fields to the desired positions */
+ if ((crf_wanted & CLF_EXTRA_FLAGS) &&
+ (rec->cr_flags & CLF_EXTRA_FLAGS)) {
+ memmove(ef_mov, changelog_rec_extra_flags(rec),
+ sizeof(struct changelog_ext_extra_flags));
+ }
+
if ((crf_wanted & CLF_JOBID) && (rec->cr_flags & CLF_JOBID))
memmove(jid_mov, changelog_rec_jobid(rec),
sizeof(struct changelog_ext_jobid));
@@ -1133,6 +1206,10 @@ static inline void changelog_remap_rec(struct changelog_rec *rec,
sizeof(struct changelog_ext_rename));
/* Clear newly added fields */
+ if ((crf_wanted & CLF_EXTRA_FLAGS) &&
+ !(rec->cr_flags & CLF_EXTRA_FLAGS))
+ memset(ef_mov, 0, sizeof(struct changelog_ext_extra_flags));
+
if ((crf_wanted & CLF_JOBID) && !(rec->cr_flags & CLF_JOBID))
memset(jid_mov, 0, sizeof(struct changelog_ext_jobid));
@@ -1141,6 +1218,10 @@ static inline void changelog_remap_rec(struct changelog_rec *rec,
/* Update the record's flags accordingly */
rec->cr_flags = (rec->cr_flags & CLF_FLAGMASK) | crf_wanted;
+ if (rec->cr_flags & CLF_EXTRA_FLAGS)
+ changelog_rec_extra_flags(rec)->cr_extra_flags =
+ changelog_rec_extra_flags(rec)->cr_extra_flags |
+ cref_want;
}
enum changelog_message_type {