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.
40 * Author: Nikita Danilov <nikita@clusterfs.com>
44 * oi uses two mechanisms to implement fid->cookie mapping:
46 * - persistent index, where cookie is a record and fid is a key, and
48 * - algorithmic mapping for "igif" fids.
53 # define EXPORT_SYMTAB
55 #define DEBUG_SUBSYSTEM S_MDS
57 #include <linux/module.h>
59 /* LUSTRE_VERSION_CODE */
60 #include <lustre_ver.h>
62 * struct OBD_{ALLOC,FREE}*()
66 #include <obd_support.h>
69 #include <lustre_fid.h>
72 /* osd_lookup(), struct osd_thread_info */
73 #include "osd_internal.h"
75 #include "dt_object.h"
83 /** to serialize concurrent OI index initialization */
84 static struct mutex oi_init_lock;
86 static struct dt_index_features oi_feat = {
87 .dif_flags = DT_IND_UPDATE,
88 .dif_recsize_min = sizeof(struct osd_inode_id),
89 .dif_recsize_max = sizeof(struct osd_inode_id),
93 static const struct oi_descr oi_descr[OSD_OI_FID_NR] = {
94 [OSD_OI_FID_SMALL] = {
97 .oid = OSD_OI_FID_SMALL_OID
99 [OSD_OI_FID_OTHER] = {
100 .fid_size = sizeof(struct lu_fid),
102 .oid = OSD_OI_FID_OTHER_OID
106 static int osd_oi_index_create(struct osd_thread_info *info,
107 struct dt_device *dev,
108 struct md_device *mdev)
110 const struct lu_env *env;
111 struct lu_fid *oi_fid = &info->oti_fid;
112 struct md_object *mdo;
118 for (i = rc = 0; i < OSD_OI_FID_NR && rc == 0; ++i) {
120 name = oi_descr[i].name;
121 lu_local_obj_fid(oi_fid, oi_descr[i].oid);
122 oi_feat.dif_keysize_min = oi_descr[i].fid_size,
123 oi_feat.dif_keysize_max = oi_descr[i].fid_size,
125 mdo = llo_store_create_index(env, mdev, dev,
130 RETURN(PTR_ERR(mdo));
132 lu_object_put(env, &mdo->mo_lu);
137 int osd_oi_init(struct osd_thread_info *info,
139 struct dt_device *dev,
140 struct md_device *mdev)
142 const struct lu_env *env;
146 CLASSERT(ARRAY_SIZE(oi->oi_dir) == ARRAY_SIZE(oi_descr));
149 mutex_lock(&oi_init_lock);
150 memset(oi, 0, sizeof *oi);
152 for (i = rc = 0; i < OSD_OI_FID_NR && rc == 0; ++i) {
154 struct dt_object *obj;
156 name = oi_descr[i].name;
157 oi_feat.dif_keysize_min = oi_descr[i].fid_size,
158 oi_feat.dif_keysize_max = oi_descr[i].fid_size,
160 obj = dt_store_open(env, dev, "", name, &info->oti_fid);
162 rc = obj->do_ops->do_index_try(env, obj, &oi_feat);
164 LASSERT(obj->do_index_ops != NULL);
167 CERROR("Wrong index \"%s\": %d\n", name, rc);
168 lu_object_put(env, &obj->do_lu);
173 rc = osd_oi_index_create(info, dev, mdev);
177 CERROR("Cannot open \"%s\": %d\n", name, rc);
181 osd_oi_fini(info, oi);
183 mutex_unlock(&oi_init_lock);
187 void osd_oi_fini(struct osd_thread_info *info, struct osd_oi *oi)
191 for (i = 0; i < ARRAY_SIZE(oi->oi_dir); ++i) {
192 if (oi->oi_dir[i] != NULL) {
193 lu_object_put(info->oti_env, &oi->oi_dir[i]->do_lu);
194 oi->oi_dir[i] = NULL;
199 static const struct dt_key *oi_fid_key(struct osd_thread_info *info,
201 const struct lu_fid *fid,
202 struct dt_object **idx)
205 struct lu_fid_pack *pack;
207 pack = &info->oti_pack;
208 fid_pack(pack, fid, &info->oti_fid);
209 for (i = 0; i < ARRAY_SIZE(oi->oi_dir); ++i) {
210 if (pack->fp_len == oi_descr[i].fid_size + sizeof pack->fp_len){
211 *idx = oi->oi_dir[i];
212 return (const struct dt_key *)&pack->fp_area;
215 CERROR("Unsupported packed fid size: %d ("DFID")\n",
216 pack->fp_len, PFID(fid));
221 static inline int fid_is_oi_fid(const struct lu_fid *fid)
223 /* We need to filter-out oi obj's fid. As we can not store it, while
224 * oi-index create operation.
226 return (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE &&
227 (fid_oid(fid) == OSD_OI_FID_SMALL_OID ||
228 fid_oid(fid) == OSD_OI_FID_OTHER_OID)));
231 int osd_oi_lookup(struct osd_thread_info *info, struct osd_oi *oi,
232 const struct lu_fid *fid, struct osd_inode_id *id)
236 if (fid_is_igif(fid)) {
237 lu_igif_to_id(fid, id);
240 struct dt_object *idx;
241 const struct dt_key *key;
243 if (fid_is_oi_fid(fid))
246 key = oi_fid_key(info, oi, fid, &idx);
247 rc = idx->do_index_ops->dio_lookup(info->oti_env, idx,
248 (struct dt_rec *)id, key,
251 id->oii_ino = be32_to_cpu(id->oii_ino);
252 id->oii_gen = be32_to_cpu(id->oii_gen);
260 int osd_oi_insert(struct osd_thread_info *info, struct osd_oi *oi,
261 const struct lu_fid *fid, const struct osd_inode_id *id0,
262 struct thandle *th, int ignore_quota)
264 struct dt_object *idx;
265 struct osd_inode_id *id;
266 const struct dt_key *key;
268 if (fid_is_igif(fid))
271 if (fid_is_oi_fid(fid))
274 key = oi_fid_key(info, oi, fid, &idx);
276 id->oii_ino = cpu_to_be32(id0->oii_ino);
277 id->oii_gen = cpu_to_be32(id0->oii_gen);
278 return idx->do_index_ops->dio_insert(info->oti_env, idx,
279 (const struct dt_rec *)id,
280 key, th, BYPASS_CAPA,
284 int osd_oi_delete(struct osd_thread_info *info,
285 struct osd_oi *oi, const struct lu_fid *fid,
288 struct dt_object *idx;
289 const struct dt_key *key;
291 if (fid_is_igif(fid))
294 key = oi_fid_key(info, oi, fid, &idx);
295 return idx->do_index_ops->dio_delete(info->oti_env, idx,
296 key, th, BYPASS_CAPA);
299 int osd_oi_mod_init()
301 mutex_init(&oi_init_lock);