1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/mdd/mdd_orphans.c
38 * Orphan handling code
40 * Author: Mike Pershin <tappro@clusterfs.com>
44 # define EXPORT_SYMTAB
46 #define DEBUG_SUBSYSTEM S_MDS
49 #include <obd_class.h>
50 #include <lustre_ver.h>
51 #include <obd_support.h>
52 #include <lustre_fid.h>
53 #include "mdd_internal.h"
55 const char orph_index_name[] = "orphans";
57 static const struct dt_index_features orph_index_features = {
58 .dif_flags = DT_IND_UPDATE,
59 .dif_keysize_min = sizeof(struct orph_key),
60 .dif_keysize_max = sizeof(struct orph_key),
61 .dif_recsize_min = sizeof(loff_t),
62 .dif_recsize_max = sizeof(loff_t)
70 static struct orph_key *orph_key_fill(const struct lu_env *env,
71 const struct lu_fid *lf, __u32 op)
73 struct orph_key *key = &mdd_env_info(env)->mti_orph_key;
75 fid_cpu_to_be(&key->ok_fid, lf);
76 key->ok_op = cpu_to_be32(op);
80 static int orph_index_insert(const struct lu_env *env,
81 struct mdd_object *obj, __u32 op,
82 loff_t *offset, struct thandle *th)
84 struct mdd_device *mdd = mdo2mdd(&obj->mod_obj);
85 struct dt_object *dor = mdd->mdd_orphans;
86 struct orph_key *key = orph_key_fill(env, mdo2fid(obj), op);
90 rc = dor->do_index_ops->dio_insert(env, dor, (struct dt_rec *)offset,
91 (struct dt_key *)key, th,
96 static int orph_index_delete(const struct lu_env *env,
97 struct mdd_object *obj, __u32 op,
100 struct mdd_device *mdd = mdo2mdd(&obj->mod_obj);
101 struct dt_object *dor = mdd->mdd_orphans;
102 struct orph_key *key = orph_key_fill(env, mdo2fid(obj), op);
106 rc = dor->do_index_ops->dio_delete(env, dor,
107 (struct dt_key *)key, th,
113 static inline struct orph_key *orph_key_empty(const struct lu_env *env,
116 struct orph_key *key = &mdd_env_info(env)->mti_orph_key;
118 fid_zero(&key->ok_fid);
119 key->ok_op = cpu_to_be32(op);
123 static void orph_key_test_and_del(const struct lu_env *env,
124 struct mdd_device *mdd,
125 const struct orph_key *key)
127 struct mdd_object *mdo;
129 mdo = mdd_object_find(env, mdd, &key->ok_fid);
131 CERROR("Invalid orphan!\n");
133 mdd_write_lock(env, mdo);
134 if (mdo->mod_count == 0) {
135 /* non-opened orphan, let's delete it */
136 struct md_attr *ma = &mdd_env_info(env)->mti_ma;
137 CWARN("Found orphan!\n");
138 mdd_object_kill(env, mdo, ma);
139 /* TODO: now handle OST objects */
140 //mdd_ost_objects_destroy(env, ma);
141 /* TODO: destroy index entry */
143 mdd_write_unlock(env, mdo);
144 mdd_object_put(env, mdo);
148 static int orph_index_iterate(const struct lu_env *env,
149 struct mdd_device *mdd)
151 struct dt_object *dt_obj = mdd->mdd_orphans;
153 struct dt_it_ops *iops;
154 struct orph_key *key = orph_key_empty(env, 0);
158 iops = &dt_obj->do_index_ops->dio_it;
159 it = iops->init(env, dt_obj, 1, BYPASS_CAPA);
161 result = iops->get(env, it, (const void *)key);
165 for (result = 0, i = 0; result == +1; ++i) {
166 key = (void *)iops->key(env, it);
167 fid_be_to_cpu(&key->ok_fid, &key->ok_fid);
168 orph_key_test_and_del(env, mdd, key);
169 result = iops->next(env, it);
171 } else if (result == 0)
172 /* Index contains no zero key? */
183 int orph_index_init(const struct lu_env *env, struct mdd_device *mdd)
190 d = dt_store_open(env, mdd->mdd_child, orph_index_name, &fid);
192 mdd->mdd_orphans = d;
193 rc = d->do_ops->do_index_try(env, d, &orph_index_features);
195 LASSERT(d->do_index_ops != NULL);
197 CERROR("\"%s\" is not an index!\n", orph_index_name);
199 CERROR("cannot find \"%s\" obj %d\n",
200 orph_index_name, (int)PTR_ERR(d));
207 void orph_index_fini(const struct lu_env *env, struct mdd_device *mdd)
210 if (mdd->mdd_orphans != NULL) {
211 lu_object_put(env, &mdd->mdd_orphans->do_lu);
212 mdd->mdd_orphans = NULL;
217 int __mdd_orphan_cleanup(const struct lu_env *env, struct mdd_device *d)
219 return orph_index_iterate(env, d);
222 int __mdd_orphan_add(const struct lu_env *env,
223 struct mdd_object *obj, struct thandle *th)
226 return orph_index_insert(env, obj, ORPH_OP_UNLINK, &offset, th);
229 int __mdd_orphan_del(const struct lu_env *env,
230 struct mdd_object *obj, struct thandle *th)
232 return orph_index_delete(env, obj, ORPH_OP_UNLINK, th);