echo.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 621 行 · 第 1/2 页

C
621
字号
/* -*- 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: Peter Braam <braam@clusterfs.com> *   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. */#ifndef EXPORT_SYMTAB# define EXPORT_SYMTAB#endif#define DEBUG_SUBSYSTEM S_ECHO#include <obd_support.h>#include <obd_class.h>#include <obd_echo.h>#include <lustre_debug.h>#include <lustre_dlm.h>#include <lprocfs_status.h>#define ECHO_INIT_OBJID      0x1000000000000000ULL#define ECHO_HANDLE_MAGIC    0xabcd0123fedc9876ULL#define ECHO_PERSISTENT_PAGES (ECHO_PERSISTENT_SIZE >> CFS_PAGE_SHIFT)static cfs_page_t *echo_persistent_pages[ECHO_PERSISTENT_PAGES];enum {        LPROC_ECHO_READ_BYTES = 1,        LPROC_ECHO_WRITE_BYTES = 2,        LPROC_ECHO_LAST = LPROC_ECHO_WRITE_BYTES +1};static int echo_connect(struct lustre_handle *conn, struct obd_device *obd,                        struct obd_uuid *cluuid, struct obd_connect_data *data,                        void *localdata){        data->ocd_connect_flags &= ECHO_CONNECT_SUPPORTED;        return class_connect(conn, obd, cluuid);}static int echo_disconnect(struct obd_export *exp){        LASSERT (exp != NULL);        ldlm_cancel_locks_for_export(exp);        /* complete all outstanding replies */        spin_lock(&exp->exp_lock);        while (!list_empty(&exp->exp_outstanding_replies)) {                struct ptlrpc_reply_state *rs =                        list_entry(exp->exp_outstanding_replies.next,                                   struct ptlrpc_reply_state, rs_exp_list);                struct ptlrpc_service *svc = rs->rs_service;                spin_lock(&svc->srv_lock);                list_del_init(&rs->rs_exp_list);                ptlrpc_schedule_difficult_reply(rs);                spin_unlock(&svc->srv_lock);        }        spin_unlock(&exp->exp_lock);        return class_disconnect(exp);}static int echo_destroy_export(struct obd_export *exp){        ENTRY;        target_destroy_export(exp);        RETURN(0);} static __u64 echo_next_id(struct obd_device *obddev){        obd_id id;        spin_lock(&obddev->u.echo.eo_lock);        id = ++obddev->u.echo.eo_lastino;        spin_unlock(&obddev->u.echo.eo_lock);        return id;}int echo_create(struct obd_export *exp, struct obdo *oa,                struct lov_stripe_md **ea, struct obd_trans_info *oti){        struct obd_device *obd = class_exp2obd(exp);        if (!obd) {                CERROR("invalid client cookie "LPX64"\n",                       exp->exp_handle.h_cookie);                return -EINVAL;        }        if (!(oa->o_mode && S_IFMT)) {                CERROR("echo obd: no type!\n");                return -ENOENT;        }        if (!(oa->o_valid & OBD_MD_FLTYPE)) {                CERROR("invalid o_valid "LPX64"\n", oa->o_valid);                return -EINVAL;        }        oa->o_id = echo_next_id(obd);        oa->o_valid = OBD_MD_FLID;        return 0;}int echo_destroy(struct obd_export *exp, struct obdo *oa,                 struct lov_stripe_md *ea, struct obd_trans_info *oti,                  struct obd_export *md_exp){        struct obd_device *obd = class_exp2obd(exp);        ENTRY;        if (!obd) {                CERROR("invalid client cookie "LPX64"\n",                       exp->exp_handle.h_cookie);                RETURN(-EINVAL);        }        if (!(oa->o_valid & OBD_MD_FLID)) {                CERROR("obdo missing FLID valid flag: "LPX64"\n", oa->o_valid);                RETURN(-EINVAL);        }        if (oa->o_id > obd->u.echo.eo_lastino || oa->o_id < ECHO_INIT_OBJID) {                CERROR("bad destroy objid: "LPX64"\n", oa->o_id);                RETURN(-EINVAL);        }        RETURN(0);}static int echo_getattr(struct obd_export *exp, struct obd_info *oinfo){        struct obd_device *obd = class_exp2obd(exp);        obd_id id = oinfo->oi_oa->o_id;        ENTRY;        if (!obd) {                CERROR("invalid client cookie "LPX64"\n",                       exp->exp_handle.h_cookie);                RETURN(-EINVAL);        }        if (!(oinfo->oi_oa->o_valid & OBD_MD_FLID)) {                CERROR("obdo missing FLID valid flag: "LPX64"\n",                        oinfo->oi_oa->o_valid);                RETURN(-EINVAL);        }        obdo_cpy_md(oinfo->oi_oa, &obd->u.echo.eo_oa, oinfo->oi_oa->o_valid);        oinfo->oi_oa->o_id = id;        RETURN(0);}static int echo_setattr(struct obd_export *exp, struct obd_info *oinfo,                        struct obd_trans_info *oti){        struct obd_device *obd = class_exp2obd(exp);        ENTRY;        if (!obd) {                CERROR("invalid client cookie "LPX64"\n",                       exp->exp_handle.h_cookie);                RETURN(-EINVAL);        }        if (!(oinfo->oi_oa->o_valid & OBD_MD_FLID)) {                CERROR("obdo missing FLID valid flag: "LPX64"\n",                        oinfo->oi_oa->o_valid);                RETURN(-EINVAL);        }        memcpy(&obd->u.echo.eo_oa, oinfo->oi_oa, sizeof(*oinfo->oi_oa));        if (oinfo->oi_oa->o_id & 4) {                /* Save lock to force ACKed reply */                ldlm_lock_addref (&obd->u.echo.eo_nl_lock, LCK_NL);                oti->oti_ack_locks[0].mode = LCK_NL;                oti->oti_ack_locks[0].lock = obd->u.echo.eo_nl_lock;        }        RETURN(0);}static voidecho_page_debug_setup(cfs_page_t *page, int rw, obd_id id,                      __u64 offset, int len){        int   page_offset = offset & ~CFS_PAGE_MASK;        char *addr        = ((char *)cfs_kmap(page)) + page_offset;        if (len % OBD_ECHO_BLOCK_SIZE != 0)                CERROR("Unexpected block size %d\n", len);        while (len > 0) {                if (rw & OBD_BRW_READ)                        block_debug_setup(addr, OBD_ECHO_BLOCK_SIZE,                                          offset, id);                else                        block_debug_setup(addr, OBD_ECHO_BLOCK_SIZE,                                          0xecc0ecc0ecc0ecc0ULL,                                          0xecc0ecc0ecc0ecc0ULL);                addr   += OBD_ECHO_BLOCK_SIZE;                offset += OBD_ECHO_BLOCK_SIZE;                len    -= OBD_ECHO_BLOCK_SIZE;        }        cfs_kunmap(page);}static intecho_page_debug_check(cfs_page_t *page, obd_id id,                      __u64 offset, int len){        int   page_offset = offset & ~CFS_PAGE_MASK;        char *addr        = ((char *)cfs_kmap(page)) + page_offset;        int   rc          = 0;        int   rc2;        if (len % OBD_ECHO_BLOCK_SIZE != 0)                CERROR("Unexpected block size %d\n", len);        while (len > 0) {                rc2 = block_debug_check("echo", addr, OBD_ECHO_BLOCK_SIZE,                                        offset, id);                if (rc2 != 0 && rc == 0)                        rc = rc2;                addr   += OBD_ECHO_BLOCK_SIZE;                offset += OBD_ECHO_BLOCK_SIZE;                len    -= OBD_ECHO_BLOCK_SIZE;        }        cfs_kunmap(page);        return (rc);}/* This allows us to verify that desc_private is passed unmolested */#define DESC_PRIV 0x10293847int echo_preprw(int cmd, struct obd_export *export, struct obdo *oa,                int objcount, struct obd_ioobj *obj, int niocount,                struct niobuf_remote *nb, struct niobuf_local *res,                struct obd_trans_info *oti){        struct obd_device *obd;        struct niobuf_local *r = res;        int tot_bytes = 0;        int rc = 0;        int i;        ENTRY;        obd = export->exp_obd;        if (obd == NULL)                RETURN(-EINVAL);        /* Temp fix to stop falling foul of osc_announce_cached() */        oa->o_valid &= ~(OBD_MD_FLBLOCKS | OBD_MD_FLGRANT);        memset(res, 0, sizeof(*res) * niocount);        CDEBUG(D_PAGE, "%s %d obdos with %d IOs\n",               cmd == OBD_BRW_READ ? "reading" : "writing", objcount, niocount);        if (oti)                oti->oti_handle = (void *)DESC_PRIV;        for (i = 0; i < objcount; i++, obj++) {                int gfp_mask = (obj->ioo_id & 1) ? CFS_ALLOC_HIGHUSER : CFS_ALLOC_STD;                int ispersistent = obj->ioo_id == ECHO_PERSISTENT_OBJID;                int debug_setup = (!ispersistent &&                                   (oa->o_valid & OBD_MD_FLFLAGS) != 0 &&                                   (oa->o_flags & OBD_FL_DEBUG_CHECK) != 0);                int j;                for (j = 0 ; j < obj->ioo_bufcnt ; j++, nb++, r++) {                        if (ispersistent &&                            (nb->offset >> CFS_PAGE_SHIFT) < ECHO_PERSISTENT_PAGES) {                                r->page = echo_persistent_pages[nb->offset >>                                                                CFS_PAGE_SHIFT];                                /* Take extra ref so __free_pages() can be called OK */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?