X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fobdclass%2Fllog_cat.c;h=1628cc854dd2ce14d2963b0bd131b260558d1a6d;hp=b6b29eb0d25fa8712015219a4f34a7184dd99d8a;hb=3442db6faf685fbdbd092bdfdc8d273e4990a141;hpb=5a8e47d0a1a7548a7f6bbf977a4fdb3935adaed6 diff --git a/lustre/obdclass/llog_cat.c b/lustre/obdclass/llog_cat.c index b6b29eb..1628cc8 100644 --- a/lustre/obdclass/llog_cat.c +++ b/lustre/obdclass/llog_cat.c @@ -85,8 +85,18 @@ static int llog_cat_new_log(const struct lu_env *env, * last_idx and cat_idx */ if ((index == llh->llh_cat_idx + 1 && llh->llh_count > 1) || (index == 0 && llh->llh_cat_idx == 0)) { - CWARN("%s: there are no more free slots in catalog\n", - loghandle->lgh_ctxt->loc_obd->obd_name); + if (cathandle->lgh_name == NULL) { + CWARN("%s: there are no more free slots in catalog " + DFID":%x\n", + loghandle->lgh_ctxt->loc_obd->obd_name, + PFID(&cathandle->lgh_id.lgl_oi.oi_fid), + cathandle->lgh_id.lgl_ogen); + } else { + CWARN("%s: there are no more free slots in " + "catalog %s\n", + loghandle->lgh_ctxt->loc_obd->obd_name, + cathandle->lgh_name); + } RETURN(-ENOSPC); } @@ -744,16 +754,38 @@ int llog_cat_cancel_records(const struct lu_env *env, continue; } + if ((cathandle->lgh_ctxt->loc_flags & + LLOG_CTXT_FLAG_NORMAL_FID) && !llog_exist(loghandle)) { + /* For update log, some of loghandles of cathandle + * might not exist because remote llog creation might + * be failed, so let's skip the record cancellation + * for these non-exist llogs. + */ + lrc = -ENOENT; + CDEBUG(D_HA, "%s: llog "DFID":%x does not exist" + ": rc = %d\n", + cathandle->lgh_ctxt->loc_obd->obd_name, + PFID(&lgl->lgl_oi.oi_fid), lgl->lgl_ogen, lrc); + failed++; + if (rc == 0) + rc = lrc; + continue; + } + lrc = llog_cancel_rec(env, loghandle, cookies->lgc_index); if (lrc == LLOG_DEL_PLAIN) { /* log has been destroyed */ index = loghandle->u.phd.phd_cookie.lgc_index; - rc = llog_cat_cleanup(env, cathandle, loghandle, index); + lrc = llog_cat_cleanup(env, cathandle, loghandle, + index); + if (rc == 0) + rc = lrc; } else if (lrc == -ENOENT) { if (rc == 0) /* ENOENT shouldn't rewrite any error */ rc = lrc; } else if (lrc < 0) { failed++; - rc = lrc; + if (rc == 0) + rc = lrc; } llog_handle_put(loghandle); } @@ -766,57 +798,76 @@ int llog_cat_cancel_records(const struct lu_env *env, } EXPORT_SYMBOL(llog_cat_cancel_records); -static int llog_cat_process_cb(const struct lu_env *env, - struct llog_handle *cat_llh, - struct llog_rec_hdr *rec, void *data) +static int llog_cat_process_common(const struct lu_env *env, + struct llog_handle *cat_llh, + struct llog_rec_hdr *rec, + struct llog_handle **llhp) { - struct llog_process_data *d = data; - struct llog_logid_rec *lir = (struct llog_logid_rec *)rec; - struct llog_handle *llh; + struct llog_logid_rec *lir = container_of(rec, typeof(*lir), lid_hdr); struct llog_log_hdr *hdr; int rc; ENTRY; - if (rec->lrh_type != LLOG_LOGID_MAGIC) { - CERROR("invalid record in catalog\n"); - RETURN(-EINVAL); + if (rec->lrh_type != le32_to_cpu(LLOG_LOGID_MAGIC)) { + rc = -EINVAL; + CWARN("%s: invalid record in catalog "DFID":%x: rc = %d\n", + cat_llh->lgh_ctxt->loc_obd->obd_name, + PFID(&cat_llh->lgh_id.lgl_oi.oi_fid), + cat_llh->lgh_id.lgl_ogen, rc); + RETURN(rc); } - CDEBUG(D_HA, "processing log "DFID":%x at index %u of catalog " - DFID"\n", PFID(&lir->lid_id.lgl_oi.oi_fid), lir->lid_id.lgl_ogen, - rec->lrh_index, PFID(&cat_llh->lgh_id.lgl_oi.oi_fid)); + CDEBUG(D_HA, "processing log "DFID":%x at index %u of catalog "DFID"\n", + PFID(&lir->lid_id.lgl_oi.oi_fid), lir->lid_id.lgl_ogen, + le32_to_cpu(rec->lrh_index), + PFID(&cat_llh->lgh_id.lgl_oi.oi_fid)); - rc = llog_cat_id2handle(env, cat_llh, &llh, &lir->lid_id); + rc = llog_cat_id2handle(env, cat_llh, llhp, &lir->lid_id); if (rc) { - CERROR("%s: cannot find handle for llog "DFID": rc = %d\n", - cat_llh->lgh_ctxt->loc_obd->obd_name, - PFID(&lir->lid_id.lgl_oi.oi_fid), rc); - if (rc == -ENOENT || rc == -ESTALE) { - /* After a server crash, a stub of index - * record in catlog could be kept, because - * plain log destroy + catlog index record - * deletion are not atomic. So we end up with - * an index but no actual record. Destroy the - * index and move on. */ - rc = llog_cat_cleanup(env, cat_llh, NULL, - rec->lrh_index); - } + /* After a server crash, a stub of index record in catlog could + * be kept, because plain log destroy + catlog index record + * deletion are not atomic. So we end up with an index but no + * actual record. Destroy the index and move on. */ + if (rc == -ENOENT || rc == -ESTALE) + rc = LLOG_DEL_RECORD; + else if (rc) + CWARN("%s: can't find llog handle "DFID":%x: rc = %d\n", + cat_llh->lgh_ctxt->loc_obd->obd_name, + PFID(&lir->lid_id.lgl_oi.oi_fid), + lir->lid_id.lgl_ogen, rc); RETURN(rc); } /* clean old empty llogs, do not consider current llog in use */ - /* ignore remote (lgh_obj=NULL) llogs */ - hdr = llh->lgh_hdr; + /* ignore remote (lgh_obj == NULL) llogs */ + hdr = (*llhp)->lgh_hdr; if ((hdr->llh_flags & LLOG_F_ZAP_WHEN_EMPTY) && hdr->llh_count == 1 && cat_llh->lgh_obj != NULL && - llh != cat_llh->u.chd.chd_current_log) { - rc = llog_destroy(env, llh); + *llhp != cat_llh->u.chd.chd_current_log) { + rc = llog_destroy(env, *llhp); 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); + CWARN("%s: can't destroy empty log "DFID": rc = %d\n", + (*llhp)->lgh_ctxt->loc_obd->obd_name, + PFID(&lir->lid_id.lgl_oi.oi_fid), rc); + rc = LLOG_DEL_PLAIN; } + RETURN(rc); +} + +static int llog_cat_process_cb(const struct lu_env *env, + struct llog_handle *cat_llh, + struct llog_rec_hdr *rec, void *data) +{ + struct llog_process_data *d = data; + struct llog_handle *llh = NULL; + int rc; + + ENTRY; + rc = llog_cat_process_common(env, cat_llh, rec, &llh); + if (rc) + GOTO(out, rc); + if (rec->lrh_index < d->lpd_startcat) { /* Skip processing of the logs until startcat */ rc = 0; @@ -836,10 +887,16 @@ static int llog_cat_process_cb(const struct lu_env *env, out: /* The empty plain log was destroyed while processing */ - if (rc == LLOG_DEL_PLAIN) + if (rc == LLOG_DEL_PLAIN) { rc = llog_cat_cleanup(env, cat_llh, llh, llh->u.phd.phd_cookie.lgc_index); - llog_handle_put(llh); + } else if (rc == LLOG_DEL_RECORD) { + /* clear wrong catalog entry */ + rc = llog_cat_cleanup(env, cat_llh, NULL, rec->lrh_index); + } + + if (llh) + llog_handle_put(llh); RETURN(rc); } @@ -900,39 +957,33 @@ static int llog_cat_size_cb(const struct lu_env *env, struct llog_rec_hdr *rec, void *data) { struct llog_process_data *d = data; - struct llog_logid_rec *lir = (struct llog_logid_rec *)rec; - struct llog_handle *llh; - int rc; + struct llog_handle *llh = NULL; __u64 *cum_size = d->lpd_data; __u64 size; + int rc; ENTRY; - if (rec->lrh_type != LLOG_LOGID_MAGIC) { - CERROR("%s: invalid record in catalog, rc = %d\n", - cat_llh->lgh_ctxt->loc_obd->obd_name, -EINVAL); - RETURN(-EINVAL); - } - CDEBUG(D_HA, "processing log "DFID":%x at index %u of catalog " - DFID"\n", PFID(&lir->lid_id.lgl_oi.oi_fid), lir->lid_id.lgl_ogen, - rec->lrh_index, PFID(&cat_llh->lgh_id.lgl_oi.oi_fid)); + rc = llog_cat_process_common(env, cat_llh, rec, &llh); - rc = llog_cat_id2handle(env, cat_llh, &llh, &lir->lid_id); - if (rc) { - CWARN("%s: cannot find handle for llog "DFID": rc = %d\n", - cat_llh->lgh_ctxt->loc_obd->obd_name, - PFID(&lir->lid_id.lgl_oi.oi_fid), rc); - RETURN(0); - } - size = llog_size(env, llh); - *cum_size += size; + if (rc == LLOG_DEL_PLAIN) { + /* empty log was deleted, don't count it */ + rc = llog_cat_cleanup(env, cat_llh, llh, + llh->u.phd.phd_cookie.lgc_index); + } else if (rc == LLOG_DEL_RECORD) { + /* clear wrong catalog entry */ + rc = llog_cat_cleanup(env, cat_llh, NULL, rec->lrh_index); + } else { + size = llog_size(env, llh); + *cum_size += size; - CDEBUG(D_INFO, "Add llog entry "DFID" size %llu\n", - PFID(&llh->lgh_id.lgl_oi.oi_fid), size); + CDEBUG(D_INFO, "Add llog entry "DFID" size=%llu, tot=%llu\n", + PFID(&llh->lgh_id.lgl_oi.oi_fid), size, *cum_size); + } - llog_handle_put(llh); + if (llh != NULL) + llog_handle_put(llh); RETURN(0); - } __u64 llog_cat_size(const struct lu_env *env, struct llog_handle *cat_llh) @@ -946,59 +997,52 @@ __u64 llog_cat_size(const struct lu_env *env, struct llog_handle *cat_llh) } EXPORT_SYMBOL(llog_cat_size); +/* currently returns the number of "free" entries in catalog, + * ie the available entries for a new plain LLOG file creation, + * even if catalog has wrapped + */ +__u32 llog_cat_free_space(struct llog_handle *cat_llh) +{ + /* simulate almost full Catalog */ + if (OBD_FAIL_CHECK(OBD_FAIL_CAT_FREE_RECORDS)) + return cfs_fail_val; + + if (cat_llh->lgh_hdr->llh_count == 1) + return LLOG_HDR_BITMAP_SIZE(cat_llh->lgh_hdr) - 1; + + if (cat_llh->lgh_last_idx > cat_llh->lgh_hdr->llh_cat_idx) + return LLOG_HDR_BITMAP_SIZE(cat_llh->lgh_hdr) - 1 + + cat_llh->lgh_hdr->llh_cat_idx - cat_llh->lgh_last_idx; + + /* catalog is presently wrapped */ + return cat_llh->lgh_hdr->llh_cat_idx - cat_llh->lgh_last_idx; +} +EXPORT_SYMBOL(llog_cat_free_space); + static int llog_cat_reverse_process_cb(const struct lu_env *env, struct llog_handle *cat_llh, struct llog_rec_hdr *rec, void *data) { 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) { - CERROR("invalid record in catalog\n"); - RETURN(-EINVAL); - } - CDEBUG(D_HA, "processing log "DFID":%x at index %u of catalog " - DFID"\n", PFID(&lir->lid_id.lgl_oi.oi_fid), lir->lid_id.lgl_ogen, - le32_to_cpu(rec->lrh_index), - PFID(&cat_llh->lgh_id.lgl_oi.oi_fid)); - - rc = llog_cat_id2handle(env, cat_llh, &llh, &lir->lid_id); - if (rc) { - CERROR("%s: cannot find handle for llog "DFID": rc = %d\n", - cat_llh->lgh_ctxt->loc_obd->obd_name, - PFID(&lir->lid_id.lgl_oi.oi_fid), rc); - if (rc == -ENOENT || rc == -ESTALE) { - /* After a server crash, a stub of index - * record in catlog could be kept, because - * plain log destroy + catlog index record - * deletion are not atomic. So we end up with - * an index but no actual record. Destroy the - * index and move on. */ - rc = llog_cat_cleanup(env, cat_llh, NULL, - rec->lrh_index); - } - - RETURN(rc); - } + ENTRY; + rc = llog_cat_process_common(env, cat_llh, rec, &llh); - /* 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); + /* The empty plain log was destroyed while processing */ + if (rc == LLOG_DEL_PLAIN) { + rc = llog_cat_cleanup(env, cat_llh, llh, + llh->u.phd.phd_cookie.lgc_index); + } else if (rc == LLOG_DEL_RECORD) { + /* clear wrong catalog entry */ + rc = llog_cat_cleanup(env, cat_llh, NULL, rec->lrh_index); } + if (rc) + RETURN(rc); 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,