⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 llog_cat.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- 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 + -