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 + -
显示快捷键?