From 33c23fcb661eeffef7ecfcc2c833ff72555678c4 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. Lustre-commit: b1bc221e1eb98314513eff07afc0b4477076c959 Lustre-change: http://review.whamcloud.com/7406 Signed-off-by: Bob Glossman Signed-off-by: Christopher J. Morrone Reviewed-by: Andreas Dilger Reviewed-by: jacques-Charles Lafoucriere Reviewed-by: Oleg Drokin Change-Id: I67068dc6e2d73df15dce7fe00957e4e204aa7e59 Reviewed-on: http://review.whamcloud.com/8170 Tested-by: Jenkins Tested-by: Maloo --- libcfs/include/libcfs/libcfs_kernelcomm.h | 2 ++ lustre/mdc/mdc_request.c | 34 +++++++++++++++---------------- lustre/utils/liblustreapi.c | 30 +++++++++++++-------------- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/libcfs/include/libcfs/libcfs_kernelcomm.h b/libcfs/include/libcfs/libcfs_kernelcomm.h index f7be4b7..ebba2d6 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 2f373ec..cc592a7 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -1495,16 +1495,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 @@ -1562,14 +1562,14 @@ 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); /* * It's important to daemonize here to close unused FDs. @@ -1578,7 +1578,7 @@ static int mdc_changelog_send_thread(void *csdata) */ cfs_daemonize("mdc_clg_send_thread"); - OBD_ALLOC(cs->cs_buf, CR_MAXSIZE); + OBD_ALLOC(cs->cs_buf, KUC_CHANGELOG_MSG_MAXSIZE); if (cs->cs_buf == NULL) GOTO(out, rc = -ENOMEM); @@ -1615,7 +1615,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); /* detach from parent process so we get cleaned up */ cfs_daemonize("cl_send"); diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 2ff8766..d83e73c 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -3919,24 +3919,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