From 0f22e4c098b1f7885ef509bbfc346b3e8905b28d Mon Sep 17 00:00:00 2001 From: Henri Doreau Date: Fri, 19 Sep 2014 15:39:56 +0200 Subject: [PATCH] LU-1996 lustre: Flexible changelog format. Added jobid fields to Changelog records (and extended records). The CLF_JOBID flags allows to check if the field is present or not (old format) when reading an entry. Jobids are expressed as 32 chars long, zero-terminated strings. Updated test_205 in sanity.sh. Signed-off-by: Henri Doreau Change-Id: Iacfe7099aa520e012535ac48c44793a1b86870a9 Reviewed-on: http://review.whamcloud.com/4060 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Aurelien Degremont --- lustre/include/cl_object.h | 2 +- lustre/include/lustre/lustre_idl.h | 18 +-- lustre/include/lustre/lustre_user.h | 172 ++++++++++++++++------ lustre/include/lustre/lustreapi.h | 16 +- lustre/include/lustre_nrs_tbf.h | 2 +- lustre/include/md_object.h | 29 ++-- lustre/llite/lcommon_cl.c | 2 +- lustre/llite/llite_internal.h | 2 +- lustre/mdc/mdc_request.c | 50 ++++--- lustre/mdd/mdd_device.c | 7 +- lustre/mdd/mdd_dir.c | 282 ++++++++++++++---------------------- lustre/mdd/mdd_internal.h | 20 ++- lustre/mdd/mdd_object.c | 50 ++++--- lustre/mdt/mdt_internal.h | 13 +- lustre/mdt/mdt_lib.c | 15 ++ lustre/obdclass/class_obd.c | 6 +- lustre/obdclass/llog.c | 18 ++- lustre/obdclass/llog_cat.c | 4 +- lustre/obdclass/llog_internal.h | 5 + lustre/obdclass/llog_osd.c | 42 ++++++ lustre/obdclass/llog_swab.c | 21 +-- lustre/obdclass/llog_test.c | 3 +- lustre/obdclass/lprocfs_jobstats.c | 12 +- lustre/ptlrpc/nrs_tbf.c | 2 +- lustre/ptlrpc/pack_generic.c | 2 +- lustre/ptlrpc/wiretest.c | 72 +++------ lustre/tests/sanity.sh | 13 ++ lustre/utils/lfs.c | 73 ++++++---- lustre/utils/liblustreapi.c | 120 +++++++-------- lustre/utils/lustre_rsync.c | 24 +-- lustre/utils/wirecheck.c | 31 ++-- lustre/utils/wiretest.c | 72 +++------ 32 files changed, 654 insertions(+), 546 deletions(-) diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index 59791bf..2e305f3 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -2418,7 +2418,7 @@ struct cl_req_attr { /** Capability. */ struct obd_capa *cra_capa; /** Jobid */ - char cra_jobid[JOBSTATS_JOBID_SIZE]; + char cra_jobid[LUSTRE_JOBID_SIZE]; }; /** diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 6359780..b6d0516 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -1171,7 +1171,6 @@ struct lustre_msg_v2 { /* without gss, ptlrpc_body is put at the first buffer. */ #define PTLRPC_NUM_VERSIONS 4 -#define JOBSTATS_JOBID_SIZE 32 /* 32 bytes string */ struct ptlrpc_body_v3 { struct lustre_handle pb_handle; __u32 pb_type; @@ -1193,7 +1192,7 @@ struct ptlrpc_body_v3 { __u64 pb_pre_versions[PTLRPC_NUM_VERSIONS]; /* padding for future needs */ __u64 pb_padding[4]; - char pb_jobid[JOBSTATS_JOBID_SIZE]; + char pb_jobid[LUSTRE_JOBID_SIZE]; }; #define ptlrpc_body ptlrpc_body_v3 @@ -3343,15 +3342,9 @@ struct changelog_setinfo { /** changelog record */ struct llog_changelog_rec { - struct llog_rec_hdr cr_hdr; - struct changelog_rec cr; - struct llog_rec_tail cr_tail; /**< for_sizezof_only */ -} __attribute__((packed)); - -struct llog_changelog_ext_rec { - struct llog_rec_hdr cr_hdr; - struct changelog_ext_rec cr; - struct llog_rec_tail cr_tail; /**< for_sizezof_only */ + struct llog_rec_hdr cr_hdr; + struct changelog_rec cr; /**< Variable length field */ + struct llog_rec_tail cr_do_not_use; /**< for_sizeof_only */ } __attribute__((packed)); #define CHANGELOG_USER_PREFIX "cl" @@ -3437,6 +3430,9 @@ enum llog_flag { LLOG_F_ZAP_WHEN_EMPTY = 0x1, LLOG_F_IS_CAT = 0x2, LLOG_F_IS_PLAIN = 0x4, + LLOG_F_EXT_JOBID = 0x8, + + LLOG_F_EXT_MASK = LLOG_F_EXT_JOBID, }; struct llog_log_hdr { diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index 6fdc747..3764a54 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -723,11 +723,17 @@ static inline const char *changelog_type2str(int type) { } /* per-record flags */ -#define CLF_VERSION 0x1000 -#define CLF_EXT_VERSION 0x2000 #define CLF_FLAGSHIFT 12 #define CLF_FLAGMASK ((1U << CLF_FLAGSHIFT) - 1) #define CLF_VERMASK (~CLF_FLAGMASK) +enum changelog_rec_flags { + CLF_VERSION = 0x1000, + CLF_RENAME = 0x2000, + CLF_JOBID = 0x4000, + CLF_SUPPORTED = CLF_VERSION | CLF_RENAME | CLF_JOBID +}; + + /* Anything under the flagmask may be per-type (if desired) */ /* Flags for unlink */ #define CLF_UNLINK_LAST 0x0001 /* Unlink of last hardlink */ @@ -809,70 +815,150 @@ static inline void hsm_set_cl_error(int *flags, int error) *flags |= (error << CLF_HSM_ERR_L); } -#define CR_MAXSIZE cfs_size_round(2*NAME_MAX + 1 + \ - sizeof(struct changelog_ext_rec)) +enum changelog_send_flag { + /* Not yet implemented */ + CHANGELOG_FLAG_FOLLOW = 0x01, + /* Blocking IO makes sense in case of slow user parsing of the records, + * but it also prevents us from cleaning up if the records are not + * consumed. */ + CHANGELOG_FLAG_BLOCK = 0x02, + /* Pack jobid into the changelog records if available. */ + CHANGELOG_FLAG_JOBID = 0x04, +}; -struct changelog_rec { - __u16 cr_namelen; - __u16 cr_flags; /**< (flags&CLF_FLAGMASK)|CLF_VERSION */ - __u32 cr_type; /**< \a changelog_rec_type */ - __u64 cr_index; /**< changelog record number */ - __u64 cr_prev; /**< last index for this target fid */ - __u64 cr_time; - union { - lustre_fid cr_tfid; /**< target fid */ - __u32 cr_markerflags; /**< CL_MARK flags */ - }; - lustre_fid cr_pfid; /**< parent fid */ - char cr_name[0]; /**< last element */ -} __attribute__((packed)); +#define CR_MAXSIZE cfs_size_round(2 * NAME_MAX + 2 + \ + changelog_rec_offset(CLF_SUPPORTED)) -/* changelog_ext_rec is 2*sizeof(lu_fid) bigger than changelog_rec, to save - * space, only rename uses changelog_ext_rec, while others use changelog_rec to - * store records. +/* 31 usable bytes string + null terminator. */ +#define LUSTRE_JOBID_SIZE 32 + +/* 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. + * + * Extensions are packed in the same order as their corresponding flags. */ -struct changelog_ext_rec { +struct changelog_rec { __u16 cr_namelen; - __u16 cr_flags; /**< (flags & CLF_FLAGMASK) | - CLF_EXT_VERSION */ + __u16 cr_flags; /**< \a changelog_rec_flags */ __u32 cr_type; /**< \a changelog_rec_type */ __u64 cr_index; /**< changelog record number */ __u64 cr_prev; /**< last index for this target fid */ __u64 cr_time; union { - lustre_fid cr_tfid; /**< target fid */ + lustre_fid cr_tfid; /**< target fid */ __u32 cr_markerflags; /**< CL_MARK flags */ }; - lustre_fid cr_pfid; /**< target parent fid */ - lustre_fid cr_sfid; /**< source fid, or zero */ - lustre_fid cr_spfid; /**< source parent fid, or zero */ - char cr_name[0]; /**< last element */ -} __attribute__((packed)); + lustre_fid cr_pfid; /**< parent fid */ +}; -#define CHANGELOG_REC_EXTENDED(rec) \ - (((rec)->cr_flags & CLF_VERMASK) == CLF_EXT_VERSION) +/* Changelog extension for RENAME. */ +struct changelog_ext_rename { + lustre_fid cr_sfid; /**< source fid, or zero */ + lustre_fid cr_spfid; /**< source parent fid, or zero */ +}; -static inline int changelog_rec_size(const struct changelog_rec *rec) +/* Changelog extension to include JOBID. */ +struct changelog_ext_jobid { + char cr_jobid[LUSTRE_JOBID_SIZE]; /**< zero-terminated string. */ +}; + + +static inline unsigned int changelog_rec_offset(enum changelog_rec_flags crf) { - return CHANGELOG_REC_EXTENDED(rec) ? sizeof(struct changelog_ext_rec): - sizeof(*rec); + unsigned int size = sizeof(struct changelog_rec); + + if (crf & CLF_RENAME) + size += sizeof(struct changelog_ext_rename); + + if (crf & CLF_JOBID) + size += sizeof(struct changelog_ext_jobid); + + return size; } -static inline const char *changelog_rec_name(const struct changelog_rec *rec) +static inline unsigned int changelog_rec_size(struct changelog_rec *rec) { - return CHANGELOG_REC_EXTENDED(rec) ? - ((struct changelog_ext_rec *)rec)->cr_name: rec->cr_name; + return changelog_rec_offset(rec->cr_flags); } -static inline int changelog_rec_snamelen(const struct changelog_ext_rec *rec) +static inline unsigned int changelog_rec_varsize(struct changelog_rec *rec) { - return rec->cr_namelen - strlen(rec->cr_name) - 1; + return changelog_rec_size(rec) - sizeof(*rec) + rec->cr_namelen; +} + +static inline +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)); } -static inline const char *changelog_rec_sname(const struct changelog_ext_rec - *rec) +/* The jobid follows the rename extension, if present */ +static inline +struct changelog_ext_jobid *changelog_rec_jobid(struct changelog_rec *rec) { - return rec->cr_name + strlen(rec->cr_name) + 1; + enum changelog_rec_flags crf = rec->cr_flags & + (CLF_VERSION | CLF_RENAME); + + return (struct changelog_ext_jobid *)((char *)rec + + changelog_rec_offset(crf)); +} + +/* The name follows the rename and jobid extensions, if present */ +static inline char *changelog_rec_name(struct changelog_rec *rec) +{ + return (char *)rec + changelog_rec_offset(rec->cr_flags & + CLF_SUPPORTED); +} + +static inline int changelog_rec_snamelen(struct changelog_rec *rec) +{ + return rec->cr_namelen - strlen(changelog_rec_name(rec)) - 1; +} + +static inline char *changelog_rec_sname(struct changelog_rec *rec) +{ + char *cr_name = changelog_rec_name(rec); + + return cr_name + strlen(cr_name) + 1; +} + +/* Remap a record to the desired format as specified by the crf flags. + * The record must be big enough to contain the final remapped version. */ +static inline void changelog_remap_rec(struct changelog_rec *rec, + enum changelog_rec_flags crf) +{ + char *var_part; + size_t var_size; + + crf &= CLF_SUPPORTED; + + if ((rec->cr_flags & CLF_SUPPORTED) == crf) + return; + + if ((crf & CLF_JOBID) && rec->cr_flags & CLF_JOBID) { + var_part = (char *)changelog_rec_jobid(rec); + var_size = rec->cr_namelen + sizeof(struct changelog_ext_jobid); + } else { + var_part = changelog_rec_name(rec); + var_size = rec->cr_namelen; + } + + memmove((char *)rec + changelog_rec_offset(crf & ~CLF_JOBID), var_part, + var_size); + + if ((crf & CLF_RENAME) && !(rec->cr_flags & CLF_RENAME)) + memset(changelog_rec_rename(rec), 0, + sizeof(struct changelog_ext_rename)); + + if ((crf & CLF_JOBID) && !(rec->cr_flags & CLF_JOBID)) + memset(changelog_rec_jobid(rec), 0, + sizeof(struct changelog_ext_jobid)); + + rec->cr_flags = (rec->cr_flags & CLF_FLAGMASK) | crf; } struct ioc_changelog { diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index 392ba5d..072df8f 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -306,23 +306,19 @@ extern int llapi_fswap_layouts(const int fd1, const int fd2, extern int llapi_swap_layouts(const char *path1, const char *path2, __u64 dv1, __u64 dv2, __u64 flags); -/* Changelog interface. priv is private state, managed internally - by these functions */ -#define CHANGELOG_FLAG_FOLLOW 0x01 /* Not yet implemented */ -#define CHANGELOG_FLAG_BLOCK 0x02 /* Blocking IO makes sense in case of - slow user parsing of the records, but it also prevents us from cleaning - up if the records are not consumed. */ +/* Changelog interface. priv is private state, managed internally by these + * functions */ /* Records received are in extentded format now, though most of them are still * written in disk in changelog_rec format (to save space and time), it's * converted to extented format in the lustre api to ease changelog analysis. */ #define HAVE_CHANGELOG_EXTEND_REC 1 -extern int llapi_changelog_start(void **priv, int flags, const char *mdtname, - long long startrec); +extern int llapi_changelog_start(void **priv, enum changelog_send_flag flags, + const char *mdtname, long long startrec); extern int llapi_changelog_fini(void **priv); -extern int llapi_changelog_recv(void *priv, struct changelog_ext_rec **rech); -extern int llapi_changelog_free(struct changelog_ext_rec **rech); +extern int llapi_changelog_recv(void *priv, struct changelog_rec **rech); +extern int llapi_changelog_free(struct changelog_rec **rech); /* Allow records up to endrec to be destroyed; requires registered id. */ extern int llapi_changelog_clear(const char *mdtname, const char *idstr, long long endrec); diff --git a/lustre/include/lustre_nrs_tbf.h b/lustre/include/lustre_nrs_tbf.h index df80599..f5f4f31 100644 --- a/lustre/include/lustre_nrs_tbf.h +++ b/lustre/include/lustre_nrs_tbf.h @@ -56,7 +56,7 @@ struct nrs_tbf_client { /** NID of the client. */ lnet_nid_t tc_nid; /** Jobid of the client. */ - char tc_jobid[JOBSTATS_JOBID_SIZE]; + char tc_jobid[LUSTRE_JOBID_SIZE]; /** Reference number of the client. */ atomic_t tc_ref; /** Likage to rule. */ diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index a93e09d..7752975 100644 --- a/lustre/include/md_object.h +++ b/lustre/include/md_object.h @@ -840,20 +840,21 @@ enum { }; struct lu_ucred { - __u32 uc_valid; - __u32 uc_o_uid; - __u32 uc_o_gid; - __u32 uc_o_fsuid; - __u32 uc_o_fsgid; - __u32 uc_uid; - __u32 uc_gid; - __u32 uc_fsuid; - __u32 uc_fsgid; - __u32 uc_suppgids[2]; - cfs_cap_t uc_cap; - __u32 uc_umask; - struct group_info *uc_ginfo; - struct md_identity *uc_identity; + __u32 uc_valid; + __u32 uc_o_uid; + __u32 uc_o_gid; + __u32 uc_o_fsuid; + __u32 uc_o_fsgid; + __u32 uc_uid; + __u32 uc_gid; + __u32 uc_fsuid; + __u32 uc_fsgid; + __u32 uc_suppgids[2]; + cfs_cap_t uc_cap; + __u32 uc_umask; + struct group_info *uc_ginfo; + struct md_identity *uc_identity; + char uc_jobid[LUSTRE_JOBID_SIZE]; }; struct lu_ucred *lu_ucred(const struct lu_env *env); diff --git a/lustre/llite/lcommon_cl.c b/lustre/llite/lcommon_cl.c index 338727f..84ff1ee 100644 --- a/lustre/llite/lcommon_cl.c +++ b/lustre/llite/lcommon_cl.c @@ -945,7 +945,7 @@ void ccc_req_attr_set(const struct lu_env *env, if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_INVALID_PFID)) oa->o_parent_oid++; memcpy(attr->cra_jobid, cl_i2info(inode)->lli_jobid, - JOBSTATS_JOBID_SIZE); + LUSTRE_JOBID_SIZE); } static const struct cl_req_operations ccc_req_ops = { diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 3835a8b..739dae2 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -250,7 +250,7 @@ struct ll_inode_info { * so the read/write statistics for jobid will not be * accurate if the file is shared by different jobs. */ - char f_jobid[JOBSTATS_JOBID_SIZE]; + char f_jobid[LUSTRE_JOBID_SIZE]; } f; #define lli_size_mutex u.f.f_size_mutex diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 032f88f..ca463cd 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -1996,26 +1996,32 @@ static struct kuc_hdr *changelog_kuc_hdr(char *buf, int len, int flags) } struct changelog_show { - __u64 cs_startrec; - __u32 cs_flags; - struct file *cs_fp; - char *cs_buf; - struct obd_device *cs_obd; + __u64 cs_startrec; + enum changelog_send_flag cs_flags; + struct file *cs_fp; + char *cs_buf; + struct obd_device *cs_obd; }; +static inline char *cs_obd_name(struct changelog_show *cs) +{ + return cs->cs_obd->obd_name; +} + static int changelog_kkuc_cb(const struct lu_env *env, struct llog_handle *llh, struct llog_rec_hdr *hdr, void *data) { - struct changelog_show *cs = data; - struct llog_changelog_rec *rec = (struct llog_changelog_rec *)hdr; - struct kuc_hdr *lh; - int len, rc; + struct changelog_show *cs = data; + struct llog_changelog_rec *rec = (struct llog_changelog_rec *)hdr; + struct kuc_hdr *lh; + int len; + int rc; ENTRY; if (rec->cr_hdr.lrh_type != CHANGELOG_REC) { rc = -EINVAL; CERROR("%s: not a changelog rec %x/%d: rc = %d\n", - cs->cs_obd->obd_name, rec->cr_hdr.lrh_type, + cs_obd_name(cs), rec->cr_hdr.lrh_type, rec->cr.cr_type, rc); RETURN(rc); } @@ -2048,11 +2054,12 @@ static int changelog_kkuc_cb(const struct lu_env *env, struct llog_handle *llh, static int mdc_changelog_send_thread(void *csdata) { - struct changelog_show *cs = csdata; - struct llog_ctxt *ctxt = NULL; - struct llog_handle *llh = NULL; - struct kuc_hdr *kuch; - int rc; + struct changelog_show *cs = csdata; + struct llog_ctxt *ctxt = NULL; + struct llog_handle *llh = NULL; + struct kuc_hdr *kuch; + enum llog_flag flags = LLOG_F_IS_CAT; + int rc; CDEBUG(D_HSM, "changelog to fp=%p start "LPU64"\n", cs->cs_fp, cs->cs_startrec); @@ -2069,10 +2076,14 @@ static int mdc_changelog_send_thread(void *csdata) LLOG_OPEN_EXISTS); if (rc) { CERROR("%s: fail to open changelog catalog: rc = %d\n", - cs->cs_obd->obd_name, rc); + cs_obd_name(cs), rc); GOTO(out, rc); } - rc = llog_init_handle(NULL, llh, LLOG_F_IS_CAT, NULL); + + if (cs->cs_flags & CHANGELOG_FLAG_JOBID) + flags |= LLOG_F_EXT_JOBID; + + rc = llog_init_handle(NULL, llh, flags, NULL); if (rc) { CERROR("llog_init_handle failed %d\n", rc); GOTO(out, rc); @@ -2126,11 +2137,12 @@ static int mdc_ioc_changelog_send(struct obd_device *obd, if (IS_ERR(task)) { rc = PTR_ERR(task); CERROR("%s: cannot start changelog thread: rc = %d\n", - obd->obd_name, rc); + cs_obd_name(cs), rc); OBD_FREE_PTR(cs); } else { rc = 0; - CDEBUG(D_HSM, "%s: started changelog thread\n", obd->obd_name); + CDEBUG(D_HSM, "%s: started changelog thread\n", + cs_obd_name(cs)); } return rc; diff --git a/lustre/mdd/mdd_device.c b/lustre/mdd/mdd_device.c index d81f193..0971cb7 100644 --- a/lustre/mdd/mdd_device.c +++ b/lustre/mdd/mdd_device.c @@ -170,7 +170,7 @@ static int changelog_init_cb(const struct lu_env *env, struct llog_handle *llh, "seeing record at index %d/%d/"LPU64" t=%x %.*s in log" DOSTID"\n", hdr->lrh_index, rec->cr_hdr.lrh_index, rec->cr.cr_index, rec->cr.cr_type, rec->cr.cr_namelen, - rec->cr.cr_name, POSTID(&llh->lgh_id.lgl_oi)); + changelog_rec_name(&rec->cr), POSTID(&llh->lgh_id.lgl_oi)); mdd->mdd_cl.mc_index = rec->cr.cr_index; return LLOG_PROC_BREAK; @@ -517,10 +517,11 @@ int mdd_changelog_write_header(const struct lu_env *env, rec->cr.cr_flags = CLF_VERSION; rec->cr.cr_type = CL_MARK; rec->cr.cr_namelen = len; - memcpy(rec->cr.cr_name, obd->obd_name, rec->cr.cr_namelen); + memcpy(changelog_rec_name(&rec->cr), obd->obd_name, rec->cr.cr_namelen); /* Status and action flags */ rec->cr.cr_markerflags = mdd->mdd_cl.mc_flags | markerflags; - rec->cr_hdr.lrh_len = llog_data_len(sizeof(*rec) + rec->cr.cr_namelen); + rec->cr_hdr.lrh_len = llog_data_len(changelog_rec_size(&rec->cr) + + rec->cr.cr_namelen); rec->cr_hdr.lrh_type = CHANGELOG_REC; rec->cr.cr_time = cl_time(); spin_lock(&mdd->mdd_cl.mc_lock); diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index a60d55b..bccc16d 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -643,51 +643,35 @@ static int __mdd_index_delete(const struct lu_env *env, struct mdd_object *pobj, RETURN(rc); } -int mdd_declare_changelog_store(const struct lu_env *env, - struct mdd_device *mdd, - const struct lu_name *fname, - struct thandle *handle) +static int mdd_llog_record_calc_size(const struct lu_env *env, + const struct lu_name *tname, + const struct lu_name *sname) { - struct obd_device *obd = mdd2obd_dev(mdd); - struct llog_ctxt *ctxt; - struct llog_changelog_rec *rec; - struct lu_buf *buf; - int reclen; - int rc; + const struct lu_ucred *uc = lu_ucred(env); + enum changelog_rec_flags crf = 0; + size_t hdr_size = sizeof(struct llog_changelog_rec) - + sizeof(struct changelog_rec); - /* Not recording */ - if (!(mdd->mdd_cl.mc_flags & CLM_ON)) - return 0; + if (sname != NULL) + crf |= CLF_RENAME; - reclen = llog_data_len(sizeof(*rec) + - (fname != NULL ? fname->ln_namelen : 0)); - buf = lu_buf_check_and_alloc(&mdd_env_info(env)->mti_big_buf, reclen); - if (buf->lb_buf == NULL) - return -ENOMEM; + if (uc != NULL && uc->uc_jobid[0] != '\0') + crf |= CLF_JOBID; - rec = buf->lb_buf; - rec->cr_hdr.lrh_len = reclen; - rec->cr_hdr.lrh_type = CHANGELOG_REC; - - ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); - if (ctxt == NULL) - return -ENXIO; - - rc = llog_declare_add(env, ctxt->loc_handle, &rec->cr_hdr, handle); - llog_ctxt_put(ctxt); - - return rc; + return llog_data_len(hdr_size + changelog_rec_offset(crf) + + (tname != NULL ? tname->ln_namelen : 0) + + (sname != NULL ? 1 + sname->ln_namelen : 0)); } -static int mdd_declare_changelog_ext_store(const struct lu_env *env, - struct mdd_device *mdd, - const struct lu_name *tname, - const struct lu_name *sname, - struct thandle *handle) +int mdd_declare_changelog_store(const struct lu_env *env, + struct mdd_device *mdd, + const struct lu_name *tname, + const struct lu_name *sname, + struct thandle *handle) { struct obd_device *obd = mdd2obd_dev(mdd); struct llog_ctxt *ctxt; - struct llog_changelog_ext_rec *rec; + struct llog_changelog_rec *rec; struct lu_buf *buf; int reclen; int rc; @@ -696,9 +680,7 @@ static int mdd_declare_changelog_ext_store(const struct lu_env *env, if (!(mdd->mdd_cl.mc_flags & CLM_ON)) return 0; - reclen = llog_data_len(sizeof(*rec) + - (tname != NULL ? tname->ln_namelen : 0) + - (sname != NULL ? 1 + sname->ln_namelen : 0)); + reclen = mdd_llog_record_calc_size(env, tname, sname); buf = lu_buf_check_and_alloc(&mdd_env_info(env)->mti_big_buf, reclen); if (buf->lb_buf == NULL) return -ENOMEM; @@ -721,7 +703,7 @@ static int mdd_declare_changelog_ext_store(const struct lu_env *env, * \param mdd * \param rec * \param handle - currently ignored since llogs start their own transaction; - * this will hopefully be fixed in llog rewrite + * this will hopefully be fixed in llog rewrite * \retval 0 ok */ int mdd_changelog_store(const struct lu_env *env, struct mdd_device *mdd, @@ -731,44 +713,9 @@ int mdd_changelog_store(const struct lu_env *env, struct mdd_device *mdd, struct llog_ctxt *ctxt; int rc; - rec->cr_hdr.lrh_len = llog_data_len(sizeof(*rec) + rec->cr.cr_namelen); - rec->cr_hdr.lrh_type = CHANGELOG_REC; - rec->cr.cr_time = cl_time(); - - spin_lock(&mdd->mdd_cl.mc_lock); - /* NB: I suppose it's possible llog_add adds out of order wrt cr_index, - * but as long as the MDD transactions are ordered correctly for e.g. - * rename conflicts, I don't think this should matter. */ - rec->cr.cr_index = ++mdd->mdd_cl.mc_index; - spin_unlock(&mdd->mdd_cl.mc_lock); - - ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); - if (ctxt == NULL) - return -ENXIO; - - rc = llog_add(env, ctxt->loc_handle, &rec->cr_hdr, NULL, th); - llog_ctxt_put(ctxt); - if (rc > 0) - rc = 0; - return rc; -} - -/** Add a changelog_ext entry \a rec to the changelog llog - * \param mdd - * \param rec - * \param handle - currently ignored since llogs start their own transaction; - * this will hopefully be fixed in llog rewrite - * \retval 0 ok - */ -static int -mdd_changelog_ext_store(const struct lu_env *env, struct mdd_device *mdd, - struct llog_changelog_ext_rec *rec, struct thandle *th) -{ - struct obd_device *obd = mdd2obd_dev(mdd); - struct llog_ctxt *ctxt; - int rc; + rec->cr_hdr.lrh_len = llog_data_len(sizeof(*rec) + + changelog_rec_varsize(&rec->cr)); - 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; rec->cr.cr_time = cl_time(); @@ -793,63 +740,36 @@ mdd_changelog_ext_store(const struct lu_env *env, struct mdd_device *mdd, return rc; } -/** 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. - * \param target - mdd_object of change - * \param parent - parent dir/object - * \param tname - target name string - * \param handle - transacion handle - */ -int mdd_changelog_ns_store(const struct lu_env *env, struct mdd_device *mdd, - enum changelog_rec_type type, unsigned flags, - struct mdd_object *target, struct mdd_object *parent, - const struct lu_name *tname, struct thandle *handle) +static void mdd_changelog_rec_ext_rename(struct changelog_rec *rec, + const struct lu_fid *sfid, + const struct lu_fid *spfid, + const struct lu_name *sname) { - struct llog_changelog_rec *rec; - struct lu_buf *buf; - int reclen; - int rc; - ENTRY; + struct changelog_ext_rename *rnm = changelog_rec_rename(rec); + size_t extsize = sname->ln_namelen + 1; - /* Not recording */ - if (!(mdd->mdd_cl.mc_flags & CLM_ON)) - RETURN(0); - if ((mdd->mdd_cl.mc_mask & (1 << type)) == 0) - RETURN(0); - - LASSERT(target != NULL); - LASSERT(parent != NULL); - LASSERT(tname != NULL); - LASSERT(handle != NULL); + LASSERT(sfid != NULL); + LASSERT(spfid != NULL); + LASSERT(sname != NULL); - reclen = llog_data_len(sizeof(*rec) + tname->ln_namelen); - buf = lu_buf_check_and_alloc(&mdd_env_info(env)->mti_big_buf, reclen); - if (buf->lb_buf == NULL) - RETURN(-ENOMEM); - rec = buf->lb_buf; + rnm->cr_sfid = *sfid; + rnm->cr_spfid = *spfid; - rec->cr.cr_flags = CLF_VERSION | (CLF_FLAGMASK & flags); - rec->cr.cr_type = (__u32)type; - rec->cr.cr_tfid = *mdo2fid(target); - rec->cr.cr_pfid = *mdo2fid(parent); - rec->cr.cr_namelen = tname->ln_namelen; - memcpy(rec->cr.cr_name, tname->ln_name, tname->ln_namelen); + changelog_rec_name(rec)[rec->cr_namelen] = '\0'; + strlcpy(changelog_rec_sname(rec), sname->ln_name, extsize); + rec->cr_namelen += extsize; +} - target->mod_cltime = cfs_time_current_64(); +void mdd_changelog_rec_ext_jobid(struct changelog_rec *rec, const char *jobid) +{ + struct changelog_ext_jobid *jid = changelog_rec_jobid(rec); - rc = mdd_changelog_store(env, mdd, rec, handle); - if (rc < 0) { - CERROR("changelog failed: rc=%d, op%d %s c"DFID" p"DFID"\n", - rc, type, tname->ln_name, PFID(&rec->cr.cr_tfid), - PFID(&rec->cr.cr_pfid)); - RETURN(-EFAULT); - } + if (jobid == NULL || jobid[0] == '\0') + return; - RETURN(0); + strlcpy(jid->cr_jobid, jobid, sizeof(jid->cr_jobid)); } - /** 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. @@ -861,55 +781,63 @@ int mdd_changelog_ns_store(const struct lu_env *env, struct mdd_device *mdd, * \param sname - source name string * \param handle - transacion handle */ -static int mdd_changelog_ext_ns_store(const struct lu_env *env, - struct mdd_device *mdd, - enum changelog_rec_type type, - unsigned flags, - struct mdd_object *target, - const struct lu_fid *tpfid, - const struct lu_fid *sfid, - const struct lu_fid *spfid, - const struct lu_name *tname, - const struct lu_name *sname, - struct thandle *handle) -{ - struct llog_changelog_ext_rec *rec; - struct lu_buf *buf; - int reclen; - int rc; +int mdd_changelog_ns_store(const struct lu_env *env, + struct mdd_device *mdd, + enum changelog_rec_type type, + enum changelog_rec_flags crf, + struct mdd_object *target, + const struct lu_fid *tpfid, + const struct lu_fid *sfid, + const struct lu_fid *spfid, + const struct lu_name *tname, + const struct lu_name *sname, + struct thandle *handle) +{ + const struct lu_ucred *uc = lu_ucred(env); + struct llog_changelog_rec *rec; + struct lu_buf *buf; + int reclen; + 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(sfid != NULL); LASSERT(tpfid != NULL); LASSERT(tname != NULL); LASSERT(handle != NULL); - reclen = llog_data_len(sizeof(*rec) + - sname != NULL ? 1 + sname->ln_namelen : 0); + reclen = mdd_llog_record_calc_size(env, tname, sname); buf = lu_buf_check_and_alloc(&mdd_env_info(env)->mti_big_buf, reclen); if (buf->lb_buf == NULL) RETURN(-ENOMEM); rec = buf->lb_buf; - rec->cr.cr_flags = CLF_EXT_VERSION | (CLF_FLAGMASK & flags); + crf = (crf & CLF_FLAGMASK); + + if (uc->uc_jobid[0] != '\0') + crf |= CLF_JOBID; + + if (sname != NULL) + crf |= CLF_RENAME; + else + crf |= CLF_VERSION; + + rec->cr.cr_flags = crf; rec->cr.cr_type = (__u32)type; rec->cr.cr_pfid = *tpfid; - rec->cr.cr_sfid = *sfid; - rec->cr.cr_spfid = *spfid; rec->cr.cr_namelen = tname->ln_namelen; - memcpy(rec->cr.cr_name, tname->ln_name, tname->ln_namelen); - if (sname) { - rec->cr.cr_name[tname->ln_namelen] = '\0'; - memcpy(rec->cr.cr_name + tname->ln_namelen + 1, sname->ln_name, - sname->ln_namelen); - rec->cr.cr_namelen += 1 + sname->ln_namelen; - } + memcpy(changelog_rec_name(&rec->cr), tname->ln_name, tname->ln_namelen); + + if (crf & CLF_RENAME) + mdd_changelog_rec_ext_rename(&rec->cr, sfid, spfid, sname); + + if (crf & CLF_JOBID) + mdd_changelog_rec_ext_jobid(&rec->cr, uc->uc_jobid); if (likely(target != NULL)) { rec->cr.cr_tfid = *mdo2fid(target); @@ -918,7 +846,7 @@ static int mdd_changelog_ext_ns_store(const struct lu_env *env, fid_zero(&rec->cr.cr_tfid); } - rc = mdd_changelog_ext_store(env, mdd, rec, handle); + rc = mdd_changelog_store(env, mdd, rec, handle); if (rc < 0) { CERROR("changelog failed: rc=%d, op%d %s c"DFID" p"DFID"\n", rc, type, tname->ln_name, PFID(sfid), PFID(tpfid)); @@ -1243,11 +1171,11 @@ static int mdd_declare_link(const struct lu_env *env, rc = mdo_declare_index_insert(env, p, mdo2fid(c), mdd_object_type(c), name->ln_name, handle); if (rc != 0) - return rc; + return rc; - rc = mdo_declare_ref_add(env, c, handle); - if (rc) - return rc; + rc = mdo_declare_ref_add(env, c, handle); + if (rc) + return rc; la->la_valid = LA_CTIME | LA_MTIME; rc = mdo_declare_attr_set(env, p, la, handle); @@ -1256,16 +1184,16 @@ static int mdd_declare_link(const struct lu_env *env, la->la_valid = LA_CTIME; rc = mdo_declare_attr_set(env, c, la, handle); - if (rc) - return rc; + if (rc) + return rc; rc = mdd_declare_links_add(env, c, handle, data); - if (rc) - return rc; + if (rc) + return rc; - rc = mdd_declare_changelog_store(env, mdd, name, handle); + rc = mdd_declare_changelog_store(env, mdd, name, NULL, handle); - return rc; + return rc; } static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj, @@ -1364,7 +1292,8 @@ out_unlock: mdd_write_unlock(env, mdd_sobj); if (rc == 0) rc = mdd_changelog_ns_store(env, mdd, CL_HARDLINK, 0, mdd_sobj, - mdd_tobj, lname, handle); + mdo2fid(mdd_tobj), NULL, NULL, + lname, NULL, handle); stop: mdd_trans_stop(env, mdd, rc, handle); @@ -1531,7 +1460,7 @@ static int mdd_declare_unlink(const struct lu_env *env, struct mdd_device *mdd, return rc; /* FIXME: need changelog for remove entry */ - rc = mdd_declare_changelog_store(env, mdd, name, handle); + rc = mdd_declare_changelog_store(env, mdd, name, NULL, handle); } return rc; @@ -1718,7 +1647,8 @@ cleanup: rc = mdd_changelog_ns_store(env, mdd, is_dir ? CL_RMDIR : CL_UNLINK, cl_flags, - mdd_cobj, mdd_pobj, lname, handle); + mdd_cobj, mdo2fid(mdd_pobj), NULL, NULL, lname, NULL, + handle); } stop: @@ -1800,7 +1730,7 @@ static int mdd_create_data(const struct lu_env *env, struct md_object *pobj, if (rc) GOTO(stop, rc); - rc = mdd_declare_changelog_store(env, mdd, NULL, handle); + rc = mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); if (rc) GOTO(stop, rc); @@ -2107,7 +2037,7 @@ static int mdd_declare_create(const struct lu_env *env, struct mdd_device *mdd, if (rc) return rc; - rc = mdd_declare_changelog_store(env, mdd, name, handle); + rc = mdd_declare_changelog_store(env, mdd, name, NULL, handle); if (rc) return rc; } @@ -2464,7 +2394,8 @@ out_volatile: S_ISDIR(attr->la_mode) ? CL_MKDIR : S_ISREG(attr->la_mode) ? CL_CREATE : S_ISLNK(attr->la_mode) ? CL_SOFTLINK : CL_MKNOD, - 0, son, mdd_pobj, lname, handle); + 0, son, mdo2fid(mdd_pobj), NULL, NULL, lname, + NULL, handle); out_stop: rc2 = mdd_trans_stop(env, mdd, rc, handle); if (rc == 0) @@ -2680,7 +2611,7 @@ static int mdd_declare_rename(const struct lu_env *env, return rc; } - rc = mdd_declare_changelog_ext_store(env, mdd, tname, sname, handle); + rc = mdd_declare_changelog_store(env, mdd, tname, sname, handle); if (rc) return rc; @@ -2981,10 +2912,9 @@ cleanup: cleanup_unlocked: if (rc == 0) - rc = mdd_changelog_ext_ns_store(env, mdd, CL_RENAME, cl_flags, - mdd_tobj, tpobj_fid, lf, - spobj_fid, ltname, lsname, - handle); + rc = mdd_changelog_ns_store(env, mdd, CL_RENAME, cl_flags, + mdd_tobj, tpobj_fid, lf, spobj_fid, + ltname, lsname, handle); stop: mdd_trans_stop(env, mdd, rc, handle); diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index 4c814098..316651f 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -277,9 +277,11 @@ struct mdd_object *mdd_object_find(const struct lu_env *env, int mdd_readpage(const struct lu_env *env, struct md_object *obj, const struct lu_rdpg *rdpg); int mdd_declare_changelog_store(const struct lu_env *env, - struct mdd_device *mdd, - const struct lu_name *fname, - struct thandle *handle); + struct mdd_device *mdd, + const struct lu_name *tname, + const struct lu_name *sname, + struct thandle *handle); +void mdd_changelog_rec_ext_jobid(struct changelog_rec *rec, const char *jobid); 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, @@ -287,9 +289,15 @@ int mdd_changelog_data_store(const struct lu_env *env, struct mdd_device *mdd, struct mdd_object *mdd_obj, struct thandle *handle); int mdd_changelog_ns_store(const struct lu_env *env, struct mdd_device *mdd, - enum changelog_rec_type type, unsigned flags, - struct mdd_object *target, struct mdd_object *parent, - const struct lu_name *tname, struct thandle *handle); + enum changelog_rec_type type, + enum changelog_rec_flags crf, + struct mdd_object *target, + const struct lu_fid *tpfid, + const struct lu_fid *sfid, + const struct lu_fid *spfid, + const struct lu_name *tname, + const struct lu_name *sname, + struct thandle *handle); int mdd_declare_object_create_internal(const struct lu_env *env, struct mdd_object *p, struct mdd_object *c, diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 76b5f0e..b3c9e0f 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -638,6 +638,7 @@ 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) { + const struct lu_ucred *uc = lu_ucred(env); const struct lu_fid *tfid; struct llog_changelog_rec *rec; struct lu_buf *buf; @@ -663,17 +664,24 @@ int mdd_changelog_data_store(const struct lu_env *env, struct mdd_device *mdd, RETURN(0); } - reclen = llog_data_len(sizeof(*rec)); + flags = (flags & CLF_FLAGMASK) | CLF_VERSION; + if (uc->uc_jobid[0] != '\0') + flags |= CLF_JOBID; + + reclen = llog_data_len(changelog_rec_offset(flags & CLF_SUPPORTED)); buf = lu_buf_check_and_alloc(&mdd_env_info(env)->mti_big_buf, reclen); if (buf->lb_buf == NULL) RETURN(-ENOMEM); rec = buf->lb_buf; - 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; - mdd_obj->mod_cltime = cfs_time_current_64(); + rec->cr.cr_flags = flags; + rec->cr.cr_type = (__u32)type; + rec->cr.cr_tfid = *tfid; + rec->cr.cr_namelen = 0; + mdd_obj->mod_cltime = cfs_time_current_64(); + + if (flags & CLF_JOBID) + mdd_changelog_rec_ext_jobid(&rec->cr, uc->uc_jobid); rc = mdd_changelog_store(env, mdd, rec, handle); @@ -693,9 +701,9 @@ static int mdd_changelog(const struct lu_env *env, enum changelog_rec_type type, if (IS_ERR(handle)) RETURN(PTR_ERR(handle)); - rc = mdd_declare_changelog_store(env, mdd, NULL, handle); - if (rc) - GOTO(stop, rc); + rc = mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); + if (rc) + GOTO(stop, rc); rc = mdd_trans_start(env, mdd, handle); if (rc) @@ -781,7 +789,7 @@ static int mdd_declare_attr_set(const struct lu_env *env, } #endif - rc = mdd_declare_changelog_store(env, mdd, NULL, handle); + rc = mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); return rc; } @@ -919,19 +927,19 @@ static int mdd_declare_xattr_set(const struct lu_env *env, if (strncmp(XATTR_USER_PREFIX, name, sizeof(XATTR_USER_PREFIX) - 1) == 0 || strcmp(XATTR_NAME_LOV, name) == 0) { - rc = mdd_declare_changelog_store(env, mdd, NULL, handle); + rc = mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); if (rc) return rc; } /* If HSM data is modified, this could add a changelog */ if (strcmp(XATTR_NAME_HSM, name) == 0) { - rc = mdd_declare_changelog_store(env, mdd, NULL, handle); + rc = mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); if (rc) return rc; } - rc = mdd_declare_changelog_store(env, mdd, NULL, handle); + rc = mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); return rc; } @@ -1105,7 +1113,7 @@ static int mdd_declare_xattr_del(const struct lu_env *env, /* Only record user xattr changes */ if ((strncmp(XATTR_USER_PREFIX, name, sizeof(XATTR_USER_PREFIX) - 1) == 0)) - rc = mdd_declare_changelog_store(env, mdd, NULL, handle); + rc = mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); return rc; } @@ -1744,9 +1752,9 @@ again: if (rc) GOTO(stop, rc); - rc = mdd_declare_changelog_store(env, mdd, NULL, handle); - if (rc) - GOTO(stop, rc); + rc = mdd_declare_changelog_store(env, mdd, NULL, NULL, handle); + if (rc) + GOTO(stop, rc); rc = mdd_trans_start(env, mdo2mdd(obj), handle); if (rc) @@ -1820,10 +1828,10 @@ out: if (IS_ERR(handle)) GOTO(stop, rc = PTR_ERR(handle)); - rc = mdd_declare_changelog_store(env, mdd, NULL, - handle); - if (rc) - GOTO(stop, rc); + rc = mdd_declare_changelog_store(env, mdd, NULL, NULL, + handle); + if (rc) + GOTO(stop, rc); rc = mdd_trans_start(env, mdo2mdd(obj), handle); if (rc) diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index d226b3b..b87cb65 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -1092,4 +1092,15 @@ static inline char *mdt_obd_name(struct mdt_device *mdt) int mds_mod_init(void); void mds_mod_exit(void); -#endif /* _MDT_H */ +static inline char *mdt_req_get_jobid(struct ptlrpc_request *req) +{ + struct obd_export *exp = req->rq_export; + char *jobid = NULL; + + if (exp_connect_flags(exp) & OBD_CONNECT_JOBSTATS) + jobid = lustre_msg_get_jobid(req->rq_reqmsg); + + return jobid; +} + +#endif /* _MDT_INTERNAL_H */ diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index 2a8e2fd..3c1099a 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -123,6 +123,18 @@ static int mdt_root_squash(struct mdt_thread_info *info, lnet_nid_t peernid) RETURN(0); } +static void ucred_set_jobid(struct mdt_thread_info *info, struct lu_ucred *uc) +{ + struct ptlrpc_request *req = mdt_info_req(info); + const char *jobid = mdt_req_get_jobid(req); + + /* set jobid if specified. */ + if (jobid) + strlcpy(uc->uc_jobid, jobid, sizeof(uc->uc_jobid)); + else + uc->uc_jobid[0] = '\0'; +} + static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, void *buf) { @@ -285,6 +297,7 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, ucred->uc_cap &= ~(CFS_CAP_SYS_RESOURCE_MASK | CFS_CAP_CHOWN_MASK); ucred->uc_valid = UCRED_NEW; + ucred_set_jobid(info, ucred); EXIT; @@ -450,6 +463,7 @@ static int old_init_ucred(struct mdt_thread_info *info, else uc->uc_cap = body->mbo_capability; uc->uc_valid = UCRED_OLD; + ucred_set_jobid(info, uc); RETURN(0); } @@ -489,6 +503,7 @@ static int old_init_ucred_reint(struct mdt_thread_info *info) if (uc->uc_fsuid) uc->uc_cap &= ~CFS_CAP_FS_MASK; uc->uc_valid = UCRED_OLD; + ucred_set_jobid(info, uc); RETURN(0); } diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c index addd5e5..465c3f3 100644 --- a/lustre/obdclass/class_obd.c +++ b/lustre/obdclass/class_obd.c @@ -124,18 +124,18 @@ EXPORT_SYMBOL(obd_memory); */ int lustre_get_jobid(char *jobid) { - int jobid_len = JOBSTATS_JOBID_SIZE; + int jobid_len = LUSTRE_JOBID_SIZE; int rc = 0; ENTRY; - memset(jobid, 0, JOBSTATS_JOBID_SIZE); + memset(jobid, 0, LUSTRE_JOBID_SIZE); /* Jobstats isn't enabled */ if (strcmp(obd_jobid_var, JOBSTATS_DISABLE) == 0) RETURN(0); /* Use process name + fsuid as jobid */ if (strcmp(obd_jobid_var, JOBSTATS_PROCNAME_UID) == 0) { - snprintf(jobid, JOBSTATS_JOBID_SIZE, "%s.%u", + snprintf(jobid, LUSTRE_JOBID_SIZE, "%s.%u", current_comm(), from_kuid(&init_user_ns, current_fsuid())); RETURN(0); diff --git a/lustre/obdclass/llog.c b/lustre/obdclass/llog.c index 932b384..a4fbc25 100644 --- a/lustre/obdclass/llog.c +++ b/lustre/obdclass/llog.c @@ -204,6 +204,7 @@ int llog_init_handle(const struct lu_env *env, struct llog_handle *handle, int flags, struct obd_uuid *uuid) { struct llog_log_hdr *llh; + enum llog_flag fmt = flags & LLOG_F_EXT_MASK; int rc; ENTRY; @@ -258,6 +259,7 @@ int llog_init_handle(const struct lu_env *env, struct llog_handle *handle, flags, LLOG_F_IS_CAT, LLOG_F_IS_PLAIN); rc = -EINVAL; } + llh->llh_flags |= fmt; out: if (rc) { OBD_FREE_PTR(llh); @@ -322,15 +324,15 @@ repeat: if (rc) GOTO(out, rc); - /* NB: when rec->lrh_len is accessed it is already swabbed - * since it is used at the "end" of the loop and the rec - * swabbing is done at the beginning of the loop. */ - for (rec = (struct llog_rec_hdr *)buf; - (char *)rec < buf + LLOG_CHUNK_SIZE; - rec = (struct llog_rec_hdr *)((char *)rec + rec->lrh_len)){ + /* NB: when rec->lrh_len is accessed it is already swabbed + * since it is used at the "end" of the loop and the rec + * swabbing is done at the beginning of the loop. */ + for (rec = (struct llog_rec_hdr *)buf; + (char *)rec < buf + LLOG_CHUNK_SIZE; + rec = llog_rec_hdr_next(rec)) { - CDEBUG(D_OTHER, "processing rec 0x%p type %#x\n", - rec, rec->lrh_type); + CDEBUG(D_OTHER, "processing rec 0x%p type %#x\n", + rec, rec->lrh_type); if (LLOG_REC_HDR_NEEDS_SWABBING(rec)) lustre_swab_llog_rec(rec); diff --git a/lustre/obdclass/llog_cat.c b/lustre/obdclass/llog_cat.c index 181fbf5..ae443e6 100644 --- a/lustre/obdclass/llog_cat.c +++ b/lustre/obdclass/llog_cat.c @@ -125,6 +125,7 @@ int llog_cat_id2handle(const struct lu_env *env, struct llog_handle *cathandle, struct llog_handle **res, struct llog_logid *logid) { struct llog_handle *loghandle; + enum llog_flag fmt; int rc = 0; ENTRY; @@ -132,6 +133,7 @@ int llog_cat_id2handle(const struct lu_env *env, struct llog_handle *cathandle, if (cathandle == NULL) RETURN(-EBADF); + fmt = cathandle->lgh_hdr->llh_flags & LLOG_F_EXT_MASK; down_write(&cathandle->lgh_lock); list_for_each_entry(loghandle, &cathandle->u.chd.chd_head, u.phd.phd_entry) { @@ -162,7 +164,7 @@ int llog_cat_id2handle(const struct lu_env *env, struct llog_handle *cathandle, RETURN(rc); } - rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL); + rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN | fmt, NULL); if (rc < 0) { llog_close(env, loghandle); loghandle = NULL; diff --git a/lustre/obdclass/llog_internal.h b/lustre/obdclass/llog_internal.h index 6eec20b..2833245 100644 --- a/lustre/obdclass/llog_internal.h +++ b/lustre/obdclass/llog_internal.h @@ -95,4 +95,9 @@ int llog_process_or_fork(const struct lu_env *env, llog_cb_t cb, void *data, void *catdata, bool fork); int llog_cat_cleanup(const struct lu_env *env, struct llog_handle *cathandle, struct llog_handle *loghandle, int index); + +static inline struct llog_rec_hdr *llog_rec_hdr_next(struct llog_rec_hdr *rec) +{ + return (struct llog_rec_hdr *)((char *)rec + rec->lrh_len); +} #endif diff --git a/lustre/obdclass/llog_osd.c b/lustre/obdclass/llog_osd.c index 8295d39..e74f552 100644 --- a/lustre/obdclass/llog_osd.c +++ b/lustre/obdclass/llog_osd.c @@ -187,6 +187,7 @@ static int llog_osd_read_header(const struct lu_env *env, struct llog_rec_hdr *llh_hdr; struct dt_object *o; struct llog_thread_info *lgi; + enum llog_flag flags; int rc; ENTRY; @@ -209,6 +210,8 @@ static int llog_osd_read_header(const struct lu_env *env, RETURN(LLOG_EEMPTY); } + flags = handle->lgh_hdr->llh_flags; + lgi->lgi_off = 0; lgi->lgi_buf.lb_buf = handle->lgh_hdr; lgi->lgi_buf.lb_len = LLOG_CHUNK_SIZE; @@ -243,6 +246,7 @@ static int llog_osd_read_header(const struct lu_env *env, RETURN(-EIO); } + handle->lgh_hdr->llh_flags |= (flags & LLOG_F_EXT_MASK); handle->lgh_last_idx = handle->lgh_hdr->llh_tail.lrt_index; RETURN(0); @@ -587,6 +591,32 @@ static inline void llog_skip_over(__u64 *off, int curr, int goal) } /** + * Remove optional fields that the client doesn't expect. + * This is typically in order to ensure compatibility with older clients. + * It is assumed that since we exclusively remove fields, the block will be + * big enough to handle the remapped records. It is also assumed that records + * of a block have the same format (i.e.: the same features enabled). + * + * \param[in,out] hdr Header of the block of records to remap. + * \param[in,out] last_hdr Last header, don't read past this point. + * \param[in] flags Flags describing the fields to keep. + */ +static void changelog_block_trim_ext(struct llog_rec_hdr *hdr, + struct llog_rec_hdr *last_hdr, + enum changelog_rec_flags flags) +{ + if (hdr->lrh_type != CHANGELOG_REC) + return; + + do { + struct changelog_rec *rec = (struct changelog_rec *)(hdr + 1); + + changelog_remap_rec(rec, rec->cr_flags & flags); + hdr = llog_rec_hdr_next(hdr); + } while ((char *)hdr <= (char *)last_hdr); +} + +/** * Implementation of the llog_operations::lop_next_block * * This function finds the the next llog block to return which contains @@ -713,6 +743,12 @@ static int llog_osd_next_block(const struct lu_env *env, rec->lrh_index, next_idx); GOTO(out, rc = -ENOENT); } + + /* Trim unsupported extensions for compat w/ older clients */ + if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_JOBID)) + changelog_block_trim_ext(rec, last_rec, + CLF_VERSION | CLF_RENAME); + GOTO(out, rc = 0); } GOTO(out, rc = -EIO); @@ -831,6 +867,12 @@ static int llog_osd_prev_block(const struct lu_env *env, rec->lrh_index, prev_idx); GOTO(out, rc = -ENOENT); } + + /* Trim unsupported extensions for compat w/ older clients */ + if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_JOBID)) + changelog_block_trim_ext(rec, last_rec, + CLF_VERSION | CLF_RENAME); + GOTO(out, rc = 0); } GOTO(out, rc = -EIO); diff --git a/lustre/obdclass/llog_swab.c b/lustre/obdclass/llog_swab.c index 25e249a..97ed7f4 100644 --- a/lustre/obdclass/llog_swab.c +++ b/lustre/obdclass/llog_swab.c @@ -182,20 +182,21 @@ void lustre_swab_llog_rec(struct llog_rec_hdr *rec) __swab64s(&cr->cr.cr_time); lustre_swab_lu_fid(&cr->cr.cr_tfid); lustre_swab_lu_fid(&cr->cr.cr_pfid); - if (CHANGELOG_REC_EXTENDED(&cr->cr)) { - struct llog_changelog_ext_rec *ext = - (struct llog_changelog_ext_rec *)rec; - - lustre_swab_lu_fid(&ext->cr.cr_sfid); - lustre_swab_lu_fid(&ext->cr.cr_spfid); - tail = &ext->cr_tail; - } else { - tail = &cr->cr_tail; + if (cr->cr.cr_flags & CLF_RENAME) { + struct changelog_ext_rename *rnm = + changelog_rec_rename(&cr->cr); + + lustre_swab_lu_fid(&rnm->cr_sfid); + lustre_swab_lu_fid(&rnm->cr_spfid); } - tail = (struct llog_rec_tail *)((char *)tail + + /* Because the tail follows a variable-length structure we need + * to compute its location at runtime */ + tail = (struct llog_rec_tail *)((char *)&cr->cr + + changelog_rec_size(&cr->cr) + cr->cr.cr_namelen); break; } + case CHANGELOG_USER_REC: { struct llog_changelog_user_rec *cur = diff --git a/lustre/obdclass/llog_test.c b/lustre/obdclass/llog_test.c index 403e571..ba8fbc8 100644 --- a/lustre/obdclass/llog_test.c +++ b/lustre/obdclass/llog_test.c @@ -837,8 +837,9 @@ static int llog_test_7(const struct lu_env *env, struct obd_device *obd) } CWARN("7e: test llog_changelog_rec\n"); + /* Direct access to cr_do_not_use: peculiar case for this test */ llog_records.lcr.cr_hdr.lrh_len = sizeof(llog_records.lcr); - llog_records.lcr.cr_tail.lrt_len = sizeof(llog_records.lcr); + llog_records.lcr.cr_do_not_use.lrt_len = sizeof(llog_records.lcr); llog_records.lcr.cr_hdr.lrh_type = CHANGELOG_REC; rc = llog_test_7_sub(env, ctxt); diff --git a/lustre/obdclass/lprocfs_jobstats.c b/lustre/obdclass/lprocfs_jobstats.c index d14ce6c..c2eff71 100644 --- a/lustre/obdclass/lprocfs_jobstats.c +++ b/lustre/obdclass/lprocfs_jobstats.c @@ -67,7 +67,7 @@ struct job_stat { struct hlist_node js_hash; struct list_head js_list; atomic_t js_refcount; - char js_jobid[JOBSTATS_JOBID_SIZE]; + char js_jobid[LUSTRE_JOBID_SIZE]; time_t js_timestamp; /* seconds */ struct lprocfs_stats *js_stats; struct obd_job_stats *js_jobstats; @@ -196,7 +196,7 @@ static struct job_stat *job_alloc(char *jobid, struct obd_job_stats *jobs) jobs->ojs_cntr_init_fn(job->js_stats); - memcpy(job->js_jobid, jobid, JOBSTATS_JOBID_SIZE); + memcpy(job->js_jobid, jobid, LUSTRE_JOBID_SIZE); job->js_timestamp = cfs_time_current_sec(); job->js_jobstats = jobs; INIT_HLIST_NODE(&job->js_hash); @@ -220,9 +220,9 @@ int lprocfs_job_stats_log(struct obd_device *obd, char *jobid, if (!jobid || !strlen(jobid)) RETURN(-EINVAL); - if (strlen(jobid) >= JOBSTATS_JOBID_SIZE) { + if (strlen(jobid) >= LUSTRE_JOBID_SIZE) { CERROR("Invalid jobid size (%lu), expect(%d)\n", - (unsigned long)strlen(jobid) + 1, JOBSTATS_JOBID_SIZE); + (unsigned long)strlen(jobid) + 1, LUSTRE_JOBID_SIZE); RETURN(-EINVAL); } @@ -433,11 +433,11 @@ static ssize_t lprocfs_jobstats_seq_write(struct file *file, { struct seq_file *seq = file->private_data; struct obd_job_stats *stats = seq->private; - char jobid[JOBSTATS_JOBID_SIZE]; + char jobid[LUSTRE_JOBID_SIZE]; int all = 0; struct job_stat *job; - if (len == 0 || len >= JOBSTATS_JOBID_SIZE) + if (len == 0 || len >= LUSTRE_JOBID_SIZE) return -EINVAL; if (copy_from_user(jobid, buf, len)) diff --git a/lustre/ptlrpc/nrs_tbf.c b/lustre/ptlrpc/nrs_tbf.c index 3cad160..6c7b5dc 100644 --- a/lustre/ptlrpc/nrs_tbf.c +++ b/lustre/ptlrpc/nrs_tbf.c @@ -626,7 +626,7 @@ nrs_tbf_jobid_cli_init(struct nrs_tbf_client *cli, if (jobid == NULL) jobid = NRS_TBF_JOBID_NULL; - LASSERT(strlen(jobid) < JOBSTATS_JOBID_SIZE); + LASSERT(strlen(jobid) < LUSTRE_JOBID_SIZE); INIT_LIST_HEAD(&cli->tc_lru); memcpy(cli->tc_jobid, jobid, strlen(jobid)); } diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index 48984bf..e5cab71 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -1554,7 +1554,7 @@ void lustre_msg_set_jobid(struct lustre_msg *msg, char *jobid) LASSERTF(pb, "invalid msg %p: no ptlrpc body!\n", msg); if (jobid != NULL) - memcpy(pb->pb_jobid, jobid, JOBSTATS_JOBID_SIZE); + memcpy(pb->pb_jobid, jobid, LUSTRE_JOBID_SIZE); else if (pb->pb_jobid[0] == '\0') lustre_get_jobid(pb->pb_jobid); return; diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 64ed09d..e769304 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -783,7 +783,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct ptlrpc_body_v3, pb_padding)); LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding) == 32, "found %lld\n", (long long)(int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding)); - CLASSERT(JOBSTATS_JOBID_SIZE == 32); + CLASSERT(LUSTRE_JOBID_SIZE == 32); LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_jobid) == 152, "found %lld\n", (long long)(int)offsetof(struct ptlrpc_body_v3, pb_jobid)); LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_jobid) == 32, "found %lld\n", @@ -3585,49 +3585,25 @@ void lustre_assert_wire_constants(void) LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_pfid) == 16, "found %lld\n", (long long)(int)sizeof(((struct changelog_rec *)0)->cr_pfid)); - /* Checks for struct changelog_ext_rec */ - LASSERTF((int)sizeof(struct changelog_ext_rec) == 96, "found %lld\n", - (long long)(int)sizeof(struct changelog_ext_rec)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_namelen) == 0, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_namelen)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_namelen) == 2, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_namelen)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_flags) == 2, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_flags)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_flags) == 2, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_flags)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_type) == 4, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_type)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_type) == 4, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_type)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_index) == 8, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_index)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_index) == 8, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_index)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_prev) == 16, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_prev)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_prev) == 8, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_prev)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_time) == 24, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_time)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_time) == 8, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_time)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_tfid) == 32, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_tfid)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_tfid) == 16, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_tfid)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_pfid) == 48, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_pfid)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_pfid) == 16, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_pfid)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_sfid) == 64, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_sfid)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_sfid) == 16, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_sfid)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_spfid) == 80, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_spfid)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_spfid) == 16, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_spfid)); + /* Checks for struct changelog_ext_rename */ + LASSERTF((int)sizeof(struct changelog_ext_rename) == 32, "found %lld\n", + (long long)(int)sizeof(struct changelog_ext_rename)); + LASSERTF((int)offsetof(struct changelog_ext_rename, cr_sfid) == 0, "found %lld\n", + (long long)(int)offsetof(struct changelog_ext_rename, cr_sfid)); + LASSERTF((int)sizeof(((struct changelog_ext_rename *)0)->cr_sfid) == 16, "found %lld\n", + (long long)(int)sizeof(((struct changelog_ext_rename *)0)->cr_sfid)); + LASSERTF((int)offsetof(struct changelog_ext_rename, cr_spfid) == 16, "found %lld\n", + (long long)(int)offsetof(struct changelog_ext_rename, cr_spfid)); + LASSERTF((int)sizeof(((struct changelog_ext_rename *)0)->cr_spfid) == 16, "found %lld\n", + (long long)(int)sizeof(((struct changelog_ext_rename *)0)->cr_spfid)); + + /* Checks for struct changelog_ext_jobid */ + LASSERTF((int)sizeof(struct changelog_ext_jobid) == 32, "found %lld\n", + (long long)(int)sizeof(struct changelog_ext_jobid)); + LASSERTF((int)offsetof(struct changelog_ext_jobid, cr_jobid) == 0, "found %lld\n", + (long long)(int)offsetof(struct changelog_ext_jobid, cr_jobid)); + LASSERTF((int)sizeof(((struct changelog_ext_jobid *)0)->cr_jobid) == 32, "found %lld\n", + (long long)(int)sizeof(((struct changelog_ext_jobid *)0)->cr_jobid)); /* Checks for struct changelog_setinfo */ LASSERTF((int)sizeof(struct changelog_setinfo) == 12, "found %lld\n", @@ -3652,10 +3628,10 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct llog_changelog_rec, cr)); LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr) == 64, "found %lld\n", (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr)); - LASSERTF((int)offsetof(struct llog_changelog_rec, cr_tail) == 80, "found %lld\n", - (long long)(int)offsetof(struct llog_changelog_rec, cr_tail)); - LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_tail) == 8, "found %lld\n", - (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_tail)); + LASSERTF((int)offsetof(struct llog_changelog_rec, cr_do_not_use) == 80, "found %lld\n", + (long long)(int)offsetof(struct llog_changelog_rec, cr_do_not_use)); + LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_do_not_use) == 8, "found %lld\n", + (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_do_not_use)); /* Checks for struct llog_changelog_user_rec */ LASSERTF((int)sizeof(struct llog_changelog_user_rec) == 40, "found %lld\n", diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index f0dcb6a..c04d64d 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -11239,6 +11239,10 @@ test_205() { # Job stats trap jobstats_set EXIT fi + local user=$(do_facet $SINGLEMDS $LCTL --device $MDT0 \ + changelog_register -n) + echo "Registered as changelog user $user" + # mkdir cmd="mkdir $DIR/$tfile" verify_jobstats "$cmd" "mdt" @@ -11270,6 +11274,15 @@ test_205() { # Job stats cmd="mv -f $DIR/$tfile $DIR/jobstats_test_rename" verify_jobstats "$cmd" "mdt" + # Ensure that jobid are present in changelog (if supported by MDS) + if [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.6.52) ] + then + $LFS changelog $MDT0 | tail -9 + jobids=$($LFS changelog $MDT0 | tail -9 | grep -c "j=") + [ $jobids -eq 9 ] || + error "Wrong changelog jobid count $jobids != 9" + fi + # cleanup rm -f $DIR/jobstats_test_rename diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 6d2ce2e..0943573 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -3147,7 +3147,7 @@ static int lfs_ls(int argc, char **argv) static int lfs_changelog(int argc, char **argv) { void *changelog_priv; - struct changelog_ext_rec *rec; + struct changelog_rec *rec; long long startrec = 0, endrec = 0; char *mdd; struct option long_opts[] = { @@ -3181,15 +3181,16 @@ static int lfs_changelog(int argc, char **argv) if (argc > optind) endrec = strtoll(argv[optind++], NULL, 10); - rc = llapi_changelog_start(&changelog_priv, - CHANGELOG_FLAG_BLOCK | - (follow ? CHANGELOG_FLAG_FOLLOW : 0), - mdd, startrec); - if (rc < 0) { - fprintf(stderr, "Can't start changelog: %s\n", - strerror(errno = -rc)); - return rc; - } + rc = llapi_changelog_start(&changelog_priv, + CHANGELOG_FLAG_BLOCK | + CHANGELOG_FLAG_JOBID | + (follow ? CHANGELOG_FLAG_FOLLOW : 0), + mdd, startrec); + if (rc < 0) { + fprintf(stderr, "Can't start changelog: %s\n", + strerror(errno = -rc)); + return rc; + } while ((rc = llapi_changelog_recv(changelog_priv, &rec)) == 0) { time_t secs; @@ -3204,28 +3205,42 @@ static int lfs_changelog(int argc, char **argv) continue; } - secs = rec->cr_time >> 30; - gmtime_r(&secs, &ts); - printf(LPU64" %02d%-5s %02d:%02d:%02d.%06d %04d.%02d.%02d " - "0x%x t="DFID, rec->cr_index, rec->cr_type, - changelog_type2str(rec->cr_type), - ts.tm_hour, ts.tm_min, ts.tm_sec, - (int)(rec->cr_time & ((1<<30) - 1)), - ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday, - rec->cr_flags & CLF_FLAGMASK, PFID(&rec->cr_tfid)); - if (rec->cr_namelen) - /* namespace rec includes parent and filename */ - printf(" p="DFID" %.*s", PFID(&rec->cr_pfid), - rec->cr_namelen, rec->cr_name); + secs = rec->cr_time >> 30; + gmtime_r(&secs, &ts); + printf(LPU64" %02d%-5s %02d:%02d:%02d.%06d %04d.%02d.%02d " + "0x%x t="DFID, rec->cr_index, rec->cr_type, + changelog_type2str(rec->cr_type), + ts.tm_hour, ts.tm_min, ts.tm_sec, + (int)(rec->cr_time & ((1<<30) - 1)), + ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday, + rec->cr_flags & CLF_FLAGMASK, PFID(&rec->cr_tfid)); + + if (rec->cr_flags & CLF_JOBID) { + struct changelog_ext_jobid *jid = + changelog_rec_jobid(rec); + + if (jid->cr_jobid[0] != '\0') + printf(" j=%s", jid->cr_jobid); + } - if (!fid_is_zero(&rec->cr_sfid)) - printf(" s="DFID" sp="DFID" %.*s", - PFID(&rec->cr_sfid), PFID(&rec->cr_spfid), - changelog_rec_snamelen(rec), - changelog_rec_sname(rec)); + if (rec->cr_namelen) + printf(" p="DFID" %.*s", PFID(&rec->cr_pfid), + rec->cr_namelen, changelog_rec_name(rec)); + + if (rec->cr_flags & CLF_RENAME) { + struct changelog_ext_rename *rnm = + changelog_rec_rename(rec); + + if (!fid_is_zero(&rnm->cr_sfid)) + printf(" s="DFID" sp="DFID" %.*s", + PFID(&rnm->cr_sfid), + PFID(&rnm->cr_spfid), + changelog_rec_snamelen(rec), + changelog_rec_sname(rec)); + } printf("\n"); - llapi_changelog_free(&rec); + llapi_changelog_free(&rec); } llapi_changelog_fini(&changelog_priv); diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index d97ff03..292acd4 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -4122,9 +4122,9 @@ static int changelog_ioctl(const char *mdtname, int opc, int id, #define CHANGELOG_PRIV_MAGIC 0xCA8E1080 struct changelog_private { - int magic; - int flags; - lustre_kernelcomm kuc; + int magic; + enum changelog_send_flag flags; + lustre_kernelcomm kuc; }; /** Start reading from a changelog @@ -4134,44 +4134,53 @@ struct changelog_private { * @param startrec Report changes beginning with this record number * (just call llapi_changelog_fini when done; don't need an endrec) */ -int llapi_changelog_start(void **priv, int flags, const char *device, - long long startrec) +int llapi_changelog_start(void **priv, enum changelog_send_flag flags, + const char *device, long long startrec) { - struct changelog_private *cp; - int rc; + struct changelog_private *cp; + static bool warned; + int rc; - /* Set up the receiver control struct */ - cp = calloc(1, sizeof(*cp)); - if (cp == NULL) - return -ENOMEM; + /* Set up the receiver control struct */ + cp = calloc(1, sizeof(*cp)); + if (cp == NULL) + return -ENOMEM; - cp->magic = CHANGELOG_PRIV_MAGIC; - cp->flags = flags; + cp->magic = CHANGELOG_PRIV_MAGIC; + cp->flags = flags; - /* Set up the receiver */ + /* Set up the receiver */ rc = libcfs_ukuc_start(&cp->kuc, 0 /* no group registration */, 0); - if (rc < 0) - goto out_free; + if (rc < 0) + goto out_free; - *priv = cp; + *priv = cp; - /* Tell the kernel to start sending */ - rc = changelog_ioctl(device, OBD_IOC_CHANGELOG_SEND, cp->kuc.lk_wfd, - startrec, flags); - /* Only the kernel reference keeps the write side open */ - close(cp->kuc.lk_wfd); - cp->kuc.lk_wfd = LK_NOFD; - if (rc < 0) { - /* frees and clears priv */ - llapi_changelog_fini(priv); - return rc; - } + /* CHANGELOG_FLAG_JOBID will eventually become mandatory. Display a + * warning if it's missing. */ + if (!(flags & CHANGELOG_FLAG_JOBID) && !warned) { + llapi_err_noerrno(LLAPI_MSG_WARN, "warning: %s() called " + "w/o CHANGELOG_FLAG_JOBID", __func__); + warned = true; + } - return 0; + /* Tell the kernel to start sending */ + rc = changelog_ioctl(device, OBD_IOC_CHANGELOG_SEND, cp->kuc.lk_wfd, + startrec, flags); + /* Only the kernel reference keeps the write side open */ + close(cp->kuc.lk_wfd); + cp->kuc.lk_wfd = LK_NOFD; + if (rc < 0) { + /* frees and clears priv */ + llapi_changelog_fini(priv); + return rc; + } + + return 0; out_free: - free(cp); - return rc; + free(cp); + return rc; } /** Finish reading from a changelog */ @@ -4188,24 +4197,15 @@ int llapi_changelog_fini(void **priv) return 0; } -/** Convert a changelog_rec to changelog_ext_rec, in this way client can treat - * all records in the format of changelog_ext_rec, this can make record - * analysis simpler. +/** + * Convert all records to a same format according to the caller's wishes. + * Default is CLF_VERSION | CLF_RENAME. + * Add CLF_JOBID if explicitely requested. + * + * \param rec The record to remap. It is expected to be big enough to + * properly handle the final format. + * \return 1 if anything changed. 0 otherwise. */ -static inline int changelog_extend_rec(struct changelog_ext_rec *ext) -{ - if (!CHANGELOG_REC_EXTENDED(ext)) { - struct changelog_rec *rec = (struct changelog_rec *)ext; - - memmove(ext->cr_name, rec->cr_name, rec->cr_namelen); - fid_zero(&ext->cr_sfid); - fid_zero(&ext->cr_spfid); - return 1; - } - - return 0; -} - /** Read the next changelog entry * @param priv Opaque private control structure * @param rech Changelog record handle; record will be allocated here @@ -4213,11 +4213,13 @@ static inline int changelog_extend_rec(struct changelog_ext_rec *ext) * <0 error code * 1 EOF */ -int llapi_changelog_recv(void *priv, struct changelog_ext_rec **rech) +#define DEFAULT_RECORD_FMT (CLF_VERSION | CLF_RENAME) +int llapi_changelog_recv(void *priv, struct changelog_rec **rech) { - struct changelog_private *cp = (struct changelog_private *)priv; - struct kuc_hdr *kuch; - int rc = 0; + struct changelog_private *cp = (struct changelog_private *)priv; + struct kuc_hdr *kuch; + enum changelog_rec_flags rec_fmt = DEFAULT_RECORD_FMT; + int rc = 0; if (!cp || (cp->magic != CHANGELOG_PRIV_MAGIC)) return -EINVAL; @@ -4227,6 +4229,9 @@ int llapi_changelog_recv(void *priv, struct changelog_ext_rec **rech) if (kuch == NULL) return -ENOMEM; + if (cp->flags & CHANGELOG_FLAG_JOBID) + rec_fmt |= CLF_JOBID; + repeat: rc = libcfs_ukuc_msg_get(&cp->kuc, (char *)kuch, KUC_CHANGELOG_MSG_MAXSIZE, @@ -4254,11 +4259,10 @@ repeat: } } - /* Our message is a changelog_ext_rec. Use pointer math to skip - * kuch_hdr and point directly to the message payload. - */ - *rech = (struct changelog_ext_rec *)(kuch + 1); - changelog_extend_rec(*rech); + /* Our message is a changelog_rec. Use pointer math to skip + * kuch_hdr and point directly to the message payload. */ + *rech = (struct changelog_rec *)(kuch + 1); + changelog_remap_rec(*rech, rec_fmt); return 0; @@ -4269,7 +4273,7 @@ out_free: } /** Release the changelog record when done with it. */ -int llapi_changelog_free(struct changelog_ext_rec **rech) +int llapi_changelog_free(struct changelog_rec **rech) { if (*rech) { /* We allocated memory starting at the kuc_hdr, but passed diff --git a/lustre/utils/lustre_rsync.c b/lustre/utils/lustre_rsync.c index b167afa..8fb2734 100644 --- a/lustre/utils/lustre_rsync.c +++ b/lustre/utils/lustre_rsync.c @@ -1111,22 +1111,27 @@ int lr_setxattr(struct lr_info *info) /* Parse a line of changelog entry */ int lr_parse_line(void *priv, struct lr_info *info) { - struct changelog_ext_rec *rec; + struct changelog_rec *rec; + struct changelog_ext_rename *rnm; if (llapi_changelog_recv(priv, &rec) != 0) return -1; - info->is_extended = CHANGELOG_REC_EXTENDED(rec); + info->is_extended = !!(rec->cr_flags & CLF_RENAME); info->recno = rec->cr_index; info->type = rec->cr_type; sprintf(info->tfid, DFID, PFID(&rec->cr_tfid)); sprintf(info->pfid, DFID, PFID(&rec->cr_pfid)); - strncpy(info->name, rec->cr_name, rec->cr_namelen); + strncpy(info->name, changelog_rec_name(rec), rec->cr_namelen); info->name[rec->cr_namelen] = '\0'; - if (fid_is_sane(&rec->cr_sfid)) { - sprintf(info->sfid, DFID, PFID(&rec->cr_sfid)); - sprintf(info->spfid, DFID, PFID(&rec->cr_spfid)); + /* Don't use rnm if CLF_RENAME isn't set */ + rnm = changelog_rec_rename(rec); + if (rec->cr_flags & CLF_RENAME && !fid_is_zero(&rnm->cr_sfid)) { + snprintf(info->sfid, sizeof(info->sfid), DFID, + PFID(&rnm->cr_sfid)); + snprintf(info->spfid, sizeof(info->spfid), DFID, + PFID(&rnm->cr_spfid)); strncpy(info->sname, changelog_rec_sname(rec), changelog_rec_snamelen(rec)); info->sname[changelog_rec_snamelen(rec)] = '\0'; @@ -1495,9 +1500,10 @@ int lr_replicate() lr_print_status(info); - /* Open changelogs for consumption*/ - rc = llapi_changelog_start(&changelog_priv, CHANGELOG_FLAG_BLOCK, - status->ls_source_fs, status->ls_last_recno); + /* Open changelogs for consumption*/ + rc = llapi_changelog_start(&changelog_priv, + CHANGELOG_FLAG_BLOCK | CHANGELOG_FLAG_JOBID, + status->ls_source_fs, status->ls_last_recno); if (rc < 0) { fprintf(stderr, "Error opening changelog file for fs %s.\n", status->ls_source_fs); diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 558bcb0..0ea8c10 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -367,7 +367,7 @@ check_ptlrpc_body(void) CHECK_CVALUE(PTLRPC_NUM_VERSIONS); CHECK_MEMBER(ptlrpc_body, pb_pre_versions); CHECK_MEMBER(ptlrpc_body, pb_padding); - CHECK_CVALUE(JOBSTATS_JOBID_SIZE); + CHECK_CVALUE(LUSTRE_JOBID_SIZE); CHECK_MEMBER(ptlrpc_body, pb_jobid); CHECK_MEMBER_SAME(ptlrpc_body_v3, ptlrpc_body_v2, pb_handle); @@ -1558,20 +1558,20 @@ check_changelog_rec(void) } static void -check_changelog_rec_ext(void) +check_changelog_ext_rename(void) { BLANK_LINE(); - CHECK_STRUCT(changelog_ext_rec); - CHECK_MEMBER(changelog_ext_rec, cr_namelen); - CHECK_MEMBER(changelog_ext_rec, cr_flags); - CHECK_MEMBER(changelog_ext_rec, cr_type); - CHECK_MEMBER(changelog_ext_rec, cr_index); - CHECK_MEMBER(changelog_ext_rec, cr_prev); - CHECK_MEMBER(changelog_ext_rec, cr_time); - CHECK_MEMBER(changelog_ext_rec, cr_tfid); - CHECK_MEMBER(changelog_ext_rec, cr_pfid); - CHECK_MEMBER(changelog_ext_rec, cr_sfid); - CHECK_MEMBER(changelog_ext_rec, cr_spfid); + CHECK_STRUCT(changelog_ext_rename); + CHECK_MEMBER(changelog_ext_rename, cr_sfid); + CHECK_MEMBER(changelog_ext_rename, cr_spfid); +} + +static void +check_changelog_ext_jobid(void) +{ + BLANK_LINE(); + CHECK_STRUCT(changelog_ext_jobid); + CHECK_MEMBER(changelog_ext_jobid, cr_jobid); } static void @@ -1590,7 +1590,7 @@ check_llog_changelog_rec(void) CHECK_STRUCT(llog_changelog_rec); CHECK_MEMBER(llog_changelog_rec, cr_hdr); CHECK_MEMBER(llog_changelog_rec, cr); - CHECK_MEMBER(llog_changelog_rec, cr_tail); + CHECK_MEMBER(llog_changelog_rec, cr_do_not_use); } static void @@ -2519,7 +2519,8 @@ main(int argc, char **argv) check_llog_setattr64_rec(); check_llog_size_change_rec(); check_changelog_rec(); - check_changelog_rec_ext(); + check_changelog_ext_rename(); + check_changelog_ext_jobid(); check_changelog_setinfo(); check_llog_changelog_rec(); check_llog_changelog_user_rec(); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 702ae0b..7c5e3bf 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -795,7 +795,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct ptlrpc_body_v3, pb_padding)); LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding) == 32, "found %lld\n", (long long)(int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding)); - CLASSERT(JOBSTATS_JOBID_SIZE == 32); + CLASSERT(LUSTRE_JOBID_SIZE == 32); LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_jobid) == 152, "found %lld\n", (long long)(int)offsetof(struct ptlrpc_body_v3, pb_jobid)); LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_jobid) == 32, "found %lld\n", @@ -3597,49 +3597,25 @@ void lustre_assert_wire_constants(void) LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_pfid) == 16, "found %lld\n", (long long)(int)sizeof(((struct changelog_rec *)0)->cr_pfid)); - /* Checks for struct changelog_ext_rec */ - LASSERTF((int)sizeof(struct changelog_ext_rec) == 96, "found %lld\n", - (long long)(int)sizeof(struct changelog_ext_rec)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_namelen) == 0, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_namelen)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_namelen) == 2, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_namelen)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_flags) == 2, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_flags)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_flags) == 2, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_flags)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_type) == 4, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_type)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_type) == 4, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_type)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_index) == 8, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_index)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_index) == 8, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_index)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_prev) == 16, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_prev)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_prev) == 8, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_prev)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_time) == 24, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_time)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_time) == 8, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_time)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_tfid) == 32, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_tfid)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_tfid) == 16, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_tfid)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_pfid) == 48, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_pfid)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_pfid) == 16, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_pfid)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_sfid) == 64, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_sfid)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_sfid) == 16, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_sfid)); - LASSERTF((int)offsetof(struct changelog_ext_rec, cr_spfid) == 80, "found %lld\n", - (long long)(int)offsetof(struct changelog_ext_rec, cr_spfid)); - LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_spfid) == 16, "found %lld\n", - (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_spfid)); + /* Checks for struct changelog_ext_rename */ + LASSERTF((int)sizeof(struct changelog_ext_rename) == 32, "found %lld\n", + (long long)(int)sizeof(struct changelog_ext_rename)); + LASSERTF((int)offsetof(struct changelog_ext_rename, cr_sfid) == 0, "found %lld\n", + (long long)(int)offsetof(struct changelog_ext_rename, cr_sfid)); + LASSERTF((int)sizeof(((struct changelog_ext_rename *)0)->cr_sfid) == 16, "found %lld\n", + (long long)(int)sizeof(((struct changelog_ext_rename *)0)->cr_sfid)); + LASSERTF((int)offsetof(struct changelog_ext_rename, cr_spfid) == 16, "found %lld\n", + (long long)(int)offsetof(struct changelog_ext_rename, cr_spfid)); + LASSERTF((int)sizeof(((struct changelog_ext_rename *)0)->cr_spfid) == 16, "found %lld\n", + (long long)(int)sizeof(((struct changelog_ext_rename *)0)->cr_spfid)); + + /* Checks for struct changelog_ext_jobid */ + LASSERTF((int)sizeof(struct changelog_ext_jobid) == 32, "found %lld\n", + (long long)(int)sizeof(struct changelog_ext_jobid)); + LASSERTF((int)offsetof(struct changelog_ext_jobid, cr_jobid) == 0, "found %lld\n", + (long long)(int)offsetof(struct changelog_ext_jobid, cr_jobid)); + LASSERTF((int)sizeof(((struct changelog_ext_jobid *)0)->cr_jobid) == 32, "found %lld\n", + (long long)(int)sizeof(((struct changelog_ext_jobid *)0)->cr_jobid)); /* Checks for struct changelog_setinfo */ LASSERTF((int)sizeof(struct changelog_setinfo) == 12, "found %lld\n", @@ -3664,10 +3640,10 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct llog_changelog_rec, cr)); LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr) == 64, "found %lld\n", (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr)); - LASSERTF((int)offsetof(struct llog_changelog_rec, cr_tail) == 80, "found %lld\n", - (long long)(int)offsetof(struct llog_changelog_rec, cr_tail)); - LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_tail) == 8, "found %lld\n", - (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_tail)); + LASSERTF((int)offsetof(struct llog_changelog_rec, cr_do_not_use) == 80, "found %lld\n", + (long long)(int)offsetof(struct llog_changelog_rec, cr_do_not_use)); + LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_do_not_use) == 8, "found %lld\n", + (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_do_not_use)); /* Checks for struct llog_changelog_user_rec */ LASSERTF((int)sizeof(struct llog_changelog_user_rec) == 40, "found %lld\n", -- 1.8.3.1