X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdfilter%2Ffilter_log.c;h=7ae5f8866c62645d92191f9f8fcccad513116db1;hb=c4118a072e98909fb95199158ed1b1d66cf421ee;hp=9d7afe9818fecc0cc176135fe1f920b6e78e97f3;hpb=89f9a5bced24ecb7c84040a1ed88dcef4384f7c6;p=fs%2Flustre-release.git diff --git a/lustre/obdfilter/filter_log.c b/lustre/obdfilter/filter_log.c index 9d7afe9..7ae5f88 100644 --- a/lustre/obdfilter/filter_log.c +++ b/lustre/obdfilter/filter_log.c @@ -1,90 +1,103 @@ /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * - * linux/fs/obdfilter/filter_log.c + * GPL HEADER START * - * Copyright (c) 2001-2003 Cluster File Systems, Inc. - * Author: Peter Braam - * Author: Andreas Dilger - * Author: Phil Schwan + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * This file is part of Lustre, http://www.lustre.org. + * 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. * - * 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. + * 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 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. + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf * - * 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. + * 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. + * + * GPL HEADER END + */ +/* + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. 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/obdfilter/filter_log.c + * + * Author: Peter Braam + * Author: Andreas Dilger + * Author: Phil Schwan */ #define DEBUG_SUBSYSTEM S_FILTER +#ifndef AUTOCONF_INCLUDED #include +#endif #include #include #include -#include -#include -#include - +#include +#include +#include #include "filter_internal.h" -int filter_log_sz_change(struct llog_handle *cathandle, - struct lustre_id *id, __u32 io_epoch, - struct llog_cookie *logcookie, +int filter_log_sz_change(struct llog_handle *cathandle, + struct ll_fid *mds_fid, + __u32 ioepoch, + struct llog_cookie *logcookie, struct inode *inode) { struct llog_size_change_rec *lsc; -#ifdef IFILTERDATA_ACTUALLY_USED - struct ost_filterdata *ofd; -#endif int rc; + struct ost_filterdata *ofd; ENTRY; - down(&inode->i_sem); -#ifdef IFILTERDATA_ACTUALLY_USED - ofd = inode->i_filterdata; - - if (ofd && ofd->ofd_epoch >= io_epoch) { - if (ofd->ofd_epoch > io_epoch) - CERROR("client sent old epoch %d for obj ino %ld\n", - io_epoch, inode->i_ino); - up(&inode->i_sem); + LOCK_INODE_MUTEX(inode); + ofd = INODE_PRIVATE_DATA(inode); + + if (ofd && ofd->ofd_epoch >= ioepoch) { + if (ofd->ofd_epoch > ioepoch) + CERROR("client sent old epoch %d for obj ino %ld\n", + ioepoch, inode->i_ino); + UNLOCK_INODE_MUTEX(inode); RETURN(0); } - if (ofd && ofd->ofd_epoch < io_epoch) { - ofd->ofd_epoch = io_epoch; + if (ofd && ofd->ofd_epoch < ioepoch) { + ofd->ofd_epoch = ioepoch; } else if (!ofd) { OBD_ALLOC(ofd, sizeof(*ofd)); if (!ofd) GOTO(out, rc = -ENOMEM); igrab(inode); - inode->i_filterdata = ofd; - ofd->ofd_epoch = io_epoch; + INODE_PRIVATE_DATA(inode) = ofd; + ofd->ofd_epoch = ioepoch; } -#endif /* the decision to write a record is now made, unlock */ - up(&inode->i_sem); + UNLOCK_INODE_MUTEX(inode); OBD_ALLOC(lsc, sizeof(*lsc)); if (lsc == NULL) RETURN(-ENOMEM); lsc->lsc_hdr.lrh_len = lsc->lsc_tail.lrt_len = sizeof(*lsc); lsc->lsc_hdr.lrh_type = OST_SZ_REC; - lsc->lsc_id = *id; - lsc->lsc_io_epoch = io_epoch; + lsc->lsc_fid = *mds_fid; + lsc->lsc_ioepoch = ioepoch; - rc = llog_cat_add_rec(cathandle, &lsc->lsc_hdr, logcookie, - NULL, NULL, NULL); + rc = llog_cat_add_rec(cathandle, &lsc->lsc_hdr, logcookie, NULL); OBD_FREE(lsc, sizeof(*lsc)); if (rc > 0) { @@ -92,102 +105,208 @@ int filter_log_sz_change(struct llog_handle *cathandle, rc = 0; } -#ifdef IFILTERDATA_ACTUALLY_USED -out: -#endif + out: RETURN(rc); } -struct obd_llogs * filter_grab_llog_for_group(struct obd_device *, - int, struct obd_export *); /* When this (destroy) operation is committed, return the cancel cookie */ void filter_cancel_cookies_cb(struct obd_device *obd, __u64 transno, void *cb_data, int error) { struct llog_cookie *cookie = cb_data; - struct obd_llogs *llogs = NULL; + struct obd_llog_group *olg; struct llog_ctxt *ctxt; + int rc; /* we have to find context for right group */ - llogs = filter_grab_llog_for_group(obd, cookie->lgc_lgl.lgl_ogr, NULL); - - if (llogs) { - ctxt = llog_get_context(llogs, cookie->lgc_subsys + 1); - if (ctxt) { - llog_cancel(ctxt, 1, cookie, 0, NULL); - } else - CERROR("no valid context for group "LPU64"\n", - cookie->lgc_lgl.lgl_ogr); - } else { - CDEBUG(D_HA, "unknown group "LPU64"!\n", cookie->lgc_lgl.lgl_ogr); + if (error != 0 || obd->obd_stopping) { + CDEBUG(D_INODE, "not cancel logcookie err %d stopping %d \n", + error, obd->obd_stopping); + GOTO (out, rc = 0); + } + + olg = filter_find_olg(obd, cookie->lgc_lgl.lgl_oseq); + if (!olg) { + CDEBUG(D_HA, "unknown group "LPU64"!\n", cookie->lgc_lgl.lgl_oseq); + GOTO(out, rc = 0); } - OBD_FREE(cb_data, sizeof(struct llog_cookie)); + ctxt = llog_group_get_ctxt(olg, cookie->lgc_subsys + 1); + if (!ctxt) { + CERROR("no valid context for group "LPU64"\n", + cookie->lgc_lgl.lgl_oseq); + GOTO(out, rc = 0); + } + + OBD_FAIL_TIMEOUT(OBD_FAIL_OST_CANCEL_COOKIE_TIMEOUT, 30); + + rc = llog_cancel(ctxt, NULL, 1, cookie, 0); + if (rc) + CERROR("error cancelling log cookies: rc = %d\n", rc); + llog_ctxt_put(ctxt); +out: + OBD_FREE(cookie, sizeof(*cookie)); } -/* Callback for processing the unlink log record received from MDS by - * llog_client_api. - */ -int filter_recov_log_unlink_cb(struct llog_handle *llh, - struct llog_rec_hdr *rec, void *data) +/* Callback for processing the unlink log record received from MDS by + * llog_client_api. */ +static int filter_recov_log_unlink_cb(struct llog_ctxt *ctxt, + struct llog_rec_hdr *rec, + struct llog_cookie *cookie) { - struct llog_ctxt *ctxt = llh->lgh_ctxt; - struct obd_device *obd = ctxt->loc_obd; - struct obd_export *exp = obd->obd_self_export; - struct llog_cookie cookie; - struct llog_gen_rec *lgr; + struct obd_export *exp = ctxt->loc_obd->obd_self_export; struct llog_unlink_rec *lur; struct obdo *oa; obd_id oid; + obd_count count; int rc = 0; ENTRY; - - if (!(le32_to_cpu(llh->lgh_hdr->llh_flags) & LLOG_F_IS_PLAIN)) { - CERROR("log is not plain\n"); - RETURN(-EINVAL); - } - if (rec->lrh_type != MDS_UNLINK_REC && - rec->lrh_type != LLOG_GEN_REC) { - CERROR("log record type error\n"); - RETURN(-EINVAL); - } - - cookie.lgc_lgl = llh->lgh_id; - cookie.lgc_subsys = LLOG_UNLINK_ORIG_CTXT; - cookie.lgc_index = le32_to_cpu(rec->lrh_index); - - if (rec->lrh_type == LLOG_GEN_REC) { - lgr = (struct llog_gen_rec *)rec; - if (llog_gen_lt(lgr->lgr_gen, ctxt->loc_gen)) - rc = 0; - else - rc = LLOG_PROC_BREAK; - CWARN("fetch generation log, send cookie\n"); - llog_cancel(ctxt, 1, &cookie, 0, NULL); - RETURN(rc); - } lur = (struct llog_unlink_rec *)rec; - oa = obdo_alloc(); - if (oa == NULL) + OBDO_ALLOC(oa); + if (oa == NULL) RETURN(-ENOMEM); oa->o_valid |= OBD_MD_FLCOOKIE; oa->o_id = lur->lur_oid; - oa->o_gr = lur->lur_ogen; + oa->o_seq = lur->lur_oseq; oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP; - memcpy(obdo_logcookie(oa), &cookie, sizeof(cookie)); + oa->o_lcookie = *cookie; oid = oa->o_id; + /* objid gap may require to destroy several objects in row */ + count = lur->lur_count + 1; + + /* This check is only valid before FID-on-OST and it should + * be removed after FID-on-OST is implemented */ + if (oa->o_seq > FID_SEQ_OST_MAX) { + CERROR("%s: invalid group number "LPU64" > MAX_CMD_GROUP %u\n", + exp->exp_obd->obd_name, oa->o_seq, FID_SEQ_OST_MAX); + RETURN(-EINVAL); + } + + while (count > 0) { + rc = filter_destroy(exp, oa, NULL, NULL, NULL, NULL); + if (rc == 0) + CDEBUG(D_RPCTRACE, "object "LPU64" is destroyed\n", + oid); + else if (rc != -ENOENT) + CEMERG("error destroying object "LPU64": %d\n", + oid, rc); + else + rc = 0; + count--; + oid++; + } + OBDO_FREE(oa); + + RETURN(rc); +} + +/* Callback for processing the setattr log record received from MDS by + * llog_client_api. */ +static int filter_recov_log_setattr_cb(struct llog_ctxt *ctxt, + struct llog_rec_hdr *rec, + struct llog_cookie *cookie) +{ + struct obd_device *obd = ctxt->loc_obd; + struct obd_export *exp = obd->obd_self_export; + struct obd_info oinfo = { { { 0 } } }; + obd_id oid; + int rc = 0; + ENTRY; + + OBDO_ALLOC(oinfo.oi_oa); + if (oinfo.oi_oa == NULL) + RETURN(-ENOMEM); + + if (rec->lrh_type == MDS_SETATTR_REC) { + struct llog_setattr_rec *lsr = (struct llog_setattr_rec *)rec; + + oinfo.oi_oa->o_id = lsr->lsr_oid; + oinfo.oi_oa->o_seq = lsr->lsr_oseq; + oinfo.oi_oa->o_uid = lsr->lsr_uid; + oinfo.oi_oa->o_gid = lsr->lsr_gid; + } else { + struct llog_setattr64_rec *lsr = (struct llog_setattr64_rec *)rec; + + oinfo.oi_oa->o_id = lsr->lsr_oid; + oinfo.oi_oa->o_seq = lsr->lsr_oseq; + oinfo.oi_oa->o_uid = lsr->lsr_uid; + oinfo.oi_oa->o_gid = lsr->lsr_gid; + } + + oinfo.oi_oa->o_valid |= (OBD_MD_FLID | OBD_MD_FLUID | OBD_MD_FLGID | + OBD_MD_FLCOOKIE); + oinfo.oi_oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP; + oinfo.oi_oa->o_lcookie = *cookie; + oid = oinfo.oi_oa->o_id; + + rc = filter_setattr(exp, &oinfo, NULL); + OBDO_FREE(oinfo.oi_oa); - rc = obd_destroy(exp, oa, NULL, NULL); - obdo_free(oa); if (rc == -ENOENT) { - CDEBUG(D_HA, "object already removed, send cookie\n"); - llog_cancel(ctxt, 1, &cookie, 0, NULL); + CDEBUG(D_RPCTRACE, "object already removed, send cookie\n"); + llog_cancel(ctxt, NULL, 1, cookie, 0); RETURN(0); } if (rc == 0) - CDEBUG(D_HA, "object: "LPU64" in record is destroyed\n", oid); + CDEBUG(D_RPCTRACE, "object "LPU64" is chown/chgrp\n", oid); + + RETURN(rc); +} + +int filter_recov_log_mds_ost_cb(struct llog_handle *llh, + struct llog_rec_hdr *rec, void *data) +{ + struct llog_ctxt *ctxt = llh->lgh_ctxt; + struct llog_cookie cookie; + int rc = 0; + ENTRY; + + if (ctxt->loc_obd->obd_stopping) + RETURN(LLOG_PROC_BREAK); + + if (rec == NULL) { + cfs_spin_lock(&ctxt->loc_obd->u.filter.fo_flags_lock); + ctxt->loc_obd->u.filter.fo_mds_ost_sync = 0; + cfs_spin_unlock(&ctxt->loc_obd->u.filter.fo_flags_lock); + RETURN(0); + } + + if (!(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN)) { + CERROR("log is not plain\n"); + RETURN(-EINVAL); + } + + OBD_FAIL_TIMEOUT(OBD_FAIL_OST_LLOG_RECOVERY_TIMEOUT, 30); + cookie.lgc_lgl = llh->lgh_id; + cookie.lgc_subsys = LLOG_MDS_OST_ORIG_CTXT; + cookie.lgc_index = rec->lrh_index; + + switch (rec->lrh_type) { + case MDS_UNLINK_REC: + rc = filter_recov_log_unlink_cb(ctxt, rec, &cookie); + break; + case MDS_SETATTR_REC: + case MDS_SETATTR64_REC: + rc = filter_recov_log_setattr_cb(ctxt, rec, &cookie); + break; + case LLOG_GEN_REC: { + struct llog_gen_rec *lgr = (struct llog_gen_rec *)rec; + if (llog_gen_lt(lgr->lgr_gen, ctxt->loc_gen)) + rc = 0; + else + rc = LLOG_PROC_BREAK; + CDEBUG(D_HA, "fetch generation log, send cookie\n"); + llog_cancel(ctxt, NULL, 1, &cookie, 0); + RETURN(rc); + } + break; + default: + CERROR("log record type %08x unknown\n", rec->lrh_type); + RETURN(-EINVAL); + break; + } RETURN(rc); }