4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, Whamcloud, Inc.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
37 #define DEBUG_SUBSYSTEM S_LMV
39 #include <linux/slab.h>
40 #include <linux/module.h>
41 #include <linux/init.h>
42 #include <linux/slab.h>
43 #include <linux/pagemap.h>
44 #include <asm/div64.h>
45 #include <linux/seq_file.h>
47 #include <liblustre.h>
50 #include <obd_support.h>
51 #include <lustre/lustre_idl.h>
52 #include <lustre_lib.h>
53 #include <lustre_net.h>
54 #include <lustre_dlm.h>
55 #include <obd_class.h>
56 #include <lprocfs_status.h>
57 #include "lmv_internal.h"
59 extern cfs_mem_cache_t *lmv_object_cache;
60 extern cfs_atomic_t lmv_object_count;
62 static CFS_LIST_HEAD(obj_list);
63 static DEFINE_SPINLOCK(obj_list_lock);
65 struct lmv_object *lmv_object_alloc(struct obd_device *obd,
66 const struct lu_fid *fid,
67 struct lmv_stripe_md *mea)
69 struct lmv_obd *lmv = &obd->u.lmv;
70 unsigned int obj_size;
71 struct lmv_object *obj;
74 LASSERT(mea->mea_magic == MEA_MAGIC_LAST_CHAR
75 || mea->mea_magic == MEA_MAGIC_ALL_CHARS
76 || mea->mea_magic == MEA_MAGIC_HASH_SEGMENT);
78 OBD_SLAB_ALLOC_PTR(obj, lmv_object_cache);
82 cfs_atomic_inc(&lmv_object_count);
87 obj->lo_hashtype = mea->mea_magic;
89 mutex_init(&obj->lo_guard);
90 cfs_atomic_set(&obj->lo_count, 0);
91 obj->lo_objcount = mea->mea_count;
93 obj_size = sizeof(struct lmv_stripe) *
94 lmv->desc.ld_tgt_count;
96 OBD_ALLOC_LARGE(obj->lo_stripes, obj_size);
100 CDEBUG(D_INODE, "Allocate object for "DFID"\n",
102 for (i = 0; i < mea->mea_count; i++) {
105 CDEBUG(D_INODE, "Process subobject "DFID"\n",
106 PFID(&mea->mea_ids[i]));
107 obj->lo_stripes[i].ls_fid = mea->mea_ids[i];
108 LASSERT(fid_is_sane(&obj->lo_stripes[i].ls_fid));
111 * Cache slave mds number to use it in all cases it is needed
112 * instead of constant lookup.
114 rc = lmv_fld_lookup(lmv, &obj->lo_stripes[i].ls_fid,
115 &obj->lo_stripes[i].ls_mds);
122 OBD_FREE(obj, sizeof(*obj));
126 void lmv_object_free(struct lmv_object *obj)
128 struct lmv_obd *lmv = &obj->lo_obd->u.lmv;
129 unsigned int obj_size;
131 LASSERT(!cfs_atomic_read(&obj->lo_count));
133 obj_size = sizeof(struct lmv_stripe) *
134 lmv->desc.ld_tgt_count;
136 OBD_FREE_LARGE(obj->lo_stripes, obj_size);
137 OBD_SLAB_FREE(obj, lmv_object_cache, sizeof(*obj));
138 cfs_atomic_dec(&lmv_object_count);
141 static void __lmv_object_add(struct lmv_object *obj)
143 cfs_atomic_inc(&obj->lo_count);
144 cfs_list_add(&obj->lo_list, &obj_list);
147 void lmv_object_add(struct lmv_object *obj)
149 spin_lock(&obj_list_lock);
150 __lmv_object_add(obj);
151 spin_unlock(&obj_list_lock);
154 static void __lmv_object_del(struct lmv_object *obj)
156 cfs_list_del(&obj->lo_list);
157 lmv_object_free(obj);
160 void lmv_object_del(struct lmv_object *obj)
162 spin_lock(&obj_list_lock);
163 __lmv_object_del(obj);
164 spin_unlock(&obj_list_lock);
167 static struct lmv_object *__lmv_object_get(struct lmv_object *obj)
169 LASSERT(obj != NULL);
170 cfs_atomic_inc(&obj->lo_count);
174 struct lmv_object *lmv_object_get(struct lmv_object *obj)
176 spin_lock(&obj_list_lock);
177 __lmv_object_get(obj);
178 spin_unlock(&obj_list_lock);
182 static void __lmv_object_put(struct lmv_object *obj)
186 if (cfs_atomic_dec_and_test(&obj->lo_count)) {
187 CDEBUG(D_INODE, "Last reference to "DFID" - "
188 "destroying\n", PFID(&obj->lo_fid));
189 __lmv_object_del(obj);
193 void lmv_object_put(struct lmv_object *obj)
195 spin_lock(&obj_list_lock);
196 __lmv_object_put(obj);
197 spin_unlock(&obj_list_lock);
200 void lmv_object_put_unlock(struct lmv_object *obj)
202 lmv_object_unlock(obj);
206 static struct lmv_object *__lmv_object_find(struct obd_device *obd, const struct lu_fid *fid)
208 struct lmv_object *obj;
211 cfs_list_for_each(cur, &obj_list) {
212 obj = cfs_list_entry(cur, struct lmv_object, lo_list);
215 * Check if object is in destroying phase. If so - skip
218 if (obj->lo_state & O_FREEING)
222 * We should make sure, that we have found object belong to
223 * passed obd. It is possible that, object manager will have two
224 * objects with the same fid belong to different obds, if client
225 * and mds runs on the same host. May be it is good idea to have
226 * objects list associated with obd.
228 if (obj->lo_obd != obd)
232 * Check if this is what we're looking for.
234 if (lu_fid_eq(&obj->lo_fid, fid))
235 return __lmv_object_get(obj);
241 struct lmv_object *lmv_object_find(struct obd_device *obd,
242 const struct lu_fid *fid)
244 struct lmv_obd *lmv = &obd->u.lmv;
245 struct lmv_object *obj = NULL;
248 /* For single MDT case, lmv_object list is always empty. */
249 if (lmv->desc.ld_tgt_count > 1) {
250 spin_lock(&obj_list_lock);
251 obj = __lmv_object_find(obd, fid);
252 spin_unlock(&obj_list_lock);
258 struct lmv_object *lmv_object_find_lock(struct obd_device *obd,
259 const struct lu_fid *fid)
261 struct lmv_object *obj;
264 obj = lmv_object_find(obd, fid);
266 lmv_object_lock(obj);
271 static struct lmv_object *__lmv_object_create(struct obd_device *obd,
272 const struct lu_fid *fid,
273 struct lmv_stripe_md *mea)
275 struct lmv_object *new;
276 struct lmv_object *obj;
279 obj = lmv_object_find(obd, fid);
283 new = lmv_object_alloc(obd, fid, mea);
288 * Check if someone created it already while we were dealing with
291 spin_lock(&obj_list_lock);
292 obj = __lmv_object_find(obd, fid);
295 * Someone created it already - put @obj and getting out.
297 spin_unlock(&obj_list_lock);
298 lmv_object_free(new);
302 __lmv_object_add(new);
303 __lmv_object_get(new);
305 spin_unlock(&obj_list_lock);
307 CDEBUG(D_INODE, "New obj in lmv cache: "DFID"\n", PFID(fid));
312 struct lmv_object *lmv_object_create(struct obd_export *exp,
313 const struct lu_fid *fid,
314 struct lmv_stripe_md *mea)
316 struct obd_device *obd = exp->exp_obd;
317 struct lmv_obd *lmv = &obd->u.lmv;
318 struct ptlrpc_request *req = NULL;
319 struct lmv_tgt_desc *tgt;
320 struct lmv_object *obj;
326 CDEBUG(D_INODE, "Get mea for "DFID" and create lmv obj\n",
332 struct md_op_data *op_data;
335 CDEBUG(D_INODE, "Mea isn't passed in, get it now\n");
336 mealen = lmv_get_easize(lmv);
339 * Time to update mea of parent fid.
342 valid = OBD_MD_FLEASIZE | OBD_MD_FLDIREA | OBD_MD_MEA;
344 tgt = lmv_find_target(lmv, fid);
346 GOTO(cleanup, obj = (void *)tgt);
348 OBD_ALLOC_PTR(op_data);
350 GOTO(cleanup, obj = ERR_PTR(-ENOMEM));
352 op_data->op_fid1 = *fid;
353 op_data->op_mode = mealen;
354 op_data->op_valid = valid;
355 rc = md_getattr(tgt->ltd_exp, op_data, &req);
356 OBD_FREE_PTR(op_data);
358 CERROR("md_getattr() failed, error %d\n", rc);
359 GOTO(cleanup, obj = ERR_PTR(rc));
362 rc = md_get_lustre_md(exp, req, NULL, exp, &md);
364 CERROR("md_get_lustre_md() failed, error %d\n", rc);
365 GOTO(cleanup, obj = ERR_PTR(rc));
369 GOTO(cleanup, obj = ERR_PTR(-ENODATA));
375 * Got mea, now create obj for it.
377 obj = __lmv_object_create(obd, fid, mea);
379 CERROR("Can't create new object "DFID"\n",
381 GOTO(cleanup, obj = ERR_PTR(-ENOMEM));
385 obd_free_memmd(exp, (void *)&md.mea);
390 ptlrpc_req_finished(req);
394 int lmv_object_delete(struct obd_export *exp, const struct lu_fid *fid)
396 struct obd_device *obd = exp->exp_obd;
397 struct lmv_object *obj;
401 spin_lock(&obj_list_lock);
402 obj = __lmv_object_find(obd, fid);
404 obj->lo_state |= O_FREEING;
405 __lmv_object_put(obj);
406 __lmv_object_put(obj);
409 spin_unlock(&obj_list_lock);
413 int lmv_object_setup(struct obd_device *obd)
416 LASSERT(obd != NULL);
418 CDEBUG(D_INFO, "LMV object manager setup (%s)\n",
424 void lmv_object_cleanup(struct obd_device *obd)
428 struct lmv_object *obj;
431 CDEBUG(D_INFO, "LMV object manager cleanup (%s)\n",
434 spin_lock(&obj_list_lock);
435 cfs_list_for_each_safe(cur, tmp, &obj_list) {
436 obj = cfs_list_entry(cur, struct lmv_object, lo_list);
438 if (obj->lo_obd != obd)
441 obj->lo_state |= O_FREEING;
442 if (cfs_atomic_read(&obj->lo_count) > 1) {
443 CERROR("Object "DFID" has count (%d)\n",
445 cfs_atomic_read(&obj->lo_count));
447 __lmv_object_put(obj);
449 spin_unlock(&obj_list_lock);