From 79c6605b87630408e95af6a63c8d405f66b7c14f Mon Sep 17 00:00:00 2001 From: pschwan Date: Mon, 27 May 2002 17:09:21 +0000 Subject: [PATCH] Last week's LOV hackery --- lustre/lov/Makefile.am | 14 ++ lustre/lov/lov_obd.c | 353 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 367 insertions(+) create mode 100644 lustre/lov/Makefile.am create mode 100644 lustre/lov/lov_obd.c diff --git a/lustre/lov/Makefile.am b/lustre/lov/Makefile.am new file mode 100644 index 0000000..8351f5b --- /dev/null +++ b/lustre/lov/Makefile.am @@ -0,0 +1,14 @@ +# Copyright (C) 2002 Cluster File Systems, Inc. +# +# This code is issued under the GNU General Public License. +# See the file COPYING in this distribution + +DEFS := + +#MODULE = lov +#modulefs_DATA = lov.o +#EXTRA_PROGRAMS = lov + +#lov_SOURCES = lov_obd.c + +include $(top_srcdir)/Rules diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c new file mode 100644 index 0000000..e74d0fe --- /dev/null +++ b/lustre/lov/lov_obd.c @@ -0,0 +1,353 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * lov/lov.c + * + * Copyright (C) 2002 Cluster File Systems, Inc. + * Author: Phil Schwan + * + * This code is issued under the GNU General Public License. + * See the file COPYING in this distribution + */ + +#define EXPORT_SYMTAB +#define DEBUG_SUBSYSTEM S_LOV + +#include +#include + +extern struct obd_device obd_dev[MAX_OBD_DEVICES]; + +/* obd methods */ +static int lov_connect(struct obd_conn *conn) +{ + int rc; + + MOD_INC_USE_COUNT; + rc = gen_connect(conn); + + if (rc) + MOD_DEC_USE_COUNT; + + return rc; +} + +static int lov_disconnect(struct obd_conn *conn) +{ + int rc; + + rc = gen_disconnect(conn); + if (!rc) + MOD_DEC_USE_COUNT; + + /* XXX cleanup preallocated inodes */ + return rc; +} + +static int lov_getattr(struct obd_conn *conn, struct obdo *oa) +{ + int rc; + ENTRY; + + if (!gen_client(conn)) + RETURN(-EINVAL); + + rc = obd_getattr(&conn->oc_dev->obd_multi_conn[0], oa); + RETURN(rc); +} + +static int lov_setattr(struct obd_conn *conn, struct obdo *oa) +{ + int rc, retval, i; + ENTRY; + + if (!gen_client(conn)) + RETURN(-EINVAL); + + for (i = 0; i < conn->oc_dev->obd_multi_count; i++) { + rc = obd_setattr(&conn->oc_dev->obd_multi_conn[i], oa); + if (i == 0) + retval = rc; + else if (retval != rc) + CERROR("different results on multiple OBDs!\n"); + } + + RETURN(rc); +} + +static int lov_open(struct obd_conn *conn, struct obdo *oa) +{ + int rc, retval, i; + ENTRY; + + if (!gen_client(conn)) + RETURN(-EINVAL); + + for (i = 0; i < conn->oc_dev->obd_multi_count; i++) { + rc = obd_open(&conn->oc_dev->obd_multi_conn[i], oa); + if (i == 0) + retval = rc; + else if (retval != rc) + CERROR("different results on multiple OBDs!\n"); + } + + RETURN(rc); +} + +static int lov_close(struct obd_conn *conn, struct obdo *oa) +{ + int rc, retval, i; + ENTRY; + + if (!gen_client(conn)) + RETURN(-EINVAL); + + for (i = 0; i < conn->oc_dev->obd_multi_count; i++) { + rc = obd_close(&conn->oc_dev->obd_multi_conn[i], oa); + if (i == 0) + retval = rc; + else if (retval != rc) + CERROR("different results on multiple OBDs!\n"); + } + + RETURN(rc); +} + +static int lov_create(struct obd_conn *conn, struct obdo *oa) +{ + int rc, i; + ENTRY; + + if (!gen_client(conn)) + RETURN(-EINVAL); + + for (i = 0; i < conn->oc_dev->obd_multi_count; i++) + rc = obd_create(&conn->oc_dev->obd_multi_conn[i], oa); + + return rc; +} + +static int filter_destroy(struct obd_conn *conn, struct obdo *oa) +{ +#if 0 + struct obd_device * obddev; + struct obd_client * cli; + struct inode * inode; + struct file *dir; + struct file *object; + int rc; + struct obd_run_ctxt saved; + + if (!(cli = gen_client(conn))) { + CERROR("invalid client %u\n", conn->oc_id); + EXIT; + return -EINVAL; + } + + obddev = conn->oc_dev; + object = filter_obj_open(obddev, oa->o_id, oa->o_mode); + if (!object || IS_ERR(object)) { + EXIT; + return -ENOENT; + } + + inode = object->f_dentry->d_inode; + inode->i_nlink = 1; + inode->i_mode = 010000; + + push_ctxt(&saved, &obddev->u.filter.fo_ctxt); + dir = filter_parent(oa->o_id, oa->o_mode); + if (IS_ERR(dir)) { + rc = PTR_ERR(dir); + EXIT; + goto out; + } + dget(dir->f_dentry); + dget(object->f_dentry); + rc = vfs_unlink(dir->f_dentry->d_inode, object->f_dentry); + + filp_close(dir, 0); + filp_close(object, 0); +out: + pop_ctxt(&saved); + EXIT; + return rc; +#endif + return 0; +} + +/* FIXME: maybe we'll just make one node the authoritative attribute node, then + * we can send this 'punch' to just the authoritative node and the nodes + * that the punch will affect. */ +static int lov_punch(struct obd_conn *conn, struct obdo *oa, + obd_size count, obd_off offset) +{ + int rc, retval, i; + ENTRY; + + if (!gen_client(conn)) + RETURN(-EINVAL); + + for (i = 0; i < conn->oc_dev->obd_multi_count; i++) { + rc = obd_punch(&conn->oc_dev->obd_multi_conn[i], oa, count, + offset); + if (i == 0) + retval = rc; + else if (retval != rc) + CERROR("different results on multiple OBDs!\n"); + } + + RETURN(rc); +} + +/* buffer must lie in user memory here */ +static int lov_read(struct obd_conn *conn, struct obdo *oa, char *buf, + obd_size *count, obd_off offset) +{ + int rc, i; + obd_off off = offset; + obd_size retval = 0; + ENTRY; + + if (!gen_client(conn)) + RETURN(-EINVAL); + + while (off < offset + count) { + int stripe, conn; + obd_size size, tmp; + + stripe = off / conn->oc_dev->u.lov.lov_stripe_size; + size = (stripe + 1) * conn->oc_dev->u.lov.lov_strip_size - off; + if (size > *count) + size = *count; + + + conn = stripe % conn->oc_dev->obd_multi_count; + + tmp = size; + rc = obd_read(&conn->oc_dev->obd_multi_conn[conn], oa, buf, + &size, off); + if (rc == 0) + retval += size; + else { + CERROR("read(off=%Lu, count=%Lu): %d\n", + (unsigned long long)off, + (unsigned long long)size, rc); + break; + } + + buf += size; + } + + *count = retval; + RETURN(rc); +} + + +/* buffer must lie in user memory here */ +static int filter_write(struct obd_conn *conn, struct obdo *oa, char *buf, + obd_size *count, obd_off offset) +{ + int err; + struct file * file; + unsigned long retval; + + ENTRY; + if (!gen_client(conn)) { + CDEBUG(D_IOCTL, "invalid client %u\n", conn->oc_id); + EXIT; + return -EINVAL; + } + + file = filter_obj_open(conn->oc_dev, oa->o_id, oa->o_mode); + if (!file || IS_ERR(file)) { + EXIT; + return -PTR_ERR(file); + } + + /* count doubles as retval */ + retval = file->f_op->write(file, buf, *count, (loff_t *)&offset); + filp_close(file, 0); + + if ( retval >= 0 ) { + err = 0; + *count = retval; + EXIT; + } else { + err = retval; + *count = 0; + EXIT; + } + + return err; +} + +static int lov_enqueue(struct obd_conn *conn, struct ldlm_namespace *ns, + struct ldlm_handle *parent_lock, __u64 *res_id, + __u32 type, struct ldlm_extent *extent, __u32 mode, + int *flags, void *data, int datalen, + struct ldlm_handle *lockh) +{ + int rc; + ENTRY; + + if (!gen_client(conn)) + RETURN(-EINVAL); + + rc = obd_enqueue(&conn->oc_dev->obd_multi_conn[0], ns, parent_lock, + res_id, type, extent, mode, flags, data, datalen, + lockh); + RETURN(rc); +} + +static int lov_cancel(struct obd_conn *conn, __u32 mode, + struct ldlm_handle *lockh) +{ + int rc; + ENTRY; + + if (!gen_client(conn)) + RETURN(-EINVAL); + + rc = obd_cancel(&conn->oc_dev->obd_multi_conn[0], oa); + RETURN(rc); +} + +struct obd_ops lov_obd_ops = { + o_setup: gen_multi_setup, + o_cleanup: gen_multi_cleanup, + o_create: lov_create, + o_destroy: lov_destroy, + o_getattr: lov_getattr, + o_setattr: lov_setattr, + o_open: lov_open, + o_close: lov_close, + o_connect: lov_connect, + o_disconnect: lov_disconnect, + o_brw: lov_pgcache_brw, + o_punch: lov_punch, + o_enqueue: lov_enqueue, + o_cancel: lov_cancel +}; + + +#define LOV_VERSION "v0.1" + +static int __init lov_init(void) +{ + printk(KERN_INFO "Lustre Logical Object Volume driver " LOV_VERSION + ", phil@clusterfs.com\n"); + return obd_register_type(&lov_obd_ops, OBD_LOV_DEVICENAME); +} + +static void __exit lov_exit(void) +{ + obd_unregister_type(OBD_LOV_DEVICENAME); +} + +MODULE_AUTHOR("Phil Schwan "); +MODULE_DESCRIPTION("Lustre Logical Object Volume OBD driver v0.1"); +MODULE_LICENSE("GPL"); + +module_init(lov_init); +module_exit(lov_exit); -- 1.8.3.1