X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fobdclass%2Fllog_cat.c;h=6541d7995189f6b7c401e03a2102345cf9cae245;hp=fc7cd132919ded036ae4ddde224f54526f3503f4;hb=dc910ede715c4f13cde0c64d74e7badaa8dcb07b;hpb=6760f383f6cd0964e70250723b9d24bce13b5318 diff --git a/lustre/obdclass/llog_cat.c b/lustre/obdclass/llog_cat.c index fc7cd13..6541d79 100644 --- a/lustre/obdclass/llog_cat.c +++ b/lustre/obdclass/llog_cat.c @@ -66,22 +66,11 @@ static int llog_cat_new_log(const struct lu_env *env, struct llog_handle *loghandle, struct thandle *th) { + struct llog_thread_info *lgi = llog_info(env); + struct llog_logid_rec *rec = &lgi->lgi_logid; + int rc; - struct llog_log_hdr *llh; - struct llog_logid_rec rec = { { 0 }, }; - int rc, index, bitmap_size; - ENTRY; - - llh = cathandle->lgh_hdr; - bitmap_size = LLOG_BITMAP_SIZE(llh); - - index = (cathandle->lgh_last_idx + 1) % bitmap_size; - - /* maximum number of available slots in catlog is bitmap_size - 2 */ - if (llh->llh_cat_idx == index) { - CERROR("no free catalog slots for log...\n"); - RETURN(-ENOSPC); - } + ENTRY; if (OBD_FAIL_CHECK(OBD_FAIL_MDS_LLOG_CREATE_FAILED)) RETURN(-ENOSPC); @@ -97,46 +86,29 @@ static int llog_cat_new_log(const struct lu_env *env, } rc = llog_init_handle(env, loghandle, - LLOG_F_IS_PLAIN | LLOG_F_ZAP_WHEN_EMPTY, - &cathandle->lgh_hdr->llh_tgtuuid); - if (rc) - GOTO(out_destroy, rc); - - if (index == 0) - index = 1; - - spin_lock(&loghandle->lgh_hdr_lock); - llh->llh_count++; - if (ext2_set_bit(index, llh->llh_bitmap)) { - CERROR("argh, index %u already set in log bitmap?\n", - index); - spin_unlock(&loghandle->lgh_hdr_lock); - LBUG(); /* should never happen */ - } - spin_unlock(&loghandle->lgh_hdr_lock); + LLOG_F_IS_PLAIN | LLOG_F_ZAP_WHEN_EMPTY, + &cathandle->lgh_hdr->llh_tgtuuid); + if (rc) + GOTO(out_destroy, rc); - cathandle->lgh_last_idx = index; - llh->llh_tail.lrt_index = index; + /* build the record for this log in the catalog */ + rec->lid_hdr.lrh_len = sizeof(*rec); + rec->lid_hdr.lrh_type = LLOG_LOGID_MAGIC; + rec->lid_id = loghandle->lgh_id; - CDEBUG(D_RPCTRACE,"new recovery log "DOSTID":%x for index %u of catalog" - DOSTID"\n", POSTID(&loghandle->lgh_id.lgl_oi), - loghandle->lgh_id.lgl_ogen, index, - POSTID(&cathandle->lgh_id.lgl_oi)); - /* build the record for this log in the catalog */ - rec.lid_hdr.lrh_len = sizeof(rec); - rec.lid_hdr.lrh_index = index; - rec.lid_hdr.lrh_type = LLOG_LOGID_MAGIC; - rec.lid_id = loghandle->lgh_id; - rec.lid_tail.lrt_len = sizeof(rec); - rec.lid_tail.lrt_index = index; - - /* update the catalog: header and record */ - rc = llog_write_rec(env, cathandle, &rec.lid_hdr, - &loghandle->u.phd.phd_cookie, 1, NULL, index, th); + /* append the new record into catalog. The new index will be + * assigned to the record and updated in rec header */ + rc = llog_write_rec(env, cathandle, &rec->lid_hdr, + &loghandle->u.phd.phd_cookie, LLOG_NEXT_IDX, th); if (rc < 0) GOTO(out_destroy, rc); - loghandle->lgh_hdr->llh_cat_idx = index; + CDEBUG(D_OTHER, "new recovery log "DOSTID":%x for index %u of catalog" + DOSTID"\n", POSTID(&loghandle->lgh_id.lgl_oi), + loghandle->lgh_id.lgl_ogen, rec->lid_hdr.lrh_index, + POSTID(&cathandle->lgh_id.lgl_oi)); + + loghandle->lgh_hdr->llh_cat_idx = rec->lid_hdr.lrh_index; RETURN(0); out_destroy: llog_destroy(env, loghandle); @@ -331,7 +303,7 @@ static struct llog_handle *llog_cat_current_log(struct llog_handle *cathandle, */ int llog_cat_add_rec(const struct lu_env *env, struct llog_handle *cathandle, struct llog_rec_hdr *rec, struct llog_cookie *reccookie, - void *buf, struct thandle *th) + struct thandle *th) { struct llog_handle *loghandle; int rc; @@ -350,7 +322,7 @@ int llog_cat_add_rec(const struct lu_env *env, struct llog_handle *cathandle, } } /* now let's try to add the record */ - rc = llog_write_rec(env, loghandle, rec, reccookie, 1, buf, -1, th); + rc = llog_write_rec(env, loghandle, rec, reccookie, LLOG_NEXT_IDX, th); if (rc < 0) CDEBUG_LIMIT(rc == -ENOSPC ? D_HA : D_ERROR, "llog_write_rec %d: lh=%p\n", rc, loghandle); @@ -368,8 +340,8 @@ int llog_cat_add_rec(const struct lu_env *env, struct llog_handle *cathandle, } } /* now let's try to add the record */ - rc = llog_write_rec(env, loghandle, rec, reccookie, 1, buf, - -1, th); + rc = llog_write_rec(env, loghandle, rec, reccookie, + LLOG_NEXT_IDX, th); if (rc < 0) CERROR("llog_write_rec %d: lh=%p\n", rc, loghandle); up_write(&loghandle->lgh_lock); @@ -383,6 +355,8 @@ int llog_cat_declare_add_rec(const struct lu_env *env, struct llog_handle *cathandle, struct llog_rec_hdr *rec, struct thandle *th) { + struct llog_thread_info *lgi = llog_info(env); + struct llog_logid_rec *lirec = &lgi->lgi_logid; struct llog_handle *loghandle, *next; int rc = 0; @@ -418,12 +392,14 @@ int llog_cat_declare_add_rec(const struct lu_env *env, if (rc) GOTO(out, rc); + lirec->lid_hdr.lrh_len = sizeof(*lirec); + if (!llog_exist(cathandle->u.chd.chd_current_log)) { rc = llog_declare_create(env, cathandle->u.chd.chd_current_log, th); if (rc) GOTO(out, rc); - llog_declare_write_rec(env, cathandle, NULL, -1, th); + llog_declare_write_rec(env, cathandle, &lirec->lid_hdr, -1, th); } /* declare records in the llogs */ rc = llog_declare_write_rec(env, cathandle->u.chd.chd_current_log, @@ -435,9 +411,14 @@ int llog_cat_declare_add_rec(const struct lu_env *env, if (next) { if (!llog_exist(next)) { rc = llog_declare_create(env, next, th); - llog_declare_write_rec(env, cathandle, NULL, -1, th); + llog_declare_write_rec(env, cathandle, &lirec->lid_hdr, + -1, th); } - llog_declare_write_rec(env, next, rec, -1, th); + /* XXX: we hope for declarations made for existing llog + * this might be not correct with some backends + * where declarations are expected against specific + * object like ZFS with full debugging enabled */ + /*llog_declare_write_rec(env, next, rec, -1, th);*/ } out: RETURN(rc); @@ -445,8 +426,7 @@ out: EXPORT_SYMBOL(llog_cat_declare_add_rec); int llog_cat_add(const struct lu_env *env, struct llog_handle *cathandle, - struct llog_rec_hdr *rec, struct llog_cookie *reccookie, - void *buf) + struct llog_rec_hdr *rec, struct llog_cookie *reccookie) { struct llog_ctxt *ctxt; struct dt_device *dt; @@ -471,7 +451,7 @@ int llog_cat_add(const struct lu_env *env, struct llog_handle *cathandle, rc = dt_trans_start_local(env, dt, th); if (rc) GOTO(out_trans, rc); - rc = llog_cat_add_rec(env, cathandle, rec, reccookie, buf, th); + rc = llog_cat_add_rec(env, cathandle, rec, reccookie, th); out_trans: dt_trans_stop(env, dt, th); RETURN(rc); @@ -538,6 +518,7 @@ int llog_cat_process_cb(const struct lu_env *env, struct llog_handle *cat_llh, struct llog_process_data *d = data; struct llog_logid_rec *lir = (struct llog_logid_rec *)rec; struct llog_handle *llh; + struct llog_log_hdr *hdr; int rc; ENTRY; @@ -557,6 +538,18 @@ int llog_cat_process_cb(const struct lu_env *env, struct llog_handle *cat_llh, RETURN(rc); } + /* clean old empty llogs, do not consider current llog in use */ + hdr = llh->lgh_hdr; + if ((hdr->llh_flags & LLOG_F_ZAP_WHEN_EMPTY) && + hdr->llh_count == 1 && + llh != cat_llh->u.chd.chd_current_log) { + rc = llog_destroy(env, llh); + if (rc) + CERROR("%s: fail to destroy empty log: rc = %d\n", + llh->lgh_ctxt->loc_obd->obd_name, rc); + GOTO(out, rc = LLOG_DEL_PLAIN); + } + if (rec->lrh_index < d->lpd_startcat) { /* Skip processing of the logs until startcat */ rc = 0; @@ -574,6 +567,7 @@ int llog_cat_process_cb(const struct lu_env *env, struct llog_handle *cat_llh, NULL, false); } +out: /* The empty plain log was destroyed while processing */ if (rc == LLOG_DEL_PLAIN) rc = llog_cat_cleanup(env, cat_llh, llh, @@ -640,6 +634,7 @@ static int llog_cat_reverse_process_cb(const struct lu_env *env, struct llog_process_data *d = data; struct llog_logid_rec *lir = (struct llog_logid_rec *)rec; struct llog_handle *llh; + struct llog_log_hdr *hdr; int rc; if (le32_to_cpu(rec->lrh_type) != LLOG_LOGID_MAGIC) { @@ -658,8 +653,21 @@ static int llog_cat_reverse_process_cb(const struct lu_env *env, RETURN(rc); } + /* clean old empty llogs, do not consider current llog in use */ + hdr = llh->lgh_hdr; + if ((hdr->llh_flags & LLOG_F_ZAP_WHEN_EMPTY) && + hdr->llh_count == 1 && + llh != cat_llh->u.chd.chd_current_log) { + rc = llog_destroy(env, llh); + if (rc) + CERROR("%s: fail to destroy empty log: rc = %d\n", + llh->lgh_ctxt->loc_obd->obd_name, rc); + GOTO(out, rc = LLOG_DEL_PLAIN); + } + rc = llog_reverse_process(env, llh, d->lpd_cb, d->lpd_data, NULL); +out: /* The empty plain was destroyed while processing */ if (rc == LLOG_DEL_PLAIN) rc = llog_cat_cleanup(env, cat_llh, llh, @@ -829,10 +837,6 @@ int llog_cat_init_and_process(const struct lu_env *env, if (rc) RETURN(rc); - rc = llog_process_or_fork(env, llh, cat_cancel_cb, NULL, NULL, false); - if (rc) - CERROR("%s: llog_process() with cat_cancel_cb failed: rc = " - "%d\n", llh->lgh_ctxt->loc_obd->obd_name, rc); RETURN(0); } EXPORT_SYMBOL(llog_cat_init_and_process);