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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
31 * This file is part of Lustre, http://www.lustre.org/
32 * Lustre is a trademark of Sun Microsystems, Inc.
34 * lustre/obdclass/md_local_object.c
36 * Lustre Local Object create APIs
37 * 'create on first mount' facility. Files registed under llo module will
38 * be created on first mount.
40 * Author: Pravin Shelar <pravin.shelar@sun.com>
43 #define DEBUG_SUBSYSTEM S_CLASS
45 # define EXPORT_SYMTAB
48 #include <obd_support.h>
49 #include <lustre_disk.h>
50 #include <lustre_fid.h>
51 #include <lu_object.h>
52 #include <libcfs/list.h>
53 #include <md_object.h>
56 /** List head to hold list of objects to be created. */
57 static cfs_list_t llo_lobj_list;
59 /** Lock to protect list manipulations */
60 static cfs_mutex_t llo_lock;
63 * Structure used to maintain state of path parsing.
64 * \see llo_find_entry, llo_store_resolve
66 struct llo_find_hint {
67 struct lu_fid *lfh_cfid;
68 struct md_device *lfh_md;
69 struct md_object *lfh_pobj;
73 * Thread Local storage for this module.
75 struct llo_thread_info {
76 /** buffer to resolve path */
77 char lti_buf[DT_MAX_PATH];
78 /** used for path resolve */
79 struct lu_fid lti_fid;
80 /** used to pass child object fid */
81 struct lu_fid lti_cfid;
82 struct llo_find_hint lti_lfh;
83 struct md_op_spec lti_spc;
84 struct md_attr lti_ma;
85 struct lu_name lti_lname;
88 LU_KEY_INIT(llod_global, struct llo_thread_info);
89 LU_KEY_FINI(llod_global, struct llo_thread_info);
91 static struct lu_context_key llod_key = {
92 .lct_tags = LCT_MD_THREAD,
93 .lct_init = llod_global_key_init,
94 .lct_fini = llod_global_key_fini
97 static inline struct llo_thread_info * llo_env_info(const struct lu_env *env)
99 return lu_context_key_get(&env->le_ctx, &llod_key);
103 * Search md object for given fid.
105 static struct md_object *llo_locate(const struct lu_env *env,
106 struct md_device *md,
107 const struct lu_fid *fid)
109 struct lu_object *obj;
110 struct md_object *mdo;
112 obj = lu_object_find(env, &md->md_lu_dev, fid, NULL);
114 obj = lu_object_locate(obj->lo_header, md->md_lu_dev.ld_type);
115 LASSERT(obj != NULL);
116 mdo = (struct md_object *) obj;
118 mdo = (struct md_object *)obj;
123 * Lookup FID for object named \a name in directory \a pobj.
125 static int llo_lookup(const struct lu_env *env,
126 struct md_object *pobj,
130 struct llo_thread_info *info = llo_env_info(env);
131 struct lu_name *lname = &info->lti_lname;
132 struct md_op_spec *spec = &info->lti_spc;
134 spec->sp_feat = NULL;
135 spec->sp_cr_flags = 0;
136 spec->sp_cr_lookup = 0;
137 spec->sp_cr_mode = 0;
138 spec->sp_ck_split = 0;
140 lname->ln_name = name;
141 lname->ln_namelen = strlen(name);
143 return mdo_lookup(env, pobj, lname, fid, spec);
147 * Function to look up path component, this is passed to parsing
148 * function. \see llo_store_resolve
150 * \retval rc returns error code for lookup or locate operation
152 * pointer to object is returned in data (lfh->lfh_pobj)
154 static int llo_find_entry(const struct lu_env *env,
155 const char *name, void *data)
157 struct llo_find_hint *lfh = data;
158 struct md_device *md = lfh->lfh_md;
159 struct lu_fid *fid = lfh->lfh_cfid;
160 struct md_object *obj = lfh->lfh_pobj;
163 /* lookup fid for object */
164 result = llo_lookup(env, obj, name, fid);
165 lu_object_put(env, &obj->mo_lu);
168 /* get md object for fid that we got in lookup */
169 obj = llo_locate(env, md, fid);
171 result = PTR_ERR(obj);
178 static struct md_object *llo_reg_open(const struct lu_env *env,
179 struct md_device *md,
187 result = llo_lookup(env, p, name, fid);
189 o = llo_locate(env, md, fid);
197 * Resolve given \a path, on success function returns
198 * md object for last directory and \a fid points to
201 struct md_object *llo_store_resolve(const struct lu_env *env,
202 struct md_device *md,
203 struct dt_device *dt,
207 struct llo_thread_info *info = llo_env_info(env);
208 struct llo_find_hint *lfh = &info->lti_lfh;
209 char *local = info->lti_buf;
210 struct md_object *obj;
213 strncpy(local, path, DT_MAX_PATH);
214 local[DT_MAX_PATH - 1] = '\0';
218 /* start path resolution from backend fs root. */
219 result = dt->dd_ops->dt_root_get(env, dt, fid);
221 /* get md object for root */
222 obj = llo_locate(env, md, fid);
224 /* start path parser from root md */
226 result = dt_path_parser(env, local, llo_find_entry, lfh);
228 obj = ERR_PTR(result);
233 obj = ERR_PTR(result);
237 EXPORT_SYMBOL(llo_store_resolve);
240 * Returns md object for \a objname in given \a dirname.
242 struct md_object *llo_store_open(const struct lu_env *env,
243 struct md_device *md,
244 struct dt_device *dt,
249 struct md_object *obj;
250 struct md_object *dir;
252 /* search md object for parent dir */
253 dir = llo_store_resolve(env, md, dt, dirname, fid);
255 obj = llo_reg_open(env, md, dir, objname, fid);
256 lu_object_put(env, &dir->mo_lu);
262 EXPORT_SYMBOL(llo_store_open);
264 static struct md_object *llo_create_obj(const struct lu_env *env,
265 struct md_device *md,
266 struct md_object *dir,
268 const struct lu_fid *fid,
269 const struct dt_index_features *feat)
271 struct llo_thread_info *info = llo_env_info(env);
272 struct md_object *mdo;
273 struct md_attr *ma = &info->lti_ma;
274 struct md_op_spec *spec = &info->lti_spc;
275 struct lu_name *lname = &info->lti_lname;
276 struct lu_attr *la = &ma->ma_attr;
279 mdo = llo_locate(env, md, fid);
283 lname->ln_name = objname;
284 lname->ln_namelen = strlen(objname);
286 spec->sp_feat = feat;
287 spec->sp_cr_flags = 0;
288 spec->sp_cr_lookup = 1;
289 spec->sp_cr_mode = 0;
290 spec->sp_ck_split = 0;
292 if (feat == &dt_directory_features)
293 la->la_mode = S_IFDIR | S_IXUGO;
295 la->la_mode = S_IFREG;
297 la->la_mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
298 la->la_uid = la->la_gid = 0;
299 la->la_valid = LA_MODE | LA_UID | LA_GID;
304 rc = mdo_create(env, dir, lname, mdo, spec, ma);
307 lu_object_put(env, &mdo->mo_lu);
315 * Create md object, object could be diretcory or
316 * special index defined by \a feat in \a directory.
319 * \param dirname parent directory
320 * \param objname file name
321 * \param fid object fid
322 * \param feat index features required for directory create
325 struct md_object *llo_store_create_index(const struct lu_env *env,
326 struct md_device *md,
327 struct dt_device *dt,
330 const struct lu_fid *fid,
331 const struct dt_index_features *feat)
333 struct llo_thread_info *info = llo_env_info(env);
334 struct md_object *obj;
335 struct md_object *dir;
336 struct lu_fid *ignore = &info->lti_fid;
338 dir = llo_store_resolve(env, md, dt, dirname, ignore);
340 obj = llo_create_obj(env, md, dir, objname, fid, feat);
341 lu_object_put(env, &dir->mo_lu);
348 EXPORT_SYMBOL(llo_store_create_index);
351 * Create md object for regular file in \a directory.
354 * \param dirname parent directory
355 * \param objname file name
356 * \param fid object fid.
359 struct md_object *llo_store_create(const struct lu_env *env,
360 struct md_device *md,
361 struct dt_device *dt,
364 const struct lu_fid *fid)
366 return llo_store_create_index(env, md, dt, dirname,
370 EXPORT_SYMBOL(llo_store_create);
373 * Register object for 'create on first mount' facility.
374 * objects are created in order of registration.
377 void llo_local_obj_register(struct lu_local_obj_desc *llod)
379 cfs_mutex_lock(&llo_lock);
380 cfs_list_add_tail(&llod->llod_linkage, &llo_lobj_list);
381 cfs_mutex_unlock(&llo_lock);
384 EXPORT_SYMBOL(llo_local_obj_register);
386 void llo_local_obj_unregister(struct lu_local_obj_desc *llod)
388 cfs_mutex_lock(&llo_lock);
389 cfs_list_del(&llod->llod_linkage);
390 cfs_mutex_unlock(&llo_lock);
393 EXPORT_SYMBOL(llo_local_obj_unregister);
396 * Created registed objects.
399 int llo_local_objects_setup(const struct lu_env *env,
400 struct md_device * md,
401 struct dt_device *dt)
403 struct llo_thread_info *info = llo_env_info(env);
405 struct lu_local_obj_desc *scan;
406 struct md_object *mdo;
410 fid = &info->lti_cfid;
411 cfs_mutex_lock(&llo_lock);
413 cfs_list_for_each_entry(scan, &llo_lobj_list, llod_linkage) {
414 lu_local_obj_fid(fid, scan->llod_oid);
417 dir = scan->llod_dir;
419 if (scan->llod_is_index)
420 mdo = llo_store_create_index(env, md, dt ,
421 dir, scan->llod_name,
425 mdo = llo_store_create(env, md, dt,
426 dir, scan->llod_name,
428 if (IS_ERR(mdo) && PTR_ERR(mdo) != -EEXIST) {
430 CERROR("creating obj [%s] fid = "DFID" rc = %d\n",
431 scan->llod_name, PFID(fid), rc);
436 lu_object_put(env, &mdo->mo_lu);
440 cfs_mutex_unlock(&llo_lock);
444 EXPORT_SYMBOL(llo_local_objects_setup);
446 int llo_global_init(void)
450 CFS_INIT_LIST_HEAD(&llo_lobj_list);
451 cfs_mutex_init(&llo_lock);
453 LU_CONTEXT_KEY_INIT(&llod_key);
454 result = lu_context_key_register(&llod_key);
458 void llo_global_fini(void)
460 lu_context_key_degister(&llod_key);
461 LASSERT(cfs_list_empty(&llo_lobj_list));