1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
7 * Copyright (c) 2006 Cluster File Systems, Inc.
8 * Author: Nikita Danilov <nikita@clusterfs.com>
10 * This file is part of the Lustre file system, http://www.lustre.org
11 * Lustre is a trademark of Cluster File Systems, Inc.
13 * You may have signed or agreed to another license before downloading
14 * this software. If so, you are bound by the terms and conditions
15 * of that agreement, and the following does not apply to you. See the
16 * LICENSE file included with this distribution for more information.
18 * If you did not agree to a different license, then this copy of Lustre
19 * is open source software; you can redistribute it and/or modify it
20 * under the terms of version 2 of the GNU General Public License as
21 * published by the Free Software Foundation.
23 * In either case, Lustre is distributed in the hope that it will be
24 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
25 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * license text for more details.
29 * oi uses two mechanisms to implement fid->cookie mapping:
31 * - persistent index, where cookie is a record and fid is a key, and
33 * - algorithmic mapping for "igif" fids.
38 # define EXPORT_SYMTAB
40 #define DEBUG_SUBSYSTEM S_MDS
42 #include <linux/module.h>
44 /* LUSTRE_VERSION_CODE */
45 #include <lustre_ver.h>
47 * struct OBD_{ALLOC,FREE}*()
51 #include <obd_support.h>
54 #include <lustre_fid.h>
57 /* osd_lookup(), struct osd_thread_info */
58 #include "osd_internal.h"
60 #include "dt_object.h"
62 static const struct dt_key *oi_fid_key(struct osd_thread_info *info,
63 const struct lu_fid *fid);
64 static const char oi_dirname[] = "oi";
66 static const struct dt_index_features oi_index_features = {
67 .dif_flags = DT_IND_UPDATE,
68 .dif_keysize_min = sizeof(struct lu_fid),
69 .dif_keysize_max = sizeof(struct lu_fid),
70 .dif_recsize_min = sizeof(struct osd_inode_id),
71 .dif_recsize_max = sizeof(struct osd_inode_id)
74 int osd_oi_init(struct osd_thread_info *info,
75 struct osd_oi *oi, struct dt_device *dev)
78 struct dt_object *obj;
79 const struct lu_env *env;
83 * Initialize ->oi_lock first, because of possible oi re-entrance in
86 init_rwsem(&oi->oi_lock);
88 obj = dt_store_open(env, dev, oi_dirname, &info->oti_fid);
90 rc = obj->do_ops->do_index_try(env, obj, &oi_index_features);
92 LASSERT(obj->do_index_ops != NULL);
95 CERROR("Wrong index \"%s\": %d\n", oi_dirname, rc);
96 lu_object_put(env, &obj->do_lu);
100 CERROR("Cannot open \"%s\": %d\n", oi_dirname, rc);
105 void osd_oi_fini(struct osd_thread_info *info, struct osd_oi *oi)
107 if (oi->oi_dir != NULL) {
108 lu_object_put(info->oti_env, &oi->oi_dir->do_lu);
113 void osd_oi_read_lock(struct osd_oi *oi)
115 down_read(&oi->oi_lock);
118 void osd_oi_read_unlock(struct osd_oi *oi)
120 up_read(&oi->oi_lock);
123 void osd_oi_write_lock(struct osd_oi *oi)
125 down_write(&oi->oi_lock);
128 void osd_oi_write_unlock(struct osd_oi *oi)
130 up_write(&oi->oi_lock);
133 static const struct dt_key *oi_fid_key(struct osd_thread_info *info,
134 const struct lu_fid *fid)
136 fid_cpu_to_be(&info->oti_fid, fid);
137 return (const struct dt_key *)&info->oti_fid;
141 OI_TXN_INSERT_CREDITS = 20,
142 OI_TXN_DELETE_CREDITS = 20
145 static inline void oid_lookup_init(struct osd_inode_id *id,
146 __u64 ino, __u32 gen)
148 id->oii_ino = be64_to_cpu(ino);
149 id->oii_gen = be32_to_cpu(gen);
152 static inline void oid_insert_init(struct osd_inode_id *id,
153 __u64 ino, __u32 gen)
155 id->oii_ino = cpu_to_be64(ino);
156 id->oii_gen = cpu_to_be32(gen);
159 * Locking: requires at least read lock on oi.
161 int osd_oi_lookup(struct osd_thread_info *info, struct osd_oi *oi,
162 const struct lu_fid *fid, struct osd_inode_id *id)
166 if (fid_is_igif(fid)) {
167 lu_igif_to_id(fid, id);
170 rc = oi->oi_dir->do_index_ops->dio_lookup
171 (info->oti_env, oi->oi_dir,
172 (struct dt_rec *)id, oi_fid_key(info, fid),
174 oid_lookup_init(id, id->oii_ino, id->oii_gen);
180 * Locking: requires write lock on oi.
182 int osd_oi_insert(struct osd_thread_info *info, struct osd_oi *oi,
183 const struct lu_fid *fid, const struct osd_inode_id *id0,
186 struct dt_object *idx;
187 struct dt_device *dev;
188 struct osd_inode_id *id;
190 if (fid_is_igif(fid))
194 dev = lu2dt_dev(idx->do_lu.lo_dev);
196 oid_insert_init(id, id0->oii_ino, id0->oii_gen);
197 return idx->do_index_ops->dio_insert(info->oti_env, idx,
198 (const struct dt_rec *)id,
199 oi_fid_key(info, fid), th,
204 * Locking: requires write lock on oi.
206 int osd_oi_delete(struct osd_thread_info *info,
207 struct osd_oi *oi, const struct lu_fid *fid,
210 struct dt_object *idx;
211 struct dt_device *dev;
213 if (fid_is_igif(fid))
217 dev = lu2dt_dev(idx->do_lu.lo_dev);
218 return idx->do_index_ops->dio_delete(info->oti_env, idx,
219 oi_fid_key(info, fid), th,