📄 llog_cat.c
字号:
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * Copyright (C) 2001-2003 Cluster File Systems, Inc. * Author: Andreas Dilger <adilger@clusterfs.com> * * This file is part of the Lustre file system, http://www.lustre.org * Lustre is a trademark of Cluster File Systems, Inc. * * You may have signed or agreed to another license before downloading * this software. If so, you are bound by the terms and conditions * of that agreement, and the following does not apply to you. See the * LICENSE file included with this distribution for more information. * * If you did not agree to a different license, then this copy of Lustre * is open source software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * In either case, Lustre is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * license text for more details. * * OST<->MDS recovery logging infrastructure. * * Invariants in implementation: * - we do not share logs among different OST<->MDS connections, so that * if an OST or MDS fails it need only look at log(s) relevant to itself */#define DEBUG_SUBSYSTEM S_LOG#ifndef EXPORT_SYMTAB#define EXPORT_SYMTAB#endif#ifndef __KERNEL__#include <liblustre.h>#endif#include <obd_class.h>#include <lustre_log.h>#include <libcfs/list.h>/* Create a new log handle and add it to the open list. * This log handle will be closed when all of the records in it are removed. * * Assumes caller has already pushed us into the kernel context and is locking. */static struct llog_handle *llog_cat_new_log(struct llog_handle *cathandle){ struct llog_handle *loghandle; 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(ERR_PTR(-ENOSPC)); } if (OBD_FAIL_CHECK_ONCE(OBD_FAIL_MDS_LLOG_CREATE_FAILED)) RETURN(ERR_PTR(-ENOSPC)); rc = llog_create(cathandle->lgh_ctxt, &loghandle, NULL, NULL); if (rc) RETURN(ERR_PTR(rc)); rc = llog_init_handle(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; if (ext2_set_bit(index, llh->llh_bitmap)) { CERROR("argh, index %u already set in log bitmap?\n", index); LBUG(); /* should never happen */ } cathandle->lgh_last_idx = index; llh->llh_count++; llh->llh_tail.lrt_index = index; CDEBUG(D_RPCTRACE,"new recovery log "LPX64":%x for index %u of catalog " LPX64"\n", loghandle->lgh_id.lgl_oid, loghandle->lgh_id.lgl_ogen, index, cathandle->lgh_id.lgl_oid); /* 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(cathandle, &rec.lid_hdr, &loghandle->u.phd.phd_cookie, 1, NULL, index); if (rc < 0) { GOTO(out_destroy, rc); } loghandle->lgh_hdr->llh_cat_idx = index; cathandle->u.chd.chd_current_log = loghandle; LASSERT(list_empty(&loghandle->u.phd.phd_entry)); list_add_tail(&loghandle->u.phd.phd_entry, &cathandle->u.chd.chd_head); out_destroy: if (rc < 0) llog_destroy(loghandle); RETURN(loghandle);}EXPORT_SYMBOL(llog_cat_new_log);/* Open an existent log handle and add it to the open list. * This log handle will be closed when all of the records in it are removed. * * Assumes caller has already pushed us into the kernel context and is locking. * We return a lock on the handle to ensure nobody yanks it from us. */int llog_cat_id2handle(struct llog_handle *cathandle, struct llog_handle **res, struct llog_logid *logid){ struct llog_handle *loghandle; int rc = 0; ENTRY; if (cathandle == NULL) RETURN(-EBADF); list_for_each_entry(loghandle, &cathandle->u.chd.chd_head, u.phd.phd_entry) { struct llog_logid *cgl = &loghandle->lgh_id; if (cgl->lgl_oid == logid->lgl_oid) { if (cgl->lgl_ogen != logid->lgl_ogen) { CERROR("log "LPX64" generation %x != %x\n", logid->lgl_oid, cgl->lgl_ogen, logid->lgl_ogen); continue; } loghandle->u.phd.phd_cat_handle = cathandle; GOTO(out, rc = 0); } } rc = llog_create(cathandle->lgh_ctxt, &loghandle, logid, NULL); if (rc) { CERROR("error opening log id "LPX64":%x: rc %d\n", logid->lgl_oid, logid->lgl_ogen, rc); } else { rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL); if (!rc) { list_add(&loghandle->u.phd.phd_entry, &cathandle->u.chd.chd_head); } } if (!rc) { loghandle->u.phd.phd_cat_handle = cathandle; loghandle->u.phd.phd_cookie.lgc_lgl = cathandle->lgh_id; loghandle->u.phd.phd_cookie.lgc_index = loghandle->lgh_hdr->llh_cat_idx; }out: *res = loghandle; RETURN(rc);}int llog_cat_put(struct llog_handle *cathandle){ struct llog_handle *loghandle, *n; int rc; ENTRY; list_for_each_entry_safe(loghandle, n, &cathandle->u.chd.chd_head, u.phd.phd_entry) { int err = llog_close(loghandle); if (err) CERROR("error closing loghandle\n"); } rc = llog_close(cathandle); RETURN(rc);}EXPORT_SYMBOL(llog_cat_put);/* Return the currently active log handle. If the current log handle doesn't * have enough space left for the current record, start a new one. * * If reclen is 0, we only want to know what the currently active log is, * otherwise we get a lock on this log so nobody can steal our space. * * Assumes caller has already pushed us into the kernel context and is locking. * * NOTE: loghandle is write-locked upon successful return */static struct llog_handle *llog_cat_current_log(struct llog_handle *cathandle, int create){ struct llog_handle *loghandle = NULL; ENTRY; down_read(&cathandle->lgh_lock); loghandle = cathandle->u.chd.chd_current_log; if (loghandle) { struct llog_log_hdr *llh = loghandle->lgh_hdr; down_write(&loghandle->lgh_lock); if (loghandle->lgh_last_idx < LLOG_BITMAP_SIZE(llh) - 1) { up_read(&cathandle->lgh_lock); RETURN(loghandle); } else { up_write(&loghandle->lgh_lock); } } if (!create) { if (loghandle) down_write(&loghandle->lgh_lock); up_read(&cathandle->lgh_lock); RETURN(loghandle); } up_read(&cathandle->lgh_lock); /* time to create new log */ /* first, we have to make sure the state hasn't changed */ down_write(&cathandle->lgh_lock); loghandle = cathandle->u.chd.chd_current_log; if (loghandle) { struct llog_log_hdr *llh = loghandle->lgh_hdr; down_write(&loghandle->lgh_lock); if (loghandle->lgh_last_idx < LLOG_BITMAP_SIZE(llh) - 1) { up_write(&cathandle->lgh_lock); RETURN(loghandle); } else { up_write(&loghandle->lgh_lock); } } CDEBUG(D_INODE, "creating new log\n"); loghandle = llog_cat_new_log(cathandle); if (!IS_ERR(loghandle)) down_write(&loghandle->lgh_lock); up_write(&cathandle->lgh_lock); RETURN(loghandle);}/* Add a single record to the recovery log(s) using a catalog * Returns as llog_write_record * * Assumes caller has already pushed us into the kernel context. */int llog_cat_add_rec(struct llog_handle *cathandle, struct llog_rec_hdr *rec, struct llog_cookie *reccookie, void *buf){ struct llog_handle *loghandle; int rc; ENTRY; LASSERT(rec->lrh_len <= LLOG_CHUNK_SIZE); loghandle = llog_cat_current_log(cathandle, 1); if (IS_ERR(loghandle)) RETURN(PTR_ERR(loghandle));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -