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