From: wangdi Date: Sun, 2 Apr 2006 03:01:23 +0000 (+0000) Subject: Branch: b_new_cmd X-Git-Tag: v1_8_0_110~486^2~2121 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=d6e0179b00e2d278ffc8510872f4ca1687da3c69;p=fs%2Flustre-release.git Branch: b_new_cmd add mdd_handler.c mdd_internal.h for mdd prototype --- diff --git a/lustre/mdd/mdd_handler.c b/lustre/mdd/mdd_handler.c new file mode 100644 index 0000000..2586a29 --- /dev/null +++ b/lustre/mdd/mdd_handler.c @@ -0,0 +1,570 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * linux/mdd/mdd_reint.c + * Lustre Metadata Server (mdd) routines + * + * Copyright (C) 2002-2005 Cluster File Systems, Inc. + * + * 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_MDD + +#include + +#include +#include + +#include + +#include "mdd_internal.h" + +static int +mdd_init(struct lu_device *lu) +{ + return 0; +} + +static int +mdd_fini(struct lu_device *lu) +{ + return 0; +} + +static struct lu_device_operations mdd_lu_ops; + +static int lu_device_is_mdd(struct lu_device *d) +{ + /* + * XXX for now. Tags in lu_device_type->ldt_something are needed. + */ + return ergo(d->ld_ops != NULL, d->ld_ops == &mdd_lu_ops); +} + +static struct mdd_object *mdd_obj(struct lu_object *o) +{ + LASSERT(lu_device_is_mdd(o->lo_dev)); + return container_of(o, struct mdd_object, mod_obj.mo_lu); +} + +static struct mdd_device *mdd_dev(struct lu_device *d) +{ + LASSERT(lu_device_is_mdd(d)); + return container_of(d, struct mdd_device, mdd_md_dev.md_lu_dev); +} + +static struct mdd_device* mdo2mdd(struct mdd_object *mdo) +{ + return mdd_dev(mdo->mo_lu->lu_device); +} + +struct lu_object *mdd_object_alloc(struct lu_device *d) +{ + struct mdd_object *mdo; + ENTRY; + + OBD_ALLOC_PTR(mdo); + if (mdo != NULL) { + lu_object_init(o, NULL, d); + return (&mdo->mod_obj); + } else + return(NULL); +} + +int mdd_object_init(struct lu_object *o) +{ + struct mdd_device *d = mdd_dev(o->lo_dev); + struct lu_object_header *loh; + struct lu_object *below, *upper; + struct lu_device *under; + ENTRY; + + under = &d->mdd_child->md_lu_dev; + below = under->ld_ops->ldo_object_alloc(under); + + if (below == NULL) + RETURN(-ENOMEM); + + if (o->lo_header) + lu_object_add_top(o->lo_header, o); + + lu_object_add(o, below); + RETURN(0); +} + +void mdd_object_free(struct lu_object *o) +{ + struct lu_object_header *h; + struct mdd_object *mdd = mdd_obj(o); + + h = o->lo_header; + lu_object_fini(o); + OBD_FREE_PTR(mdd); +} + +void mdd_object_release(struct lu_object *o) +{ + struct mdt_device *d = mdt_dev(o->lo_dev); + + lu_object_release(o); +} + +static struct lu_device_operations mdd_lu_ops = { + .ldo_init = mdd_init, + .ldo_fini = mdd_fini, + .ldo_object_alloc = mdd_object_alloc, + .ldo_object_init = mdd_object_init, + .ldo_object_free = mdd_object_free, + .ldo_object_release = mdd_object_release, + .ldo_object_print = mdd_object_print +} + +struct lu_object* mdd_object_child(struct mdd_object *o) +{ + return lu_object_next(&o->mod_obj.mo_lu); +} + +static void +mdd_lock(struct mdd_device *mdd, struct mdd_obj *obj, __u32 mode) +{ + mdd->mdd_child->osd_ops->osd_lock_obj(osd, mdd_object_child(obj), mode); +} + +static void +mdd_unlock(struct mdd_device *mdd, struct mdd_obj *obj, __u32 mode) +{ + mdd->mdd_child->osd_ops->osd_unlock_obj(osd, mdd_object_child(obj), + mode); +} + +static void* mdd_trans_start(struct mdd_device *mdd, struct mdd_object *obj) +{ + return mdd->mdd_child->osd_ops->osd_trans_start(obj); +} + +static void mdd_trans_stop(struct mdd_device *mdd, void *handle) +{ + mdd->mdd_child->osd_ops->osd_trans_stop(handle); +} + +static int +__mdd_object_create(struct mdd_device *mdd, struct mdd_object *pobj, + struct context *uc_context, void *handle) +{ + struct mdd_object *mdd_obj; + struct lu_object *lu; + int rc; + ENTRY; + + rc = mdd->mdd_child->osd_ops->osd_create_obj(mdd->mdd_child, mdd_obj_child(pobj), + &lu, uctxt, handle); + /*XXX increase the refcount of the object or not?*/ +exit: + RETURN(rc); +} + +static int +mdd_object_create(struct mdd_obj *pobj, struct context *uc_context) +{ + struct mdd_device *mdd = mdo2mdd(pobj); + void *handle = NULL; + int rc; + ENTRY; + + handle = mdd_trans_start(mdd, obj); + if (!handle) + RETURN(-ENOMEM); + + rc = __mdd_object_create(mdd, obj, uc_context, handle); + + mdd_trans_stop(handle); + + RETURN(rc); +} + +static int mdd_add_orphan(struct obd_device *obd, struct mdd_object *mdd_obj, + void *handle) +{ + int rc = 0; + ENTRY; + + RETURN(rc); +} + +static int +_mdd_object_destroy(struct mdd_device *mdd, struct mdd_obj *obj, + void *handle) +{ + int rc = 0; + + rc = mdd->mdd_child->osd_ops->osd_object_destroy(mdd->mdd_child, + mdd_object_child(obj), handle); + + RETURN(rc); +} + +static int +mdd_object_destroy(struct mdd_object *pobj, struct mdd_object *obj) +{ + struct mdd_device *mdd = mdo2mdd(pobj); + void *handle; + ENTRY; + + handle = mdd_trans_start(mdd, pobj); + if (!handle) + RETURN(-ENOMEM); + + mdd_lock(mdd, pobj, WRITE_LOCK); + if (open_orphan(mdd_obj)) + rc = mdd_add_orphan(mdd, mdd_obj, handle); + else { + rc = __mdd_object_destroy(mdd, mdd_obj, handle); + if (rc) + GOTO(exit, rc); + + rc = mdd_add_unlink_log(mdd, mdd_obj, handle); + } +exit: + mdd_unlock(mdd, pobj, WRITE_LOCK); + mdd_trans_stop(handle); + RETURN(rc); +} + +static void +mdd_object_get(struct mdd_device *mdd, struct mdd_obj *obj) +{ + mdd->mdd_child->osd_ops->osd_object_get(mdd->mdd_child, + mdd_object_child(obj)); +} + +static int +mdd_attr_get(struct mdd_device *mdd, struct mdd_obj *obj, void *buf, + int buf_len, const char *name, struct context *uc_context) +{ + int rc; + ENTRY; + + mdd_object_get(mdd, obj); + rc = mdd->mdd_child->osd_ops->osd_attr_get(mdd->mdd_child, + mdd_object_child(obj), + buf, buf_len, name, + uc_context); + mdd_object_put(mdd, obj); + RETURN(rc); +} + +static int +__mdd_attr_set(struct mdd_device *mdd, struct mdd_obj *obj, void *buf, + int buf_len, const char *name, struct context *uc_context, + void *handle) +{ + return mdd->mdd_child->osd_ops->osd_attr_set(mdd->mdd_child, + mdd_object_child(obj), + buf, buf_len, + name, uc_context, + handle); +} + +static int +mdd_attr_set(struct mdd_device *mdd, struct mdd_obj *obj, void *buf, + int buf_len, const char *name, struct context *uc_context) +{ + int rc; + void *handle = NULL; + ENTRY; + + handle = mdd_trans_start(mdd, obj); + if (!handle) + RETURN(-ENOMEM); + + __mdd_attr_set(mdd, obj, buf, buf_len, name, uc_context, handle); + + mdd_trans_stop(mdd, handle); + + RETURN(rc); +} + + +static int +mdd_object_put(struct mdd_device *mdd, struct mdd_obj *obj) +{ + int nlink, rc = 0; + + mdd->mdd_child->osd_ops->osd_object_put(mdd->mdd_child, + mdd_object_child(obj)); + + if ((mdd_object_count(obj)) == 0) { + rc = mdd_attr_get(mdd, obj, &nlink, sizeof(nlink), + "NLINK", uc_context); + if (!rc) + RETURN(-EINVAL); + } + if (nlink == 0) + rc = mdd_object_destroy(mdd, obj); + + RETURN(rc); +} + +static struct ll_fid *mdd_object_getfid(struct mdd_object *obj) +{ + return &(obj->mod_obj.mo_lu->lo_header->loh_fid); +} + +static int +__mdd_index_insert(struct mdd_device *mdd, struct mdd_obj *obj, + const char *name, struct mdd_obj *obj, + struct uc_context *uc_context, void *handle) +{ + mdd_object_get(mdd, mdd_pobj); + mdd_lock(mdd, mdd_pobj, WRITE_LOCK); + mdd_lock(mdd, mdd_obj, WRITE_LOCK); + + mdd->mdd_child->osd_ops->osd_insert_index(mdd->mdd_child, + mdd_object_child(obj), + name, mdd_object_getfid(obj), + uctxt, handle); + mdd_unlock(mdd, mdd_pobj, WRITE_LOCK); + mdd_unlock(mdd, mdd_obj, WRITE_LOCK); + mdd_put_obj(mdd, mdd_pobj); +} + +static int +mdd_index_insert(struct mdd_device *mdd, struct mdd_obj *pobj, + const char *name, struct mdd_obj *obj, + struct uc_context *uc_context) +{ + void *handle = NULL; + ENTRY; + + handle = mdd_trans_start(mdd, obj); + if (!handle) + RETURN(-ENOMEM); + + __mdd_index_insert(mdd, pobj, name, obj, uc_context, handle); + + mdd_trans_stop(mdd, handle); +} + +static int +__mdd_index_delete(struct mdd_device *mdd, struct mdd_obj *pobj, + const char *name, struct mdd_obj *obj, + struct uc_context *uc_context, void *handle) +{ + mdd_object_get(mdd, mdd_pobj); + mdd_lock(mdd, mdd_pobj, WRITE_LOCK); + mdd_lock(mdd, mdd_obj, WRITE_LOCK); + + mdd->mdd_child->osd_ops->osd_insert_delete(mdd->mdd_child, + mdd_object_child(obj), + name, mdd_object_getfid(obj), + uctxt, handle); + mdd_unlock(mdd, mdd_pobj, WRITE_LOCK); + mdd_unlock(mdd, mdd_obj, WRITE_LOCK); + mdd_put_obj(mdd, mdd_pobj); + +} + +static int +mdd_index_delete(struct mdd_device *obd, struct lustre_obj *pobj, + const char *name, struct lustre_obj *obj, + struct uc_context *uc_context) +{ + void *handle = NULL; + ENTRY; + + handle = mdd_trans_start(mdd, obj); + if (!handle) + RETURN(-ENOMEM); + + __mdd_index_delete(mdd, pobj, name, obj, uc_context, handle); + + mdd_trans_stop(handle); +} + +static int +mdd_link(struct mdd_device *mdd, struct mdd_object *tgt_obj, + struct mdd_object *src_obj, const char *name, + struct context *uc_context) +{ + void *handle = NULL; + int rc, nlink; + ENTRY; + + handle = mdd_trans_start(mdd, src_obj); + if (!handle) + RETURN(-ENOMEM); + + mdd_lock(mdd, tgt_obj, WRITE_LOCK); + mdd_lock(mdd, src_obj, WRITE_LOCK); + + rc = __mdd_index_insert(mdd, tgt_obj, name, src_obj + uctxt, handle); + if (rc) + GOTO(trans_exit, rc); + + rc = mdd_attr_get(mdd, src_obj, &nlink, sizeof(nlink), + "NLINK", uc_context); + ++nlink; + + rc = __mdd_attr_set(mdd, obj, &nlink, sizeof(nlink), "NLINK", + uc_context, handle); + +exit: + mdd_unlock(tgt_obj->mdd_obj, WRITE_LOCK); + mdd_unlock(src_obj->mdd_obj, WRITE_LOCK); + + mdd_trans_stop(mdd, handle); + RETURN(rc); +} + +static void mdd_rename_lock(struct mdd_device *mdd, struct mdd_object *src_pobj, + struct mdd_object *tgt_pobj, struct mdd_object *sobj, + struct mdd_object *tobj) +{ + return; +} + +static void mdd_rename_unlock(struct mdd_device *mdd, struct mdd_object *src_pobj, + struct mdd_object *tgt_pobj, struct mdd_object *sobj, + struct mdd_object *tobj) +{ + return; +} + +static int +int mdd_rename(struct mdd_device *mdd, struct mdd_object *src_pobj, + struct lustre_obj *tgt_pobj, struct lustre_obj *sobj, + const char *sname, struct lustre_obj, *tobj, + const char *tname, struct context *uctxt) +{ + + handle = mdd_trans_start(mdd, src_pobj); + if (!handle) + GOTO(cleanup, rc); + + mdd_rename_lock(mdd, src_pobj, tgt_pobj, sobj, tobj); + + rc = __mdd_index_delete(mdd, src_pobj, sname, sobj, uctxt, handle); + if (rc) + GOTO(cleanup, rc); + + rc = __mdd_index_delete(mdd, tgt_pobj, tname, tobj, uctxt, handle); + if (rc) + GOTO(cleanup, rc); + + rc = __mdd_index_insert(mdd, src_pobj, tname, tobj, uctxt, handle); + if (rc) + GOTO(cleanup, rc); + + rc = __mdd_obj_destroy(mdd, src_pobj, sname, sobj, uctxt, handle); + if (rc) + GOTO(cleanup, rc); +cleanup: + mdd_rename_unlock(mdd, src_pobj, tgt_pobj, sobj, tobj); + mdd_trans_stop(mdd, handle); + RETURN(rc); +} + +static int mdd_fs_setup(struct mdd_device *mdd) +{ + return 0; +} +static int mdd_setup(struct mdd_device *mdd, obd_count len, void *buf) +{ + struct lprocfs_static_vars lvars; + struct lustre_cfg* lcfg = buf; + struct mds_obd *mds = &obd->u.mds; + struct lustre_mount_info *lmi; + struct vfsmount *mnt; + struct obd_uuid uuid; + __u8 *uuid_ptr; + char *options, *str, *label; + char ns_name[48]; + unsigned long page; + int rc = 0; + ENTRY; + + + sema_init(&mdd->mdd_orphan_recovery_sem, 1); + sema_init(&mdd->mdd_epoch_sem, 1); + spin_lock_init(&mds->mds_transno_lock); + mds->mds_max_mdsize = sizeof(struct lov_mds_md); + mds->mds_max_cookiesize = sizeof(struct llog_cookie); + mds->mds_atime_diff = MAX_ATIME_DIFF; + + rc = mdd_fs_setup(mdd); + if (rc) { + CERROR("%s: MDS filesystem method init failed: rc = %d\n", + obd->obd_name, rc); + GOTO(err_ns, rc); + } + + rc = lquota_setup(quota_interface, obd, lcfg); + if (rc) + GOTO(err_fs, rc); + + RETURN(rc); +err_qctxt: + lquota_cleanup(quota_interface, obd); +err_fs: + /* No extra cleanup needed for llog_init_commit_thread() */ + mdd_fs_cleanup(mdd); + RETURN(rc); +} + +static struct obd_ops mdt_ops = { + .o_owner = THIS_MODULE, + .o_connect = mdd_connect, + .o_reconnect = mdd_reconnect, + .o_init_export = mdd_init_export, + .o_destroy_export = mdd_destroy_export, + .o_disconnect = mdd_disconnect, + .o_setup = mdd_setup, + .o_precleanup = mdd_precleanup, + .o_cleanup = mdd_cleanup, + .o_postrecov = mdd_postrecov, + .o_statfs = mdd_obd_statfs, + .o_iocontrol = mdd_iocontrol, + .o_create = mdd_obd_create, + .o_destroy = mdd_obd_destroy, + .o_llog_init = mdd_llog_init, + .o_llog_finish = mdd_llog_finish, + .o_notify = mdd_notify, + .o_health_check = mdd_health_check, +}; + +static int __init mdd_mod_init(void) +{ + return 0; +} + +static void __exit mdd_mod_exit(void) +{ + return; +} + +MODULE_AUTHOR("Cluster File Systems, Inc. "); +MODULE_DESCRIPTION("Lustre Meta-data Target Prototype ("LUSTRE_MDD_NAME")"); +MODULE_LICENSE("GPL"); + +cfs_module(mdd, "0.0.2", mdd_mod_init, mdd_mod_exit); + diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h new file mode 100644 index 0000000..358d7ee --- /dev/null +++ b/lustre/mdd/mdd_internal.h @@ -0,0 +1,48 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + */ +#ifndef _MDD_INTERNAL_H +#define _MDD_INTERNAL_H + +struct osd_device { + struct lu_device osd_lu_dev; + struct osd_device_operations *osd_ops; +} + +struct osd_device_operations { + int (*osd_object_lock)(struct lu_object *lu __u32 mode); + int (*osd_object_unlock)(struct lu_object *lu, __32 mode); + int (*osd_trans_start)(struct lu_object *lu); + int (*osd_trans_stop)(struct lu_object *lu); +} +#define LUSTRE_MDD_NAME "mdd" +#define LUSTRE_OSD_NAME "osd" + +struct mdd_device { + /* NB this field MUST be first */ + struct md_device *mdd_md_device; + struct osd_device *mdd_child; + int mdd_max_mddize; + int mdd_max_cookiesize; + struct file *mdd_rcvd_filp; + spinlock_t mdd_transno_lock; + __u64 mdd_last_transno; + __u64 mdd_mount_count; + __u64 mdd_io_epoch; + unsigned long mdd_atime_diff; + struct semaphore mdd_epoch_sem; + struct ll_fid mdd_rootfid; + struct lr_server_data *mdd_server_data; + struct dentry *mdd_pending_dir; + struct dentry *mdd_logs_dir; + struct dentry *mdd_objects_dir; + struct llog_handle *mdd_cfg_llh; + struct file *mdd_health_check_filp; + struct lustre_quota_info mdd_quota_info; + struct semaphore mdd_qonoff_sem; + struct semaphore mdd_health_sem; + unsigned long mdd_lov_objids_valid:1, + mdd_fl_user_xattr:1, + mdd_fl_acl:1; +}; +#endif