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 struct list_head llo_lobj_list;
61 /** Lock to protect list manipulations */
62 static struct mutex 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 = 1;
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 static int llo_find_entry(const struct lu_env *env,
153 const char *name, void *data)
155 struct llo_find_hint *lfh = data;
156 struct md_device *md = lfh->lfh_md;
157 struct lu_fid *fid = lfh->lfh_cfid;
158 struct md_object *obj = lfh->lfh_pobj;
161 /* lookup fid for object */
162 result = llo_lookup(env, obj, name, fid);
163 lu_object_put(env, &obj->mo_lu);
166 /* get md object for fid that we got in lookup */
167 obj = llo_locate(env, md, fid);
169 result = PTR_ERR(obj);
176 static struct md_object *llo_reg_open(const struct lu_env *env,
177 struct md_device *md,
185 result = llo_lookup(env, p, name, fid);
187 o = llo_locate(env, md, fid);
195 * Resolve given \a path, on success function returns
196 * md object for last directory and \a fid points to
199 struct md_object *llo_store_resolve(const struct lu_env *env,
200 struct md_device *md,
201 struct dt_device *dt,
205 struct llo_thread_info *info = llo_env_info(env);
206 struct llo_find_hint *lfh = &info->lti_lfh;
207 char *local = info->lti_buf;
208 struct md_object *obj = lfh->lfh_pobj;
211 strncpy(local, path, DT_MAX_PATH);
212 local[DT_MAX_PATH - 1] = '\0';
216 /* start path resolution from backend fs root. */
217 result = dt->dd_ops->dt_root_get(env, dt, fid);
219 /* get md object for root */
220 obj = llo_locate(env, md, fid);
222 /* start path parser from root md */
224 result = dt_path_parser(env, local, llo_find_entry, lfh);
226 obj = ERR_PTR(result);
229 obj = ERR_PTR(result);
233 EXPORT_SYMBOL(llo_store_resolve);
236 * Returns md object for \a objname in given \a dirname.
238 struct md_object *llo_store_open(const struct lu_env *env,
239 struct md_device *md,
240 struct dt_device *dt,
245 struct md_object *obj;
246 struct md_object *dir;
248 /* search md object for parent dir */
249 dir = llo_store_resolve(env, md, dt, dirname, fid);
251 obj = llo_reg_open(env, md, dir, objname, fid);
252 lu_object_put(env, &dir->mo_lu);
258 EXPORT_SYMBOL(llo_store_open);
260 static struct md_object *llo_create_obj(const struct lu_env *env,
261 struct md_device *md,
262 struct md_object *dir,
264 const struct lu_fid *fid,
265 const struct dt_index_features *feat)
267 struct llo_thread_info *info = llo_env_info(env);
268 struct md_object *mdo;
269 struct md_attr *ma = &info->lti_ma;
270 struct md_op_spec *spec = &info->lti_spc;
271 struct lu_name *lname = &info->lti_lname;
272 struct lu_attr *la = &ma->ma_attr;
275 mdo = llo_locate(env, md, fid);
279 lname->ln_name = objname;
280 lname->ln_namelen = strlen(objname);
282 spec->sp_feat = feat;
283 spec->sp_cr_flags = 0;
284 spec->sp_cr_lookup = 1;
285 spec->sp_cr_mode = 0;
286 spec->sp_ck_split = 0;
288 if (feat == &dt_directory_features)
289 la->la_mode = S_IFDIR;
291 la->la_mode = S_IFREG;
293 la->la_mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
294 la->la_uid = la->la_gid = 0;
295 la->la_valid = LA_MODE | LA_UID | LA_GID;
300 rc = mdo_create(env, dir, lname, mdo, spec, ma);
303 lu_object_put(env, &mdo->mo_lu);
311 * Create md object, object could be diretcory or
312 * special index defined by \a feat in \a directory.
315 * \param dir parent directory
316 * \param objname file name
317 * \param fid object fid
318 * \param feat index features required for directory create
321 struct md_object *llo_store_create_index(const struct lu_env *env,
322 struct md_device *md,
323 struct dt_device *dt,
326 const struct lu_fid *fid,
327 const struct dt_index_features *feat)
329 struct llo_thread_info *info = llo_env_info(env);
330 struct md_object *obj;
331 struct md_object *dir;
332 struct lu_fid *ignore = &info->lti_fid;
334 dir = llo_store_resolve(env, md, dt, dirname, ignore);
336 obj = llo_create_obj(env, md, dir, objname, fid, feat);
337 lu_object_put(env, &dir->mo_lu);
344 EXPORT_SYMBOL(llo_store_create_index);
347 * Create md object for regular file in \a directory.
350 * \param dir parent directory
351 * \param objname file name
352 * \param fid object fid.
355 struct md_object *llo_store_create(const struct lu_env *env,
356 struct md_device *md,
357 struct dt_device *dt,
360 const struct lu_fid *fid)
362 return llo_store_create_index(env, md, dt, dirname,
366 EXPORT_SYMBOL(llo_store_create);
369 * Register object for 'create on first mount' facility.
372 int llo_local_obj_register(struct lu_local_obj_desc *llod)
374 mutex_lock(&llo_lock);
375 list_add(&llod->llod_linkage, &llo_lobj_list);
376 mutex_unlock(&llo_lock);
381 EXPORT_SYMBOL(llo_local_obj_register);
384 * Created registed objects.
387 int llo_local_objects_setup(const struct lu_env *env,
388 struct md_device * md,
389 struct dt_device *dt)
391 struct llo_thread_info *info = llo_env_info(env);
393 struct lu_local_obj_desc *scan;
394 struct md_object *mdo;
397 fid = &info->lti_cfid;
399 mutex_lock(&llo_lock);
401 list_for_each_entry(scan, &llo_lobj_list, llod_linkage) {
403 lu_local_obj_fid(fid, scan->llod_oid);
405 if (scan->llod_is_index)
406 mdo = llo_store_create_index(env, md, dt ,
411 mdo = llo_store_create(env, md, dt,
414 if (IS_ERR(mdo) && PTR_ERR(mdo) != -EEXIST) {
416 CERROR("creating obj [%s] fid = "DFID" rc = %d\n",
417 scan->llod_name, PFID(fid), rc);
422 lu_object_put(env, &mdo->mo_lu);
426 mutex_unlock(&llo_lock);
430 EXPORT_SYMBOL(llo_local_objects_setup);
432 int llo_global_init(void)
436 CFS_INIT_LIST_HEAD(&llo_lobj_list);
437 mutex_init(&llo_lock);
439 LU_CONTEXT_KEY_INIT(&llod_key);
440 result = lu_context_key_register(&llod_key);
444 void llo_global_fini(void)
446 lu_context_key_degister(&llod_key);