Whamcloud - gitweb
b=306
authorpschwan <pschwan>
Sun, 17 Nov 2002 04:50:14 +0000 (04:50 +0000)
committerpschwan <pschwan>
Sun, 17 Nov 2002 04:50:14 +0000 (04:50 +0000)
the echo client has moved out of obdclass, and into obdecho

lustre/obdecho/echo_client.c [new file with mode: 0644]

diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c
new file mode 100644 (file)
index 0000000..524e779
--- /dev/null
@@ -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 <linux/version.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+
+#define DEBUG_SUBSYSTEM S_ECHO
+
+#include <linux/obd_support.h>
+#include <linux/obd_class.h>
+#include <linux/obd_echo.h>
+#include <linux/lustre_debug.h>
+#include <linux/lprocfs_status.h>
+
+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);
+}