From b1bc221e1eb98314513eff07afc0b4477076c959 Mon Sep 17 00:00:00 2001 From: "Christopher J. Morrone" Date: Mon, 19 Aug 2013 18:15:31 -0700 Subject: [PATCH] LU-3587 changelogs: Correct KUC code max changelog msg size The kernel to userspace communication routines (KUC) allocate and limit the maximum cs_buf size to CR_MAXSIZE. However this fails to account for the fact that the buffer is assumed to begin with a struct kuc_hdr. To allocate and account for that space, we introduce a new define, KUC_CHANGELOG_MSG_MAXSIZE. Change-Id: I623746126dd64c8016366ee5fdce094129e4103e Signed-off-by: Christopher J. Morrone Reviewed-on: http://review.whamcloud.com/7406 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: jacques-Charles Lafoucriere Reviewed-by: Oleg Drokin --- libcfs/include/libcfs/libcfs_kernelcomm.h | 2 ++ lustre/mdc/mdc_request.c | 38 +++++++++++++++---------------- lustre/utils/liblustreapi.c | 30 ++++++++++++------------ 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/libcfs/include/libcfs/libcfs_kernelcomm.h b/libcfs/include/libcfs/libcfs_kernelcomm.h index acf4779..c630ba3 100644 --- a/libcfs/include/libcfs/libcfs_kernelcomm.h +++ b/libcfs/include/libcfs/libcfs_kernelcomm.h @@ -61,6 +61,8 @@ struct kuc_hdr { __u16 kuc_msglen; /* Including header */ } __attribute__((aligned(sizeof(__u64)))); +#define KUC_CHANGELOG_MSG_MAXSIZE (sizeof(struct kuc_hdr)+CR_MAXSIZE) + #define KUC_MAGIC 0x191C /*Lustre9etLinC */ #define KUC_FL_BLOCK 0x01 /* Wait for send */ diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index b435b07..24b50c7 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -1531,16 +1531,16 @@ out: static struct kuc_hdr *changelog_kuc_hdr(char *buf, int len, int flags) { - struct kuc_hdr *lh = (struct kuc_hdr *)buf; + struct kuc_hdr *lh = (struct kuc_hdr *)buf; - LASSERT(len <= CR_MAXSIZE); + LASSERT(len <= KUC_CHANGELOG_MSG_MAXSIZE); - lh->kuc_magic = KUC_MAGIC; - lh->kuc_transport = KUC_TRANSPORT_CHANGELOG; - lh->kuc_flags = flags; - lh->kuc_msgtype = CL_RECORD; - lh->kuc_msglen = len; - return lh; + lh->kuc_magic = KUC_MAGIC; + lh->kuc_transport = KUC_TRANSPORT_CHANGELOG; + lh->kuc_flags = flags; + lh->kuc_msgtype = CL_RECORD; + lh->kuc_msglen = len; + return lh; } #define D_CHANGELOG 0 @@ -1598,18 +1598,18 @@ 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; + int rc; - CDEBUG(D_CHANGELOG, "changelog to fp=%p start "LPU64"\n", - cs->cs_fp, cs->cs_startrec); + CDEBUG(D_CHANGELOG, "changelog to fp=%p start "LPU64"\n", + cs->cs_fp, cs->cs_startrec); - OBD_ALLOC(cs->cs_buf, CR_MAXSIZE); - if (cs->cs_buf == NULL) - GOTO(out, rc = -ENOMEM); + OBD_ALLOC(cs->cs_buf, KUC_CHANGELOG_MSG_MAXSIZE); + if (cs->cs_buf == NULL) + GOTO(out, rc = -ENOMEM); /* Set up the remote catalog handle */ ctxt = llog_get_context(cs->cs_obd, LLOG_CHANGELOG_REPL_CTXT); @@ -1644,7 +1644,7 @@ out: if (ctxt) llog_ctxt_put(ctxt); if (cs->cs_buf) - OBD_FREE(cs->cs_buf, CR_MAXSIZE); + OBD_FREE(cs->cs_buf, KUC_CHANGELOG_MSG_MAXSIZE); OBD_FREE_PTR(cs); return rc; } diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index ed8ce97..015036d 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -3945,24 +3945,24 @@ static inline int changelog_extend_rec(struct changelog_ext_rec *ext) */ int llapi_changelog_recv(void *priv, struct changelog_ext_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; + int rc = 0; - if (!cp || (cp->magic != CHANGELOG_PRIV_MAGIC)) - return -EINVAL; - if (rech == NULL) - return -EINVAL; - kuch = malloc(CR_MAXSIZE + sizeof(*kuch)); - if (kuch == NULL) - return -ENOMEM; + if (!cp || (cp->magic != CHANGELOG_PRIV_MAGIC)) + return -EINVAL; + if (rech == NULL) + return -EINVAL; + kuch = malloc(KUC_CHANGELOG_MSG_MAXSIZE); + if (kuch == NULL) + return -ENOMEM; repeat: - rc = libcfs_ukuc_msg_get(&cp->kuc, (char *)kuch, - CR_MAXSIZE + sizeof(*kuch), - KUC_TRANSPORT_CHANGELOG); - if (rc < 0) - goto out_free; + rc = libcfs_ukuc_msg_get(&cp->kuc, (char *)kuch, + KUC_CHANGELOG_MSG_MAXSIZE, + KUC_TRANSPORT_CHANGELOG); + if (rc < 0) + goto out_free; if ((kuch->kuc_transport != KUC_TRANSPORT_CHANGELOG) || ((kuch->kuc_msgtype != CL_RECORD) && -- 1.8.3.1