From a6f85573572b454e223dd65ea9c533d121c316d7 Mon Sep 17 00:00:00 2001 From: pschwan Date: Sun, 17 Nov 2002 04:50:14 +0000 Subject: [PATCH] b=306 the echo client has moved out of obdclass, and into obdecho --- lustre/obdecho/echo_client.c | 262 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 lustre/obdecho/echo_client.c diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c new file mode 100644 index 0000000..524e779 --- /dev/null +++ b/lustre/obdecho/echo_client.c @@ -0,0 +1,262 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (c) 2001, 2002 Cluster File Systems, Inc. + * + * This file is part of Lustre, http://www.lustre.org. + * + * 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. + * + * 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 + * along with Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#define DEBUG_SUBSYSTEM S_ECHO + +#include +#include +#include +#include +#include + +static int echo_iocontrol(long cmd, struct lustre_handle *obdconn, int len, + void *karg, void *uarg) +{ + struct obd_device *obd = class_conn2obd(obdconn); + struct echo_client_obd *ec = &obd->u.echo_client; + struct obd_ioctl_data *data = karg; + int rw = OBD_BRW_READ, rc = 0; + ENTRY; + + if (obd == NULL) { + CERROR("ioctl: No device\n"); + GOTO(out, rc = -EINVAL); + } + + switch (cmd) { + case OBD_IOC_CREATE: { + struct lov_stripe_md *lsm = NULL; +#warning FIXME: save lsm into file handle for other ops, release on close + rc = obd_create(&ec->conn, &data->ioc_obdo1, &lsm); + GOTO(out, rc); + } + + case OBD_IOC_GETATTR: + rc = obd_getattr(&ec->conn, &data->ioc_obdo1, NULL); + GOTO(out, rc); + + case OBD_IOC_SETATTR: + rc = obd_setattr(&ec->conn, &data->ioc_obdo1, NULL); + GOTO(out, rc); + + case OBD_IOC_DESTROY: { + //void *ea; + rc = obd_destroy(&ec->conn, &data->ioc_obdo1, NULL); + GOTO(out, rc); + } + + case OBD_IOC_OPEN: { + struct lov_stripe_md *lsm = NULL; // XXX fill in from create + + rc = obd_open(&ec->conn, &data->ioc_obdo1, lsm); + GOTO(out, rc); + } + + case OBD_IOC_CLOSE: { + struct lov_stripe_md *lsm = NULL; // XXX fill in from create + + rc = obd_close(&ec->conn, &data->ioc_obdo1, lsm); + GOTO(out, rc); + } + + case OBD_IOC_BRW_WRITE: + rw = OBD_BRW_WRITE; + case OBD_IOC_BRW_READ: { + struct lov_stripe_md tmp_lsm; // XXX fill in from create + struct lov_stripe_md *lsm = &tmp_lsm; // XXX fill in from create + struct obd_brw_set *set; + obd_count pages = 0; + struct brw_page *pga, *pgp; + __u64 id = data->ioc_obdo1.o_id; + int gfp_mask = (id & 1) ? GFP_HIGHUSER : GFP_KERNEL; + int verify = (id != 0); + __u64 off; + int j; + + set = obd_brw_set_new(); + if (set == NULL) + GOTO(out, rc = -ENOMEM); + + pages = data->ioc_count / PAGE_SIZE; + off = data->ioc_offset; + + CDEBUG(D_INODE, "BRW %s with %d pages @ "LPX64"\n", + rw == OBD_BRW_READ ? "read" : "write", pages, off); + OBD_ALLOC(pga, pages * sizeof(*pga)); + if (!pga) { + CERROR("no memory for %d BRW per-page data\n", pages); + GOTO(brw_free, rc = -ENOMEM); + } + + memset(lsm, 0, sizeof(*lsm)); // XXX don't do this later + lsm->lsm_object_id = id; // ensure id == lsm->lsm_object_id + + for (j = 0, pgp = pga; j < pages; j++, off += PAGE_SIZE, pgp++){ + pgp->pg = alloc_pages(gfp_mask, 0); + if (!pgp->pg) { + CERROR("no memory for brw pages\n"); + GOTO(brw_cleanup, rc = -ENOMEM); + } + pgp->count = PAGE_SIZE; + pgp->off = off; + pgp->flag = 0; + + if (verify) { + void *addr = kmap(pgp->pg); + + if (rw == OBD_BRW_WRITE) + page_debug_setup(addr, pgp->count, + pgp->off, id); + else + page_debug_setup(addr, pgp->count, + 0xdeadbeef00c0ffee, + 0xdeadbeef00c0ffee); + kunmap(pgp->pg); + } + } + + set->brw_callback = ll_brw_sync_wait; + rc = obd_brw(rw, &ec->conn, lsm, j, pga, set); + if (rc) + CERROR("test_brw: error from obd_brw: rc = %d\n", rc); + else { + rc = ll_brw_sync_wait(set, CB_PHASE_START); + if (rc) + CERROR("test_brw: error from callback: rc = " + "%d\n", rc); + } + EXIT; + brw_cleanup: + for (j = 0, pgp = pga; j < pages; j++, pgp++) { + if (pgp->pg == NULL) + continue; + + if (verify && !rc) { + void *addr = kmap(pgp->pg); + + rc = page_debug_check("test_brw", addr, + PAGE_SIZE, pgp->off, id); + kunmap(pgp->pg); + } + __free_pages(pgp->pg, 0); + } + brw_free: + obd_brw_set_free(set); + OBD_FREE(pga, pages * sizeof(*pga)); + GOTO(out, rc); + } + default: + return -ENOTTY; + } + + out: + RETURN(rc); +} + +static int echo_setup(struct obd_device *obddev, obd_count len, void *buf) +{ + struct obd_ioctl_data* data = buf; + struct echo_client_obd *ec = &obddev->u.echo_client; + struct obd_device *tgt; + int rc; + ENTRY; + + if (data->ioc_inllen1 < 1) { + CERROR("requires a TARGET OBD UUID\n"); + RETURN(-EINVAL); + } + if (data->ioc_inllen1 > 37) { + CERROR("OBD UUID must be less than 38 characters\n"); + RETURN(-EINVAL); + } + + MOD_INC_USE_COUNT; + tgt = class_uuid2obd(data->ioc_inlbuf1); + if (!tgt || !(tgt->obd_flags & OBD_ATTACHED) || + !(tgt->obd_flags & OBD_SET_UP)) { + CERROR("device not attached or not set up (%d)\n", + data->ioc_dev); + GOTO(error_dec, rc = -EINVAL); + } + + rc = obd_connect(&ec->conn, tgt, NULL, NULL, NULL); + if (rc) { + CERROR("fail to connect to device %d\n", data->ioc_dev); + GOTO(error_dec, rc = -EINVAL); + } + RETURN(rc); +error_dec: + MOD_DEC_USE_COUNT; + RETURN(rc); +} + +static int echo_cleanup(struct obd_device * obddev) +{ + struct echo_client_obd *ec = &obddev->u.echo_client; + int rc; + ENTRY; + + if (!list_empty(&obddev->obd_exports)) { + CERROR("still has clients!\n"); + RETURN(-EBUSY); + } + + rc = obd_disconnect(&ec->conn); + if (rc) { + CERROR("fail to disconnect device: %d\n", rc); + RETURN(-EINVAL); + } + + MOD_DEC_USE_COUNT; + RETURN(0); +} + +static int echo_connect(struct lustre_handle *conn, struct obd_device *src, + obd_uuid_t cluuid, struct recovd_obd *recovd, + ptlrpc_recovery_cb_t recover) +{ + return class_connect(conn, src, cluuid); +} + +static struct obd_ops echo_obd_ops = { + o_setup: echo_setup, + o_cleanup: echo_cleanup, + o_iocontrol: echo_iocontrol, + o_connect: echo_connect, + o_disconnect: class_disconnect +}; + +int echo_client_init(void) +{ + extern struct lprocfs_vars status_class_var[]; + + return class_register_type(&echo_obd_ops, status_class_var, + OBD_ECHO_CLIENT_DEVICENAME); +} + +void echo_client_cleanup(void) +{ + class_unregister_type(OBD_ECHO_CLIENT_DEVICENAME); +} -- 1.8.3.1