示例#1
0
static int llog_origin_close(const struct lu_env *env, struct llog_handle *lgh)
{
	if (lgh->lgh_hdr != NULL && lgh->lgh_hdr->llh_flags & LLOG_F_IS_CAT)
		return llog_cat_close(env, lgh);
	else
		return llog_close(env, lgh);
}
示例#2
0
文件: llog.c 项目: Lezval/lustre
/**
 * Helper function to delete existent llog.
 */
int llog_erase(const struct lu_env *env, struct llog_ctxt *ctxt,
	       struct llog_logid *logid, char *name)
{
	struct llog_handle	*handle;
	int			 rc = 0, rc2;

	ENTRY;

	/* nothing to erase */
	if (name == NULL && logid == NULL)
		RETURN(0);

	rc = llog_open(env, ctxt, &handle, logid, name, LLOG_OPEN_EXISTS);
	if (rc < 0)
		RETURN(rc);

	rc = llog_init_handle(env, handle, LLOG_F_IS_PLAIN, NULL);
	if (rc == 0)
		rc = llog_destroy(env, handle);

	rc2 = llog_close(env, handle);
	if (rc == 0)
		rc = rc2;
	RETURN(rc);
}
示例#3
0
/**
 * Helper function to get the llog size in records. It is used by MGS
 * mostly to check that config llog exists and contains data.
 *
 * \param[in] env	execution environment
 * \param[in] ctxt	llog context
 * \param[in] name	llog name
 *
 * \retval		true if there are records in llog besides a header
 * \retval		false on error or llog without records
 */
int llog_is_empty(const struct lu_env *env, struct llog_ctxt *ctxt,
		  char *name)
{
	struct llog_handle	*llh;
	int			 rc = 0;

	rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
	if (rc < 0) {
		if (likely(rc == -ENOENT))
			rc = 0;
		GOTO(out, rc);
	}

	rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
	if (rc)
		GOTO(out_close, rc);
	rc = llog_get_size(llh);

out_close:
	llog_close(env, llh);
out:
	/* The header is record 1, the llog is still considered as empty
	 * if there is only header */
	return (rc <= 1);
}
示例#4
0
文件: llog_server.c 项目: LLNL/lustre
static int llog_catinfo_cb(struct llog_handle *cat,
                           struct llog_rec_hdr *rec, void *data)
{
        static char *out = NULL;
        static int remains = 0;
        struct llog_ctxt *ctxt = NULL;
        struct llog_handle *handle = NULL;
        struct llog_logid *logid;
        struct llog_logid_rec *lir;
        int l, rc, index, count = 0;
        struct cb_data *cbd = (struct cb_data*)data;
        ENTRY;

        if (cbd->init) {
                out = cbd->out;
                remains = cbd->remains;
                cbd->init = 0;
        }

        if (!(cat->lgh_hdr->llh_flags & LLOG_F_IS_CAT))
                RETURN(-EINVAL);

        if (!cbd->ctxt)
                RETURN(-ENODEV);

        lir = (struct llog_logid_rec *)rec;
        logid = &lir->lid_id;
        rc = llog_create(ctxt, &handle, logid, NULL);
        if (rc)
                RETURN(-EINVAL);
        rc = llog_init_handle(handle, 0, NULL);
        if (rc)
                GOTO(out_close, rc);

        for (index = 1; index < (LLOG_BITMAP_BYTES * 8); index++) {
                if (ext2_test_bit(index, handle->lgh_hdr->llh_bitmap))
                        count++;
        }

        l = snprintf(out, remains, "\t[Log ID]: #"LPX64"#"LPX64"#%08x\n"
                     "\tLog Size: %llu\n\tLast Index: %d\n"
                     "\tUncanceled Records: %d\n",
                     logid->lgl_oid, logid->lgl_oseq, logid->lgl_ogen,
                     i_size_read(handle->lgh_file->f_dentry->d_inode),
                     handle->lgh_last_idx, count);
        out += l;
        remains -= l;
        cbd->out = out;
        cbd->remains = remains;
        if (remains <= 0) {
                CWARN("Not enough memory\n");
                rc = -ENOMEM;
        }
        EXIT;
out_close:
        llog_close(handle);
        return rc;
}
示例#5
0
文件: llog_server.c 项目: LLNL/lustre
int llog_origin_handle_create(struct ptlrpc_request *req)
{
        struct obd_export    *exp = req->rq_export;
        struct obd_device    *obd = exp->exp_obd;
        struct obd_device    *disk_obd;
        struct llog_handle   *loghandle;
        struct llogd_body    *body;
        struct lvfs_run_ctxt  saved;
        struct llog_logid    *logid = NULL;
        struct llog_ctxt     *ctxt;
        char                 *name = NULL;
        int                   rc, rc2;
        ENTRY;

        body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
        if (body == NULL)
                RETURN(-EFAULT);

        if (body->lgd_logid.lgl_oid > 0)
                logid = &body->lgd_logid;

        if (req_capsule_field_present(&req->rq_pill, &RMF_NAME, RCL_CLIENT)) {
                name = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
                if (name == NULL)
                        RETURN(-EFAULT);
                CDEBUG(D_INFO, "%s: opening log %s\n", obd->obd_name, name);
        }

        ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
        if (ctxt == NULL) {
                CDEBUG(D_WARNING, "%s: no ctxt. group=%p idx=%d name=%s\n",
                       obd->obd_name, &obd->obd_olg, body->lgd_ctxt_idx, name);
                RETURN(-ENODEV);
        }
        disk_obd = ctxt->loc_exp->exp_obd;
        push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);

        rc = llog_create(ctxt, &loghandle, logid, name);
        if (rc)
                GOTO(out_pop, rc);

        rc = req_capsule_server_pack(&req->rq_pill);
        if (rc)
                GOTO(out_close, rc = -ENOMEM);

        body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
        body->lgd_logid = loghandle->lgh_id;

        GOTO(out_close, rc);
out_close:
        rc2 = llog_close(loghandle);
        if (!rc)
                rc = rc2;
out_pop:
        pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
        llog_ctxt_put(ctxt);
        return rc;
}
示例#6
0
/* -------------------------------------------------------------------------
 * Tests above, boring obd functions below
 * ------------------------------------------------------------------------- */
static int llog_run_tests(const struct lu_env *env, struct obd_device *obd)
{
	struct llog_handle	*llh = NULL;
	struct llog_ctxt	*ctxt;
	int			 rc, err;
	char			 name[10];

	ENTRY;
	ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
	LASSERT(ctxt);

	sprintf(name, "%x", llog_test_rand);

	rc = llog_test_1(env, obd, name);
	if (rc)
		GOTO(cleanup_ctxt, rc);

	rc = llog_test_2(env, obd, name, &llh);
	if (rc)
		GOTO(cleanup_ctxt, rc);

	rc = llog_test_3(env, obd, llh);
	if (rc)
		GOTO(cleanup, rc);

	rc = llog_test_4(env, obd);
	if (rc)
		GOTO(cleanup, rc);

	rc = llog_test_5(env, obd);
	if (rc)
		GOTO(cleanup, rc);

	rc = llog_test_6(env, obd, name);
	if (rc)
		GOTO(cleanup, rc);

	rc = llog_test_7(env, obd);
	if (rc)
		GOTO(cleanup, rc);

	rc = llog_test_8(env, obd);
	if (rc)
		GOTO(cleanup, rc);

cleanup:
	err = llog_destroy(env, llh);
	if (err)
		CERROR("cleanup: llog_destroy failed: %d\n", err);
	llog_close(env, llh);
	if (rc == 0)
		rc = err;
cleanup_ctxt:
	llog_ctxt_put(ctxt);
	return rc;
}
示例#7
0
文件: llog_test.c 项目: DCteam/lustre
/* -------------------------------------------------------------------------
 * Tests above, boring obd functions below
 * ------------------------------------------------------------------------- */
static int llog_run_tests(struct obd_device *obd)
{
        struct llog_handle *llh;
        struct lvfs_run_ctxt saved;
        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
        int rc, err, cleanup_phase = 0;
        char name[10];
        ENTRY;

        sprintf(name, "%x", llog_test_rand);
        push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);

        rc = llog_test_1(obd, name);
        if (rc)
                GOTO(cleanup, rc);

        rc = llog_test_2(obd, name, &llh);
        if (rc)
                GOTO(cleanup, rc);
        cleanup_phase = 1; /* close llh */

        rc = llog_test_3(obd, llh);
        if (rc)
                GOTO(cleanup, rc);

        rc = llog_test_4(obd);
        if (rc)
                GOTO(cleanup, rc);

        rc = llog_test_5(obd);
        if (rc)
                GOTO(cleanup, rc);

        rc = llog_test_6(obd, name);
        if (rc)
                GOTO(cleanup, rc);

        rc = llog_test_7(obd);
        if (rc)
                GOTO(cleanup, rc);

 cleanup:
        switch (cleanup_phase) {
        case 1:
                err = llog_close(llh);
                if (err)
                        CERROR("cleanup: llog_close failed: %d\n", err);
                if (!rc)
                        rc = err;
        case 0:
                pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
        }
        llog_ctxt_put(ctxt);
        return rc;
}
示例#8
0
文件: llog_server.c 项目: LLNL/lustre
int llog_origin_handle_read_header(struct ptlrpc_request *req)
{
        struct obd_export    *exp = req->rq_export;
        struct obd_device    *obd = exp->exp_obd;
        struct obd_device    *disk_obd;
        struct llog_handle   *loghandle;
        struct llogd_body    *body;
        struct llog_log_hdr  *hdr;
        struct lvfs_run_ctxt  saved;
        struct llog_ctxt     *ctxt;
        __u32                 flags;
        int                   rc, rc2;
        ENTRY;

        body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
        if (body == NULL)
                RETURN(-EFAULT);

        ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
        if (ctxt == NULL)
                RETURN(-ENODEV);

        disk_obd = ctxt->loc_exp->exp_obd;
        push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);

        rc = llog_create(ctxt, &loghandle, &body->lgd_logid, NULL);
        if (rc)
                GOTO(out_pop, rc);

        /*
         * llog_init_handle() reads the llog header
         */
        flags = body->lgd_llh_flags;
        rc = llog_init_handle(loghandle, flags, NULL);
        if (rc)
                GOTO(out_close, rc);

        rc = req_capsule_server_pack(&req->rq_pill);
        if (rc)
                GOTO(out_close, rc = -ENOMEM);

        hdr = req_capsule_server_get(&req->rq_pill, &RMF_LLOG_LOG_HDR);
        *hdr = *loghandle->lgh_hdr;
        GOTO(out_close, rc);
out_close:
        rc2 = llog_close(loghandle);
        if (!rc)
                rc = rc2;
out_pop:
        pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
        llog_ctxt_put(ctxt);
        return rc;
}
示例#9
0
文件: llog_server.c 项目: LLNL/lustre
int llog_origin_handle_destroy(struct ptlrpc_request *req)
{
        struct obd_export    *exp = req->rq_export;
        struct obd_device    *obd = exp->exp_obd;
        struct obd_device    *disk_obd;
        struct llog_handle   *loghandle;
        struct llogd_body    *body;
        struct lvfs_run_ctxt  saved;
        struct llog_logid    *logid = NULL;
        struct llog_ctxt     *ctxt;
        int                   rc;
        ENTRY;

        body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
        if (body == NULL)
                RETURN(-EFAULT);

        if (body->lgd_logid.lgl_oid > 0)
                logid = &body->lgd_logid;

        ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
        if (ctxt == NULL)
                RETURN(-ENODEV);

        disk_obd = ctxt->loc_exp->exp_obd;
        push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);

        rc = llog_create(ctxt, &loghandle, logid, NULL);
        if (rc)
                GOTO(out_pop, rc);

        rc = req_capsule_server_pack(&req->rq_pill);
        if (rc)
                GOTO(out_close, rc = -ENOMEM);

        body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
        body->lgd_logid = loghandle->lgh_id;
        rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
        if (rc)
                GOTO(out_close, rc);
        rc = llog_destroy(loghandle);
        if (rc)
                GOTO(out_close, rc);
        llog_free_handle(loghandle);
        GOTO(out_close, rc);
out_close:
        if (rc)
                llog_close(loghandle);
out_pop:
        pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
        llog_ctxt_put(ctxt);
        return rc;
}
示例#10
0
文件: llog_test.c 项目: DCteam/lustre
/* Test named-log reopen; returns opened log on success */
static int llog_test_2(struct obd_device *obd, char *name,
                       struct llog_handle **llh)
{
        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
        int rc;
        ENTRY;

        CWARN("2a: re-open a log with name: %s\n", name);
        rc = llog_create(ctxt, llh, NULL, name);
        if (rc) {
                CERROR("2a: re-open log with name %s failed: %d\n", name, rc);
                GOTO(out, rc);
        }
        llog_init_handle(*llh, LLOG_F_IS_PLAIN, &uuid);

        if ((rc = verify_handle("2", *llh, 1)))
                GOTO(out, rc);
#if 0
        CWARN("2b: create a log without specified NAME & LOGID\n");
        rc = llog_create(ctxt, &loghandle, NULL, NULL);
        if (rc) {
                CERROR("2b: create log failed\n");
                GOTO(out, rc);
        }
        llog_init_handle(loghandle, LLOG_F_IS_PLAIN, &uuid);
        logid = loghandle->lgh_id;
        llog_close(loghandle);

        CWARN("2b: re-open the log by LOGID\n");
        rc = llog_create(ctxt, &loghandle, &logid, NULL);
        if (rc) {
                CERROR("2b: re-open log by LOGID failed\n");
                GOTO(out, rc);
        }
        llog_init_handle(loghandle, LLOG_F_IS_PLAIN, &uuid);

        CWARN("2b: destroy this log\n");
        rc = llog_destroy(loghandle);
        if (rc) {
                CERROR("2b: destroy log failed\n");
                GOTO(out, rc);
        }
        llog_free_handle(loghandle);
#endif
out:
        llog_ctxt_put(ctxt);

        RETURN(rc);
}
示例#11
0
/**
 * Helper function to open llog or create it if doesn't exist.
 * It hides all transaction handling from caller.
 */
int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt,
		     struct llog_handle **res, struct llog_logid *logid,
		     char *name)
{
	struct dt_device	*d;
	struct thandle		*th;
	int			 rc;

	ENTRY;

	rc = llog_open(env, ctxt, res, logid, name, LLOG_OPEN_NEW);
	if (rc)
		RETURN(rc);

	if (llog_exist(*res))
		RETURN(0);

	LASSERT((*res)->lgh_obj != NULL);

	d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev);

	th = dt_trans_create(env, d);
	if (IS_ERR(th))
		GOTO(out, rc = PTR_ERR(th));

	/* Create update llog object synchronously, which
	 * happens during inialization process see
	 * lod_sub_prep_llog(), to make sure the update
	 * llog object is created before corss-MDT writing
	 * updates into the llog object */
	if (ctxt->loc_flags & LLOG_CTXT_FLAG_NORMAL_FID)
		th->th_sync = 1;

	th->th_wait_submit = 1;
	rc = llog_declare_create(env, *res, th);
	if (rc == 0) {
		rc = dt_trans_start_local(env, d, th);
		if (rc == 0)
			rc = llog_create(env, *res, th);
	}
	dt_trans_stop(env, d, th);
out:
	if (rc)
		llog_close(env, *res);
	RETURN(rc);
}
示例#12
0
文件: llog_test.c 项目: Lezval/lustre
/* Test named-log create/open, close */
static int llog_test_1(const struct lu_env *env,
		       struct obd_device *obd, char *name)
{
	struct llog_handle	*llh;
	struct llog_ctxt	*ctxt;
	int rc;
	int rc2;

	ENTRY;

	CWARN("1a: create a log with name: %s\n", name);
	ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
	LASSERT(ctxt);

	rc = llog_open_create(env, ctxt, &llh, NULL, name);
	if (rc) {
		CERROR("1a: llog_create with name %s failed: %d\n", name, rc);
		GOTO(out, rc);
	}
	rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, &uuid);
	if (rc) {
		CERROR("1a: can't init llog handle: %d\n", rc);
		GOTO(out_close, rc);
	}

	rc = verify_handle("1", llh, 1);

	CWARN("1b: close newly-created log\n");
out_close:
	rc2 = llog_close(env, llh);
	if (rc2) {
		CERROR("1b: close log %s failed: %d\n", name, rc2);
		if (rc == 0)
			rc = rc2;
	}
out:
	llog_ctxt_put(ctxt);
	RETURN(rc);
}
示例#13
0
文件: llog.c 项目: 19Dan01/linux
/**
 * Helper function to open llog or create it if doesn't exist.
 * It hides all transaction handling from caller.
 */
int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt,
		     struct llog_handle **res, struct llog_logid *logid,
		     char *name)
{
	struct dt_device	*d;
	struct thandle		*th;
	int			 rc;

	rc = llog_open(env, ctxt, res, logid, name, LLOG_OPEN_NEW);
	if (rc)
		return rc;

	if (llog_exist(*res))
		return 0;

	LASSERT((*res)->lgh_obj != NULL);

	d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev);

	th = dt_trans_create(env, d);
	if (IS_ERR(th)) {
		rc = PTR_ERR(th);
		goto out;
	}

	rc = llog_declare_create(env, *res, th);
	if (rc == 0) {
		rc = dt_trans_start_local(env, d, th);
		if (rc == 0)
			rc = llog_create(env, *res, th);
	}
	dt_trans_stop(env, d, th);
out:
	if (rc)
		llog_close(env, *res);
	return rc;
}
示例#14
0
文件: llog.c 项目: 19Dan01/linux
int llog_is_empty(const struct lu_env *env, struct llog_ctxt *ctxt,
		  char *name)
{
	struct llog_handle	*llh;
	int			 rc = 0;

	rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
	if (rc < 0) {
		if (likely(rc == -ENOENT))
			rc = 0;
		goto out;
	}

	rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
	if (rc)
		goto out_close;
	rc = llog_get_size(llh);

out_close:
	llog_close(env, llh);
out:
	/* header is record 1 */
	return rc <= 1;
}
示例#15
0
static int llog_test_7_sub(const struct lu_env *env, struct llog_ctxt *ctxt)
{
	struct llog_handle	*llh;
	int			 rc = 0, i, process_count;
	int			 num_recs = 0;

	rc = llog_open_create(env, ctxt, &llh, NULL, NULL);
	if (rc) {
		CERROR("7_sub: create log failed\n");
		return rc;
	}

	rc = llog_init_handle(env, llh,
			      LLOG_F_IS_PLAIN | LLOG_F_ZAP_WHEN_EMPTY,
			      &uuid);
	if (rc) {
		CERROR("7_sub: can't init llog handle: %d\n", rc);
		GOTO(out_close, rc);
	}
	for (i = 0; i < LLOG_BITMAP_SIZE(llh->lgh_hdr); i++) {
		rc = llog_write(env, llh, &llog_records.lrh, NULL, 0,
				NULL, -1);
		if (rc == -ENOSPC) {
			break;
		} else if (rc < 0) {
			CERROR("7_sub: write recs failed at #%d: %d\n",
			       i + 1, rc);
			GOTO(out_close, rc);
		}
		num_recs++;
	}
	if (rc != -ENOSPC) {
		CWARN("7_sub: write record more than BITMAP size!\n");
		GOTO(out_close, rc = -EINVAL);
	}

	rc = verify_handle("7_sub", llh, num_recs + 1);
	if (rc) {
		CERROR("7_sub: verify handle failed: %d\n", rc);
		GOTO(out_close, rc);
	}
	if (num_recs < LLOG_BITMAP_SIZE(llh->lgh_hdr) - 1)
		CWARN("7_sub: records are not aligned, written %d from %u\n",
		      num_recs, LLOG_BITMAP_SIZE(llh->lgh_hdr) - 1);

	plain_counter = 0;
	rc = llog_process(env, llh, test_7_print_cb, "test 7", NULL);
	if (rc) {
		CERROR("7_sub: llog process failed: %d\n", rc);
		GOTO(out_close, rc);
	}
	process_count = plain_counter;
	if (process_count != num_recs) {
		CERROR("7_sub: processed %d records from %d total\n",
		       process_count, num_recs);
		GOTO(out_close, rc = -EINVAL);
	}

	plain_counter = 0;
	rc = llog_reverse_process(env, llh, test_7_cancel_cb, "test 7", NULL);
	if (rc) {
		CERROR("7_sub: reverse llog process failed: %d\n", rc);
		GOTO(out_close, rc);
	}
	if (process_count != plain_counter) {
		CERROR("7_sub: Reverse/direct processing found different"
		       "number of records: %d/%d\n",
		       plain_counter, process_count);
		GOTO(out_close, rc = -EINVAL);
	}
	if (llog_exist(llh)) {
		CERROR("7_sub: llog exists but should be zapped\n");
		GOTO(out_close, rc = -EEXIST);
	}

	rc = verify_handle("7_sub", llh, 1);
out_close:
	if (rc)
		llog_destroy(env, llh);
	llog_close(env, llh);
	return rc;
}
示例#16
0
/* Test client api; open log by name and process */
static int llog_test_6(const struct lu_env *env, struct obd_device *obd,
		       char *name)
{
	struct obd_device	*mgc_obd;
	struct llog_ctxt	*ctxt;
	struct obd_uuid		*mgs_uuid;
	struct obd_export	*exp;
	struct obd_uuid		 uuid = { "LLOG_TEST6_UUID" };
	struct llog_handle	*llh = NULL;
	struct llog_ctxt	*nctxt;
	int			 rc, rc2;

	ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
	LASSERT(ctxt);
	mgs_uuid = &ctxt->loc_exp->exp_obd->obd_uuid;

	CWARN("6a: re-open log %s using client API\n", name);
	mgc_obd = class_find_client_obd(mgs_uuid, LUSTRE_MGC_NAME, NULL);
	if (mgc_obd == NULL) {
		CERROR("6a: no MGC devices connected to %s found.\n",
		       mgs_uuid->uuid);
		GOTO(ctxt_release, rc = -ENOENT);
	}

	rc = obd_connect(NULL, &exp, mgc_obd, &uuid,
			 NULL /* obd_connect_data */, NULL);
	if (rc != -EALREADY) {
		CERROR("6a: connect on connected MGC (%s) failed to return"
		       " -EALREADY", mgc_obd->obd_name);
		if (rc == 0)
			obd_disconnect(exp);
		GOTO(ctxt_release, rc = -EINVAL);
	}

	nctxt = llog_get_context(mgc_obd, LLOG_CONFIG_REPL_CTXT);
	rc = llog_open(env, nctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
	if (rc) {
		CERROR("6a: llog_open failed %d\n", rc);
		GOTO(nctxt_put, rc);
	}

	rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
	if (rc) {
		CERROR("6a: llog_init_handle failed %d\n", rc);
		GOTO(parse_out, rc);
	}

	plain_counter = 1; /* llog header is first record */
	CWARN("6b: process log %s using client API\n", name);
	rc = llog_process(env, llh, plain_print_cb, NULL, NULL);
	if (rc)
		CERROR("6b: llog_process failed %d\n", rc);
	CWARN("6b: processed %d records\n", plain_counter);

	rc = verify_handle("6b", llh, plain_counter);
	if (rc)
		GOTO(parse_out, rc);

	plain_counter = 1; /* llog header is first record */
	CWARN("6c: process log %s reversely using client API\n", name);
	rc = llog_reverse_process(env, llh, plain_print_cb, NULL, NULL);
	if (rc)
		CERROR("6c: llog_reverse_process failed %d\n", rc);
	CWARN("6c: processed %d records\n", plain_counter);

	rc = verify_handle("6c", llh, plain_counter);
	if (rc)
		GOTO(parse_out, rc);

parse_out:
	rc2 = llog_close(env, llh);
	if (rc2) {
		CERROR("6: llog_close failed: rc = %d\n", rc2);
		if (rc == 0)
			rc = rc2;
	}
nctxt_put:
	llog_ctxt_put(nctxt);
ctxt_release:
	llog_ctxt_put(ctxt);
	return rc;
}
示例#17
0
/* Test named-log reopen; returns opened log on success */
static int llog_test_2(const struct lu_env *env, struct obd_device *obd,
		       char *name, struct llog_handle **llh)
{
	struct llog_ctxt	*ctxt;
	struct llog_handle	*loghandle;
	struct llog_logid	 logid;
	int			 rc;

	CWARN("2a: re-open a log with name: %s\n", name);
	ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
	LASSERT(ctxt);

	rc = llog_open(env, ctxt, llh, NULL, name, LLOG_OPEN_EXISTS);
	if (rc) {
		CERROR("2a: re-open log with name %s failed: %d\n", name, rc);
		GOTO(out_put, rc);
	}

	rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &uuid);
	if (rc) {
		CERROR("2a: can't init llog handle: %d\n", rc);
		GOTO(out_close_llh, rc);
	}

	rc = verify_handle("2", *llh, 1);
	if (rc)
		GOTO(out_close_llh, rc);

	/* XXX: there is known issue with tests 2b, MGS is not able to create
	 * anonymous llog, exit now to allow following tests run.
	 * It is fixed in upcoming llog over OSD code */
	GOTO(out_put, rc);

	CWARN("2b: create a log without specified NAME & LOGID\n");
	rc = llog_open_create(env, ctxt, &loghandle, NULL, NULL);
	if (rc) {
		CERROR("2b: create log failed\n");
		GOTO(out_close_llh, rc);
	}
	rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, &uuid);
	if (rc) {
		CERROR("2b: can't init llog handle: %d\n", rc);
		GOTO(out_close, rc);
	}

	logid = loghandle->lgh_id;
	llog_close(env, loghandle);

	CWARN("2c: re-open the log by LOGID\n");
	rc = llog_open(env, ctxt, &loghandle, &logid, NULL, LLOG_OPEN_EXISTS);
	if (rc) {
		CERROR("2c: re-open log by LOGID failed\n");
		GOTO(out_close_llh, rc);
	}

	rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, &uuid);
	if (rc) {
		CERROR("2c: can't init llog handle: %d\n", rc);
		GOTO(out_close, rc);
	}

	CWARN("2b: destroy this log\n");
	rc = llog_destroy(env, loghandle);
	if (rc)
		CERROR("2d: destroy log failed\n");
out_close:
	llog_close(env, loghandle);
out_close_llh:
	if (rc)
		llog_close(env, *llh);
out_put:
	llog_ctxt_put(ctxt);

	return rc;
}
示例#18
0
文件: llog.c 项目: 7799/linux
/* backup plain llog */
int llog_backup(const struct lu_env *env, struct obd_device *obd,
		struct llog_ctxt *ctxt, struct llog_ctxt *bctxt,
		char *name, char *backup)
{
	struct llog_handle	*llh, *bllh;
	int			 rc;



	/* open original log */
	rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
	if (rc < 0) {
		/* the -ENOENT case is also reported to the caller
		 * but silently so it should handle that if needed.
		 */
		if (rc != -ENOENT)
			CERROR("%s: failed to open log %s: rc = %d\n",
			       obd->obd_name, name, rc);
		return rc;
	}

	rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
	if (rc)
		GOTO(out_close, rc);

	/* Make sure there's no old backup log */
	rc = llog_erase(env, bctxt, NULL, backup);
	if (rc < 0 && rc != -ENOENT)
		GOTO(out_close, rc);

	/* open backup log */
	rc = llog_open_create(env, bctxt, &bllh, NULL, backup);
	if (rc) {
		CERROR("%s: failed to open backup logfile %s: rc = %d\n",
		       obd->obd_name, backup, rc);
		GOTO(out_close, rc);
	}

	/* check that backup llog is not the same object as original one */
	if (llh->lgh_obj == bllh->lgh_obj) {
		CERROR("%s: backup llog %s to itself (%s), objects %p/%p\n",
		       obd->obd_name, name, backup, llh->lgh_obj,
		       bllh->lgh_obj);
		GOTO(out_backup, rc = -EEXIST);
	}

	rc = llog_init_handle(env, bllh, LLOG_F_IS_PLAIN, NULL);
	if (rc)
		GOTO(out_backup, rc);

	/* Copy log record by record */
	rc = llog_process_or_fork(env, llh, llog_copy_handler, (void *)bllh,
				  NULL, false);
	if (rc)
		CERROR("%s: failed to backup log %s: rc = %d\n",
		       obd->obd_name, name, rc);
out_backup:
	llog_close(env, bllh);
out_close:
	llog_close(env, llh);
	return rc;
}
示例#19
0
文件: llog_ioctl.c 项目: hpc/lustre
static int llog_check_cb(struct llog_handle *handle, struct llog_rec_hdr *rec,
                         void *data)
{
        struct obd_ioctl_data *ioc_data = (struct obd_ioctl_data *)data;
        static int l, remains, from, to;
        static char *out;
        char *endp;
        int cur_index, rc = 0;

        ENTRY;
        cur_index = rec->lrh_index;

        if (ioc_data && (ioc_data->ioc_inllen1)) {
                l = 0;
                remains = ioc_data->ioc_inllen4 +
                        cfs_size_round(ioc_data->ioc_inllen1) +
                        cfs_size_round(ioc_data->ioc_inllen2) +
                        cfs_size_round(ioc_data->ioc_inllen3);
                from = simple_strtol(ioc_data->ioc_inlbuf2, &endp, 0);
                if (*endp != '\0')
                        RETURN(-EINVAL);
                to = simple_strtol(ioc_data->ioc_inlbuf3, &endp, 0);
                if (*endp != '\0')
                        RETURN(-EINVAL);
                ioc_data->ioc_inllen1 = 0;
                out = ioc_data->ioc_bulk;
                if (cur_index < from)
                        RETURN(0);
                if (to > 0 && cur_index > to)
                        RETURN(-LLOG_EEMPTY);
        }
        if (handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT) {
                struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;
                struct llog_handle *log_handle;

                if (rec->lrh_type != LLOG_LOGID_MAGIC) {
                        l = snprintf(out, remains, "[index]: %05d  [type]: "
                                     "%02x  [len]: %04d failed\n",
                                     cur_index, rec->lrh_type,
                                     rec->lrh_len);
                }
                if (handle->lgh_ctxt == NULL)
                        RETURN(-EOPNOTSUPP);
                rc = llog_cat_id2handle(handle, &log_handle, &lir->lid_id);
                if (rc) {
                        CDEBUG(D_IOCTL,
                               "cannot find log #"LPX64"#"LPX64"#%08x\n",
                               lir->lid_id.lgl_oid, lir->lid_id.lgl_oseq,
                               lir->lid_id.lgl_ogen);
                        RETURN(rc);
                }
                rc = llog_process(log_handle, llog_check_cb, NULL, NULL);
                llog_close(log_handle);
        } else {
                switch (rec->lrh_type) {
                case OST_SZ_REC:
                case OST_RAID1_REC:
                case MDS_UNLINK_REC:
                case MDS_SETATTR_REC:
                case MDS_SETATTR64_REC:
                case OBD_CFG_REC:
                case LLOG_HDR_MAGIC: {
                         l = snprintf(out, remains, "[index]: %05d  [type]: "
                                      "%02x  [len]: %04d ok\n",
                                      cur_index, rec->lrh_type,
                                      rec->lrh_len);
                         out += l;
                         remains -= l;
                         if (remains <= 0) {
                                CERROR("no space to print log records\n");
                                RETURN(-LLOG_EEMPTY);
                         }
                         RETURN(0);
                }
                default: {
                         l = snprintf(out, remains, "[index]: %05d  [type]: "
                                      "%02x  [len]: %04d failed\n",
                                      cur_index, rec->lrh_type,
                                      rec->lrh_len);
                         out += l;
                         remains -= l;
                         if (remains <= 0) {
                                CERROR("no space to print log records\n");
                                RETURN(-LLOG_EEMPTY);
                         }
                         RETURN(0);
                }
                }
        }
        RETURN(rc);
}
示例#20
0
文件: llog_ioctl.c 项目: hpc/lustre
int llog_ioctl(struct llog_ctxt *ctxt, int cmd, struct obd_ioctl_data *data)
{
        struct llog_logid logid;
        int err = 0;
        struct llog_handle *handle = NULL;

        ENTRY;
        if (*data->ioc_inlbuf1 == '#') {
                err = str2logid(&logid, data->ioc_inlbuf1, data->ioc_inllen1);
                if (err)
                        GOTO(out, err);
                err = llog_create(ctxt, &handle, &logid, NULL);
                if (err)
                        GOTO(out, err);
        } else if (*data->ioc_inlbuf1 == '$') {
                char *name = data->ioc_inlbuf1 + 1;
                err = llog_create(ctxt, &handle, NULL, name);
                if (err)
                        GOTO(out, err);
        } else {
                GOTO(out, err = -EINVAL);
        }

        err = llog_init_handle(handle, 0, NULL);
        if (err)
                GOTO(out_close, err = -ENOENT);

        switch (cmd) {
        case OBD_IOC_LLOG_INFO: {
                int l;
                int remains = data->ioc_inllen2 +
                        cfs_size_round(data->ioc_inllen1);
                char *out = data->ioc_bulk;

                l = snprintf(out, remains,
                             "logid:            #"LPX64"#"LPX64"#%08x\n"
                             "flags:            %x (%s)\n"
                             "records count:    %d\n"
                             "last index:       %d\n",
                             handle->lgh_id.lgl_oid, handle->lgh_id.lgl_oseq,
                             handle->lgh_id.lgl_ogen,
                             handle->lgh_hdr->llh_flags,
                             handle->lgh_hdr->llh_flags &
                             LLOG_F_IS_CAT ? "cat" : "plain",
                             handle->lgh_hdr->llh_count,
                             handle->lgh_last_idx);
                out += l;
                remains -= l;
                if (remains <= 0)
                        CERROR("not enough space for log header info\n");

                GOTO(out_close, err);
        }
        case OBD_IOC_LLOG_CHECK: {
                LASSERT(data->ioc_inllen1);
                err = llog_process(handle, llog_check_cb, data, NULL);
                if (err == -LLOG_EEMPTY)
                        err = 0;
                GOTO(out_close, err);
        }

        case OBD_IOC_LLOG_PRINT: {
                LASSERT(data->ioc_inllen1);
                err = llog_process(handle, class_config_dump_handler,data,NULL);
                if (err == -LLOG_EEMPTY)
                        err = 0;
                else
                        err = llog_process(handle, llog_print_cb, data, NULL);

                GOTO(out_close, err);
        }
        case OBD_IOC_LLOG_CANCEL: {
                struct llog_cookie cookie;
                struct llog_logid plain;
                char *endp;

                cookie.lgc_index = simple_strtoul(data->ioc_inlbuf3, &endp, 0);
                if (*endp != '\0')
                        GOTO(out_close, err = -EINVAL);

                if (handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT) {
                        cfs_down_write(&handle->lgh_lock);
                        err = llog_cancel_rec(handle, cookie.lgc_index);
                        cfs_up_write(&handle->lgh_lock);
                        GOTO(out_close, err);
                }

                err = str2logid(&plain, data->ioc_inlbuf2, data->ioc_inllen2);
                if (err)
                        GOTO(out_close, err);
                cookie.lgc_lgl = plain;

                if (!(handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT))
                        GOTO(out_close, err = -EINVAL);

                err = llog_cat_cancel_records(handle, 1, &cookie);
                GOTO(out_close, err);
        }
        case OBD_IOC_LLOG_REMOVE: {
                struct llog_logid plain;

                if (handle->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN) {
                        err = llog_destroy(handle);
                        if (!err)
                                llog_free_handle(handle);
                        GOTO(out, err);
                }

                if (!(handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT))
                        GOTO(out_close, err = -EINVAL);

                if (data->ioc_inlbuf2) {
                        /*remove indicate log from the catalog*/
                        err = str2logid(&plain, data->ioc_inlbuf2,
                                        data->ioc_inllen2);
                        if (err)
                                GOTO(out_close, err);
                        err = llog_remove_log(handle, &plain);
                } else {
                        /*remove all the log of the catalog*/
                        llog_process(handle, llog_delete_cb, NULL, NULL);
                }
                GOTO(out_close, err);
        }
        }

out_close:
        if (handle->lgh_hdr &&
            handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)
                llog_cat_put(handle);
        else
                llog_close(handle);
out:
        RETURN(err);
}
示例#21
0
文件: llog_ioctl.c 项目: 7799/linux
int llog_ioctl(const struct lu_env *env, struct llog_ctxt *ctxt, int cmd,
	       struct obd_ioctl_data *data)
{
	struct llog_logid	 logid;
	int			 rc = 0;
	struct llog_handle	*handle = NULL;

	if (*data->ioc_inlbuf1 == '#') {
		rc = str2logid(&logid, data->ioc_inlbuf1, data->ioc_inllen1);
		if (rc)
			return rc;
		rc = llog_open(env, ctxt, &handle, &logid, NULL,
			       LLOG_OPEN_EXISTS);
		if (rc)
			return rc;
	} else if (*data->ioc_inlbuf1 == '$') {
		char *name = data->ioc_inlbuf1 + 1;

		rc = llog_open(env, ctxt, &handle, NULL, name,
			       LLOG_OPEN_EXISTS);
		if (rc)
			return rc;
	} else {
		return -EINVAL;
	}

	rc = llog_init_handle(env, handle, 0, NULL);
	if (rc)
		GOTO(out_close, rc = -ENOENT);

	switch (cmd) {
	case OBD_IOC_LLOG_INFO: {
		int	 l;
		int	 remains = data->ioc_inllen2 +
				   cfs_size_round(data->ioc_inllen1);
		char	*out = data->ioc_bulk;

		l = snprintf(out, remains,
			     "logid:	    #"DOSTID"#%08x\n"
			     "flags:	    %x (%s)\n"
			     "records count:    %d\n"
			     "last index:       %d\n",
			     POSTID(&handle->lgh_id.lgl_oi),
			     handle->lgh_id.lgl_ogen,
			     handle->lgh_hdr->llh_flags,
			     handle->lgh_hdr->llh_flags &
			     LLOG_F_IS_CAT ? "cat" : "plain",
			     handle->lgh_hdr->llh_count,
			     handle->lgh_last_idx);
		out += l;
		remains -= l;
		if (remains <= 0) {
			CERROR("%s: not enough space for log header info\n",
			       ctxt->loc_obd->obd_name);
			rc = -ENOSPC;
		}
		break;
	}
	case OBD_IOC_LLOG_CHECK:
		LASSERT(data->ioc_inllen1 > 0);
		rc = llog_process(env, handle, llog_check_cb, data, NULL);
		if (rc == -LLOG_EEMPTY)
			rc = 0;
		else if (rc)
			GOTO(out_close, rc);
		break;
	case OBD_IOC_LLOG_PRINT:
		LASSERT(data->ioc_inllen1 > 0);
		rc = llog_process(env, handle, llog_print_cb, data, NULL);
		if (rc == -LLOG_EEMPTY)
			rc = 0;
		else if (rc)
			GOTO(out_close, rc);
		break;
	case OBD_IOC_LLOG_CANCEL: {
		struct llog_cookie cookie;
		struct llog_logid plain;
		char *endp;

		cookie.lgc_index = simple_strtoul(data->ioc_inlbuf3, &endp, 0);
		if (*endp != '\0')
			GOTO(out_close, rc = -EINVAL);

		if (handle->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN) {
			rc = llog_cancel_rec(NULL, handle, cookie.lgc_index);
			GOTO(out_close, rc);
		} else if (!(handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)) {
			GOTO(out_close, rc = -EINVAL);
		}

		if (data->ioc_inlbuf2 == NULL) /* catalog but no logid */
			GOTO(out_close, rc = -ENOTTY);

		rc = str2logid(&plain, data->ioc_inlbuf2, data->ioc_inllen2);
		if (rc)
			GOTO(out_close, rc);
		cookie.lgc_lgl = plain;
		rc = llog_cat_cancel_records(env, handle, 1, &cookie);
		if (rc)
			GOTO(out_close, rc);
		break;
	}
	case OBD_IOC_LLOG_REMOVE: {
		struct llog_logid plain;

		if (handle->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN) {
			rc = llog_destroy(env, handle);
			GOTO(out_close, rc);
		} else if (!(handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)) {
			GOTO(out_close, rc = -EINVAL);
		}

		if (data->ioc_inlbuf2 > 0) {
			/* remove indicate log from the catalog */
			rc = str2logid(&plain, data->ioc_inlbuf2,
				       data->ioc_inllen2);
			if (rc)
				GOTO(out_close, rc);
			rc = llog_remove_log(env, handle, &plain);
		} else {
			/* remove all the log of the catalog */
			rc = llog_process(env, handle, llog_delete_cb, NULL,
					  NULL);
			if (rc)
				GOTO(out_close, rc);
		}
		break;
	}
	default:
		CERROR("%s: Unknown ioctl cmd %#x\n",
		       ctxt->loc_obd->obd_name, cmd);
		GOTO(out_close, rc = -ENOTTY);
	}

out_close:
	if (handle->lgh_hdr &&
	    handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)
		llog_cat_close(env, handle);
	else
		llog_close(env, handle);
	return rc;
}
示例#22
0
文件: llog_test.c 项目: DCteam/lustre
/* Test client api; open log by name and process */
static int llog_test_6(struct obd_device *obd, char *name)
{
        struct obd_device *mgc_obd;
        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
        struct obd_uuid *mgs_uuid = &ctxt->loc_exp->exp_obd->obd_uuid;
        struct obd_export *exp;
        struct obd_uuid uuid = {"LLOG_TEST6_UUID"};
        struct llog_handle *llh = NULL;
        struct llog_ctxt *nctxt;
        int rc;

        CWARN("6a: re-open log %s using client API\n", name);
        mgc_obd = class_find_client_obd(mgs_uuid, LUSTRE_MGC_NAME, NULL);
        if (mgc_obd == NULL) {
                CERROR("6: no MGC devices connected to %s found.\n",
                       mgs_uuid->uuid);
                GOTO(ctxt_release, rc = -ENOENT);
        }

        rc = obd_connect(NULL, &exp, mgc_obd, &uuid,
                         NULL /* obd_connect_data */, NULL);
        if (rc != -EALREADY) {
                CERROR("6: connect on connected MDC (%s) failed to return"
                       " -EALREADY", mgc_obd->obd_name);
                if (rc == 0)
                        obd_disconnect(exp);
                GOTO(ctxt_release, rc = -EINVAL);
        }

        nctxt = llog_get_context(mgc_obd, LLOG_CONFIG_REPL_CTXT);
        rc = llog_create(nctxt, &llh, NULL, name);
        if (rc) {
                CERROR("6: llog_create failed %d\n", rc);
                llog_ctxt_put(nctxt);
                GOTO(ctxt_release, rc);
        }

        rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
        if (rc) {
                CERROR("6: llog_init_handle failed %d\n", rc);
                GOTO(parse_out, rc);
        }

        rc = llog_process(llh, plain_print_cb, NULL, NULL);
        if (rc)
                CERROR("6: llog_process failed %d\n", rc);

        rc = llog_reverse_process(llh, plain_print_cb, NULL, NULL);
        if (rc)
                CERROR("6: llog_reverse_process failed %d\n", rc);

parse_out:
        rc = llog_close(llh);
        llog_ctxt_put(nctxt);
        if (rc) {
                CERROR("6: llog_close failed: rc = %d\n", rc);
        }
ctxt_release:
        llog_ctxt_put(ctxt);
        RETURN(rc);
}
示例#23
0
文件: llog_server.c 项目: LLNL/lustre
static int llog_catinfo_deletions(struct obd_device *obd, char *buf,
                                  int buf_len)
{
        struct mds_obd *mds = &obd->u.mds;
        struct llog_handle *handle;
        struct lvfs_run_ctxt saved;
        int size, i, count;
        struct llog_catid *idarray;
        char name[32] = CATLIST;
        struct cb_data data;
        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
        int rc;
        ENTRY;

        if (ctxt == NULL || mds == NULL)
                GOTO(release_ctxt, rc = -ENODEV);

        count = mds->mds_lov_desc.ld_tgt_count;
        size = sizeof(*idarray) * count;

        OBD_ALLOC_LARGE(idarray, size);
        if (!idarray)
                GOTO(release_ctxt, rc = -ENOMEM);

        cfs_mutex_lock(&obd->obd_olg.olg_cat_processing);
        rc = llog_get_cat_list(obd, name, 0, count, idarray);
        if (rc)
                GOTO(out_free, rc);

        push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);

        data.ctxt = ctxt;
        data.out = buf;
        data.remains = buf_len;
        for (i = 0; i < count; i++) {
                int l, index, uncanceled = 0;

                rc = llog_create(ctxt, &handle, &idarray[i].lci_logid, NULL);
                if (rc)
                        GOTO(out_pop, rc);
                rc = llog_init_handle(handle, 0, NULL);
                if (rc) {
                        llog_close(handle);
                        GOTO(out_pop, rc = -ENOENT);
                }
                for (index = 1; index < (LLOG_BITMAP_BYTES * 8); index++) {
                        if (ext2_test_bit(index, handle->lgh_hdr->llh_bitmap))
                                uncanceled++;
                }
                l = snprintf(data.out, data.remains,
                             "\n[Catlog ID]: #"LPX64"#"LPX64"#%08x  "
                             "[Log Count]: %d\n",
                             idarray[i].lci_logid.lgl_oid,
                             idarray[i].lci_logid.lgl_oseq,
                             idarray[i].lci_logid.lgl_ogen, uncanceled);

                data.out += l;
                data.remains -= l;
                data.init = 1;

                llog_process(handle, llog_catinfo_cb, &data, NULL);
                llog_close(handle);

                if (data.remains <= 0)
                        break;
        }
        EXIT;
out_pop:
        pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
out_free:
        cfs_mutex_unlock(&obd->obd_olg.olg_cat_processing);
        OBD_FREE_LARGE(idarray, size);
release_ctxt:
        llog_ctxt_put(ctxt);
        return rc;
}
示例#24
0
文件: llog_server.c 项目: LLNL/lustre
int llog_origin_handle_prev_block(struct ptlrpc_request *req)
{
        struct obd_export    *exp = req->rq_export;
        struct obd_device    *obd = exp->exp_obd;
        struct llog_handle   *loghandle;
        struct llogd_body    *body;
        struct llogd_body    *repbody;
        struct obd_device    *disk_obd;
        struct lvfs_run_ctxt  saved;
        struct llog_ctxt     *ctxt;
        __u32                 flags;
        __u8                 *buf;
        void                 *ptr;
        int                   rc, rc2;
        ENTRY;

        body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
        if (body == NULL)
                RETURN(-EFAULT);

        OBD_ALLOC(buf, LLOG_CHUNK_SIZE);
        if (!buf)
                RETURN(-ENOMEM);

        ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
        if (ctxt == NULL)
                GOTO(out_free, rc = -ENODEV);

        disk_obd = ctxt->loc_exp->exp_obd;
        push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);

        rc = llog_create(ctxt, &loghandle, &body->lgd_logid, NULL);
        if (rc)
                GOTO(out_pop, rc);

        flags = body->lgd_llh_flags;
        rc = llog_init_handle(loghandle, flags, NULL);
        if (rc)
                GOTO(out_close, rc);

        memset(buf, 0, LLOG_CHUNK_SIZE);
        rc = llog_prev_block(loghandle, body->lgd_index,
                             buf, LLOG_CHUNK_SIZE);
        if (rc)
                GOTO(out_close, rc);

        req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
                             LLOG_CHUNK_SIZE);
        rc = req_capsule_server_pack(&req->rq_pill);
        if (rc)
                GOTO(out_close, rc = -ENOMEM);

        repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
        *repbody = *body;

        ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
        memcpy(ptr, buf, LLOG_CHUNK_SIZE);
        GOTO(out_close, rc);
out_close:
        rc2 = llog_close(loghandle);
        if (!rc)
                rc = rc2;

out_pop:
        pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
        llog_ctxt_put(ctxt);
out_free:
        OBD_FREE(buf, LLOG_CHUNK_SIZE);
        return rc;
}