X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fofd%2Fofd_trans.c;h=41e097157dc49a1837503e873a91725e4caf1069;hp=cd238f35a86d965fce1343551991b4e1d7eab3d2;hb=refs%2Fchanges%2F15%2F35815%2F2;hpb=fa32b478599bbdfe6d51e41d8715665632d011b3 diff --git a/lustre/ofd/ofd_trans.c b/lustre/ofd/ofd_trans.c index cd238f3..41e0971 100644 --- a/lustre/ofd/ofd_trans.c +++ b/lustre/ofd/ofd_trans.c @@ -15,11 +15,7 @@ * * 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 - * - * 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. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,22 +23,37 @@ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Whamcloud, Inc. + * Copyright (c) 2012, 2014, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ * Lustre is a trademark of Sun Microsystems, Inc. * - * lustre/ofd/ofd_recovery.c + * lustre/ofd/ofd_trans.c + * + * This file provides functions for OBD Filter Device (OFD) transaction + * management. * - * Author: Alex Zhuravlev - * Author: Mikhail Pershin + * Author: Alex Zhuravlev + * Author: Mikhail Pershin */ #define DEBUG_SUBSYSTEM S_FILTER #include "ofd_internal.h" +/** + * Create new transaction in OFD. + * + * This function creates a transaction with dt_trans_create() + * and makes it synchronous if required by the export state. + * + * \param[in] env execution environment + * \param[in] ofd OFD device + * + * \retval struct thandle if transaction was created successfully + * \retval ERR_PTR on negative value in case of error + */ struct thandle *ofd_trans_create(const struct lu_env *env, struct ofd_device *ofd) { @@ -61,193 +72,47 @@ struct thandle *ofd_trans_create(const struct lu_env *env, return th; } +/** + * Start transaction in OFD. + * + * This function updates the given \a obj object version and calls + * dt_trans_start(). + * + * \param[in] env execution environment + * \param[in] ofd OFD device + * \param[in] obj OFD object affected by this transaction + * \param[in] th transaction handle + * + * \retval 0 if successful + * \retval negative value in case of error + */ int ofd_trans_start(const struct lu_env *env, struct ofd_device *ofd, struct ofd_object *obj, struct thandle *th) { - struct ofd_thread_info *info = ofd_info(env); - int rc; - - if (info->fti_exp == NULL) - return 0; - - /* declare last_rcvd update */ - rc = dt_declare_record_write(env, ofd->ofd_lut.lut_last_rcvd, - sizeof(struct lsd_client_data), - info->fti_exp->exp_target_data.ted_lr_off, - th); - if (rc) - RETURN(rc); - - /* declare last_rcvd header update */ - rc = dt_declare_record_write(env, ofd->ofd_lut.lut_last_rcvd, - sizeof(ofd->ofd_lut.lut_lsd), 0, th); - if (rc) - RETURN(rc); - /* version change is required for this object */ - if (obj) { - ofd_info(env)->fti_obj = obj; - rc = dt_declare_version_set(env, ofd_object_child(obj), th); - if (rc) - RETURN(rc); - } + if (obj != NULL) + tgt_vbr_obj_set(env, ofd_object_child(obj)); return dt_trans_start(env, ofd->ofd_osd, th); } -void ofd_trans_stop(const struct lu_env *env, struct ofd_device *ofd, +/** + * Stop transaction in OFD. + * + * This function fills thandle::th_result with result of whole operation + * and calls dt_trans_stop(). + * + * \param[in] env execution environment + * \param[in] ofd OFD device + * \param[in] th transaction handle + * \param[in] rc result code of whole operation + * + * \retval 0 if successful + * \retval negative value if case of error + */ +int ofd_trans_stop(const struct lu_env *env, struct ofd_device *ofd, struct thandle *th, int rc) { th->th_result = rc; - dt_trans_stop(env, ofd->ofd_osd, th); -} - -/* - * last_rcvd & last_committed update callbacks - */ -static int ofd_last_rcvd_update(struct ofd_thread_info *info, - struct thandle *th) -{ - struct ofd_device *ofd = ofd_exp(info->fti_exp); - struct filter_export_data *fed; - struct lsd_client_data *lcd; - __s32 rc = th->th_result; - __u64 *transno_p; - loff_t off; - int err; - bool lw_client = false; - - ENTRY; - - LASSERT(ofd); - LASSERT(info->fti_exp); - - if ((info->fti_exp->exp_connect_flags & OBD_CONNECT_LIGHTWEIGHT) != 0) - lw_client = true; - - fed = &info->fti_exp->exp_filter_data; - LASSERT(fed); - lcd = fed->fed_ted.ted_lcd; - /* if the export has already been disconnected, we have no last_rcvd - * slot, update server data with latest transno then */ - if (lcd == NULL) { - CWARN("commit transaction for disconnected client %s: rc %d\n", - info->fti_exp->exp_client_uuid.uuid, rc); - err = lut_server_data_write(info->fti_env, &ofd->ofd_lut, th); - RETURN(err); - } - /* ofd connect may cause transaction before export has last_rcvd - * slot */ - if (fed->fed_ted.ted_lr_idx < 0 && !lw_client) - RETURN(0); - off = fed->fed_ted.ted_lr_off; - - transno_p = &lcd->lcd_last_transno; - lcd->lcd_last_xid = info->fti_xid; - - /* - * When we store zero transno in mcd we can lost last transno value - * because mcd contains 0, but msd is not yet written - * The server data should be updated also if the latest - * transno is rewritten by zero. See the bug 11125 for details. - */ - if (info->fti_transno == 0 && - *transno_p == ofd->ofd_lut.lut_last_transno) { - cfs_spin_lock(&ofd->ofd_lut.lut_translock); - ofd->ofd_lut.lut_lsd.lsd_last_transno = - ofd->ofd_lut.lut_last_transno; - cfs_spin_unlock(&ofd->ofd_lut.lut_translock); - lut_server_data_write(info->fti_env, &ofd->ofd_lut, th); - } - - *transno_p = info->fti_transno; - if (lw_client) { - /* Although lightweight (LW) connections have no slot in - * last_rcvd, we still want to maintain the in-memory - * lsd_client_data structure in order to properly handle reply - * reconstruction. */ - struct lu_target *tg =&ofd->ofd_lut; - bool update = false; - - err = 0; - /* All operations performed by LW clients are synchronous and - * we store the committed transno in the last_rcvd header */ - cfs_spin_lock(&tg->lut_translock); - if (info->fti_transno > tg->lut_lsd.lsd_last_transno) { - tg->lut_lsd.lsd_last_transno = info->fti_transno; - update = true; - } - cfs_spin_unlock(&tg->lut_translock); - if (update) - err = lut_server_data_write(info->fti_env, tg, th); - } else { - LASSERT(fed->fed_ted.ted_lr_off > 0); - err = lut_client_data_write(info->fti_env, &ofd->ofd_lut, lcd, - &off, th); - } - - RETURN(err); + return dt_trans_stop(env, ofd->ofd_osd, th); } - -/* Update last_rcvd records with the latest transaction data */ -int ofd_txn_stop_cb(const struct lu_env *env, struct thandle *txn, - void *cookie) -{ - struct ofd_device *ofd = cookie; - struct ofd_thread_info *info; - - ENTRY; - - info = lu_context_key_get(&env->le_ctx, &ofd_thread_key); - - if (info->fti_exp == NULL) - RETURN(0); - - LASSERT(ofd_exp(info->fti_exp) == ofd); - if (info->fti_has_trans) { - if (info->fti_mult_trans == 0) { - CERROR("More than one transaction "LPU64"\n", - info->fti_transno); - RETURN(0); - } - /* we need another transno to be assigned */ - info->fti_transno = 0; - } else if (txn->th_result == 0) { - info->fti_has_trans = 1; - } - - cfs_spin_lock(&ofd->ofd_lut.lut_translock); - if (txn->th_result != 0) { - if (info->fti_transno != 0) { - CERROR("Replay transno "LPU64" failed: rc %d\n", - info->fti_transno, txn->th_result); - info->fti_transno = 0; - } - } else if (info->fti_transno == 0) { - info->fti_transno = ++ofd->ofd_lut.lut_last_transno; - } else { - /* should be replay */ - if (info->fti_transno > ofd->ofd_lut.lut_last_transno) - ofd->ofd_lut.lut_last_transno = info->fti_transno; - } - cfs_spin_unlock(&ofd->ofd_lut.lut_translock); - - /** VBR: set new versions */ - if (txn->th_result == 0 && info->fti_obj != NULL) { - dt_version_set(env, ofd_object_child(info->fti_obj), - info->fti_transno, txn); - info->fti_obj = NULL; - } - - /* filling reply data */ - CDEBUG(D_INODE, "transno = %llu, last_committed = %llu\n", - info->fti_transno, ofd_obd(ofd)->obd_last_committed); - - /* if can't add callback, do sync write */ - txn->th_sync = !!lut_last_commit_cb_add(txn, &ofd->ofd_lut, - info->fti_exp, - info->fti_transno); - - return ofd_last_rcvd_update(info, txn); -} -