From 36da2ef5a4478adb7a8633108c31f76746625e67 Mon Sep 17 00:00:00 2001 From: wangdi Date: Thu, 19 Oct 2006 09:52:26 +0000 Subject: [PATCH] Branch: b_new_cmd split mdd_handler.c into several files --- lustre/mdd/Makefile.in | 2 +- lustre/mdd/mdd_device.c | 489 +++++++++++++++++++++++++++++++++++ lustre/mdd/mdd_handler.c | 647 +---------------------------------------------- lustre/mdd/mdd_trans.c | 231 +++++++++++++++++ 4 files changed, 724 insertions(+), 645 deletions(-) create mode 100644 lustre/mdd/mdd_device.c create mode 100644 lustre/mdd/mdd_trans.c diff --git a/lustre/mdd/Makefile.in b/lustre/mdd/Makefile.in index 2328054..012c75d 100644 --- a/lustre/mdd/Makefile.in +++ b/lustre/mdd/Makefile.in @@ -1,5 +1,5 @@ MODULES := mdd -mdd-objs := mdd_handler.o mdd_lov.o mdd_orphans.o mdd_lproc.o +mdd-objs := mdd_handler.o mdd_lov.o mdd_orphans.o mdd_lproc.o mdd_device.o mdd_trans.o EXTRA_PRE_CFLAGS := -I@LINUX@/fs -I@LUSTRE@ -I@LUSTRE@/ldiskfs diff --git a/lustre/mdd/mdd_device.c b/lustre/mdd/mdd_device.c new file mode 100644 index 0000000..5afbfd9 --- /dev/null +++ b/lustre/mdd/mdd_device.c @@ -0,0 +1,489 @@ +/* -*- MODE: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * mdd/mdd_handler.c + * Lustre Metadata Server (mdd) routines + * + * Copyright (C) 2006 Cluster File Systems, Inc. + * Author: Wang Di + * + * 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_MDS + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mdd_internal.h" + +struct md_device_operations mdd_ops; + +static const char *mdd_root_dir_name = "root"; +static int mdd_device_init(const struct lu_env *env, struct lu_device *d, + const char *name, struct lu_device *next) +{ + struct mdd_device *mdd = lu2mdd_dev(d); + struct dt_device *dt; + int rc = 0; + ENTRY; + + mdd->mdd_child = lu2dt_dev(next); + + dt = mdd->mdd_child; + /* prepare transactions callbacks */ + mdd->mdd_txn_cb.dtc_txn_start = mdd_txn_start_cb; + mdd->mdd_txn_cb.dtc_txn_stop = mdd_txn_stop_cb; + mdd->mdd_txn_cb.dtc_txn_commit = mdd_txn_commit_cb; + mdd->mdd_txn_cb.dtc_cookie = mdd; + rc = mdd_procfs_init(mdd); + RETURN(rc); +} + +static struct lu_device *mdd_device_fini(const struct lu_env *env, + struct lu_device *d) +{ + struct mdd_device *mdd = lu2mdd_dev(d); + struct lu_device *next = &mdd->mdd_child->dd_lu_dev; + int rc; + + rc = mdd_procfs_fini(mdd); + if (rc) { + CERROR("proc fini error %d \n", rc); + return ERR_PTR(rc); + } + return next; +} + +static int mdd_mount(const struct lu_env *env, struct mdd_device *mdd) +{ + int rc; + struct dt_object *root; + ENTRY; + + dt_txn_callback_add(mdd->mdd_child, &mdd->mdd_txn_cb); + root = dt_store_open(env, mdd->mdd_child, mdd_root_dir_name, + &mdd->mdd_root_fid); + if (!IS_ERR(root)) { + LASSERT(root != NULL); + lu_object_put(env, &root->do_lu); + rc = orph_index_init(env, mdd); + } else + rc = PTR_ERR(root); + + RETURN(rc); +} + +static void mdd_device_shutdown(const struct lu_env *env, + struct mdd_device *m) +{ + dt_txn_callback_del(m->mdd_child, &m->mdd_txn_cb); + if (m->mdd_obd_dev) + mdd_fini_obd(env, m); + orph_index_fini(env, m); +} + +static int mdd_process_config(const struct lu_env *env, + struct lu_device *d, struct lustre_cfg *cfg) +{ + struct mdd_device *m = lu2mdd_dev(d); + struct dt_device *dt = m->mdd_child; + struct lu_device *next = &dt->dd_lu_dev; + int rc; + ENTRY; + + switch (cfg->lcfg_command) { + case LCFG_SETUP: + rc = next->ld_ops->ldo_process_config(env, next, cfg); + if (rc) + GOTO(out, rc); + dt->dd_ops->dt_conf_get(env, dt, &m->mdd_dt_conf); + + rc = mdd_init_obd(env, m, cfg); + if (rc) { + CERROR("lov init error %d \n", rc); + GOTO(out, rc); + } + rc = mdd_mount(env, m); + if (rc) + GOTO(out, rc); + rc = mdd_txn_init_credits(env, m); + break; + case LCFG_CLEANUP: + mdd_device_shutdown(env, m); + default: + rc = next->ld_ops->ldo_process_config(env, next, cfg); + break; + } +out: + RETURN(rc); +} +#if 0 +static int mdd_lov_set_nextid(const struct lu_env *env, + struct mdd_device *mdd) +{ + struct mds_obd *mds = &mdd->mdd_obd_dev->u.mds; + int rc; + ENTRY; + + LASSERT(mds->mds_lov_objids != NULL); + rc = obd_set_info_async(mds->mds_osc_exp, strlen(KEY_NEXT_ID), + KEY_NEXT_ID, mds->mds_lov_desc.ld_tgt_count, + mds->mds_lov_objids, NULL); + + RETURN(rc); +} + +static int mdd_cleanup_unlink_llog(const struct lu_env *env, + struct mdd_device *mdd) +{ + /* XXX: to be implemented! */ + return 0; +} +#endif + +static int mdd_recovery_complete(const struct lu_env *env, + struct lu_device *d) +{ + struct mdd_device *mdd = lu2mdd_dev(d); + struct lu_device *next = &mdd->mdd_child->dd_lu_dev; + struct obd_device *obd = mdd2obd_dev(mdd); + int rc; + ENTRY; + + LASSERT(mdd != NULL); + LASSERT(obd != NULL); +#if 0 + /* XXX: Do we need this in new stack? */ + rc = mdd_lov_set_nextid(env, mdd); + if (rc) { + CERROR("mdd_lov_set_nextid() failed %d\n", + rc); + RETURN(rc); + } + + /* XXX: cleanup unlink. */ + rc = mdd_cleanup_unlink_llog(env, mdd); + if (rc) { + CERROR("mdd_cleanup_unlink_llog() failed %d\n", + rc); + RETURN(rc); + } +#endif + obd_notify(obd->u.mds.mds_osc_obd, NULL, + (obd->obd_async_recov ? + OBD_NOTIFY_SYNC_NONBLOCK : + OBD_NOTIFY_SYNC), NULL); + + obd->obd_recovering = 0; + obd->obd_type->typ_dt_ops->o_postrecov(obd); + + /* XXX: orphans handling. */ + __mdd_orphan_cleanup(env, mdd); + rc = next->ld_ops->ldo_recovery_complete(env, next); + + RETURN(rc); +} + +struct lu_device_operations mdd_lu_ops = { + .ldo_object_alloc = mdd_object_alloc, + .ldo_process_config = mdd_process_config, + .ldo_recovery_complete = mdd_recovery_complete +}; + +/* + * No permission check is needed. + */ +static int mdd_root_get(const struct lu_env *env, + struct md_device *m, struct lu_fid *f) +{ + struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); + + ENTRY; + *f = mdd->mdd_root_fid; + RETURN(0); +} + +/* + * No permission check is needed. + */ +static int mdd_statfs(const struct lu_env *env, struct md_device *m, + struct kstatfs *sfs) +{ + struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); + int rc; + + ENTRY; + + rc = mdd_child_ops(mdd)->dt_statfs(env, mdd->mdd_child, sfs); + + RETURN(rc); +} + +/* + * No permission check is needed. + */ +static int mdd_maxsize_get(const struct lu_env *env, struct md_device *m, + int *md_size, int *cookie_size) +{ + struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); + ENTRY; + + *md_size = mdd_lov_mdsize(env, mdd); + *cookie_size = mdd_lov_cookiesize(env, mdd); + + RETURN(0); +} + +static int mdd_init_capa_ctxt(const struct lu_env *env, struct md_device *m, + int mode, unsigned long timeout, __u32 alg, + struct lustre_capa_key *keys) +{ + struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); + struct mds_obd *mds = &mdd2obd_dev(mdd)->u.mds; + int rc; + ENTRY; + + mds->mds_capa_keys = keys; + rc = mdd_child_ops(mdd)->dt_init_capa_ctxt(env, mdd->mdd_child, mode, + timeout, alg, keys); + RETURN(rc); +} + +static int mdd_update_capa_key(const struct lu_env *env, + struct md_device *m, + struct lustre_capa_key *key) +{ + struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); + struct obd_export *lov_exp = mdd2obd_dev(mdd)->u.mds.mds_osc_exp; + int rc; + ENTRY; + + rc = obd_set_info_async(lov_exp, strlen(KEY_CAPA_KEY), KEY_CAPA_KEY, + sizeof(*key), key, NULL); + RETURN(rc); +} + +static struct lu_device *mdd_device_alloc(const struct lu_env *env, + struct lu_device_type *t, + struct lustre_cfg *lcfg) +{ + struct lu_device *l; + struct mdd_device *m; + + OBD_ALLOC_PTR(m); + if (m == NULL) { + l = ERR_PTR(-ENOMEM); + } else { + md_device_init(&m->mdd_md_dev, t); + l = mdd2lu_dev(m); + l->ld_ops = &mdd_lu_ops; + m->mdd_md_dev.md_ops = &mdd_ops; + } + + return l; +} + +static void mdd_device_free(const struct lu_env *env, + struct lu_device *lu) +{ + struct mdd_device *m = lu2mdd_dev(lu); + + LASSERT(atomic_read(&lu->ld_ref) == 0); + md_device_fini(&m->mdd_md_dev); + OBD_FREE_PTR(m); +} + +static struct obd_ops mdd_obd_device_ops = { + .o_owner = THIS_MODULE +}; + +static void *mdd_ucred_key_init(const struct lu_context *ctx, + struct lu_context_key *key) +{ + struct md_ucred *uc; + + OBD_ALLOC_PTR(uc); + if (uc == NULL) + uc = ERR_PTR(-ENOMEM); + return uc; +} + +static void mdd_ucred_key_fini(const struct lu_context *ctx, + struct lu_context_key *key, void *data) +{ + struct md_ucred *uc = data; + OBD_FREE_PTR(uc); +} + +static struct lu_context_key mdd_ucred_key = { + .lct_tags = LCT_SESSION, + .lct_init = mdd_ucred_key_init, + .lct_fini = mdd_ucred_key_fini +}; + +struct md_ucred *md_ucred(const struct lu_env *env) +{ + LASSERT(env->le_ses != NULL); + return lu_context_key_get(env->le_ses, &mdd_ucred_key); +} +EXPORT_SYMBOL(md_ucred); + +static void *mdd_capainfo_key_init(const struct lu_context *ctx, + struct lu_context_key *key) +{ + struct md_capainfo *ci; + + OBD_ALLOC_PTR(ci); + if (ci == NULL) + ci = ERR_PTR(-ENOMEM); + return ci; +} + +static void mdd_capainfo_key_fini(const struct lu_context *ctx, + struct lu_context_key *key, void *data) +{ + struct md_capainfo *ci = data; + OBD_FREE_PTR(ci); +} + +struct lu_context_key mdd_capainfo_key = { + .lct_tags = LCT_SESSION, + .lct_init = mdd_capainfo_key_init, + .lct_fini = mdd_capainfo_key_fini +}; + +struct md_capainfo *md_capainfo(const struct lu_env *env) +{ + /* NB, in mdt_init0 */ + if (env->le_ses == NULL) + return NULL; + return lu_context_key_get(env->le_ses, &mdd_capainfo_key); +} +EXPORT_SYMBOL(md_capainfo); + +static int mdd_type_init(struct lu_device_type *t) +{ + int result; + + result = lu_context_key_register(&mdd_thread_key); + if (result == 0) + result = lu_context_key_register(&mdd_ucred_key); + if (result == 0) + result = lu_context_key_register(&mdd_capainfo_key); + return result; +} + +static void mdd_type_fini(struct lu_device_type *t) +{ + lu_context_key_degister(&mdd_capainfo_key); + lu_context_key_degister(&mdd_ucred_key); + lu_context_key_degister(&mdd_thread_key); +} + +struct md_device_operations mdd_ops = { + .mdo_statfs = mdd_statfs, + .mdo_root_get = mdd_root_get, + .mdo_maxsize_get = mdd_maxsize_get, + .mdo_init_capa_ctxt = mdd_init_capa_ctxt, + .mdo_update_capa_key= mdd_update_capa_key, +}; + +static struct lu_device_type_operations mdd_device_type_ops = { + .ldto_init = mdd_type_init, + .ldto_fini = mdd_type_fini, + + .ldto_device_alloc = mdd_device_alloc, + .ldto_device_free = mdd_device_free, + + .ldto_device_init = mdd_device_init, + .ldto_device_fini = mdd_device_fini +}; + +static struct lu_device_type mdd_device_type = { + .ldt_tags = LU_DEVICE_MD, + .ldt_name = LUSTRE_MDD_NAME, + .ldt_ops = &mdd_device_type_ops, + .ldt_ctx_tags = LCT_MD_THREAD +}; + +static void *mdd_key_init(const struct lu_context *ctx, + struct lu_context_key *key) +{ + struct mdd_thread_info *info; + + OBD_ALLOC_PTR(info); + if (info == NULL) + info = ERR_PTR(-ENOMEM); + return info; +} + +static void mdd_key_fini(const struct lu_context *ctx, + struct lu_context_key *key, void *data) +{ + struct mdd_thread_info *info = data; + OBD_FREE_PTR(info); +} + +struct lu_context_key mdd_thread_key = { + .lct_tags = LCT_MD_THREAD, + .lct_init = mdd_key_init, + .lct_fini = mdd_key_fini +}; + +struct lprocfs_vars lprocfs_mdd_obd_vars[] = { + { 0 } +}; + +struct lprocfs_vars lprocfs_mdd_module_vars[] = { + { 0 } +}; + +LPROCFS_INIT_VARS(mdd, lprocfs_mdd_module_vars, lprocfs_mdd_obd_vars); + +static int __init mdd_mod_init(void) +{ + struct lprocfs_static_vars lvars; + printk(KERN_INFO "Lustre: MetaData Device; info@clusterfs.com\n"); + lprocfs_init_vars(mdd, &lvars); + return class_register_type(&mdd_obd_device_ops, NULL, lvars.module_vars, + LUSTRE_MDD_NAME, &mdd_device_type); +} + +static void __exit mdd_mod_exit(void) +{ + class_unregister_type(LUSTRE_MDD_NAME); +} + +MODULE_AUTHOR("Cluster File Systems, Inc. "); +MODULE_DESCRIPTION("Lustre Meta-data Device Prototype ("LUSTRE_MDD_NAME")"); +MODULE_LICENSE("GPL"); + +cfs_module(mdd, "0.1.0", mdd_mod_init, mdd_mod_exit); diff --git a/lustre/mdd/mdd_handler.c b/lustre/mdd/mdd_handler.c index 77763e4..1120379 100644 --- a/lustre/mdd/mdd_handler.c +++ b/lustre/mdd/mdd_handler.c @@ -75,188 +75,9 @@ static struct md_object_operations mdd_obj_ops; static struct md_dir_operations mdd_dir_ops; static struct lu_object_operations mdd_lu_obj_ops; -static struct lu_context_key mdd_thread_key; - -static const char *mdd_root_dir_name = "root"; static const char dot[] = "."; static const char dotdot[] = ".."; -enum mdd_txn_op { - MDD_TXN_OBJECT_DESTROY_OP, - MDD_TXN_OBJECT_CREATE_OP, - MDD_TXN_ATTR_SET_OP, - MDD_TXN_XATTR_SET_OP, - MDD_TXN_INDEX_INSERT_OP, - MDD_TXN_INDEX_DELETE_OP, - MDD_TXN_LINK_OP, - MDD_TXN_UNLINK_OP, - MDD_TXN_RENAME_OP, - MDD_TXN_RENAME_TGT_OP, - MDD_TXN_CREATE_DATA_OP, - MDD_TXN_MKDIR_OP -}; - -struct mdd_txn_op_descr { - enum mdd_txn_op mod_op; - unsigned int mod_credits; -}; - -enum { - MDD_TXN_OBJECT_DESTROY_CREDITS = 0, - MDD_TXN_OBJECT_CREATE_CREDITS = 0, - MDD_TXN_ATTR_SET_CREDITS = 0, - MDD_TXN_XATTR_SET_CREDITS = 0, - MDD_TXN_INDEX_INSERT_CREDITS = 0, - MDD_TXN_INDEX_DELETE_CREDITS = 0, - MDD_TXN_LINK_CREDITS = 0, - MDD_TXN_UNLINK_CREDITS = 0, - MDD_TXN_RENAME_CREDITS = 0, - MDD_TXN_RENAME_TGT_CREDITS = 0, - MDD_TXN_CREATE_DATA_CREDITS = 0, - MDD_TXN_MKDIR_CREDITS = 0 -}; - -#define DEFINE_MDD_TXN_OP_ARRAY(opname, base) \ -[opname ## _OP - base ## _OP]= { \ - .mod_op = opname ## _OP, \ - .mod_credits = opname ## _CREDITS, \ -} - -/* - * number of blocks to reserve for particular operations. Should be function - * of ... something. Stub for now. - */ - -#define DEFINE_MDD_TXN_OP_DESC(opname) \ - DEFINE_MDD_TXN_OP_ARRAY(opname, MDD_TXN_OBJECT_DESTROY) - -static struct mdd_txn_op_descr mdd_txn_descrs[] = { - DEFINE_MDD_TXN_OP_DESC(MDD_TXN_OBJECT_DESTROY), - DEFINE_MDD_TXN_OP_DESC(MDD_TXN_OBJECT_CREATE), - DEFINE_MDD_TXN_OP_DESC(MDD_TXN_ATTR_SET), - DEFINE_MDD_TXN_OP_DESC(MDD_TXN_XATTR_SET), - DEFINE_MDD_TXN_OP_DESC(MDD_TXN_INDEX_INSERT), - DEFINE_MDD_TXN_OP_DESC(MDD_TXN_INDEX_DELETE), - DEFINE_MDD_TXN_OP_DESC(MDD_TXN_LINK), - DEFINE_MDD_TXN_OP_DESC(MDD_TXN_UNLINK), - DEFINE_MDD_TXN_OP_DESC(MDD_TXN_RENAME), - DEFINE_MDD_TXN_OP_DESC(MDD_TXN_RENAME_TGT), - DEFINE_MDD_TXN_OP_DESC(MDD_TXN_CREATE_DATA), - DEFINE_MDD_TXN_OP_DESC(MDD_TXN_MKDIR) -}; - -static void mdd_txn_param_build(const struct lu_env *env, enum mdd_txn_op op) -{ - LASSERT(0 <= op && op < ARRAY_SIZE(mdd_txn_descrs)); - - mdd_env_info(env)->mti_param.tp_credits = - mdd_txn_descrs[op].mod_credits; -} - -static int mdd_credit_get(const struct lu_env *env, struct mdd_device *mdd, - int op) -{ - int credits; - credits = mdd_child_ops(mdd)->dt_credit_get(env, mdd->mdd_child, - op); - LASSERT(credits > 0); - return credits; -} - -/* XXX: we should calculate it by lsm count, not ost count. */ -int mdd_txn_init_credits(const struct lu_env *env, struct mdd_device *mdd) -{ - struct mds_obd *mds = &mdd->mdd_obd_dev->u.mds; - int ost_count = mds->mds_lov_desc.ld_tgt_count; - - int index_create_credits; - int index_delete_credits; - - int xattr_credits; - int log_credits; - int create_credits; - int destroy_credits; - int attr_credits; - int num_entries; - int i; - - /* Init credits for each ops. */ - num_entries = ARRAY_SIZE(mdd_txn_descrs); - LASSERT(num_entries > 0); - - /* Init the basic credits from osd layer. */ - index_create_credits = mdd_credit_get(env, mdd, DTO_INDEX_INSERT); - index_delete_credits = mdd_credit_get(env, mdd, DTO_INDEX_DELETE); - log_credits = mdd_credit_get(env, mdd, DTO_LOG_REC); - attr_credits = mdd_credit_get(env, mdd, DTO_ATTR_SET); - xattr_credits = mdd_credit_get(env, mdd, DTO_XATTR_SET); - create_credits = mdd_credit_get(env, mdd, DTO_OBJECT_CREATE); - destroy_credits = mdd_credit_get(env, mdd, DTO_OBJECT_DELETE); - - /* Calculate the mdd credits. */ - for (i = 0; i < num_entries; i++) { - int opcode = mdd_txn_descrs[i].mod_op; - int *c = &mdd_txn_descrs[i].mod_credits; - switch(opcode) { - case MDD_TXN_OBJECT_DESTROY_OP: - *c = destroy_credits; - break; - case MDD_TXN_OBJECT_CREATE_OP: - /* OI_INSERT + CREATE OBJECT */ - *c = index_create_credits + create_credits; - break; - case MDD_TXN_ATTR_SET_OP: - /* ATTR set + XATTR(lsm, lmv) set */ - *c = attr_credits + xattr_credits; - break; - case MDD_TXN_XATTR_SET_OP: - *c = xattr_credits; - break; - case MDD_TXN_INDEX_INSERT_OP: - *c = index_create_credits; - break; - case MDD_TXN_INDEX_DELETE_OP: - *c = index_delete_credits; - break; - case MDD_TXN_LINK_OP: - *c = index_create_credits; - break; - case MDD_TXN_UNLINK_OP: - /* delete index + Unlink log */ - *c = index_delete_credits + - log_credits * ost_count; - break; - case MDD_TXN_RENAME_OP: - /* 2 delete index + 1 insert + Unlink log */ - *c = 2 * index_delete_credits + - index_create_credits + - log_credits * ost_count; - break; - case MDD_TXN_RENAME_TGT_OP: - /* index insert + index delete */ - *c = index_delete_credits + - index_create_credits; - break; - case MDD_TXN_CREATE_DATA_OP: - /* same as set xattr(lsm) */ - *c = xattr_credits; - break; - case MDD_TXN_MKDIR_OP: - /* INDEX INSERT + OI INSERT + CREATE_OBJECT_CREDITS - * SET_MD CREDITS is already counted in - * CREATE_OBJECT CREDITS - */ - *c = 2 * index_create_credits + create_credits; - break; - default: - CERROR("Invalid op %d init its credit\n", - opcode); - LBUG(); - } - } - RETURN(0); -} - struct lu_buf *mdd_buf_get(const struct lu_env *env, void *area, ssize_t len) { struct lu_buf *buf; @@ -360,9 +181,9 @@ struct mdd_thread_info *mdd_env_info(const struct lu_env *env) return info; } -static struct lu_object *mdd_object_alloc(const struct lu_env *env, - const struct lu_object_header *hdr, - struct lu_device *d) +struct lu_object *mdd_object_alloc(const struct lu_env *env, + const struct lu_object_header *hdr, + struct lu_device *d) { struct mdd_object *mdd_obj; @@ -833,199 +654,6 @@ static int mdd_xattr_list(const struct lu_env *env, struct md_object *obj, RETURN(rc); } -static int mdd_txn_start_cb(const struct lu_env *env, - struct txn_param *param, void *cookie) -{ - return 0; -} - -static int mdd_txn_stop_cb(const struct lu_env *env, - struct thandle *txn, void *cookie) -{ - struct mdd_device *mdd = cookie; - struct obd_device *obd = mdd2obd_dev(mdd); - - LASSERT(obd); - return mds_lov_write_objids(obd); -} - -static int mdd_txn_commit_cb(const struct lu_env *env, - struct thandle *txn, void *cookie) -{ - return 0; -} - -static int mdd_device_init(const struct lu_env *env, struct lu_device *d, - const char *name, struct lu_device *next) -{ - struct mdd_device *mdd = lu2mdd_dev(d); - struct dt_device *dt; - int rc = 0; - ENTRY; - - mdd->mdd_child = lu2dt_dev(next); - - dt = mdd->mdd_child; - /* prepare transactions callbacks */ - mdd->mdd_txn_cb.dtc_txn_start = mdd_txn_start_cb; - mdd->mdd_txn_cb.dtc_txn_stop = mdd_txn_stop_cb; - mdd->mdd_txn_cb.dtc_txn_commit = mdd_txn_commit_cb; - mdd->mdd_txn_cb.dtc_cookie = mdd; - rc = mdd_procfs_init(mdd); - RETURN(rc); -} - -static struct lu_device *mdd_device_fini(const struct lu_env *env, - struct lu_device *d) -{ - struct mdd_device *mdd = lu2mdd_dev(d); - struct lu_device *next = &mdd->mdd_child->dd_lu_dev; - int rc; - - rc = mdd_procfs_fini(mdd); - if (rc) { - CERROR("proc fini error %d \n", rc); - return ERR_PTR(rc); - } - return next; -} - -static int mdd_mount(const struct lu_env *env, struct mdd_device *mdd) -{ - int rc; - struct dt_object *root; - ENTRY; - - dt_txn_callback_add(mdd->mdd_child, &mdd->mdd_txn_cb); - root = dt_store_open(env, mdd->mdd_child, mdd_root_dir_name, - &mdd->mdd_root_fid); - if (!IS_ERR(root)) { - LASSERT(root != NULL); - lu_object_put(env, &root->do_lu); - rc = orph_index_init(env, mdd); - } else - rc = PTR_ERR(root); - - RETURN(rc); -} - -static void mdd_device_shutdown(const struct lu_env *env, - struct mdd_device *m) -{ - dt_txn_callback_del(m->mdd_child, &m->mdd_txn_cb); - if (m->mdd_obd_dev) - mdd_fini_obd(env, m); - orph_index_fini(env, m); -} - -static int mdd_process_config(const struct lu_env *env, - struct lu_device *d, struct lustre_cfg *cfg) -{ - struct mdd_device *m = lu2mdd_dev(d); - struct dt_device *dt = m->mdd_child; - struct lu_device *next = &dt->dd_lu_dev; - int rc; - ENTRY; - - switch (cfg->lcfg_command) { - case LCFG_SETUP: - rc = next->ld_ops->ldo_process_config(env, next, cfg); - if (rc) - GOTO(out, rc); - dt->dd_ops->dt_conf_get(env, dt, &m->mdd_dt_conf); - - rc = mdd_init_obd(env, m, cfg); - if (rc) { - CERROR("lov init error %d \n", rc); - GOTO(out, rc); - } - rc = mdd_mount(env, m); - if (rc) - GOTO(out, rc); - rc = mdd_txn_init_credits(env, m); - break; - case LCFG_CLEANUP: - mdd_device_shutdown(env, m); - default: - rc = next->ld_ops->ldo_process_config(env, next, cfg); - break; - } -out: - RETURN(rc); -} -#if 0 -static int mdd_lov_set_nextid(const struct lu_env *env, - struct mdd_device *mdd) -{ - struct mds_obd *mds = &mdd->mdd_obd_dev->u.mds; - int rc; - ENTRY; - - LASSERT(mds->mds_lov_objids != NULL); - rc = obd_set_info_async(mds->mds_osc_exp, strlen(KEY_NEXT_ID), - KEY_NEXT_ID, mds->mds_lov_desc.ld_tgt_count, - mds->mds_lov_objids, NULL); - - RETURN(rc); -} - -static int mdd_cleanup_unlink_llog(const struct lu_env *env, - struct mdd_device *mdd) -{ - /* XXX: to be implemented! */ - return 0; -} -#endif - -static int mdd_recovery_complete(const struct lu_env *env, - struct lu_device *d) -{ - struct mdd_device *mdd = lu2mdd_dev(d); - struct lu_device *next = &mdd->mdd_child->dd_lu_dev; - struct obd_device *obd = mdd2obd_dev(mdd); - int rc; - ENTRY; - - LASSERT(mdd != NULL); - LASSERT(obd != NULL); -#if 0 - /* XXX: Do we need this in new stack? */ - rc = mdd_lov_set_nextid(env, mdd); - if (rc) { - CERROR("mdd_lov_set_nextid() failed %d\n", - rc); - RETURN(rc); - } - - /* XXX: cleanup unlink. */ - rc = mdd_cleanup_unlink_llog(env, mdd); - if (rc) { - CERROR("mdd_cleanup_unlink_llog() failed %d\n", - rc); - RETURN(rc); - } -#endif - obd_notify(obd->u.mds.mds_osc_obd, NULL, - (obd->obd_async_recov ? - OBD_NOTIFY_SYNC_NONBLOCK : - OBD_NOTIFY_SYNC), NULL); - - obd->obd_recovering = 0; - obd->obd_type->typ_dt_ops->o_postrecov(obd); - - /* XXX: orphans handling. */ - __mdd_orphan_cleanup(env, mdd); - rc = next->ld_ops->ldo_recovery_complete(env, next); - - RETURN(rc); -} - -struct lu_device_operations mdd_lu_ops = { - .ldo_object_alloc = mdd_object_alloc, - .ldo_process_config = mdd_process_config, - .ldo_recovery_complete = mdd_recovery_complete -}; - void mdd_write_lock(const struct lu_env *env, struct mdd_object *obj) { struct dt_object *next = mdd_object_child(obj); @@ -3089,79 +2717,6 @@ cleanup: RETURN(rc); } -/* - * No permission check is needed. - */ -static int mdd_root_get(const struct lu_env *env, - struct md_device *m, struct lu_fid *f) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - - ENTRY; - *f = mdd->mdd_root_fid; - RETURN(0); -} - -/* - * No permission check is needed. - */ -static int mdd_statfs(const struct lu_env *env, struct md_device *m, - struct kstatfs *sfs) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - int rc; - - ENTRY; - - rc = mdd_child_ops(mdd)->dt_statfs(env, mdd->mdd_child, sfs); - - RETURN(rc); -} - -/* - * No permission check is needed. - */ -static int mdd_maxsize_get(const struct lu_env *env, struct md_device *m, - int *md_size, int *cookie_size) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - ENTRY; - - *md_size = mdd_lov_mdsize(env, mdd); - *cookie_size = mdd_lov_cookiesize(env, mdd); - - RETURN(0); -} - -static int mdd_init_capa_ctxt(const struct lu_env *env, struct md_device *m, - int mode, unsigned long timeout, __u32 alg, - struct lustre_capa_key *keys) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - struct mds_obd *mds = &mdd2obd_dev(mdd)->u.mds; - int rc; - ENTRY; - - mds->mds_capa_keys = keys; - rc = mdd_child_ops(mdd)->dt_init_capa_ctxt(env, mdd->mdd_child, mode, - timeout, alg, keys); - RETURN(rc); -} - -static int mdd_update_capa_key(const struct lu_env *env, - struct md_device *m, - struct lustre_capa_key *key) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - struct obd_export *lov_exp = mdd2obd_dev(mdd)->u.mds.mds_osc_exp; - int rc; - ENTRY; - - rc = obd_set_info_async(lov_exp, strlen(KEY_CAPA_KEY), KEY_CAPA_KEY, - sizeof(*key), key, NULL); - RETURN(rc); -} - static void __mdd_ref_add(const struct lu_env *env, struct mdd_object *obj, struct thandle *handle) { @@ -3654,14 +3209,6 @@ static int mdd_capa_get(const struct lu_env *env, struct md_object *obj, RETURN(rc); } -struct md_device_operations mdd_ops = { - .mdo_statfs = mdd_statfs, - .mdo_root_get = mdd_root_get, - .mdo_maxsize_get = mdd_maxsize_get, - .mdo_init_capa_ctxt = mdd_init_capa_ctxt, - .mdo_update_capa_key= mdd_update_capa_key, -}; - static struct md_dir_operations mdd_dir_ops = { .mdo_is_subdir = mdd_is_subdir, .mdo_lookup = mdd_lookup, @@ -3693,191 +3240,3 @@ static struct md_object_operations mdd_obj_ops = { .moo_capa_get = mdd_capa_get }; -static struct obd_ops mdd_obd_device_ops = { - .o_owner = THIS_MODULE -}; - -static struct lu_device *mdd_device_alloc(const struct lu_env *env, - struct lu_device_type *t, - struct lustre_cfg *lcfg) -{ - struct lu_device *l; - struct mdd_device *m; - - OBD_ALLOC_PTR(m); - if (m == NULL) { - l = ERR_PTR(-ENOMEM); - } else { - md_device_init(&m->mdd_md_dev, t); - l = mdd2lu_dev(m); - l->ld_ops = &mdd_lu_ops; - m->mdd_md_dev.md_ops = &mdd_ops; - } - - return l; -} - -static void mdd_device_free(const struct lu_env *env, - struct lu_device *lu) -{ - struct mdd_device *m = lu2mdd_dev(lu); - - LASSERT(atomic_read(&lu->ld_ref) == 0); - md_device_fini(&m->mdd_md_dev); - OBD_FREE_PTR(m); -} - -static void *mdd_ucred_key_init(const struct lu_context *ctx, - struct lu_context_key *key) -{ - struct md_ucred *uc; - - OBD_ALLOC_PTR(uc); - if (uc == NULL) - uc = ERR_PTR(-ENOMEM); - return uc; -} - -static void mdd_ucred_key_fini(const struct lu_context *ctx, - struct lu_context_key *key, void *data) -{ - struct md_ucred *uc = data; - OBD_FREE_PTR(uc); -} - -static struct lu_context_key mdd_ucred_key = { - .lct_tags = LCT_SESSION, - .lct_init = mdd_ucred_key_init, - .lct_fini = mdd_ucred_key_fini -}; - -struct md_ucred *md_ucred(const struct lu_env *env) -{ - LASSERT(env->le_ses != NULL); - return lu_context_key_get(env->le_ses, &mdd_ucred_key); -} -EXPORT_SYMBOL(md_ucred); - -static void *mdd_capainfo_key_init(const struct lu_context *ctx, - struct lu_context_key *key) -{ - struct md_capainfo *ci; - - OBD_ALLOC_PTR(ci); - if (ci == NULL) - ci = ERR_PTR(-ENOMEM); - return ci; -} - -static void mdd_capainfo_key_fini(const struct lu_context *ctx, - struct lu_context_key *key, void *data) -{ - struct md_capainfo *ci = data; - OBD_FREE_PTR(ci); -} - -struct lu_context_key mdd_capainfo_key = { - .lct_tags = LCT_SESSION, - .lct_init = mdd_capainfo_key_init, - .lct_fini = mdd_capainfo_key_fini -}; - -struct md_capainfo *md_capainfo(const struct lu_env *env) -{ - /* NB, in mdt_init0 */ - if (env->le_ses == NULL) - return NULL; - return lu_context_key_get(env->le_ses, &mdd_capainfo_key); -} -EXPORT_SYMBOL(md_capainfo); - -static int mdd_type_init(struct lu_device_type *t) -{ - int result; - - result = lu_context_key_register(&mdd_thread_key); - if (result == 0) - result = lu_context_key_register(&mdd_ucred_key); - if (result == 0) - result = lu_context_key_register(&mdd_capainfo_key); - return result; -} - -static void mdd_type_fini(struct lu_device_type *t) -{ - lu_context_key_degister(&mdd_capainfo_key); - lu_context_key_degister(&mdd_ucred_key); - lu_context_key_degister(&mdd_thread_key); -} - -static struct lu_device_type_operations mdd_device_type_ops = { - .ldto_init = mdd_type_init, - .ldto_fini = mdd_type_fini, - - .ldto_device_alloc = mdd_device_alloc, - .ldto_device_free = mdd_device_free, - - .ldto_device_init = mdd_device_init, - .ldto_device_fini = mdd_device_fini -}; - -static struct lu_device_type mdd_device_type = { - .ldt_tags = LU_DEVICE_MD, - .ldt_name = LUSTRE_MDD_NAME, - .ldt_ops = &mdd_device_type_ops, - .ldt_ctx_tags = LCT_MD_THREAD -}; - -static void *mdd_key_init(const struct lu_context *ctx, - struct lu_context_key *key) -{ - struct mdd_thread_info *info; - - OBD_ALLOC_PTR(info); - if (info == NULL) - info = ERR_PTR(-ENOMEM); - return info; -} - -static void mdd_key_fini(const struct lu_context *ctx, - struct lu_context_key *key, void *data) -{ - struct mdd_thread_info *info = data; - OBD_FREE_PTR(info); -} - -static struct lu_context_key mdd_thread_key = { - .lct_tags = LCT_MD_THREAD, - .lct_init = mdd_key_init, - .lct_fini = mdd_key_fini -}; - -struct lprocfs_vars lprocfs_mdd_obd_vars[] = { - { 0 } -}; - -struct lprocfs_vars lprocfs_mdd_module_vars[] = { - { 0 } -}; - -LPROCFS_INIT_VARS(mdd, lprocfs_mdd_module_vars, lprocfs_mdd_obd_vars); - -static int __init mdd_mod_init(void) -{ - struct lprocfs_static_vars lvars; - printk(KERN_INFO "Lustre: MetaData Device; info@clusterfs.com\n"); - lprocfs_init_vars(mdd, &lvars); - return class_register_type(&mdd_obd_device_ops, NULL, lvars.module_vars, - LUSTRE_MDD_NAME, &mdd_device_type); -} - -static void __exit mdd_mod_exit(void) -{ - class_unregister_type(LUSTRE_MDD_NAME); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Meta-data Device Prototype ("LUSTRE_MDD_NAME")"); -MODULE_LICENSE("GPL"); - -cfs_module(mdd, "0.1.0", mdd_mod_init, mdd_mod_exit); diff --git a/lustre/mdd/mdd_trans.c b/lustre/mdd/mdd_trans.c new file mode 100644 index 0000000..e0fc51e --- /dev/null +++ b/lustre/mdd/mdd_trans.c @@ -0,0 +1,231 @@ +/* -*- MODE: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * mdd/mdd_handler.c + * Lustre Metadata Server (mdd) routines + * + * Copyright (C) 2006 Cluster File Systems, Inc. + * Author: Wang Di + * + * 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_MDS + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mdd_internal.h" + + +struct mdd_txn_op_descr { + enum mdd_txn_op mod_op; + unsigned int mod_credits; +}; + +enum { + MDD_TXN_OBJECT_DESTROY_CREDITS = 0, + MDD_TXN_OBJECT_CREATE_CREDITS = 0, + MDD_TXN_ATTR_SET_CREDITS = 0, + MDD_TXN_XATTR_SET_CREDITS = 0, + MDD_TXN_INDEX_INSERT_CREDITS = 0, + MDD_TXN_INDEX_DELETE_CREDITS = 0, + MDD_TXN_LINK_CREDITS = 0, + MDD_TXN_UNLINK_CREDITS = 0, + MDD_TXN_RENAME_CREDITS = 0, + MDD_TXN_RENAME_TGT_CREDITS = 0, + MDD_TXN_CREATE_DATA_CREDITS = 0, + MDD_TXN_MKDIR_CREDITS = 0 +}; + +#define DEFINE_MDD_TXN_OP_ARRAY(opname, base) \ +[opname ## _OP - base ## _OP]= { \ + .mod_op = opname ## _OP, \ + .mod_credits = opname ## _CREDITS, \ +} + +/* + * number of blocks to reserve for particular operations. Should be function + * of ... something. Stub for now. + */ + +#define DEFINE_MDD_TXN_OP_DESC(opname) \ + DEFINE_MDD_TXN_OP_ARRAY(opname, MDD_TXN_OBJECT_DESTROY) + +static struct mdd_txn_op_descr mdd_txn_descrs[] = { + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_OBJECT_DESTROY), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_OBJECT_CREATE), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_ATTR_SET), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_XATTR_SET), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_INDEX_INSERT), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_INDEX_DELETE), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_LINK), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_UNLINK), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_RENAME), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_RENAME_TGT), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_CREATE_DATA), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_MKDIR) +}; + +int mdd_txn_start_cb(const struct lu_env *env, struct txn_param *param, + void *cookie) +{ + return 0; +} + +int mdd_txn_stop_cb(const struct lu_env *env, struct thandle *txn, + void *cookie) +{ + struct mdd_device *mdd = cookie; + struct obd_device *obd = mdd2obd_dev(mdd); + + LASSERT(obd); + return mds_lov_write_objids(obd); +} + +int mdd_txn_commit_cb(const struct lu_env *env, struct thandle *txn, + void *cookie) +{ + return 0; +} + +void mdd_txn_param_build(const struct lu_env *env, enum mdd_txn_op op) +{ + LASSERT(0 <= op && op < ARRAY_SIZE(mdd_txn_descrs)); + + mdd_env_info(env)->mti_param.tp_credits = + mdd_txn_descrs[op].mod_credits; +} + +static int mdd_credit_get(const struct lu_env *env, struct mdd_device *mdd, + int op) +{ + int credits; + credits = mdd_child_ops(mdd)->dt_credit_get(env, mdd->mdd_child, + op); + LASSERT(credits > 0); + return credits; +} + +/* XXX: we should calculate it by lsm count, not ost count. */ +int mdd_txn_init_credits(const struct lu_env *env, struct mdd_device *mdd) +{ + struct mds_obd *mds = &mdd->mdd_obd_dev->u.mds; + int ost_count = mds->mds_lov_desc.ld_tgt_count; + + int index_create_credits; + int index_delete_credits; + + int xattr_credits; + int log_credits; + int create_credits; + int destroy_credits; + int attr_credits; + int num_entries; + int i; + + /* Init credits for each ops. */ + num_entries = ARRAY_SIZE(mdd_txn_descrs); + LASSERT(num_entries > 0); + + /* Init the basic credits from osd layer. */ + index_create_credits = mdd_credit_get(env, mdd, DTO_INDEX_INSERT); + index_delete_credits = mdd_credit_get(env, mdd, DTO_INDEX_DELETE); + log_credits = mdd_credit_get(env, mdd, DTO_LOG_REC); + attr_credits = mdd_credit_get(env, mdd, DTO_ATTR_SET); + xattr_credits = mdd_credit_get(env, mdd, DTO_XATTR_SET); + create_credits = mdd_credit_get(env, mdd, DTO_OBJECT_CREATE); + destroy_credits = mdd_credit_get(env, mdd, DTO_OBJECT_DELETE); + + /* Calculate the mdd credits. */ + for (i = 0; i < num_entries; i++) { + int opcode = mdd_txn_descrs[i].mod_op; + int *c = &mdd_txn_descrs[i].mod_credits; + switch(opcode) { + case MDD_TXN_OBJECT_DESTROY_OP: + *c = destroy_credits; + break; + case MDD_TXN_OBJECT_CREATE_OP: + /* OI_INSERT + CREATE OBJECT */ + *c = index_create_credits + create_credits; + break; + case MDD_TXN_ATTR_SET_OP: + /* ATTR set + XATTR(lsm, lmv) set */ + *c = attr_credits + xattr_credits; + break; + case MDD_TXN_XATTR_SET_OP: + *c = xattr_credits; + break; + case MDD_TXN_INDEX_INSERT_OP: + *c = index_create_credits; + break; + case MDD_TXN_INDEX_DELETE_OP: + *c = index_delete_credits; + break; + case MDD_TXN_LINK_OP: + *c = index_create_credits; + break; + case MDD_TXN_UNLINK_OP: + /* delete index + Unlink log */ + *c = index_delete_credits + + log_credits * ost_count; + break; + case MDD_TXN_RENAME_OP: + /* 2 delete index + 1 insert + Unlink log */ + *c = 2 * index_delete_credits + + index_create_credits + + log_credits * ost_count; + break; + case MDD_TXN_RENAME_TGT_OP: + /* index insert + index delete */ + *c = index_delete_credits + + index_create_credits; + break; + case MDD_TXN_CREATE_DATA_OP: + /* same as set xattr(lsm) */ + *c = xattr_credits; + break; + case MDD_TXN_MKDIR_OP: + /* INDEX INSERT + OI INSERT + CREATE_OBJECT_CREDITS + * SET_MD CREDITS is already counted in + * CREATE_OBJECT CREDITS + */ + *c = 2 * index_create_credits + create_credits; + break; + default: + CERROR("Invalid op %d init its credit\n", + opcode); + LBUG(); + } + } + RETURN(0); +} + + -- 1.8.3.1