* 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.
*/
#define DEBUG_SUBSYSTEM S_MDS
+#include <linux/module.h>
#include <obd_class.h>
-#include <lprocfs_status.h>
-#include <lustre_fid.h>
#include <lustre_mds.h>
-#include <lustre_disk.h> /* for changelogs */
+#include <obd_support.h>
+#include <lu_object.h>
#include <lustre_param.h>
#include <lustre_fid.h>
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:
{
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);
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,
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);
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;
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);
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
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;
}
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);
* \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);
}
/**
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);
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);
}
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);
}
/* 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);
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:
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 */
__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
/* 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);
}
/* 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);
}
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);
(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,
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);
}
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,
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,
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
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;
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),
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;
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));
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;
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 */
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,
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)
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);
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,
* \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))
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;
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,
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)
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);
}
#endif
- return rc;
+ rc = mdd_declare_changelog_store(env, mdd, NULL, handle);
+ return rc;
}
/* set attr and LOV EA at once, return updated attr */
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;
}
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
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)
{
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);
}
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;
}
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;
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);
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)
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,
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,
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,
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;
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);
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,
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);
}
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)
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)
[ "$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}
# 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