1 /* -*- MODE: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
5 * Lustre Metadata Server (mdd) routines
7 * Copyright (C) 2006 Cluster File Systems, Inc.
8 * Author: Wang Di <wangdi@clusterfs.com>
10 * This file is part of the Lustre file system, http://www.lustre.org
11 * Lustre is a trademark of Cluster File Systems, Inc.
13 * You may have signed or agreed to another license before downloading
14 * this software. If so, you are bound by the terms and conditions
15 * of that agreement, and the following does not apply to you. See the
16 * LICENSE file included with this distribution for more information.
18 * If you did not agree to a different license, then this copy of Lustre
19 * is open source software; you can redistribute it and/or modify it
20 * under the terms of version 2 of the GNU General Public License as
21 * published by the Free Software Foundation.
23 * In either case, Lustre is distributed in the hope that it will be
24 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
25 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * license text for more details.
29 # define EXPORT_SYMTAB
31 #define DEBUG_SUBSYSTEM S_MDS
33 #include <linux/module.h>
34 #include <linux/jbd.h>
36 #include <obd_class.h>
37 #include <lustre_ver.h>
38 #include <obd_support.h>
39 #include <lprocfs_status.h>
41 #include <linux/ldiskfs_fs.h>
42 #include <lustre_mds.h>
43 #include <lustre/lustre_idl.h>
45 #include "mdd_internal.h"
47 int mdd_txn_start_cb(const struct lu_env *env, struct txn_param *param,
53 int mdd_txn_stop_cb(const struct lu_env *env, struct thandle *txn,
56 struct mdd_device *mdd = cookie;
57 struct obd_device *obd = mdd2obd_dev(mdd);
60 return mds_lov_write_objids(obd);
63 int mdd_txn_commit_cb(const struct lu_env *env, struct thandle *txn,
69 static int dto_txn_credits[DTO_NR];
70 void mdd_txn_param_build(const struct lu_env *env, struct mdd_device *mdd,
73 LASSERT(0 <= op && op < MDD_TXN_LAST_OP);
75 txn_param_init(&mdd_env_info(env)->mti_param,
76 mdd->mdd_tod[op].mod_credits);
79 int mdd_log_txn_param_build(const struct lu_env *env, struct md_object *obj,
80 struct md_attr *ma, enum mdd_txn_op op)
82 struct mdd_device *mdd = mdo2mdd(&md2mdd_obj(obj)->mod_obj);
83 int rc, log_credits, stripe;
86 mdd_txn_param_build(env, mdd, op);
88 if (S_ISDIR(lu_object_attr(&obj->mo_lu)))
91 LASSERT(op == MDD_TXN_UNLINK_OP || op == MDD_TXN_RENAME_OP);
92 rc = mdd_lmm_get_locked(env, md2mdd_obj(obj), ma);
93 if (rc || !(ma->ma_valid & MA_LOV))
96 LASSERT(le32_to_cpu(ma->ma_lmm->lmm_magic) == LOV_MAGIC);
97 if ((int)le32_to_cpu(ma->ma_lmm->lmm_stripe_count) < 0)
98 stripe = mdd2obd_dev(mdd)->u.mds.mds_lov_desc.ld_tgt_count;
100 stripe = le32_to_cpu(ma->ma_lmm->lmm_stripe_count);
102 log_credits = stripe * dto_txn_credits[DTO_LOG_REC];
103 mdd_env_info(env)->mti_param.tp_credits += log_credits;
107 static void mdd_txn_init_dto_credits(const struct lu_env *env,
108 struct mdd_device *mdd, int *dto_credits)
111 for (op = 0; op < DTO_NR; op++) {
112 credits = mdd_child_ops(mdd)->dt_credit_get(env, mdd->mdd_child,
114 LASSERT(credits > 0);
115 dto_txn_credits[op] = credits;
119 int mdd_txn_init_credits(const struct lu_env *env, struct mdd_device *mdd)
123 /* Init credits for each ops. */
124 mdd_txn_init_dto_credits(env, mdd, dto_txn_credits);
126 /* Calculate the mdd credits. */
127 for (op = MDD_TXN_OBJECT_DESTROY_OP; op < MDD_TXN_LAST_OP; op++) {
128 int *c = &mdd->mdd_tod[op].mod_credits;
129 int *dt = dto_txn_credits;
130 mdd->mdd_tod[op].mod_op = op;
132 case MDD_TXN_OBJECT_DESTROY_OP:
133 *c = dt[DTO_OBJECT_DELETE];
135 case MDD_TXN_OBJECT_CREATE_OP:
136 /* OI_INSERT + CREATE OBJECT */
137 *c = dt[DTO_INDEX_INSERT] +
138 dt[DTO_OBJECT_CREATE];
140 case MDD_TXN_ATTR_SET_OP:
141 /* ATTR set + XATTR(lsm, lmv) set */
142 *c = dt[DTO_ATTR_SET] + dt[DTO_XATTR_SET];
144 case MDD_TXN_XATTR_SET_OP:
145 *c = dt[DTO_XATTR_SET];
147 case MDD_TXN_INDEX_INSERT_OP:
148 *c = dt[DTO_INDEX_INSERT];
150 case MDD_TXN_INDEX_DELETE_OP:
151 *c = dt[DTO_INDEX_DELETE];
153 case MDD_TXN_LINK_OP:
154 *c = dt[DTO_INDEX_INSERT];
156 case MDD_TXN_UNLINK_OP:
157 /* delete index + Unlink log */
158 *c = dt[DTO_INDEX_DELETE];
160 case MDD_TXN_RENAME_OP:
161 /* 2 delete index + 1 insert + Unlink log */
162 *c = 2 * dt[DTO_INDEX_DELETE] +
163 dt[DTO_INDEX_INSERT];
165 case MDD_TXN_RENAME_TGT_OP:
166 /* index insert + index delete */
167 *c = dt[DTO_INDEX_DELETE] +
168 dt[DTO_INDEX_INSERT];
170 case MDD_TXN_CREATE_DATA_OP:
171 /* same as set xattr(lsm) */
172 *c = dt[DTO_XATTR_SET];
174 case MDD_TXN_MKDIR_OP:
175 /* INDEX INSERT + OI INSERT +
176 * CREATE_OBJECT_CREDITS
177 * SET_MD CREDITS is already counted in
178 * CREATE_OBJECT CREDITS
180 *c = 2 * dt[DTO_INDEX_INSERT] +
181 dt[DTO_OBJECT_CREATE];
184 CERROR("Invalid op %d init its credit\n", op);
191 struct thandle* mdd_trans_start(const struct lu_env *env,
192 struct mdd_device *mdd)
194 struct txn_param *p = &mdd_env_info(env)->mti_param;
197 th = mdd_child_ops(mdd)->dt_trans_start(env, mdd->mdd_child, p);
201 void mdd_trans_stop(const struct lu_env *env, struct mdd_device *mdd,
202 int result, struct thandle *handle)
204 handle->th_result = result;
205 mdd_child_ops(mdd)->dt_trans_stop(env, handle);