Ejemplo n.º 1
0
Archivo: llog.c Proyecto: 7799/linux
/*
 * Helper function for write record in llog.
 * It hides all transaction handling from caller.
 * Valid only with local llog.
 */
int llog_write(const struct lu_env *env, struct llog_handle *loghandle,
	       struct llog_rec_hdr *rec, struct llog_cookie *reccookie,
	       int cookiecount, void *buf, int idx)
{
	struct dt_device	*dt;
	struct thandle		*th;
	int			 rc;

	LASSERT(loghandle);
	LASSERT(loghandle->lgh_ctxt);
	LASSERT(loghandle->lgh_obj != NULL);

	dt = lu2dt_dev(loghandle->lgh_obj->do_lu.lo_dev);

	th = dt_trans_create(env, dt);
	if (IS_ERR(th))
		return PTR_ERR(th);

	rc = llog_declare_write_rec(env, loghandle, rec, idx, th);
	if (rc)
		GOTO(out_trans, rc);

	rc = dt_trans_start_local(env, dt, th);
	if (rc)
		GOTO(out_trans, rc);

	down_write(&loghandle->lgh_lock);
	rc = llog_write_rec(env, loghandle, rec, reccookie,
			    cookiecount, buf, idx, th);
	up_write(&loghandle->lgh_lock);
out_trans:
	dt_trans_stop(env, dt, th);
	return rc;
}
Ejemplo n.º 2
0
/*
 * Helper function for write record in llog.
 * It hides all transaction handling from caller.
 * Valid only with local llog.
 */
int llog_write(const struct lu_env *env, struct llog_handle *loghandle,
	       struct llog_rec_hdr *rec, int idx)
{
	struct dt_device	*dt;
	struct thandle		*th;
	int			 rc;

	ENTRY;

	LASSERT(loghandle);
	LASSERT(loghandle->lgh_ctxt);
	LASSERT(loghandle->lgh_obj != NULL);

	dt = lu2dt_dev(loghandle->lgh_obj->do_lu.lo_dev);

	th = dt_trans_create(env, dt);
	if (IS_ERR(th))
		RETURN(PTR_ERR(th));

	rc = llog_declare_write_rec(env, loghandle, rec, idx, th);
	if (rc)
		GOTO(out_trans, rc);

	th->th_wait_submit = 1;
	rc = dt_trans_start_local(env, dt, th);
	if (rc)
		GOTO(out_trans, rc);

	down_write(&loghandle->lgh_lock);
	rc = llog_write_rec(env, loghandle, rec, NULL, idx, th);
	up_write(&loghandle->lgh_lock);
out_trans:
	dt_trans_stop(env, dt, th);
	RETURN(rc);
}
Ejemplo n.º 3
0
static int llog_test_7(struct obd_device *obd)
{
        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
        struct llog_handle *llh;
        struct llog_create_rec lcr;
        char name[10];
        int rc;
        ENTRY;

        sprintf(name, "%x", llog_test_rand+2);
        CWARN("7: create a log with name: %s\n", name);
        LASSERT(ctxt);

        rc = llog_create(ctxt, &llh, NULL, name);
        if (rc) {
                CERROR("7: llog_create with name %s failed: %d\n", name, rc);
                GOTO(ctxt_release, rc);
        }
        llog_init_handle(llh, LLOG_F_IS_PLAIN, &uuid);

        lcr.lcr_hdr.lrh_len = lcr.lcr_tail.lrt_len = sizeof(lcr);
        lcr.lcr_hdr.lrh_type = OST_SZ_REC;
        rc = llog_write_rec(llh,  &lcr.lcr_hdr, NULL, 0, NULL, -1);
        if (rc) {
                CERROR("7: write one log record failed: %d\n", rc);
                GOTO(ctxt_release, rc);
        }

        rc = llog_destroy(llh);
        if (rc)
                CERROR("7: llog_destroy failed: %d\n", rc);
        else
                llog_free_handle(llh);
ctxt_release:
        llog_ctxt_put(ctxt);
        RETURN(rc);
}
Ejemplo n.º 4
0
/* returns negative on error; 0 if success; 1 if success & log destroyed */
int llog_cancel_rec(const struct lu_env *env, struct llog_handle *loghandle,
		    int index)
{
	struct llog_thread_info *lgi = llog_info(env);
	struct dt_device	*dt;
	struct llog_log_hdr	*llh = loghandle->lgh_hdr;
	struct thandle		*th;
	int			 rc;
	int rc1;
	bool subtract_count = false;

	ENTRY;

	CDEBUG(D_RPCTRACE, "Canceling %d in log "DOSTID"\n", index,
	       POSTID(&loghandle->lgh_id.lgl_oi));

	if (index == 0) {
		CERROR("Can't cancel index 0 which is header\n");
		RETURN(-EINVAL);
	}

	LASSERT(loghandle != NULL);
	LASSERT(loghandle->lgh_ctxt != NULL);
	LASSERT(loghandle->lgh_obj != NULL);

	dt = lu2dt_dev(loghandle->lgh_obj->do_lu.lo_dev);

	th = dt_trans_create(env, dt);
	if (IS_ERR(th))
		RETURN(PTR_ERR(th));

	rc = llog_declare_write_rec(env, loghandle, &llh->llh_hdr, index, th);
	if (rc < 0)
		GOTO(out_trans, rc);

	if ((llh->llh_flags & LLOG_F_ZAP_WHEN_EMPTY))
		rc = llog_declare_destroy(env, loghandle, th);

	th->th_wait_submit = 1;
	rc = dt_trans_start_local(env, dt, th);
	if (rc < 0)
		GOTO(out_trans, rc);

	down_write(&loghandle->lgh_lock);
	/* clear bitmap */
	mutex_lock(&loghandle->lgh_hdr_mutex);
	if (!ext2_clear_bit(index, LLOG_HDR_BITMAP(llh))) {
		CDEBUG(D_RPCTRACE, "Catalog index %u already clear?\n", index);
		GOTO(out_unlock, rc);
	}

	loghandle->lgh_hdr->llh_count--;
	subtract_count = true;
	/* Pass this index to llog_osd_write_rec(), which will use the index
	 * to only update the necesary bitmap. */
	lgi->lgi_cookie.lgc_index = index;
	/* update header */
	rc = llog_write_rec(env, loghandle, &llh->llh_hdr, &lgi->lgi_cookie,
			    LLOG_HEADER_IDX, th);
	if (rc != 0)
		GOTO(out_unlock, rc);

	if ((llh->llh_flags & LLOG_F_ZAP_WHEN_EMPTY) &&
	    (llh->llh_count == 1) &&
	    ((loghandle->lgh_last_idx == LLOG_HDR_BITMAP_SIZE(llh) - 1) ||
	     (loghandle->u.phd.phd_cat_handle != NULL &&
	      loghandle->u.phd.phd_cat_handle->u.chd.chd_current_log !=
		loghandle))) {
		/* never try to destroy it again */
		llh->llh_flags &= ~LLOG_F_ZAP_WHEN_EMPTY;
		rc = llog_trans_destroy(env, loghandle, th);
		if (rc < 0) {
			/* Sigh, can not destroy the final plain llog, but
			 * the bitmap has been clearly, so the record can not
			 * be accessed anymore, let's return 0 for now, and
			 * the orphan will be handled by LFSCK. */
			CERROR("%s: can't destroy empty llog #"DOSTID
			       "#%08x: rc = %d\n",
			       loghandle->lgh_ctxt->loc_obd->obd_name,
			       POSTID(&loghandle->lgh_id.lgl_oi),
			       loghandle->lgh_id.lgl_ogen, rc);
			GOTO(out_unlock, rc);
		}
		rc = LLOG_DEL_PLAIN;
	}

out_unlock:
	mutex_unlock(&loghandle->lgh_hdr_mutex);
	up_write(&loghandle->lgh_lock);
out_trans:
	rc1 = dt_trans_stop(env, dt, th);
	if (rc == 0)
		rc = rc1;
	if (rc < 0 && subtract_count) {
		mutex_lock(&loghandle->lgh_hdr_mutex);
		loghandle->lgh_hdr->llh_count++;
		ext2_set_bit(index, LLOG_HDR_BITMAP(llh));
		mutex_unlock(&loghandle->lgh_hdr_mutex);
	}
	RETURN(rc);
}
Ejemplo n.º 5
0
/* Test record writing, single and in bulk */
static int llog_test_3(struct obd_device *obd, struct llog_handle *llh)
{
        struct llog_create_rec lcr;
        int rc, i;
        int num_recs = 1;       /* 1 for the header */
        ENTRY;

        lcr.lcr_hdr.lrh_len = lcr.lcr_tail.lrt_len = sizeof(lcr);
        lcr.lcr_hdr.lrh_type = OST_SZ_REC;

        CWARN("3a: write one create_rec\n");
        rc = llog_write_rec(llh,  &lcr.lcr_hdr, NULL, 0, NULL, -1);
        num_recs++;
        if (rc) {
                CERROR("3a: write one log record failed: %d\n", rc);
                RETURN(rc);
        }

        if ((rc = verify_handle("3a", llh, num_recs)))
                RETURN(rc);

        CWARN("3b: write 10 cfg log records with 8 bytes bufs\n");
        for (i = 0; i < 10; i++) {
                struct llog_rec_hdr hdr;
                char buf[8];
                hdr.lrh_len = 8;
                hdr.lrh_type = OBD_CFG_REC;
                memset(buf, 0, sizeof buf);
                rc = llog_write_rec(llh, &hdr, NULL, 0, buf, -1);
                if (rc) {
                        CERROR("3b: write 10 records failed at #%d: %d\n",
                               i + 1, rc);
                        RETURN(rc);
                }
                num_recs++;
                if ((rc = verify_handle("3c", llh, num_recs)))
                        RETURN(rc);
        }

        if ((rc = verify_handle("3b", llh, num_recs)))
                RETURN(rc);

        CWARN("3c: write 1000 more log records\n");
        for (i = 0; i < 1000; i++) {
                rc = llog_write_rec(llh, &lcr.lcr_hdr, NULL, 0, NULL, -1);
                if (rc) {
                        CERROR("3c: write 1000 records failed at #%d: %d\n",
                               i + 1, rc);
                        RETURN(rc);
                }
                num_recs++;
                if ((rc = verify_handle("3b", llh, num_recs)))
                        RETURN(rc);
        }

        if ((rc = verify_handle("3c", llh, num_recs)))
                RETURN(rc);

        CWARN("3d: write log more than BITMAP_SIZE, return -ENOSPC\n");
        for (i = 0; i < LLOG_BITMAP_SIZE(llh->lgh_hdr) + 1; i++) {
                struct llog_rec_hdr hdr;
                char buf_even[24];
                char buf_odd[32];

                memset(buf_odd, 0, sizeof buf_odd);
                memset(buf_even, 0, sizeof buf_even);
                if ((i % 2) == 0) {
                        hdr.lrh_len = 24;
                        hdr.lrh_type = OBD_CFG_REC;
                        rc = llog_write_rec(llh, &hdr, NULL, 0, buf_even, -1);
                } else {
                        hdr.lrh_len = 32;
                        hdr.lrh_type = OBD_CFG_REC;
                        rc = llog_write_rec(llh, &hdr, NULL, 0, buf_odd, -1);
                }
                if (rc) {
                        if (rc == -ENOSPC) {
                                break;
                        } else {
                                CERROR("3c: write recs failed at #%d: %d\n",
                                        i + 1, rc);
                                RETURN(rc);
                        }
                }
                num_recs++;
        }
        if (rc != -ENOSPC) {
                CWARN("3d: write record more than BITMAP size!\n");
                RETURN(-EINVAL);
        }
        if ((rc = verify_handle("3d", llh, num_recs)))
                RETURN(rc);

        RETURN(rc);
}