X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Flov%2Flov_log.c;h=77e047c2daf624099088fc03e2cc599ed06c2cc8;hp=c6174d7bda7f9e5d3a347631cdd50923e21e7c2b;hb=70e80ade90af09300396706b8910e196a7928520;hpb=45d054e77353bf5b09637923e5abeb3e72a997fd diff --git a/lustre/lov/lov_log.c b/lustre/lov/lov_log.c index c6174d7..77e047c 100644 --- a/lustre/lov/lov_log.c +++ b/lustre/lov/lov_log.c @@ -1,25 +1,43 @@ - /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * Author: Phil Schwan - * Peter Braam - * Mike Shaver + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. * - * This file is part of Lustre, http://www.lustre.org. + * This program 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 GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). * - * Lustre is free 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. + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see [sun.com URL with a + * copy of GPLv2]. * - * 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 - * GNU General Public License for more details. + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * GPL HEADER END + */ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Use is subject to license terms. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * lustre/lov/lov_log.c + * + * Author: Phil Schwan + * Author: Peter Braam + * Author: Mike Shaver */ #ifndef EXPORT_SYMTAB @@ -27,27 +45,21 @@ #endif #define DEBUG_SUBSYSTEM S_LOV #ifdef __KERNEL__ -#include -#include -#include -#include -#include -#include -#include +#include #else #include #endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "lov_internal.h" @@ -56,104 +68,115 @@ * we need to keep cookies in stripe order, even if some are NULL, so that * the right cookies are passed back to the right OSTs at the client side. * Unset cookies should be all-zero (which will never occur naturally). */ -static int lov_llog_origin_add(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec, - void *buf, struct llog_cookie *logcookies, - int numcookies, void *data, - struct rw_semaphore **lock, int *lock_count) +static int lov_llog_origin_add(struct llog_ctxt *ctxt, + struct llog_rec_hdr *rec, struct lov_stripe_md *lsm, + struct llog_cookie *logcookies, int numcookies) { struct obd_device *obd = ctxt->loc_obd; struct lov_obd *lov = &obd->u.lov; - struct lov_oinfo *loi; - struct llog_unlink_rec *lur; - struct lov_stripe_md *lsm = (struct lov_stripe_md *)buf; - int i, rc = 0; + int i, rc = 0, rc1; ENTRY; - OBD_ALLOC(lur, sizeof(*lur)); - if (!lur) - RETURN(-ENOMEM); - lur->lur_hdr.lrh_len = lur->lur_tail.lrt_len = sizeof(*lur); - lur->lur_hdr.lrh_type = MDS_UNLINK_REC; + LASSERTF(logcookies && numcookies >= lsm->lsm_stripe_count, + "logcookies %p, numcookies %d lsm->lsm_stripe_count %d \n", + logcookies, numcookies, lsm->lsm_stripe_count); - LASSERT(logcookies && numcookies >= lsm->lsm_stripe_count); + for (i = 0; i < lsm->lsm_stripe_count; i++) { + struct lov_oinfo *loi = lsm->lsm_oinfo[i]; + struct obd_device *child = + lov->lov_tgts[loi->loi_ost_idx]->ltd_exp->exp_obd; + struct llog_ctxt *cctxt = llog_get_context(child, ctxt->loc_idx); - for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - struct obd_device *child = - lov->tgts[loi->loi_ost_idx].ltd_exp->exp_obd; - struct llog_ctxt *cctxt; - cctxt = llog_get_context(&child->obd_llogs, ctxt->loc_idx); - - lur->lur_oid = loi->loi_id; - lur->lur_ogen = loi->loi_gr; + /* fill mds unlink/setattr log record */ + switch (rec->lrh_type) { + case MDS_UNLINK_REC: { + struct llog_unlink_rec *lur = (struct llog_unlink_rec *)rec; + lur->lur_oid = loi->loi_id; + lur->lur_ogen = loi->loi_gr; + break; + } + case MDS_SETATTR_REC: { + struct llog_setattr_rec *lsr = (struct llog_setattr_rec *)rec; + lsr->lsr_oid = loi->loi_id; + lsr->lsr_ogen = loi->loi_gr; + break; + } + default: + break; + } LASSERT(lsm->lsm_object_gr == loi->loi_gr); - rc += llog_add(cctxt, &lur->lur_hdr, NULL, logcookies + rc, - numcookies - rc, NULL, - lock != NULL ? lock + rc : NULL, lock_count); + rc1 = llog_add(cctxt, rec, NULL, logcookies + rc, + numcookies - rc); + llog_ctxt_put(cctxt); + if (rc1 < 0) + RETURN(rc1); + rc += rc1; } - OBD_FREE(lur, sizeof(*lur)); RETURN(rc); } static int lov_llog_origin_connect(struct llog_ctxt *ctxt, int count, struct llog_logid *logid, - struct llog_gen *gen, struct obd_uuid *uuid) + struct llog_gen *gen, + struct obd_uuid *uuid) { struct obd_device *obd = ctxt->loc_obd; struct lov_obd *lov = &obd->u.lov; - struct lov_tgt_desc *tgt; - int i, rc = 0; + int i, rc = 0, err = 0; ENTRY; - LASSERT(lov->desc.ld_tgt_count == count); - for (i = 0, tgt = lov->tgts; i < lov->desc.ld_tgt_count; i++, tgt++) { + lov_getref(obd); + for (i = 0; i < count; i++) { struct obd_device *child; struct llog_ctxt *cctxt; - - if (!tgt->active) + + if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) continue; - child = tgt->ltd_exp->exp_obd; - - cctxt = llog_get_context(&child->obd_llogs, ctxt->loc_idx); - if (uuid && !obd_uuid_equals(uuid, &lov->tgts[i].uuid)) + if (uuid && !obd_uuid_equals(uuid, &lov->lov_tgts[i]->ltd_uuid)) continue; - + CDEBUG(D_CONFIG, "connect %d/%d\n", i, count); + child = lov->lov_tgts[i]->ltd_exp->exp_obd; + cctxt = llog_get_context(child, ctxt->loc_idx); rc = llog_connect(cctxt, 1, logid, gen, uuid); + llog_ctxt_put(cctxt); + if (rc) { - CERROR("error osc_llog_connect %d\n", i); - break; + CERROR("error osc_llog_connect tgt %d (%d)\n", i, rc); + if (!err) + err = rc; } } + lov_putref(obd); - RETURN(rc); + RETURN(err); } /* the replicators commit callback */ -static int lov_llog_repl_cancel(struct llog_ctxt *ctxt, int count, - struct llog_cookie *cookies, int flags, - void *data) +static int lov_llog_repl_cancel(struct llog_ctxt *ctxt, struct lov_stripe_md *lsm, + int count, struct llog_cookie *cookies, int flags) { - struct lov_stripe_md *lsm = (struct lov_stripe_md *)data; struct lov_obd *lov; struct obd_device *obd = ctxt->loc_obd; - struct lov_oinfo *loi; int rc = 0, i; ENTRY; LASSERT(lsm != NULL); LASSERT(count == lsm->lsm_stripe_count); - loi = lsm->lsm_oinfo; lov = &obd->u.lov; - for (i = 0; i < count; i++, cookies++, loi++) { - struct obd_device *child = - lov->tgts[loi->loi_ost_idx].ltd_exp->exp_obd; - struct llog_ctxt *cctxt; + lov_getref(obd); + for (i = 0; i < count; i++, cookies++) { + struct lov_oinfo *loi = lsm->lsm_oinfo[i]; + struct obd_device *child = + lov->lov_tgts[loi->loi_ost_idx]->ltd_exp->exp_obd; + struct llog_ctxt *cctxt = + llog_get_context(child, ctxt->loc_idx); int err; - cctxt = llog_get_context(&child->obd_llogs, ctxt->loc_idx); - err = llog_cancel(cctxt, 1, cookies, flags, NULL); - if (err && lov->tgts[loi->loi_ost_idx].active) { + err = llog_cancel(cctxt, NULL, 1, cookies, flags); + llog_ctxt_put(cctxt); + if (err && lov->lov_tgts[loi->loi_ost_idx]->ltd_active) { CERROR("error: objid "LPX64" subobj "LPX64 " on OST idx %d: rc = %d\n", lsm->lsm_object_id, loi->loi_id, loi->loi_ost_idx, err); @@ -161,10 +184,11 @@ static int lov_llog_repl_cancel(struct llog_ctxt *ctxt, int count, rc = err; } } + lov_putref(obd); RETURN(rc); } -static struct llog_operations lov_unlink_orig_logops = { +static struct llog_operations lov_mds_ost_orig_logops = { lop_add: lov_llog_origin_add, lop_connect: lov_llog_origin_connect }; @@ -173,72 +197,67 @@ static struct llog_operations lov_size_repl_logops = { lop_cancel: lov_llog_repl_cancel }; -int lov_llog_init(struct obd_device *obd, struct obd_llogs *llogs, - struct obd_device *tgt, int count, struct llog_catid *logid) +int lov_llog_init(struct obd_device *obd, struct obd_llog_group *olg, + struct obd_device *tgt, int count, struct llog_catid *logid, + struct obd_uuid *uuid) { struct lov_obd *lov = &obd->u.lov; - struct lov_tgt_desc *ctgt; - int i, rc = 0; + struct obd_device *child; + int i, rc = 0, err = 0; ENTRY; - - rc = obd_llog_setup(obd, llogs, LLOG_UNLINK_ORIG_CTXT, tgt, 0, NULL, - &lov_unlink_orig_logops); + + LASSERT(olg == &obd->obd_olg); + rc = llog_setup(obd, olg, LLOG_MDS_OST_ORIG_CTXT, tgt, 0, NULL, + &lov_mds_ost_orig_logops); if (rc) RETURN(rc); - rc = obd_llog_setup(obd, llogs, LLOG_SIZE_REPL_CTXT, tgt, 0, NULL, - &lov_size_repl_logops); + rc = llog_setup(obd, olg, LLOG_SIZE_REPL_CTXT, tgt, 0, NULL, + &lov_size_repl_logops); if (rc) RETURN(rc); - LASSERT(lov->desc.ld_tgt_count == count); - for (i = 0, ctgt = lov->tgts; i < lov->desc.ld_tgt_count; i++, ctgt++) { - struct obd_device *child; - - if (!ctgt->active) + lov_getref(obd); + /* count may not match lov->desc.ld_tgt_count during dynamic ost add */ + for (i = 0; i < count; i++) { + if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) + continue; + if (uuid && !obd_uuid_equals(uuid, &lov->lov_tgts[i]->ltd_uuid)) continue; - child = ctgt->ltd_exp->exp_obd; - rc = obd_llog_init(child, &child->obd_llogs, tgt, 1, logid + i); + CDEBUG(D_CONFIG, "init %d/%d\n", i, count); + LASSERT(lov->lov_tgts[i]->ltd_exp); + child = lov->lov_tgts[i]->ltd_exp->exp_obd; + rc = obd_llog_init(child, &child->obd_olg, tgt, 1, logid + i, uuid); if (rc) { - CERROR("error osc_llog_init %d\n", i); - break; + CERROR("error osc_llog_init idx %d osc '%s' tgt '%s' " + "(rc=%d)\n", i, child->obd_name, tgt->obd_name, + rc); + if (!err) + err = rc; } } - RETURN(rc); + lov_putref(obd); + RETURN(err); } -int lov_llog_finish(struct obd_device *obd, struct obd_llogs *llogs, int count) +int lov_llog_finish(struct obd_device *obd, int count) { - struct lov_obd *lov = &obd->u.lov; - struct lov_tgt_desc *tgt; - int i, rc = 0; + struct llog_ctxt *ctxt; + int rc = 0, rc2 = 0; ENTRY; - rc = obd_llog_cleanup(llog_get_context(llogs, LLOG_UNLINK_ORIG_CTXT)); - if (rc) - RETURN(rc); - - rc = obd_llog_cleanup(llog_get_context(llogs, LLOG_SIZE_REPL_CTXT)); - if (rc) - RETURN(rc); + /* cleanup our llogs only if the ctxts have been setup + * (client lov doesn't setup, mds lov does). */ + ctxt = llog_get_context(obd, LLOG_MDS_OST_ORIG_CTXT); + if (ctxt) + rc = llog_cleanup(ctxt); - if (lov->desc.ld_tgt_count != count) { - CERROR("LOV tgt count != passed tgt count (%d != %d)\n", - lov->desc.ld_tgt_count, count); - count = MIN(lov->desc.ld_tgt_count, count); - } - for (i = 0, tgt = lov->tgts; i < count; i++, tgt++) { - struct obd_device *child; + ctxt = llog_get_context(obd, LLOG_SIZE_REPL_CTXT); + if (ctxt) + rc2 = llog_cleanup(ctxt); + if (!rc) + rc = rc2; - if (!tgt->active) - continue; - child = tgt->ltd_exp->exp_obd; - rc = obd_llog_finish(child, &child->obd_llogs, 1); - if (rc) { - CERROR("osc_llog_finish error; index=%d; rc=%d\n", - i, rc); - break; - } - } + /* lov->tgt llogs are cleaned during osc_cleanup. */ RETURN(rc); }