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"
59 /* lu_fid_is_igif() */
61 #include "dt_object.h"
63 static const struct dt_key *oi_fid_key(struct osd_thread_info *info,
64 const struct lu_fid *fid);
65 static const char oi_dirname[] = "oi";
67 static const struct dt_index_features oi_index_features = {
68 .dif_flags = DT_IND_UPDATE,
69 .dif_keysize_min = sizeof(struct lu_fid),
70 .dif_keysize_max = sizeof(struct lu_fid),
71 .dif_recsize_min = sizeof(struct osd_inode_id),
72 .dif_recsize_max = sizeof(struct osd_inode_id)
75 int osd_oi_init(struct osd_thread_info *info,
76 struct osd_oi *oi, struct dt_device *dev)
79 struct dt_object *obj;
80 const struct lu_context *ctx;
84 * Initialize ->oi_lock first, because of possible oi re-entrance in
87 init_rwsem(&oi->oi_lock);
89 obj = dt_store_open(ctx, dev, oi_dirname, &info->oti_fid);
91 rc = obj->do_ops->do_index_try(ctx, obj, &oi_index_features);
93 LASSERT(obj->do_index_ops != NULL);
96 CERROR("Wrong index \"%s\": %d\n", oi_dirname, rc);
97 lu_object_put(ctx, &obj->do_lu);
101 CERROR("Cannot open \"%s\": %d\n", oi_dirname, rc);
106 void osd_oi_fini(struct osd_thread_info *info, struct osd_oi *oi)
108 if (oi->oi_dir != NULL) {
109 lu_object_put(info->oti_ctx, &oi->oi_dir->do_lu);
114 void osd_oi_read_lock(struct osd_oi *oi)
116 down_read(&oi->oi_lock);
119 void osd_oi_read_unlock(struct osd_oi *oi)
121 up_read(&oi->oi_lock);
124 void osd_oi_write_lock(struct osd_oi *oi)
126 down_write(&oi->oi_lock);
129 void osd_oi_write_unlock(struct osd_oi *oi)
131 up_write(&oi->oi_lock);
134 static const struct dt_key *oi_fid_key(struct osd_thread_info *info,
135 const struct lu_fid *fid)
137 fid_cpu_to_be(&info->oti_fid, fid);
138 return (const struct dt_key *)&info->oti_fid;
142 OI_TXN_INSERT_CREDITS = 20,
143 OI_TXN_DELETE_CREDITS = 20
146 static inline void osd_inode_id_init(struct osd_inode_id *id,
147 __u64 ino, __u32 gen)
149 id->oii_ino = be64_to_cpu(ino);
150 id->oii_gen = be32_to_cpu(gen);
154 * Locking: requires at least read lock on oi.
156 int osd_oi_lookup(struct osd_thread_info *info, struct osd_oi *oi,
157 const struct lu_fid *fid, struct osd_inode_id *id)
161 if (lu_fid_is_igif(fid)) {
162 lu_igif_to_id(fid, id);
165 rc = oi->oi_dir->do_index_ops->dio_lookup
166 (info->oti_ctx, oi->oi_dir,
167 (struct dt_rec *)id, oi_fid_key(info, fid));
168 osd_inode_id_init(id, id->oii_ino, id->oii_gen);
174 * Locking: requires write lock on oi.
176 int osd_oi_insert(struct osd_thread_info *info, struct osd_oi *oi,
177 const struct lu_fid *fid, const struct osd_inode_id *id0,
180 struct dt_object *idx;
181 struct dt_device *dev;
182 struct osd_inode_id *id;
184 if (lu_fid_is_igif(fid))
188 dev = lu2dt_dev(idx->do_lu.lo_dev);
190 osd_inode_id_init(id, id0->oii_ino, id0->oii_gen);
191 return idx->do_index_ops->dio_insert(info->oti_ctx, idx,
192 (const struct dt_rec *)id,
193 oi_fid_key(info, fid), th);
197 * Locking: requires write lock on oi.
199 int osd_oi_delete(struct osd_thread_info *info,
200 struct osd_oi *oi, const struct lu_fid *fid,
203 struct dt_object *idx;
204 struct dt_device *dev;
206 if (lu_fid_is_igif(fid))
210 dev = lu2dt_dev(idx->do_lu.lo_dev);
211 return idx->do_index_ops->dio_delete(info->oti_ctx, idx,
212 oi_fid_key(info, fid), th);