コード例 #1
0
ファイル: llog.c プロジェクト: 7799/linux
int llog_copy_handler(const struct lu_env *env, struct llog_handle *llh,
		      struct llog_rec_hdr *rec, void *data)
{
	struct llog_handle	*copy_llh = data;

	/* Append all records */
	return llog_write(env, copy_llh, rec, NULL, 0, NULL, -1);
}
コード例 #2
0
ファイル: llog.c プロジェクト: Lezval/lustre
/* 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_log_hdr *llh = loghandle->lgh_hdr;
        int rc = 0;
        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);
        }

	spin_lock(&loghandle->lgh_hdr_lock);
	if (!ext2_clear_bit(index, llh->llh_bitmap)) {
		spin_unlock(&loghandle->lgh_hdr_lock);
		CDEBUG(D_RPCTRACE, "Catalog index %u already clear?\n", index);
		RETURN(-ENOENT);
	}

	llh->llh_count--;

	if ((llh->llh_flags & LLOG_F_ZAP_WHEN_EMPTY) &&
	    (llh->llh_count == 1) &&
	    (loghandle->lgh_last_idx == (LLOG_BITMAP_BYTES * 8) - 1)) {
		spin_unlock(&loghandle->lgh_hdr_lock);
		rc = llog_destroy(env, loghandle);
		if (rc < 0) {
			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_err, rc);
		}
		RETURN(1);
	}
	spin_unlock(&loghandle->lgh_hdr_lock);

	rc = llog_write(env, loghandle, &llh->llh_hdr, NULL, 0, NULL, 0);
	if (rc < 0) {
		CERROR("%s: fail to write header for 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_err, rc);
	}
	RETURN(0);
out_err:
	spin_lock(&loghandle->lgh_hdr_lock);
	ext2_set_bit(index, llh->llh_bitmap);
	llh->llh_count++;
	spin_unlock(&loghandle->lgh_hdr_lock);
	return rc;
}
コード例 #3
0
ファイル: mdd_device.c プロジェクト: EMSL-MSC/lustre-release
/** Two things:
 * 1. Find the smallest record everyone is willing to purge
 * 2. Update the last purgeable record for this user
 */
static int mdd_changelog_user_purge_cb(const struct lu_env *env,
				       struct llog_handle *llh,
				       struct llog_rec_hdr *hdr, void *data)
{
	struct llog_changelog_user_rec	*rec;
	struct mdd_changelog_user_data	*mcud = data;
	int				 rc;

        ENTRY;

        LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);

        rec = (struct llog_changelog_user_rec *)hdr;

        mcud->mcud_usercount++;

        /* If we have a new endrec for this id, use it for the following
           min check instead of its old value */
        if (rec->cur_id == mcud->mcud_id)
                rec->cur_endrec = max(rec->cur_endrec, mcud->mcud_endrec);

        /* Track the minimum referenced record */
        if (mcud->mcud_minid == 0 || mcud->mcud_minrec > rec->cur_endrec) {
                mcud->mcud_minid = rec->cur_id;
                mcud->mcud_minrec = rec->cur_endrec;
        }

        if (rec->cur_id != mcud->mcud_id)
                RETURN(0);

        /* Update this user's record */
        mcud->mcud_found = 1;

        /* Special case: unregister this user */
        if (mcud->mcud_endrec == MCUD_UNREGISTER) {
                struct llog_cookie cookie;

                cookie.lgc_lgl = llh->lgh_id;
                cookie.lgc_index = hdr->lrh_index;

		rc = llog_cat_cancel_records(env, llh->u.phd.phd_cat_handle,
					     1, &cookie);
                if (rc == 0)
                        mcud->mcud_usercount--;

                RETURN(rc);
        }

        /* Update the endrec */
        CDEBUG(D_IOCTL, "Rewriting changelog user %d endrec to "LPU64"\n",
               mcud->mcud_id, rec->cur_endrec);

	rc = llog_write(env, llh, hdr, hdr->lrh_index);

        RETURN(rc);
}
コード例 #4
0
ファイル: llog_test.c プロジェクト: AkyZero/wrapfs-latest
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;
}
コード例 #5
0
ファイル: llog_test.c プロジェクト: AkyZero/wrapfs-latest
/* Test record writing, single and in bulk */
static int llog_test_3(const struct lu_env *env, struct obd_device *obd,
		       struct llog_handle *llh)
{
	struct llog_gen_rec	 lgr;
	int			 rc, i;
	int			 num_recs = 1; /* 1 for the header */

	lgr.lgr_hdr.lrh_len = lgr.lgr_tail.lrt_len = sizeof(lgr);
	lgr.lgr_hdr.lrh_type = LLOG_GEN_REC;

	CWARN("3a: write one create_rec\n");
	rc = llog_write(env, llh,  &lgr.lgr_hdr, NULL, 0, NULL, -1);
	num_recs++;
	if (rc < 0) {
		CERROR("3a: write one log record failed: %d\n", rc);
		return rc;
	}

	rc = verify_handle("3a", llh, num_recs);
	if (rc)
		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(env, llh, &hdr, NULL, 0, buf, -1);
		if (rc < 0) {
			CERROR("3b: write 10 records failed at #%d: %d\n",
			       i + 1, rc);
			return rc;
		}
		num_recs++;
	}

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

	CWARN("3c: write 1000 more log records\n");
	for (i = 0; i < 1000; i++) {
		rc = llog_write(env, llh, &lgr.lgr_hdr, NULL, 0, NULL, -1);
		if (rc < 0) {
			CERROR("3c: write 1000 records failed at #%d: %d\n",
			       i + 1, rc);
			return rc;
		}
		num_recs++;
	}

	rc = verify_handle("3c", llh, num_recs);
	if (rc)
		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(env, llh, &hdr, NULL, 0, buf_even, -1);
		} else {
			hdr.lrh_len = 32;
			hdr.lrh_type = OBD_CFG_REC;
			rc = llog_write(env, llh, &hdr, NULL, 0, buf_odd, -1);
		}
		if (rc == -ENOSPC) {
			break;
		} else if (rc < 0) {
			CERROR("3d: 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;
	}
	CWARN("3d: wrote %d more records before end of llog is reached\n",
	      num_recs);

	rc = verify_handle("3d", llh, num_recs);

	return rc;
}
コード例 #6
0
ファイル: llog_test.c プロジェクト: Zealsathish/lustre
/* Test record writing, single and in bulk */
static int llog_test_3(const struct lu_env *env, struct obd_device *obd,
		       struct llog_handle *llh)
{
	struct llog_gen_rec	 lgr;
	int			 rc, i;
	int			 num_recs = 1; /* 1 for the header */

	ENTRY;

	lgr.lgr_hdr.lrh_len = lgr.lgr_tail.lrt_len = sizeof(lgr);
	lgr.lgr_hdr.lrh_type = LLOG_GEN_REC;

	CWARN("3a: write one create_rec\n");
	rc = llog_write(env, llh,  &lgr.lgr_hdr, LLOG_NEXT_IDX);
	num_recs++;
	if (rc < 0) {
		CERROR("3a: write one log record failed: %d\n", rc);
		RETURN(rc);
	}

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

	CWARN("3c: write 1000 more log records\n");
	for (i = 0; i < 1000; i++) {
		rc = llog_write(env, llh, &lgr.lgr_hdr, LLOG_NEXT_IDX);
		if (rc < 0) {
			CERROR("3c: write 1000 records failed at #%d: %d\n",
			       i + 1, rc);
			RETURN(rc);
		}
		num_recs++;
	}

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

	CWARN("3d: write records with variable size until BITMAP_SIZE, "
	      "return -ENOSPC\n");
	for (i = 0; i < LLOG_BITMAP_SIZE(llh->lgh_hdr) + 1; i++) {
		char			 buf[64];
		struct llog_rec_hdr	*hdr = (void *)&buf;

		memset(buf, 0, sizeof buf);
		if ((i % 2) == 0)
			hdr->lrh_len = 40;
		else
			hdr->lrh_len = 64;
		hdr->lrh_type = OBD_CFG_REC;
		rc = llog_write(env, llh, hdr, LLOG_NEXT_IDX);

		if (rc == -ENOSPC) {
			break;
		} else if (rc < 0) {
			CERROR("3d: 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);
	}
	CWARN("3d: wrote %d more records before end of llog is reached\n",
	      num_recs);

	rc = verify_handle("3d", llh, num_recs);

	RETURN(rc);
}