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/obdclass/md_local_object.c
38 * Lustre Local Object create APIs
39 * 'create on first mount' facility. Files registed under llo module will
40 * be created on first mount.
42 * Author: Pravin Shelar <pravin.shelar@sun.com>
45 #define DEBUG_SUBSYSTEM S_CLASS
47 # define EXPORT_SYMTAB
50 #include <obd_support.h>
51 #include <lustre_disk.h>
52 #include <lustre_fid.h>
53 #include <lu_object.h>
54 #include <libcfs/list.h>
55 #include <md_object.h>
58 /** List head to hold list of objects to be created. */
59 static cfs_list_t llo_lobj_list;
61 /** Lock to protect list manipulations */
62 static cfs_mutex_t llo_lock;
65 * Structure used to maintain state of path parsing.
66 * \see llo_find_entry, llo_store_resolve
68 struct llo_find_hint {
69 struct lu_fid *lfh_cfid;
70 struct md_device *lfh_md;
71 struct md_object *lfh_pobj;
75 * Thread Local storage for this module.
77 struct llo_thread_info {
78 /** buffer to resolve path */
79 char lti_buf[DT_MAX_PATH];
80 /** used for path resolve */
81 struct lu_fid lti_fid;
82 /** used to pass child object fid */
83 struct lu_fid lti_cfid;
84 struct llo_find_hint lti_lfh;
85 struct md_op_spec lti_spc;
86 struct md_attr lti_ma;
87 struct lu_name lti_lname;
90 LU_KEY_INIT(llod_global, struct llo_thread_info);
91 LU_KEY_FINI(llod_global, struct llo_thread_info);
93 static struct lu_context_key llod_key = {
94 .lct_tags = LCT_MD_THREAD | LCT_DT_THREAD,
95 .lct_init = llod_global_key_init,
96 .lct_fini = llod_global_key_fini
99 static inline struct llo_thread_info * llo_env_info(const struct lu_env *env)
101 return lu_context_key_get(&env->le_ctx, &llod_key);
105 * Search md object for given fid.
107 static struct md_object *llo_locate(const struct lu_env *env,
108 struct md_device *md,
109 const struct lu_fid *fid)
111 struct lu_object *obj;
112 struct md_object *mdo;
114 obj = lu_object_find(env, &md->md_lu_dev, fid, NULL);
116 obj = lu_object_locate(obj->lo_header, md->md_lu_dev.ld_type);
117 LASSERT(obj != NULL);
118 mdo = (struct md_object *) obj;
120 mdo = (struct md_object *)obj;
125 * Lookup FID for object named \a name in directory \a pobj.
127 static int llo_lookup(const struct lu_env *env,
128 struct md_object *pobj,
132 struct llo_thread_info *info = llo_env_info(env);
133 struct lu_name *lname = &info->lti_lname;
134 struct md_op_spec *spec = &info->lti_spc;
136 spec->sp_feat = NULL;
137 spec->sp_cr_flags = 0;
138 spec->sp_cr_lookup = 0;
139 spec->sp_cr_mode = 0;
140 spec->sp_ck_split = 0;
142 lname->ln_name = name;
143 lname->ln_namelen = strlen(name);
145 return mdo_lookup(env, pobj, lname, fid, spec);
149 * Function to look up path component, this is passed to parsing
150 * function. \see llo_store_resolve
152 * \retval rc returns error code for lookup or locate operation
154 * pointer to object is returned in data (lfh->lfh_pobj)
156 static int llo_find_entry(const struct lu_env *env,
157 const char *name, void *data)
159 struct llo_find_hint *lfh = data;
160 struct md_device *md = lfh->lfh_md;
161 struct lu_fid *fid = lfh->lfh_cfid;
162 struct md_object *obj = lfh->lfh_pobj;
165 /* lookup fid for object */
166 result = llo_lookup(env, obj, name, fid);
167 lu_object_put(env, &obj->mo_lu);
170 /* get md object for fid that we got in lookup */
171 obj = llo_locate(env, md, fid);
173 result = PTR_ERR(obj);
180 static struct md_object *llo_reg_open(const struct lu_env *env,
181 struct md_device *md,
189 result = llo_lookup(env, p, name, fid);
191 o = llo_locate(env, md, fid);
199 * Resolve given \a path, on success function returns
200 * md object for last directory and \a fid points to
203 struct md_object *llo_store_resolve(const struct lu_env *env,
204 struct md_device *md,
205 struct dt_device *dt,
209 struct llo_thread_info *info = llo_env_info(env);
210 struct llo_find_hint *lfh = &info->lti_lfh;
211 char *local = info->lti_buf;
212 struct md_object *obj;
215 strncpy(local, path, DT_MAX_PATH);
216 local[DT_MAX_PATH - 1] = '\0';
220 /* start path resolution from backend fs root. */
221 result = dt->dd_ops->dt_root_get(env, dt, fid);
223 /* get md object for root */
224 obj = llo_locate(env, md, fid);
226 /* start path parser from root md */
228 result = dt_path_parser(env, local, llo_find_entry, lfh);
230 obj = ERR_PTR(result);
235 obj = ERR_PTR(result);
239 EXPORT_SYMBOL(llo_store_resolve);
242 * Returns md object for \a objname in given \a dirname.
244 struct md_object *llo_store_open(const struct lu_env *env,
245 struct md_device *md,
246 struct dt_device *dt,
251 struct md_object *obj;
252 struct md_object *dir;
254 /* search md object for parent dir */
255 dir = llo_store_resolve(env, md, dt, dirname, fid);
257 obj = llo_reg_open(env, md, dir, objname, fid);
258 lu_object_put(env, &dir->mo_lu);
264 EXPORT_SYMBOL(llo_store_open);
266 static struct md_object *llo_create_obj(const struct lu_env *env,
267 struct md_device *md,
268 struct md_object *dir,
270 const struct lu_fid *fid,
271 const struct dt_index_features *feat)
273 struct llo_thread_info *info = llo_env_info(env);
274 struct md_object *mdo;
275 struct md_attr *ma = &info->lti_ma;
276 struct md_op_spec *spec = &info->lti_spc;
277 struct lu_name *lname = &info->lti_lname;
278 struct lu_attr *la = &ma->ma_attr;
281 mdo = llo_locate(env, md, fid);
285 lname->ln_name = objname;
286 lname->ln_namelen = strlen(objname);
288 spec->sp_feat = feat;
289 spec->sp_cr_flags = 0;
290 spec->sp_cr_lookup = 1;
291 spec->sp_cr_mode = 0;
292 spec->sp_ck_split = 0;
294 if (feat == &dt_directory_features)
295 la->la_mode = S_IFDIR | S_IXUGO;
297 la->la_mode = S_IFREG;
299 la->la_mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
300 la->la_uid = la->la_gid = 0;
301 la->la_valid = LA_MODE | LA_UID | LA_GID;
306 rc = mdo_create(env, dir, lname, mdo, spec, ma);
309 lu_object_put(env, &mdo->mo_lu);
317 * Create md object, object could be diretcory or
318 * special index defined by \a feat in \a directory.
321 * \param dirname parent directory
322 * \param objname file name
323 * \param fid object fid
324 * \param feat index features required for directory create
327 struct md_object *llo_store_create_index(const struct lu_env *env,
328 struct md_device *md,
329 struct dt_device *dt,
332 const struct lu_fid *fid,
333 const struct dt_index_features *feat)
335 struct llo_thread_info *info = llo_env_info(env);
336 struct md_object *obj;
337 struct md_object *dir;
338 struct lu_fid *ignore = &info->lti_fid;
340 dir = llo_store_resolve(env, md, dt, dirname, ignore);
342 obj = llo_create_obj(env, md, dir, objname, fid, feat);
343 lu_object_put(env, &dir->mo_lu);
350 EXPORT_SYMBOL(llo_store_create_index);
353 * Create md object for regular file in \a directory.
356 * \param dirname parent directory
357 * \param objname file name
358 * \param fid object fid.
361 struct md_object *llo_store_create(const struct lu_env *env,
362 struct md_device *md,
363 struct dt_device *dt,
366 const struct lu_fid *fid)
368 return llo_store_create_index(env, md, dt, dirname,
372 EXPORT_SYMBOL(llo_store_create);
375 * Register object for 'create on first mount' facility.
376 * objects are created in order of registration.
379 void llo_local_obj_register(struct lu_local_obj_desc *llod)
381 cfs_mutex_lock(&llo_lock);
382 cfs_list_add_tail(&llod->llod_linkage, &llo_lobj_list);
383 cfs_mutex_unlock(&llo_lock);
386 EXPORT_SYMBOL(llo_local_obj_register);
388 void llo_local_obj_unregister(struct lu_local_obj_desc *llod)
390 cfs_mutex_lock(&llo_lock);
391 cfs_list_del(&llod->llod_linkage);
392 cfs_mutex_unlock(&llo_lock);
395 EXPORT_SYMBOL(llo_local_obj_unregister);
398 * Created registed objects.
401 int llo_local_objects_setup(const struct lu_env *env,
402 struct md_device * md,
403 struct dt_device *dt)
405 struct llo_thread_info *info = llo_env_info(env);
407 struct lu_local_obj_desc *scan;
408 struct md_object *mdo;
412 fid = &info->lti_cfid;
413 cfs_mutex_lock(&llo_lock);
415 cfs_list_for_each_entry(scan, &llo_lobj_list, llod_linkage) {
416 lu_local_obj_fid(fid, scan->llod_oid);
419 dir = scan->llod_dir;
421 if (scan->llod_is_index)
422 mdo = llo_store_create_index(env, md, dt ,
423 dir, scan->llod_name,
427 mdo = llo_store_create(env, md, dt,
428 dir, scan->llod_name,
430 if (IS_ERR(mdo) && PTR_ERR(mdo) != -EEXIST) {
432 CERROR("creating obj [%s] fid = "DFID" rc = %d\n",
433 scan->llod_name, PFID(fid), rc);
438 lu_object_put(env, &mdo->mo_lu);
442 cfs_mutex_unlock(&llo_lock);
446 EXPORT_SYMBOL(llo_local_objects_setup);
448 int llo_global_init(void)
452 CFS_INIT_LIST_HEAD(&llo_lobj_list);
453 cfs_mutex_init(&llo_lock);
455 LU_CONTEXT_KEY_INIT(&llod_key);
456 result = lu_context_key_register(&llod_key);
460 void llo_global_fini(void)
462 lu_context_key_degister(&llod_key);
463 LASSERT(cfs_list_empty(&llo_lobj_list));