From 7b6aaef15a6547550c99cdaa538ea8b1d4d87c88 Mon Sep 17 00:00:00 2001 From: Mikhail Pershin Date: Thu, 27 Sep 2012 16:16:26 +0400 Subject: [PATCH] LU-2034 changelog: redo changelog using OSD llog changelog to use llog over OSD Signed-off-by: Mikhail Pershin Change-Id: I4b9d1ee5146ef882db6031e996a6d81b6cae870b Reviewed-on: http://review.whamcloud.com/4120 Tested-by: Hudson Reviewed-by: Alex Zhuravlev Reviewed-by: Andreas Dilger Tested-by: Maloo --- lustre/include/lu_object.h | 4 + lustre/mdd/mdd_device.c | 488 ++++++++++++++++++++------------------ lustre/mdd/mdd_dir.c | 153 ++++++++++-- lustre/mdd/mdd_internal.h | 29 +-- lustre/mdd/mdd_lproc.c | 26 +- lustre/mdd/mdd_object.c | 47 ++-- lustre/mds/handler.c | 2 - lustre/mds/mds_log.c | 158 ------------ lustre/mdt/mdt_handler.c | 13 +- lustre/obdclass/llog_osd.c | 75 ++++-- lustre/osd-ldiskfs/osd_handler.c | 1 + lustre/osd-zfs/osd_handler.c | 1 + lustre/tests/lustre-rsync-test.sh | 3 - lustre/tests/sanity.sh | 4 +- 14 files changed, 503 insertions(+), 501 deletions(-) diff --git a/lustre/include/lu_object.h b/lustre/include/lu_object.h index d47db12..0d816d2 100644 --- a/lustre/include/lu_object.h +++ b/lustre/include/lu_object.h @@ -628,6 +628,10 @@ struct lu_site { * Top-level device for this stack. */ struct lu_device *ls_top_dev; + /** + * Bottom-level device for this stack + */ + struct lu_device *ls_bottom_dev; /** * Linkage into global list of sites. */ diff --git a/lustre/mdd/mdd_device.c b/lustre/mdd/mdd_device.c index 9d33861..af403b0 100644 --- a/lustre/mdd/mdd_device.c +++ b/lustre/mdd/mdd_device.c @@ -42,11 +42,11 @@ #define DEBUG_SUBSYSTEM S_MDS +#include #include -#include -#include #include -#include /* for changelogs */ +#include +#include #include #include @@ -105,6 +105,7 @@ static int mdd_connect_to_next(const struct lu_env *env, struct mdd_device *m, lud->ld_site = m->mdd_child_exp->exp_obd->obd_lu_dev->ld_site; LASSERT(lud->ld_site); m->mdd_child = lu2dt_dev(m->mdd_child_exp->exp_obd->obd_lu_dev); + m->mdd_bottom = lu2dt_dev(lud->ld_site->ls_bottom_dev); lu_dev_add_linkage(lud->ld_site, lud); out: @@ -192,7 +193,6 @@ static int changelog_init_cb(const struct lu_env *env, struct llog_handle *llh, { struct mdd_device *mdd = (struct mdd_device *)data; struct llog_changelog_rec *rec = (struct llog_changelog_rec *)hdr; - ENTRY; LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN); LASSERT(rec->cr_hdr.lrh_type == CHANGELOG_REC); @@ -204,7 +204,7 @@ static int changelog_init_cb(const struct lu_env *env, struct llog_handle *llh, llh->lgh_id.lgl_oid); mdd->mdd_cl.mc_index = rec->cr.cr_index; - RETURN(LLOG_PROC_BREAK); + return LLOG_PROC_BREAK; } static int changelog_user_init_cb(const struct lu_env *env, @@ -214,7 +214,6 @@ static int changelog_user_init_cb(const struct lu_env *env, struct mdd_device *mdd = (struct mdd_device *)data; struct llog_changelog_user_rec *rec = (struct llog_changelog_user_rec *)hdr; - ENTRY; LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN); LASSERT(rec->cur_hdr.lrh_type == CHANGELOG_USER_REC); @@ -227,93 +226,220 @@ static int changelog_user_init_cb(const struct lu_env *env, mdd->mdd_cl.mc_lastuser = rec->cur_id; cfs_spin_unlock(&mdd->mdd_cl.mc_user_lock); - RETURN(LLOG_PROC_BREAK); + return LLOG_PROC_BREAK; } +static int llog_changelog_cancel_cb(const struct lu_env *env, + struct llog_handle *llh, + struct llog_rec_hdr *hdr, void *data) +{ + struct llog_changelog_rec *rec = (struct llog_changelog_rec *)hdr; + struct llog_cookie cookie; + long long endrec = *(long long *)data; + int rc; + + ENTRY; + + /* This is always a (sub)log, not the catalog */ + LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN); + + if (rec->cr.cr_index > endrec) + /* records are in order, so we're done */ + RETURN(LLOG_PROC_BREAK); + + cookie.lgc_lgl = llh->lgh_id; + cookie.lgc_index = hdr->lrh_index; + + /* cancel them one at a time. I suppose we could store up the cookies + * and cancel them all at once; probably more efficient, but this is + * done as a user call, so who cares... */ + rc = llog_cat_cancel_records(env, llh->u.phd.phd_cat_handle, 1, + &cookie); + RETURN(rc < 0 ? rc : 0); +} -static int mdd_changelog_llog_init(struct mdd_device *mdd) +static int llog_changelog_cancel(const struct lu_env *env, + struct llog_ctxt *ctxt, + struct lov_stripe_md *lsm, int count, + struct llog_cookie *cookies, int flags) { - struct obd_device *obd = mdd2obd_dev(mdd); - struct llog_ctxt *ctxt; - int rc; + struct llog_handle *cathandle = ctxt->loc_handle; + int rc; - /* Find last changelog entry number */ - ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); - if (ctxt == NULL) { - CERROR("no changelog context\n"); - return -EINVAL; - } - if (!ctxt->loc_handle) { - llog_ctxt_put(ctxt); - return -EINVAL; - } + ENTRY; + + /* This should only be called with the catalog handle */ + LASSERT(cathandle->lgh_hdr->llh_flags & LLOG_F_IS_CAT); + + rc = llog_cat_process(env, cathandle, llog_changelog_cancel_cb, + (void *)cookies, 0, 0); + if (rc >= 0) + /* 0 or 1 means we're done */ + rc = 0; + else + CERROR("%s: cancel idx %u of catalog "LPX64" rc=%d\n", + ctxt->loc_obd->obd_name, cathandle->lgh_last_idx, + cathandle->lgh_id.lgl_oid, rc); + + RETURN(rc); +} + +static struct llog_operations changelog_orig_logops; + +int mdd_changelog_on(const struct lu_env *env, struct mdd_device *mdd, int on); + +static int mdd_changelog_llog_init(const struct lu_env *env, + struct mdd_device *mdd) +{ + struct obd_device *obd = mdd2obd_dev(mdd); + struct llog_ctxt *ctxt = NULL, *uctxt = NULL; + struct lu_fid rfid; + int rc; + + OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt); + obd->obd_lvfs_ctxt.dt = mdd->mdd_bottom; + rc = dt_root_get(env, mdd->mdd_bottom, &rfid); + if (rc) + RETURN(-ENODEV); + + changelog_orig_logops = llog_osd_ops; + changelog_orig_logops.lop_cancel = llog_changelog_cancel; + rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CHANGELOG_ORIG_CTXT, + obd, &changelog_orig_logops); + if (rc) { + CERROR("%s: changelog llog setup failed: rc = %d\n", + obd->obd_name, rc); + RETURN(rc); + } + + ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); + LASSERT(ctxt); + + rc = llog_open_create(env, ctxt, &ctxt->loc_handle, NULL, + CHANGELOG_CATALOG); + if (rc) + GOTO(out_cleanup, rc); + + ctxt->loc_handle->lgh_logops->lop_add = llog_cat_add_rec; + ctxt->loc_handle->lgh_logops->lop_declare_add = + llog_cat_declare_add_rec; + + rc = llog_cat_init_and_process(env, ctxt->loc_handle); + if (rc) + GOTO(out_close, rc); - rc = llog_cat_reverse_process(NULL, ctxt->loc_handle, + rc = llog_cat_reverse_process(env, ctxt->loc_handle, changelog_init_cb, mdd); - llog_ctxt_put(ctxt); - if (rc < 0) { - CERROR("changelog init failed: %d\n", rc); - return rc; - } - CDEBUG(D_IOCTL, "changelog starting index="LPU64"\n", - mdd->mdd_cl.mc_index); - - /* Find last changelog user id */ - ctxt = llog_get_context(obd, LLOG_CHANGELOG_USER_ORIG_CTXT); - if (ctxt == NULL) { - CERROR("no changelog user context\n"); - return -EINVAL; - } - if (!ctxt->loc_handle) { - llog_ctxt_put(ctxt); - return -EINVAL; - } + if (rc < 0) { + CERROR("%s: changelog init failed: rc = %d\n", obd->obd_name, + rc); + GOTO(out_close, rc); + } - rc = llog_cat_reverse_process(NULL, ctxt->loc_handle, - changelog_user_init_cb, mdd); - llog_ctxt_put(ctxt); + CDEBUG(D_IOCTL, "changelog starting index="LPU64"\n", + mdd->mdd_cl.mc_index); - if (rc < 0) { - CERROR("changelog user init failed: %d\n", rc); - return rc; - } + /* setup user changelog */ + rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CHANGELOG_USER_ORIG_CTXT, + obd, &changelog_orig_logops); + if (rc) { + CERROR("%s: changelog users llog setup failed: rc = %d\n", + obd->obd_name, rc); + GOTO(out_close, rc); + } - /* If we have registered users, assume we want changelogs on */ - if (mdd->mdd_cl.mc_lastuser > 0) - rc = mdd_changelog_on(mdd, 1); + uctxt = llog_get_context(obd, LLOG_CHANGELOG_USER_ORIG_CTXT); + LASSERT(ctxt); - return rc; + rc = llog_open_create(env, uctxt, &uctxt->loc_handle, NULL, + CHANGELOG_USERS); + if (rc) + GOTO(out_ucleanup, rc); + + uctxt->loc_handle->lgh_logops->lop_add = llog_cat_add_rec; + uctxt->loc_handle->lgh_logops->lop_declare_add = llog_cat_declare_add_rec; + + rc = llog_cat_init_and_process(env, uctxt->loc_handle); + if (rc) + GOTO(out_uclose, rc); + + rc = llog_cat_reverse_process(env, ctxt->loc_handle, + changelog_user_init_cb, mdd); + if (rc < 0) { + CERROR("%s: changelog user init failed: rc = %d\n", + obd->obd_name, rc); + GOTO(out_uclose, rc); + } + + /* If we have registered users, assume we want changelogs on */ + if (mdd->mdd_cl.mc_lastuser > 0) { + rc = mdd_changelog_on(env, mdd, 1); + if (rc < 0) + GOTO(out_uclose, rc); + } + llog_ctxt_put(ctxt); + llog_ctxt_put(uctxt); + RETURN(0); +out_uclose: + llog_cat_close(env, uctxt->loc_handle); +out_ucleanup: + llog_cleanup(env, uctxt); +out_close: + llog_cat_close(env, ctxt->loc_handle); +out_cleanup: + llog_cleanup(env, ctxt); + return rc; } static int mdd_changelog_init(const struct lu_env *env, struct mdd_device *mdd) { - int rc; + struct obd_device *obd = mdd2obd_dev(mdd); + int rc; - mdd->mdd_cl.mc_index = 0; - cfs_spin_lock_init(&mdd->mdd_cl.mc_lock); - mdd->mdd_cl.mc_starttime = cfs_time_current_64(); - mdd->mdd_cl.mc_flags = 0; /* off by default */ - mdd->mdd_cl.mc_mask = CHANGELOG_DEFMASK; - cfs_spin_lock_init(&mdd->mdd_cl.mc_user_lock); - mdd->mdd_cl.mc_lastuser = 0; + mdd->mdd_cl.mc_index = 0; + cfs_spin_lock_init(&mdd->mdd_cl.mc_lock); + mdd->mdd_cl.mc_starttime = cfs_time_current_64(); + mdd->mdd_cl.mc_flags = 0; /* off by default */ + mdd->mdd_cl.mc_mask = CHANGELOG_DEFMASK; + cfs_spin_lock_init(&mdd->mdd_cl.mc_user_lock); + mdd->mdd_cl.mc_lastuser = 0; - rc = mdd_changelog_llog_init(mdd); - if (rc) { - CERROR("Changelog setup during init failed %d\n", rc); - mdd->mdd_cl.mc_flags |= CLM_ERR; - } + rc = mdd_changelog_llog_init(env, mdd); + if (rc) { + CERROR("%s: changelog setup during init failed: rc = %d\n", + obd->obd_name, rc); + mdd->mdd_cl.mc_flags |= CLM_ERR; + } - return rc; + return rc; } -static void mdd_changelog_fini(const struct lu_env *env, struct mdd_device *mdd) +static void mdd_changelog_fini(const struct lu_env *env, + struct mdd_device *mdd) { - mdd->mdd_cl.mc_flags = 0; + struct obd_device *obd = mdd2obd_dev(mdd); + struct llog_ctxt *ctxt; + + mdd->mdd_cl.mc_flags = 0; + + ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); + if (ctxt) { + llog_cat_close(env, ctxt->loc_handle); + llog_cleanup(env, ctxt); + } + ctxt = llog_get_context(obd, LLOG_CHANGELOG_USER_ORIG_CTXT); + if (ctxt) { + llog_cat_close(env, ctxt->loc_handle); + llog_cleanup(env, ctxt); + } } +int mdd_changelog_write_header(const struct lu_env *env, + struct mdd_device *mdd, int markerflags); + /* Start / stop recording */ -int mdd_changelog_on(struct mdd_device *mdd, int on) +int mdd_changelog_on(const struct lu_env *env, struct mdd_device *mdd, int on) { int rc = 0; @@ -328,11 +454,11 @@ int mdd_changelog_on(struct mdd_device *mdd, int on) cfs_spin_lock(&mdd->mdd_cl.mc_lock); mdd->mdd_cl.mc_flags |= CLM_ON; cfs_spin_unlock(&mdd->mdd_cl.mc_lock); - rc = mdd_changelog_write_header(mdd, CLM_START); + rc = mdd_changelog_write_header(env, mdd, CLM_START); } } else if ((on == 0) && ((mdd->mdd_cl.mc_flags & CLM_ON) == CLM_ON)) { LCONSOLE_INFO("%s: changelog off\n",mdd2obd_dev(mdd)->obd_name); - rc = mdd_changelog_write_header(mdd, CLM_FINI); + rc = mdd_changelog_write_header(env, mdd, CLM_FINI); cfs_spin_lock(&mdd->mdd_cl.mc_lock); mdd->mdd_cl.mc_flags &= ~CLM_ON; cfs_spin_unlock(&mdd->mdd_cl.mc_lock); @@ -340,85 +466,6 @@ int mdd_changelog_on(struct mdd_device *mdd, int on) return rc; } -static __u64 cl_time(void) { - cfs_fs_time_t time; - - cfs_fs_time_current(&time); - return (((__u64)time.tv_sec) << 30) + time.tv_nsec; -} - -/** Add a changelog 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 - */ -int mdd_changelog_llog_write(struct mdd_device *mdd, - struct llog_changelog_rec *rec, - struct thandle *handle) -{ - struct obd_device *obd = mdd2obd_dev(mdd); - struct llog_ctxt *ctxt; - int rc; - - 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(); - cfs_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; - cfs_spin_unlock(&mdd->mdd_cl.mc_lock); - ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); - if (ctxt == NULL) - return -ENXIO; - - /* nested journal transaction */ - rc = llog_obd_add(NULL, ctxt, &rec->cr_hdr, NULL, NULL, 0); - llog_ctxt_put(ctxt); - - 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 - */ -int mdd_changelog_ext_llog_write(struct mdd_device *mdd, - struct llog_changelog_ext_rec *rec, - struct thandle *handle) -{ - struct obd_device *obd = mdd2obd_dev(mdd); - struct llog_ctxt *ctxt; - int rc; - - 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(); - cfs_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; - cfs_spin_unlock(&mdd->mdd_cl.mc_lock); - ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); - if (ctxt == NULL) - return -ENXIO; - - /* nested journal transaction */ - rc = llog_obd_add(NULL, ctxt, &rec->cr_hdr, NULL, NULL, 0); - llog_ctxt_put(ctxt); - - return rc; -} - /** Remove entries with indicies up to and including \a endrec from the * changelog * \param mdd @@ -453,7 +500,7 @@ int mdd_changelog_llog_cancel(const struct lu_env *env, allright. */ if (endrec == cur) { /* XXX: transaction is started by llog itself */ - rc = mdd_changelog_write_header(mdd, CLM_PURGE); + rc = mdd_changelog_write_header(env, mdd, CLM_PURGE); if (rc) goto out; } @@ -463,7 +510,6 @@ int mdd_changelog_llog_cancel(const struct lu_env *env, changed since the last purge) */ mdd->mdd_cl.mc_starttime = cfs_time_current_64(); - /* XXX: transaction is started by llog itself */ rc = llog_cancel(env, ctxt, NULL, 1, (struct llog_cookie *)&endrec, 0); out: llog_ctxt_put(ctxt); @@ -475,36 +521,54 @@ out: * \param markerflags - CLM_* * \retval 0 ok */ -int mdd_changelog_write_header(struct mdd_device *mdd, int markerflags) -{ - struct obd_device *obd = mdd2obd_dev(mdd); - struct llog_changelog_rec *rec; - int reclen; - int len = strlen(obd->obd_name); - int rc; - ENTRY; +int mdd_changelog_write_header(const struct lu_env *env, + struct mdd_device *mdd, int markerflags) +{ + struct obd_device *obd = mdd2obd_dev(mdd); + struct llog_changelog_rec *rec; + struct lu_buf *buf; + struct llog_ctxt *ctxt; + int reclen; + int len = strlen(obd->obd_name); + int rc; - reclen = llog_data_len(sizeof(*rec) + len); - OBD_ALLOC(rec, reclen); - if (rec == NULL) - RETURN(-ENOMEM); + ENTRY; + + if (mdd->mdd_cl.mc_mask & (1 << CL_MARK)) { + mdd->mdd_cl.mc_starttime = cfs_time_current_64(); + RETURN(0); + } + + reclen = llog_data_len(sizeof(*rec) + len); + buf = mdd_buf_alloc(env, reclen); + if (buf->lb_buf == NULL) + RETURN(-ENOMEM); + rec = buf->lb_buf; 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); /* Status and action flags */ - rec->cr.cr_markerflags = mdd->mdd_cl.mc_flags | markerflags; + 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_type = CHANGELOG_REC; + rec->cr.cr_time = cl_time(); + cfs_spin_lock(&mdd->mdd_cl.mc_lock); + rec->cr.cr_index = ++mdd->mdd_cl.mc_index; + cfs_spin_unlock(&mdd->mdd_cl.mc_lock); - /* XXX: transaction is started by llog itself */ - rc = (mdd->mdd_cl.mc_mask & (1 << CL_MARK)) ? - mdd_changelog_llog_write(mdd, rec, NULL) : 0; + ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); + LASSERT(ctxt); - /* assume on or off event; reset repeat-access time */ - mdd->mdd_cl.mc_starttime = cfs_time_current_64(); + rc = llog_cat_add(env, ctxt->loc_handle, &rec->cr_hdr, NULL, NULL); + if (rc > 0) + rc = 0; + llog_ctxt_put(ctxt); - OBD_FREE(rec, reclen); - RETURN(rc); + /* assume on or off event; reset repeat-access time */ + mdd->mdd_cl.mc_starttime = cfs_time_current_64(); + RETURN(rc); } /** @@ -1070,8 +1134,6 @@ static int mdd_process_config(const struct lu_env *env, if (rc) GOTO(out, rc); dt->dd_ops->dt_conf_get(env, dt, &m->mdd_dt_conf); - - mdd_changelog_init(env, m); break; case LCFG_CLEANUP: rc = next->ld_ops->ldo_process_config(env, next, cfg); @@ -1143,7 +1205,14 @@ static int mdd_prepare(const struct lu_env *env, GOTO(out, rc = PTR_ERR(root)); mdd->mdd_capa = root; + rc = mdd_lfsck_setup(env, mdd); + if (rc) { + CERROR("%s: failed to initialize lfsck: rc = %d\n", + mdd2obd_dev(mdd)->obd_name, rc); + GOTO(out, rc); + } + rc = mdd_changelog_init(env, mdd); GOTO(out, rc); @@ -1380,14 +1449,16 @@ struct md_capainfo *md_capainfo(const struct lu_env *env) } EXPORT_SYMBOL(md_capainfo); -static int mdd_changelog_user_register(struct mdd_device *mdd, int *id) +static int mdd_changelog_user_register(const struct lu_env *env, + struct mdd_device *mdd, int *id) { struct llog_ctxt *ctxt; struct llog_changelog_user_rec *rec; int rc; ENTRY; - ctxt = llog_get_context(mdd2obd_dev(mdd),LLOG_CHANGELOG_USER_ORIG_CTXT); + ctxt = llog_get_context(mdd2obd_dev(mdd), + LLOG_CHANGELOG_USER_ORIG_CTXT); if (ctxt == NULL) RETURN(-ENXIO); @@ -1398,7 +1469,7 @@ static int mdd_changelog_user_register(struct mdd_device *mdd, int *id) } /* Assume we want it on since somebody registered */ - rc = mdd_changelog_on(mdd, 1); + rc = mdd_changelog_on(env, mdd, 1); if (rc) GOTO(out, rc); @@ -1414,7 +1485,7 @@ static int mdd_changelog_user_register(struct mdd_device *mdd, int *id) rec->cur_endrec = mdd->mdd_cl.mc_index; cfs_spin_unlock(&mdd->mdd_cl.mc_user_lock); - rc = llog_obd_add(NULL, ctxt, &rec->cur_hdr, NULL, NULL, 0); + rc = llog_cat_add(env, ctxt->loc_handle, &rec->cur_hdr, NULL, NULL); CDEBUG(D_IOCTL, "Registered changelog user %d\n", *id); out: @@ -1423,35 +1494,6 @@ out: RETURN(rc); } -int mdd_declare_llog_cancel(const struct lu_env *env, struct mdd_device *mdd, - struct thandle *handle) -{ - int rc; - - - /* XXX: this is a temporary solution to declare llog changes - * will be fixed in 2.3 with new llog implementation */ - - LASSERT(mdd->mdd_capa); - - /* the llog record could be canceled either by modifying - * the plain llog's header or by destroying the llog itself - * when this record is the last one in it, it can't be known - * here, but the catlog's header will also be modified for - * the second case, then the first case can be covered and - * is no need to declare it */ - - /* destroy empty plain log */ - rc = dt_declare_destroy(env, mdd->mdd_capa, handle); - if (rc) - return rc; - - /* record the catlog's header if an empty plain log was destroyed */ - rc = dt_declare_record_write(env, mdd->mdd_capa, - sizeof(struct llog_logid_rec), 0, handle); - return rc; -} - struct mdd_changelog_user_data { __u64 mcud_endrec; /**< purge record for this user */ __u64 mcud_minrec; /**< lowest changelog recno still referenced */ @@ -1459,7 +1501,6 @@ struct mdd_changelog_user_data { __u32 mcud_minid; /**< user id with lowest rec reference */ __u32 mcud_usercount; int mcud_found:1; - struct mdd_device *mcud_mdd; }; #define MCUD_UNREGISTER -1LL @@ -1503,35 +1544,15 @@ static int mdd_changelog_user_purge_cb(const struct lu_env *env, /* Special case: unregister this user */ if (mcud->mcud_endrec == MCUD_UNREGISTER) { struct llog_cookie cookie; - void *th; - struct mdd_device *mdd = mcud->mcud_mdd; cookie.lgc_lgl = llh->lgh_id; cookie.lgc_index = hdr->lrh_index; - /* XXX This is a workaround for the deadlock of changelog - * adding vs. changelog cancelling. LU-81. */ - th = mdd_trans_create(env, mdd); - if (IS_ERR(th)) { - CERROR("Cannot get thandle\n"); - RETURN(-ENOMEM); - } - - rc = mdd_declare_llog_cancel(env, mdd, th); - if (rc) - GOTO(stop, rc); - - rc = mdd_trans_start(env, mdd, th); - if (rc) - GOTO(stop, rc); - rc = llog_cat_cancel_records(env, llh->u.phd.phd_cat_handle, 1, &cookie); if (rc == 0) mcud->mcud_usercount--; -stop: - mdd_trans_stop(env, mdd, 0, th); RETURN(rc); } @@ -1541,8 +1562,8 @@ stop: /* hdr+1 is loc of data */ hdr->lrh_len -= sizeof(*hdr) + sizeof(struct llog_rec_tail); - rc = llog_write_rec(env, llh, hdr, NULL, 0, (void *)(hdr + 1), - hdr->lrh_index, NULL); + rc = llog_write(env, llh, hdr, NULL, 0, (void *)(hdr + 1), + hdr->lrh_index); RETURN(rc); } @@ -1563,7 +1584,6 @@ static int mdd_changelog_user_purge(const struct lu_env *env, data.mcud_minrec = 0; data.mcud_usercount = 0; data.mcud_endrec = endrec; - data.mcud_mdd = mdd; cfs_spin_lock(&mdd->mdd_cl.mc_lock); endrec = mdd->mdd_cl.mc_index; cfs_spin_unlock(&mdd->mdd_cl.mc_lock); @@ -1572,9 +1592,11 @@ static int mdd_changelog_user_purge(const struct lu_env *env, (data.mcud_endrec != MCUD_UNREGISTER))) data.mcud_endrec = endrec; - ctxt = llog_get_context(mdd2obd_dev(mdd),LLOG_CHANGELOG_USER_ORIG_CTXT); + ctxt = llog_get_context(mdd2obd_dev(mdd), + LLOG_CHANGELOG_USER_ORIG_CTXT); if (ctxt == NULL) return -ENXIO; + LASSERT(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT); rc = llog_cat_process(env, ctxt->loc_handle, @@ -1601,7 +1623,7 @@ static int mdd_changelog_user_purge(const struct lu_env *env, if (!rc && data.mcud_usercount == 0) /* No more users; turn changelogs off */ - rc = mdd_changelog_on(mdd, 0); + rc = mdd_changelog_on(env, mdd, 0); RETURN (rc); } @@ -1666,7 +1688,7 @@ static int mdd_iocontrol(const struct lu_env *env, struct md_device *m, switch (cmd) { case OBD_IOC_CHANGELOG_REG: - rc = mdd_changelog_user_register(mdd, &data->ioc_u32_1); + rc = mdd_changelog_user_register(env, mdd, &data->ioc_u32_1); break; case OBD_IOC_CHANGELOG_DEREG: rc = mdd_changelog_user_purge(env, mdd, data->ioc_u32_1, diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 1fb0ffd..0095d89 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -610,19 +610,35 @@ int mdd_declare_changelog_store(const struct lu_env *env, const struct lu_name *fname, struct thandle *handle) { - int reclen; + struct obd_device *obd = mdd2obd_dev(mdd); + struct llog_ctxt *ctxt; + struct llog_changelog_rec *rec; + struct lu_buf *buf; + int reclen; + int rc; /* Not recording */ if (!(mdd->mdd_cl.mc_flags & CLM_ON)) return 0; - /* we'll be writing payload + llog header */ - reclen = sizeof(struct llog_changelog_rec); - if (fname) - reclen += fname->ln_namelen; - reclen = llog_data_len(reclen); + reclen = llog_data_len(sizeof(*rec) + + (fname != NULL ? fname->ln_namelen : 0)); + buf = mdd_buf_alloc(env, reclen); + if (buf->lb_buf == NULL) + return -ENOMEM; + + 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; - return mdd_declare_llog_record(env, mdd, reclen, handle); + rc = llog_declare_add(env, ctxt->loc_handle, &rec->cr_hdr, handle); + llog_ctxt_put(ctxt); + + return rc; } static int mdd_declare_changelog_ext_store(const struct lu_env *env, @@ -631,21 +647,112 @@ static int mdd_declare_changelog_ext_store(const struct lu_env *env, const struct lu_name *sname, struct thandle *handle) { - int reclen; + struct obd_device *obd = mdd2obd_dev(mdd); + struct llog_ctxt *ctxt; + struct llog_changelog_ext_rec *rec; + struct lu_buf *buf; + int reclen; + int rc; /* Not recording */ if (!(mdd->mdd_cl.mc_flags & CLM_ON)) return 0; - /* we'll be writing payload + llog header */ - reclen = sizeof(struct llog_changelog_ext_rec); - if (tname) - reclen += tname->ln_namelen; - if (sname) - reclen += 1 + sname->ln_namelen; - reclen = llog_data_len(reclen); + reclen = llog_data_len(sizeof(*rec) + + (tname != NULL ? tname->ln_namelen : 0) + + (sname != NULL ? 1 + sname->ln_namelen : 0)); + buf = mdd_buf_alloc(env, reclen); + if (buf->lb_buf == NULL) + return -ENOMEM; + + rec = buf->lb_buf; + rec->cr_hdr.lrh_len = reclen; + rec->cr_hdr.lrh_type = CHANGELOG_REC; - return mdd_declare_llog_record(env, mdd, reclen, handle); + 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; +} + +/** Add a changelog 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 + */ +int mdd_changelog_store(const struct lu_env *env, struct mdd_device *mdd, + struct llog_changelog_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) + rec->cr.cr_namelen); + rec->cr_hdr.lrh_type = CHANGELOG_REC; + rec->cr.cr_time = cl_time(); + + cfs_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; + cfs_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, 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 + */ +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) + 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(); + + cfs_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; + cfs_spin_unlock(&mdd->mdd_cl.mc_lock); + + ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); + if (ctxt == NULL) + return -ENXIO; + + /* nested journal transaction */ + rc = llog_add(env, ctxt->loc_handle, &rec->cr_hdr, NULL, NULL, th); + llog_ctxt_put(ctxt); + if (rc > 0) + rc = 0; + + return rc; } /** Store a namespace change changelog record @@ -686,7 +793,7 @@ static int mdd_changelog_ns_store(const struct lu_env *env, buf = mdd_buf_alloc(env, reclen); if (buf->lb_buf == NULL) RETURN(-ENOMEM); - rec = (struct llog_changelog_rec *)buf->lb_buf; + rec = buf->lb_buf; rec->cr.cr_flags = CLF_VERSION | (CLF_FLAGMASK & flags); rec->cr.cr_type = (__u32)type; @@ -697,7 +804,7 @@ static int mdd_changelog_ns_store(const struct lu_env *env, target->mod_cltime = cfs_time_current_64(); - rc = mdd_changelog_llog_write(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(&rec->cr.cr_tfid), @@ -749,14 +856,12 @@ static int mdd_changelog_ext_ns_store(const struct lu_env *env, LASSERT(tname != NULL); LASSERT(handle != NULL); - reclen = sizeof(*rec) + tname->ln_namelen; - if (sname != NULL) - reclen += 1 + sname->ln_namelen; - reclen = llog_data_len(reclen); + reclen = llog_data_len(sizeof(*rec) + + sname != NULL ? 1 + sname->ln_namelen : 0); buf = mdd_buf_alloc(env, reclen); if (buf->lb_buf == NULL) RETURN(-ENOMEM); - rec = (struct llog_changelog_ext_rec *)buf->lb_buf; + rec = buf->lb_buf; rec->cr.cr_flags = CLF_EXT_VERSION | (CLF_FLAGMASK & flags); rec->cr.cr_type = (__u32)type; @@ -780,7 +885,7 @@ static int mdd_changelog_ext_ns_store(const struct lu_env *env, fid_zero(&rec->cr.cr_tfid); } - rc = mdd_changelog_ext_llog_write(mdd, rec, handle); + rc = mdd_changelog_ext_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)); diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index d8eb869..8350312 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -79,6 +79,13 @@ struct mdd_changelog { int mc_lastuser; }; +static inline __u64 cl_time(void) { + cfs_fs_time_t time; + + cfs_fs_time_current(&time); + return (((__u64)time.tv_sec) << 30) + time.tv_nsec; +} + /** Objects in .lustre dir */ struct mdd_dot_lustre_objs { struct mdd_object *mdd_obf; @@ -112,6 +119,7 @@ struct mdd_device { struct md_device mdd_md_dev; struct obd_export *mdd_child_exp; struct dt_device *mdd_child; + struct dt_device *mdd_bottom; struct lu_fid mdd_root_fid; struct dt_device_param mdd_dt_conf; struct dt_object *mdd_orphans; /* PENDING directory */ @@ -387,11 +395,11 @@ int mdd_readpage(const struct lu_env *env, struct md_object *obj, int mdd_declare_llog_record(const struct lu_env *env, struct mdd_device *mdd, int reclen, struct thandle *handle); int mdd_declare_changelog_store(const struct lu_env *env, - struct mdd_device *mdd, - const struct lu_name *fname, - struct thandle *handle); -int mdd_changelog(const struct lu_env *env, enum changelog_rec_type type, - int flags, struct md_object *obj); + struct mdd_device *mdd, + const struct lu_name *fname, + struct thandle *handle); +int mdd_changelog_store(const struct lu_env *env, struct mdd_device *mdd, + struct llog_changelog_rec *rec, struct thandle *th); int mdd_declare_object_create_internal(const struct lu_env *env, struct mdd_object *p, struct mdd_object *c, @@ -435,17 +443,6 @@ void mdd_lfsck_cleanup(const struct lu_env *env, struct mdd_device *mdd); struct lu_object *mdd_object_alloc(const struct lu_env *env, const struct lu_object_header *hdr, struct lu_device *d); -struct llog_changelog_rec; -int mdd_changelog_llog_write(struct mdd_device *mdd, - struct llog_changelog_rec *rec, - struct thandle *handle); -int mdd_changelog_ext_llog_write(struct mdd_device *mdd, - struct llog_changelog_ext_rec *rec, - struct thandle *handle); -int mdd_changelog_llog_cancel(const struct lu_env *env, struct mdd_device *mdd, - long long endrec); -int mdd_changelog_write_header(struct mdd_device *mdd, int markerflags); -int mdd_changelog_on(struct mdd_device *mdd, int on); /* mdd_permission.c */ #define mdd_cap_t(x) (x) diff --git a/lustre/mdd/mdd_lproc.c b/lustre/mdd/mdd_lproc.c index 1ca8cfc..8ec3ae2 100644 --- a/lustre/mdd/mdd_lproc.c +++ b/lustre/mdd/mdd_lproc.c @@ -217,18 +217,27 @@ static int lprocfs_changelog_users_cb(const struct lu_env *env, static int lprocfs_rd_changelog_users(char *page, char **start, off_t off, int count, int *eof, void *data) { - struct mdd_device *mdd = data; - struct llog_ctxt *ctxt; - struct cucb_data cucb; - __u64 cur; + struct lu_env env; + struct mdd_device *mdd = data; + struct llog_ctxt *ctxt; + struct cucb_data cucb; + __u64 cur; + int rc; *eof = 1; - ctxt = llog_get_context(mdd2obd_dev(mdd),LLOG_CHANGELOG_USER_ORIG_CTXT); + ctxt = llog_get_context(mdd2obd_dev(mdd), + LLOG_CHANGELOG_USER_ORIG_CTXT); if (ctxt == NULL) return -ENXIO; LASSERT(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT); + rc = lu_env_init(&env, LCT_LOCAL); + if (rc) { + llog_ctxt_put(ctxt); + return rc; + } + cfs_spin_lock(&mdd->mdd_cl.mc_lock); cur = mdd->mdd_cl.mc_index; cfs_spin_unlock(&mdd->mdd_cl.mc_lock); @@ -243,11 +252,12 @@ static int lprocfs_rd_changelog_users(char *page, char **start, off_t off, cucb.idx += snprintf(cucb.page + cucb.idx, cucb.count - cucb.idx, "%-5s %s\n", "ID", "index"); - llog_cat_process(NULL, ctxt->loc_handle, lprocfs_changelog_users_cb, + llog_cat_process(&env, ctxt->loc_handle, lprocfs_changelog_users_cb, &cucb, 0, 0); - llog_ctxt_put(ctxt); - return cucb.idx; + lu_env_fini(&env); + llog_ctxt_put(ctxt); + return cucb.idx; } static int lprocfs_rd_sync_perm(char *page, char **start, off_t off, diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index f9596ee..2851a70 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -947,19 +947,17 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, * \param mdd_obj - mdd_object of change * \param handle - transacion handle */ -static 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) +static 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_fid *tfid = mdo2fid(mdd_obj); - struct llog_changelog_rec *rec; - struct thandle *th = NULL; - struct lu_buf *buf; - int reclen; - int rc; + const struct lu_fid *tfid = mdo2fid(mdd_obj); + struct llog_changelog_rec *rec; + struct lu_buf *buf; + int reclen; + int rc; /* Not recording */ if (!(mdd->mdd_cl.mc_flags & CLM_ON)) @@ -982,7 +980,7 @@ static int mdd_changelog_data_store(const struct lu_env *env, buf = mdd_buf_alloc(env, reclen); if (buf->lb_buf == NULL) RETURN(-ENOMEM); - rec = (struct llog_changelog_rec *)buf->lb_buf; + rec = buf->lb_buf; rec->cr.cr_flags = CLF_VERSION | (CLF_FLAGMASK & flags); rec->cr.cr_type = (__u32)type; @@ -990,18 +988,9 @@ static int mdd_changelog_data_store(const struct lu_env *env, rec->cr.cr_namelen = 0; mdd_obj->mod_cltime = cfs_time_current_64(); - rc = mdd_changelog_llog_write(mdd, rec, handle ? : th); - - if (th) - mdd_trans_stop(env, mdd, rc, th); + rc = mdd_changelog_store(env, mdd, rec, handle); - if (rc < 0) { - CERROR("changelog failed: rc=%d op%d t"DFID"\n", - rc, type, PFID(tfid)); - return -EFAULT; - } - - return 0; + RETURN(rc); } int mdd_changelog(const struct lu_env *env, enum changelog_rec_type type, @@ -1015,7 +1004,7 @@ int mdd_changelog(const struct lu_env *env, enum changelog_rec_type type, handle = mdd_trans_create(env, mdd); if (IS_ERR(handle)) - return(PTR_ERR(handle)); + RETURN(PTR_ERR(handle)); rc = mdd_declare_changelog_store(env, mdd, NULL, handle); if (rc) @@ -1083,10 +1072,6 @@ static int mdd_declare_attr_set(const struct lu_env *env, if (rc) return rc; - rc = mdd_declare_changelog_store(env, mdd, NULL, handle); - if (rc) - return rc; - #ifdef CONFIG_FS_POSIX_ACL if (attr->la_valid & LA_MODE) { mdd_read_lock(env, obj, MOR_TGT_CHILD); @@ -1109,7 +1094,8 @@ static int mdd_declare_attr_set(const struct lu_env *env, } #endif - return rc; + rc = mdd_declare_changelog_store(env, mdd, NULL, handle); + return rc; } /* set attr and LOV EA at once, return updated attr */ @@ -1213,6 +1199,7 @@ static int mdd_declare_xattr_set(const struct lu_env *env, if ((strncmp("user.", name, 5) == 0)) rc = mdd_declare_changelog_store(env, mdd, NULL, handle); + rc = mdd_declare_changelog_store(env, mdd, NULL, handle); return rc; } diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 75f3640..dfafa7a 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -130,8 +130,6 @@ static int mds_postsetup(struct obd_device *obd) if (rc) RETURN(rc); - mds_changelog_llog_init(obd, obd); - if (mds->mds_profile) { struct lustre_profile *lprof; /* The profile defines which osc and mdc to connect to, for a diff --git a/lustre/mds/mds_log.c b/lustre/mds/mds_log.c index 76a68b8..0e66eaa 100644 --- a/lustre/mds/mds_log.c +++ b/lustre/mds/mds_log.c @@ -116,153 +116,6 @@ static struct llog_operations mds_size_repl_logops = { lop_cancel: mds_llog_repl_cancel, }; -static struct llog_operations changelog_orig_logops; - -static int llog_changelog_cancel_cb(const struct lu_env *env, - struct llog_handle *llh, - struct llog_rec_hdr *hdr, void *data) -{ - struct llog_changelog_rec *rec = (struct llog_changelog_rec *)hdr; - struct llog_cookie cookie; - long long endrec = *(long long *)data; - int rc, err; - struct obd_device *obd; - void *trans_h; - struct inode *inode; - ENTRY; - - /* This is always a (sub)log, not the catalog */ - LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN); - - if (rec->cr.cr_index > endrec) - /* records are in order, so we're done */ - RETURN(LLOG_PROC_BREAK); - - cookie.lgc_lgl = llh->lgh_id; - cookie.lgc_index = hdr->lrh_index; - obd = llh->lgh_ctxt->loc_exp->exp_obd; - inode = llh->lgh_file->f_dentry->d_inode; - - /* XXX This is a workaround for the deadlock of changelog adding vs. - * changelog cancelling. Changelog adding always start transaction - * before acquiring the catlog lock (lgh_lock), whereas, changelog - * cancelling do start transaction after holding catlog lock. - * - * We start the transaction earlier here to keep the locking ordering: - * 'start transaction -> catlog lock'. LU-81. */ - trans_h = fsfilt_start_log(obd, inode, FSFILT_OP_CANCEL_UNLINK, - NULL, 1); - if (IS_ERR(trans_h)) { - CERROR("fsfilt_start_log failed: %ld\n", PTR_ERR(trans_h)); - RETURN(PTR_ERR(trans_h)); - } - - /* cancel them one at a time. I suppose we could store up the cookies - and cancel them all at once; probably more efficient, but this is - done as a user call, so who cares... */ - rc = llog_cat_cancel_records(env, llh->u.phd.phd_cat_handle, 1, - &cookie); - - err = fsfilt_commit(obd, inode, trans_h, 0); - if (err) { - CERROR("fsfilt_commit failed: %d\n", err); - rc = (rc >= 0) ? err : rc; - } - - RETURN(rc < 0 ? rc : 0); -} - -static int llog_changelog_cancel(const struct lu_env *env, - struct llog_ctxt *ctxt, - struct lov_stripe_md *lsm, int count, - struct llog_cookie *cookies, int flags) -{ - struct llog_handle *cathandle = ctxt->loc_handle; - int rc; - ENTRY; - - /* This should only be called with the catalog handle */ - LASSERT(cathandle->lgh_hdr->llh_flags & LLOG_F_IS_CAT); - - rc = llog_cat_process(env, cathandle, llog_changelog_cancel_cb, - (void *)cookies, 0, 0); - if (rc >= 0) - /* 0 or 1 means we're done */ - rc = 0; - else - CERROR("cancel idx %u of catalog "LPX64" rc=%d\n", - cathandle->lgh_last_idx, cathandle->lgh_id.lgl_oid, rc); - - RETURN(rc); -} - -int mds_changelog_llog_init(struct obd_device *obd, struct obd_device *tgt) -{ - struct llog_ctxt *ctxt = NULL, *uctxt = NULL; - int rc; - - /* see osc_llog_init */ - changelog_orig_logops = llog_lvfs_ops; - changelog_orig_logops.lop_obd_add = llog_obd_origin_add; - changelog_orig_logops.lop_cancel = llog_changelog_cancel; - - rc = llog_setup(NULL, obd, &obd->obd_olg, LLOG_CHANGELOG_ORIG_CTXT, - tgt, &changelog_orig_logops); - if (rc) { - CERROR("%s: changelog llog setup failed: rc = %d\n", - obd->obd_name, rc); - RETURN(rc); - } - - ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); - LASSERT(ctxt); - - rc = llog_open_create(NULL, ctxt, &ctxt->loc_handle, NULL, - CHANGELOG_CATALOG); - if (rc) - GOTO(out_cleanup, rc); - - rc = llog_cat_init_and_process(NULL, ctxt->loc_handle); - if (rc) - GOTO(out_close, rc); - - /* setup user changelog */ - rc = llog_setup(NULL, obd, &obd->obd_olg, - LLOG_CHANGELOG_USER_ORIG_CTXT, tgt, - &changelog_orig_logops); - if (rc) { - CERROR("%s: changelog users llog setup failed: rc = %d\n", - obd->obd_name, rc); - GOTO(out_close, rc); - } - - uctxt = llog_get_context(obd, LLOG_CHANGELOG_USER_ORIG_CTXT); - LASSERT(uctxt); - - rc = llog_open_create(NULL, uctxt, &uctxt->loc_handle, NULL, - CHANGELOG_USERS); - if (rc) - GOTO(out_ucleanup, rc); - - rc = llog_cat_init_and_process(NULL, uctxt->loc_handle); - if (rc) - GOTO(out_uclose, rc); - - llog_ctxt_put(ctxt); - llog_ctxt_put(uctxt); - RETURN(0); -out_uclose: - llog_cat_close(NULL, uctxt->loc_handle); -out_ucleanup: - llog_cleanup(NULL, uctxt); -out_close: - llog_cat_close(NULL, ctxt->loc_handle); -out_cleanup: - llog_cleanup(NULL, ctxt); - return rc; -} -EXPORT_SYMBOL(mds_changelog_llog_init); - int mds_llog_init(struct obd_device *obd, struct obd_llog_group *olg, struct obd_device *disk_obd, int *index) { @@ -314,17 +167,6 @@ int mds_llog_finish(struct obd_device *obd, int count) if (ctxt) llog_cleanup(NULL, ctxt); - ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); - if (ctxt) { - llog_cat_close(NULL, ctxt->loc_handle); - llog_cleanup(NULL, ctxt); - } - - ctxt = llog_get_context(obd, LLOG_CHANGELOG_USER_ORIG_CTXT); - if (ctxt) { - llog_cat_close(NULL, ctxt->loc_handle); - llog_cleanup(NULL, ctxt); - } RETURN(0); } diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 0afd419..fd174aa 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -2286,11 +2286,6 @@ static int mdt_llog_ctxt_clone(const struct lu_env *env, struct mdt_device *mdt, rc = next->md_ops->mdo_llog_ctxt_get(env, next, idx, (void **)&ctxt); if (rc || ctxt == NULL) { - /* XXX: no support for changelogs yet - in another patch */ - /*CERROR("Can't get mdd ctxt %d\n", rc);*/ -#if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 3, 90, 0) -#error "do not forget about changelogs" -#endif return 0; } @@ -5132,10 +5127,6 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m, if (rc) GOTO(err_fs_cleanup, rc); - rc = mdt_llog_ctxt_clone(env, m, LLOG_CHANGELOG_ORIG_CTXT); - if (rc) - GOTO(err_llog_cleanup, rc); - mdt_adapt_sptlrpc_conf(obd, 1); next = m->mdt_child; @@ -5403,6 +5394,10 @@ static int mdt_prepare(const struct lu_env *env, if (rc) RETURN(rc); + rc = mdt_llog_ctxt_clone(env, mdt, LLOG_CHANGELOG_ORIG_CTXT); + if (rc) + RETURN(rc); + rc = mdt_fld_init(env, obd->obd_name, mdt); if (rc) RETURN(rc); diff --git a/lustre/obdclass/llog_osd.c b/lustre/obdclass/llog_osd.c index 4ebe3a8..b96964a 100644 --- a/lustre/obdclass/llog_osd.c +++ b/lustre/obdclass/llog_osd.c @@ -708,6 +708,28 @@ out: return rc; } +struct dt_object *llog_osd_dir_get(const struct lu_env *env, + struct llog_ctxt *ctxt) +{ + struct dt_device *dt; + struct dt_thread_info *dti = dt_info(env); + struct dt_object *dir; + int rc; + + dt = ctxt->loc_exp->exp_obd->obd_lvfs_ctxt.dt; + if (ctxt->loc_dir == NULL) { + rc = dt_root_get(env, dt, &dti->dti_fid); + if (rc) + return ERR_PTR(rc); + dir = dt_locate(env, dt, &dti->dti_fid); + } else { + lu_object_get(&ctxt->loc_dir->do_lu); + dir = ctxt->loc_dir; + } + + return dir; +} + static int llog_osd_open(const struct lu_env *env, struct llog_handle *handle, struct llog_logid *logid, char *name, enum llog_open_param open_param) @@ -744,10 +766,15 @@ static int llog_osd_open(const struct lu_env *env, struct llog_handle *handle, if (logid != NULL) { logid_to_fid(logid, &lgi->lgi_fid); } else if (name) { - LASSERT(ctxt->loc_dir); - dt_read_lock(env, ctxt->loc_dir, 0); - rc = dt_lookup_dir(env, ctxt->loc_dir, name, &lgi->lgi_fid); - dt_read_unlock(env, ctxt->loc_dir); + struct dt_object *llog_dir; + + llog_dir = llog_osd_dir_get(env, ctxt); + if (IS_ERR(llog_dir)) + GOTO(out, rc = PTR_ERR(llog_dir)); + dt_read_lock(env, llog_dir, 0); + rc = dt_lookup_dir(env, llog_dir, name, &lgi->lgi_fid); + dt_read_unlock(env, llog_dir); + lu_object_put(env, &llog_dir->do_lu); if (rc == -ENOENT && open_param == LLOG_OPEN_NEW) { /* generate fid for new llog */ rc = local_object_fid_generate(env, los, @@ -830,12 +857,17 @@ static int llog_osd_declare_create(const struct lu_env *env, RETURN(rc); if (res->lgh_name) { - LASSERT(res->lgh_ctxt->loc_dir); + struct dt_object *llog_dir; + + llog_dir = llog_osd_dir_get(env, res->lgh_ctxt); + if (IS_ERR(llog_dir)) + RETURN(PTR_ERR(llog_dir)); dt_declare_ref_add(env, o, th); logid_to_fid(&res->lgh_id, &lgi->lgi_fid); - rc = dt_declare_insert(env, res->lgh_ctxt->loc_dir, + rc = dt_declare_insert(env, llog_dir, (struct dt_rec *)&lgi->lgi_fid, (struct dt_key *)res->lgh_name, th); + lu_object_put(env, &llog_dir->do_lu); if (rc) CERROR("%s: can't declare named llog %s: rc = %d\n", o->do_lu.lo_dev->ld_obd->obd_name, @@ -879,14 +911,20 @@ static int llog_osd_create(const struct lu_env *env, struct llog_handle *res, RETURN(rc); if (res->lgh_name) { - LASSERT(res->lgh_ctxt->loc_dir); + struct dt_object *llog_dir; + + llog_dir = llog_osd_dir_get(env, res->lgh_ctxt); + if (IS_ERR(llog_dir)) + RETURN(PTR_ERR(llog_dir)); + logid_to_fid(&res->lgh_id, &lgi->lgi_fid); - dt_read_lock(env, res->lgh_ctxt->loc_dir, 0); - rc = dt_insert(env, res->lgh_ctxt->loc_dir, + dt_read_lock(env, llog_dir, 0); + rc = dt_insert(env, llog_dir, (struct dt_rec *)&lgi->lgi_fid, (struct dt_key *)res->lgh_name, th, BYPASS_CAPA, 1); - dt_read_unlock(env, res->lgh_ctxt->loc_dir); + dt_read_unlock(env, llog_dir); + lu_object_put(env, &llog_dir->do_lu); if (rc) CERROR("%s: can't create named llog %s: rc = %d\n", o->do_lu.lo_dev->ld_obd->obd_name, @@ -920,7 +958,7 @@ static int llog_osd_destroy(const struct lu_env *env, struct llog_handle *loghandle) { struct llog_ctxt *ctxt; - struct dt_object *o; + struct dt_object *o, *llog_dir = NULL; struct dt_device *d; struct thandle *th; char *name = NULL; @@ -943,10 +981,13 @@ static int llog_osd_destroy(const struct lu_env *env, RETURN(PTR_ERR(th)); if (loghandle->lgh_name) { - LASSERT(ctxt->loc_dir); + llog_dir = llog_osd_dir_get(env, ctxt); + if (IS_ERR(llog_dir)) + GOTO(out_trans, rc = PTR_ERR(llog_dir)); + dt_declare_ref_del(env, o, th); name = loghandle->lgh_name; - rc = dt_declare_delete(env, ctxt->loc_dir, + rc = dt_declare_delete(env, llog_dir, (struct dt_key *)name, th); if (rc) GOTO(out_trans, rc); @@ -966,11 +1007,11 @@ static int llog_osd_destroy(const struct lu_env *env, if (dt_object_exists(o)) { if (name) { dt_ref_del(env, o, th); - dt_read_lock(env, ctxt->loc_dir, 0); - rc = dt_delete(env, ctxt->loc_dir, + dt_read_lock(env, llog_dir, 0); + rc = dt_delete(env, llog_dir, (struct dt_key *) name, th, BYPASS_CAPA); - dt_read_unlock(env, ctxt->loc_dir); + dt_read_unlock(env, llog_dir); if (rc) { CERROR("%s: can't remove llog %s: rc = %d\n", o->do_lu.lo_dev->ld_obd->obd_name, @@ -987,6 +1028,8 @@ out_unlock: dt_write_unlock(env, o); out_trans: dt_trans_stop(env, d, th); + if (llog_dir != NULL) + lu_object_put(env, &llog_dir->do_lu); RETURN(rc); } diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 3c721d0..426717b 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -4514,6 +4514,7 @@ static int osd_device_init0(const struct lu_env *env, rc = lu_site_init(&o->od_site, l); if (rc) GOTO(out_compat, rc); + o->od_site.ls_bottom_dev = l; rc = lu_site_init_finish(&o->od_site); if (rc) diff --git a/lustre/osd-zfs/osd_handler.c b/lustre/osd-zfs/osd_handler.c index 6bd4bf4..c7cb402 100644 --- a/lustre/osd-zfs/osd_handler.c +++ b/lustre/osd-zfs/osd_handler.c @@ -548,6 +548,7 @@ static int osd_mount(const struct lu_env *env, rc = lu_site_init(&o->od_site, osd2lu_dev(o)); if (rc) GOTO(err, rc); + o->od_site.ls_bottom_dev = osd2lu_dev(o); rc = lu_site_init_finish(&o->od_site); if (rc) diff --git a/lustre/tests/lustre-rsync-test.sh b/lustre/tests/lustre-rsync-test.sh index b07d1e7..de9f428 100644 --- a/lustre/tests/lustre-rsync-test.sh +++ b/lustre/tests/lustre-rsync-test.sh @@ -20,9 +20,6 @@ ALWAYS_EXCEPT="$LRSYNC_EXCEPT" [ "$ALWAYS_EXCEPT$EXCEPT" ] && \ echo "Skipping tests: `echo $ALWAYS_EXCEPT $EXCEPT`" -# disable till changelogs from orion landed (LU-2034) -ALWAYS_EXCEPT="1 2 3 4 5 6 7 8 9" - KILL=/bin/kill TMP=${TMP:-/tmp} diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index fdec8e0..da12150 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -12,8 +12,8 @@ ALWAYS_EXCEPT=" 27u 42a 42b 42c 42d 45 51d 68b $SANIT # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT! # with LOD/OSP landing -# bug number for skipped tests: LU2036 LU2034 -ALWAYS_EXCEPT=" 76 160 $ALWAYS_EXCEPT" +# bug number for skipped tests: LU2036 +ALWAYS_EXCEPT=" 76 $ALWAYS_EXCEPT" # Tests that fail on uml -- 1.8.3.1