1 /* -*- MODE: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
8 * Copyright (C) 2006 Cluster File Systems, Inc.
9 * Author: Mike Pershin <tappro@clusterfs.com>
11 * This file is part of the Lustre file system, http://www.lustre.org
12 * Lustre is a trademark of Cluster File Systems, Inc.
14 * You may have signed or agreed to another license before downloading
15 * this software. If so, you are bound by the terms and conditions
16 * of that agreement, and the following does not apply to you. See the
17 * LICENSE file included with this distribution for more information.
19 * If you did not agree to a different license, then this copy of Lustre
20 * is open source software; you can redistribute it and/or modify it
21 * under the terms of version 2 of the GNU General Public License as
22 * published by the Free Software Foundation.
24 * In either case, Lustre is distributed in the hope that it will be
25 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
26 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * license text for more details.
30 # define EXPORT_SYMTAB
32 #define DEBUG_SUBSYSTEM S_MDS
35 #include <obd_class.h>
36 #include <lustre_ver.h>
37 #include <obd_support.h>
38 #include <lustre_fid.h>
39 #include "mdd_internal.h"
41 const char orph_index_name[] = "orphans";
43 static const struct dt_index_features orph_index_features = {
44 .dif_flags = DT_IND_UPDATE,
45 .dif_keysize_min = sizeof(struct orph_key),
46 .dif_keysize_max = sizeof(struct orph_key),
47 .dif_recsize_min = sizeof(loff_t),
48 .dif_recsize_max = sizeof(loff_t)
56 static struct orph_key *orph_key_fill(const struct lu_env *env,
57 const struct lu_fid *lf, __u32 op)
59 struct orph_key *key = &mdd_env_info(env)->mti_orph_key;
61 fid_cpu_to_be(&key->ok_fid, lf);
62 key->ok_op = cpu_to_be32(op);
66 static int orph_index_insert(const struct lu_env *env,
67 struct mdd_object *obj, __u32 op,
68 loff_t *offset, struct thandle *th)
70 struct mdd_device *mdd = mdo2mdd(&obj->mod_obj);
71 struct dt_object *dor = mdd->mdd_orphans;
72 struct orph_key *key = orph_key_fill(env, mdo2fid(obj), op);
76 rc = dor->do_index_ops->dio_insert(env, dor, (struct dt_rec *)offset,
77 (struct dt_key *)key, th,
82 static int orph_index_delete(const struct lu_env *env,
83 struct mdd_object *obj, __u32 op,
86 struct mdd_device *mdd = mdo2mdd(&obj->mod_obj);
87 struct dt_object *dor = mdd->mdd_orphans;
88 struct orph_key *key = orph_key_fill(env, mdo2fid(obj), op);
92 rc = dor->do_index_ops->dio_delete(env, dor,
93 (struct dt_key *)key, th,
99 static inline struct orph_key *orph_key_empty(const struct lu_env *env,
102 struct orph_key *key = &mdd_env_info(env)->mti_orph_key;
104 fid_zero(&key->ok_fid);
105 key->ok_op = cpu_to_be32(op);
109 static void orph_key_test_and_del(const struct lu_env *env,
110 struct mdd_device *mdd,
111 const struct orph_key *key)
113 struct mdd_object *mdo;
115 mdo = mdd_object_find(env, mdd, &key->ok_fid);
117 CERROR("Invalid orphan!\n");
119 mdd_write_lock(env, mdo);
120 if (mdo->mod_count == 0) {
121 /* non-opened orphan, let's delete it */
122 struct md_attr *ma = &mdd_env_info(env)->mti_ma;
123 CWARN("Found orphan!\n");
124 mdd_object_kill(env, mdo, ma);
125 /* TODO: now handle OST objects */
126 //mdd_ost_objects_destroy(env, ma);
127 /* TODO: destroy index entry */
129 mdd_write_unlock(env, mdo);
130 mdd_object_put(env, mdo);
134 static int orph_index_iterate(const struct lu_env *env,
135 struct mdd_device *mdd)
137 struct dt_object *dt_obj = mdd->mdd_orphans;
139 struct dt_it_ops *iops;
140 struct orph_key *key = orph_key_empty(env, 0);
144 iops = &dt_obj->do_index_ops->dio_it;
145 it = iops->init(env, dt_obj, 1, BYPASS_CAPA);
147 result = iops->get(env, it, (const void *)key);
151 for (result = 0, i = 0; result == +1; ++i) {
152 key = (void *)iops->key(env, it);
153 fid_be_to_cpu(&key->ok_fid, &key->ok_fid);
154 orph_key_test_and_del(env, mdd, key);
155 result = iops->next(env, it);
157 } else if (result == 0)
158 /* Index contains no zero key? */
169 int orph_index_init(const struct lu_env *env, struct mdd_device *mdd)
176 d = dt_store_open(env, mdd->mdd_child, orph_index_name, &fid);
178 mdd->mdd_orphans = d;
179 rc = d->do_ops->do_index_try(env, d, &orph_index_features);
181 LASSERT(d->do_index_ops != NULL);
183 CERROR("\"%s\" is not an index!\n", orph_index_name);
185 CERROR("cannot find \"%s\" obj %d\n",
186 orph_index_name, (int)PTR_ERR(d));
193 void orph_index_fini(const struct lu_env *env, struct mdd_device *mdd)
196 if (mdd->mdd_orphans != NULL) {
197 lu_object_put(env, &mdd->mdd_orphans->do_lu);
198 mdd->mdd_orphans = NULL;
203 int __mdd_orphan_cleanup(const struct lu_env *env, struct mdd_device *d)
205 return orph_index_iterate(env, d);
208 int __mdd_orphan_add(const struct lu_env *env,
209 struct mdd_object *obj, struct thandle *th)
212 return orph_index_insert(env, obj, ORPH_OP_UNLINK, &offset, th);
215 int __mdd_orphan_del(const struct lu_env *env,
216 struct mdd_object *obj, struct thandle *th)
218 return orph_index_delete(env, obj, ORPH_OP_UNLINK, th);
222 * used when destroying orphanes and from mds_reint_unlink() when MDS wants to
223 * destroy objects on OSS.
226 int mdd_objects_destroy(struct mds_obd *mds, struct inode *inode,
227 struct lov_mds_md *lmm, int lmm_size,
228 struct llog_cookie *logcookies,
229 int log_unlink, int async)
231 struct lov_stripe_md *lsm = NULL;
232 struct obd_trans_info oti = { 0 };
240 rc = obd_unpackmd(mds->mds_dt_exp, &lsm, lmm, lmm_size);
242 CERROR("Error unpack md %p\n", lmm);
245 LASSERT(rc >= sizeof(*lsm));
249 oa = obdo_alloc(); // XXX use mdd_thread_info.mti_oa instead.
251 GOTO(out_free_memmd, rc = -ENOMEM);
252 oa->o_id = lsm->lsm_object_id;
253 oa->o_gr = FILTER_GROUP_MDS0 + mds->mds_num;
254 oa->o_mode = inode->i_mode & S_IFMT;
255 oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLGROUP;
257 if (log_unlink && logcookies) {
258 oa->o_valid |= OBD_MD_FLCOOKIE;
259 oti.oti_logcookies = logcookies;
262 CDEBUG(D_INODE, "destroy OSS object %d/%d\n",
263 (int)oa->o_id, (int)oa->o_gr);
266 oti.oti_flags |= OBD_MODE_ASYNC;
268 rc = obd_destroy(mds->mds_dt_exp, oa, lsm, &oti);
271 obd_free_memmd(mds->mds_dt_exp, &lsm);