Whamcloud - gitweb
b=16098
[fs/lustre-release.git] / lustre / osd / osd_oi.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
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.
11  *
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).
17  *
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
21  *
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
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/osd/osd_oi.c
37  *
38  * Object Index.
39  *
40  * Author: Nikita Danilov <nikita@clusterfs.com>
41  */
42
43 /*
44  * oi uses two mechanisms to implement fid->cookie mapping:
45  *
46  *     - persistent index, where cookie is a record and fid is a key, and
47  *
48  *     - algorithmic mapping for "igif" fids.
49  *
50  */
51
52 #ifndef EXPORT_SYMTAB
53 # define EXPORT_SYMTAB
54 #endif
55 #define DEBUG_SUBSYSTEM S_MDS
56
57 #include <linux/module.h>
58
59 /* LUSTRE_VERSION_CODE */
60 #include <lustre_ver.h>
61 /*
62  * struct OBD_{ALLOC,FREE}*()
63  * OBD_FAIL_CHECK
64  */
65 #include <obd.h>
66 #include <obd_support.h>
67
68 /* fid_cpu_to_be() */
69 #include <lustre_fid.h>
70
71 #include "osd_oi.h"
72 /* osd_lookup(), struct osd_thread_info */
73 #include "osd_internal.h"
74 #include "osd_igif.h"
75 #include "dt_object.h"
76
77 struct oi_descr {
78         int   fid_size;
79         char *name;
80 };
81
82 static const struct oi_descr oi_descr[OSD_OI_FID_NR] = {
83         [OSD_OI_FID_SMALL] = {
84                 .fid_size = 5,
85                 .name     = "oi.5"
86         },
87         [OSD_OI_FID_OTHER] = {
88                 .fid_size = sizeof(struct lu_fid),
89                 .name     = "oi.16"
90         }
91 };
92
93 int osd_oi_init(struct osd_thread_info *info,
94                 struct osd_oi *oi, struct dt_device *dev)
95 {
96         int rc;
97         int i;
98         const struct lu_env *env;
99
100         CLASSERT(ARRAY_SIZE(oi->oi_dir) == ARRAY_SIZE(oi_descr));
101
102         env = info->oti_env;
103
104         memset(oi, 0, sizeof *oi);
105
106         for (i = rc = 0; i < ARRAY_SIZE(oi->oi_dir) && rc == 0; ++i) {
107                 const char       *name;
108                 /*
109                  * Allocate on stack---this is initialization.
110                  */
111                 const struct dt_index_features feat = {
112                         .dif_flags       = DT_IND_UPDATE,
113                         .dif_keysize_min = oi_descr[i].fid_size,
114                         .dif_keysize_max = oi_descr[i].fid_size,
115                         .dif_recsize_min = sizeof(struct osd_inode_id),
116                         .dif_recsize_max = sizeof(struct osd_inode_id)
117                 };
118                 struct dt_object *obj;
119
120                 name = oi_descr[i].name;
121                 obj = dt_store_open(env, dev, name, &info->oti_fid);
122                 if (!IS_ERR(obj)) {
123                         rc = obj->do_ops->do_index_try(env, obj, &feat);
124                         if (rc == 0) {
125                                 LASSERT(obj->do_index_ops != NULL);
126                                 oi->oi_dir[i] = obj;
127                         } else {
128                                 CERROR("Wrong index \"%s\": %d\n", name, rc);
129                                 lu_object_put(env, &obj->do_lu);
130                         }
131                 } else {
132                         rc = PTR_ERR(obj);
133                         CERROR("Cannot open \"%s\": %d\n", name, rc);
134                 }
135         }
136         if (rc != 0)
137                 osd_oi_fini(info, oi);
138         return rc;
139 }
140
141 void osd_oi_fini(struct osd_thread_info *info, struct osd_oi *oi)
142 {
143         int i;
144         for (i = 0; i < ARRAY_SIZE(oi->oi_dir); ++i) {
145                 if (oi->oi_dir[i] != NULL) {
146                         lu_object_put(info->oti_env, &oi->oi_dir[i]->do_lu);
147                         oi->oi_dir[i] = NULL;
148                 }
149         }
150 }
151
152 static const struct dt_key *oi_fid_key(struct osd_thread_info *info,
153                                        struct osd_oi *oi,
154                                        const struct lu_fid *fid,
155                                        struct dt_object **idx)
156 {
157         int i;
158         struct lu_fid_pack *pack;
159
160         pack = &info->oti_pack;
161         fid_pack(pack, fid, &info->oti_fid);
162         for (i = 0; i < ARRAY_SIZE(oi->oi_dir); ++i) {
163                 if (pack->fp_len == oi_descr[i].fid_size + sizeof pack->fp_len){
164                         *idx = oi->oi_dir[i];
165                         return (const struct dt_key *)&pack->fp_area;
166                 }
167         }
168         CERROR("Unsupported packed fid size: %d ("DFID")\n",
169                pack->fp_len, PFID(fid));
170         LBUG();
171         return NULL;
172 }
173
174 int osd_oi_lookup(struct osd_thread_info *info, struct osd_oi *oi,
175                   const struct lu_fid *fid, struct osd_inode_id *id)
176 {
177         int rc;
178
179         if (fid_is_igif(fid)) {
180                 lu_igif_to_id(fid, id);
181                 rc = 0;
182         } else {
183                 struct dt_object    *idx;
184                 const struct dt_key *key;
185
186                 key = oi_fid_key(info, oi, fid, &idx);
187                 rc = idx->do_index_ops->dio_lookup(info->oti_env, idx,
188                                                    (struct dt_rec *)id, key,
189                                                    BYPASS_CAPA);
190                 id->oii_ino = be32_to_cpu(id->oii_ino);
191                 id->oii_gen = be32_to_cpu(id->oii_gen);
192         }
193         return rc;
194 }
195
196 int osd_oi_insert(struct osd_thread_info *info, struct osd_oi *oi,
197                   const struct lu_fid *fid, const struct osd_inode_id *id0,
198                   struct thandle *th)
199 {
200         struct dt_object    *idx;
201         struct osd_inode_id *id;
202         const struct dt_key *key;
203
204         if (fid_is_igif(fid))
205                 return 0;
206
207         key = oi_fid_key(info, oi, fid, &idx);
208         id  = &info->oti_id;
209         id->oii_ino = cpu_to_be32(id0->oii_ino);
210         id->oii_gen = cpu_to_be32(id0->oii_gen);
211         return idx->do_index_ops->dio_insert(info->oti_env, idx,
212                                              (const struct dt_rec *)id,
213                                              key, th, BYPASS_CAPA);
214 }
215
216 int osd_oi_delete(struct osd_thread_info *info,
217                   struct osd_oi *oi, const struct lu_fid *fid,
218                   struct thandle *th)
219 {
220         struct dt_object    *idx;
221         const struct dt_key *key;
222
223         if (fid_is_igif(fid))
224                 return 0;
225
226         key = oi_fid_key(info, oi, fid, &idx);
227         return idx->do_index_ops->dio_delete(info->oti_env, idx,
228                                              key, th, BYPASS_CAPA);
229 }