Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / fld / fld_index.c
1 /* -*- MODE: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  fld/fld_index.c
5  *
6  *  Copyright (C) 2006 Cluster File Systems, Inc.
7  *   Author: WangDi <wangdi@clusterfs.com>
8  *           Yury Umanets <umka@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 #ifndef EXPORT_SYMTAB
29 # define EXPORT_SYMTAB
30 #endif
31 #define DEBUG_SUBSYSTEM S_FLD
32
33 #ifdef __KERNEL__
34 # include <libcfs/libcfs.h>
35 # include <linux/module.h>
36 # include <linux/jbd.h>
37 #else /* __KERNEL__ */
38 # include <liblustre.h>
39 #endif
40
41 #include <obd.h>
42 #include <obd_class.h>
43 #include <lustre_ver.h>
44 #include <obd_support.h>
45 #include <lprocfs_status.h>
46
47 #include <dt_object.h>
48 #include <md_object.h>
49 #include <lustre_mdc.h>
50 #include <lustre_fld.h>
51 #include "fld_internal.h"
52
53 const char fld_index_name[] = "fld";
54
55 static const struct dt_index_features fld_index_features = {
56         .dif_flags       = DT_IND_UPDATE,
57         .dif_keysize_min = sizeof(seqno_t),
58         .dif_keysize_max = sizeof(seqno_t),
59         .dif_recsize_min = sizeof(mdsno_t),
60         .dif_recsize_max = sizeof(mdsno_t)
61 };
62
63 /*
64  * number of blocks to reserve for particular operations. Should be function of
65  * ... something. Stub for now.
66  */
67 enum {
68         FLD_TXN_INDEX_INSERT_CREDITS  = 20,
69         FLD_TXN_INDEX_DELETE_CREDITS  = 20,
70 };
71
72 extern struct lu_context_key fld_thread_key;
73
74 static struct dt_key *fld_key(const struct lu_env *env,
75                               const seqno_t seq)
76 {
77         struct fld_thread_info *info;
78         ENTRY;
79
80         info = lu_context_key_get(&env->le_ctx, &fld_thread_key);
81         LASSERT(info != NULL);
82
83         info->fti_key = cpu_to_be64(seq);
84         RETURN((void *)&info->fti_key);
85 }
86
87 static struct dt_rec *fld_rec(const struct lu_env *env,
88                               const mdsno_t mds)
89 {
90         struct fld_thread_info *info;
91         ENTRY;
92
93         info = lu_context_key_get(&env->le_ctx, &fld_thread_key);
94         LASSERT(info != NULL);
95
96         info->fti_rec = cpu_to_be64(mds);
97         RETURN((void *)&info->fti_rec);
98 }
99
100 int fld_index_create(struct lu_server_fld *fld,
101                      const struct lu_env *env,
102                      seqno_t seq, mdsno_t mds)
103 {
104         struct dt_object *dt_obj = fld->lsf_obj;
105         struct dt_device *dt_dev;
106         struct txn_param txn;
107         struct thandle *th;
108         int rc;
109         ENTRY;
110
111         dt_dev = lu2dt_dev(fld->lsf_obj->do_lu.lo_dev);
112
113         /* stub here, will fix it later */
114         txn_param_init(&txn, FLD_TXN_INDEX_INSERT_CREDITS);
115
116         th = dt_dev->dd_ops->dt_trans_start(env, dt_dev, &txn);
117         if (!IS_ERR(th)) {
118                 rc = dt_obj->do_index_ops->dio_insert(env, dt_obj,
119                                                       fld_rec(env, mds),
120                                                       fld_key(env, seq),
121                                                       th, BYPASS_CAPA);
122                 dt_dev->dd_ops->dt_trans_stop(env, th);
123         } else
124                 rc = PTR_ERR(th);
125         RETURN(rc);
126 }
127
128 int fld_index_delete(struct lu_server_fld *fld,
129                      const struct lu_env *env,
130                      seqno_t seq)
131 {
132         struct dt_object *dt_obj = fld->lsf_obj;
133         struct dt_device *dt_dev;
134         struct txn_param txn;
135         struct thandle *th;
136         int rc;
137         ENTRY;
138
139         dt_dev = lu2dt_dev(fld->lsf_obj->do_lu.lo_dev);
140         txn_param_init(&txn, FLD_TXN_INDEX_DELETE_CREDITS);
141         th = dt_dev->dd_ops->dt_trans_start(env, dt_dev, &txn);
142         if (!IS_ERR(th)) {
143                 rc = dt_obj->do_index_ops->dio_delete(env, dt_obj,
144                                                       fld_key(env, seq), th,
145                                                       BYPASS_CAPA);
146                 dt_dev->dd_ops->dt_trans_stop(env, th);
147         } else
148                 rc = PTR_ERR(th);
149         RETURN(rc);
150 }
151
152 int fld_index_lookup(struct lu_server_fld *fld,
153                      const struct lu_env *env,
154                      seqno_t seq, mdsno_t *mds)
155 {
156         struct dt_object *dt_obj = fld->lsf_obj;
157         struct dt_rec    *rec = fld_rec(env, 0);
158         int rc;
159         ENTRY;
160
161         rc = dt_obj->do_index_ops->dio_lookup(env, dt_obj, rec,
162                                               fld_key(env, seq), BYPASS_CAPA);
163         if (rc == 0)
164                 *mds = be64_to_cpu(*(__u64 *)rec);
165         RETURN(rc);
166 }
167
168 int fld_index_init(struct lu_server_fld *fld,
169                    const struct lu_env *env,
170                    struct dt_device *dt)
171 {
172         struct dt_object *dt_obj;
173         struct lu_fid fid;
174         int rc;
175         ENTRY;
176
177         dt_obj = dt_store_open(env, dt, fld_index_name, &fid);
178         if (!IS_ERR(dt_obj)) {
179                 fld->lsf_obj = dt_obj;
180                 rc = dt_obj->do_ops->do_index_try(env, dt_obj,
181                                                   &fld_index_features);
182                 if (rc == 0)
183                         LASSERT(dt_obj->do_index_ops != NULL);
184                 else
185                         CERROR("%s: File \"%s\" is not an index!\n",
186                                fld->lsf_name, fld_index_name);
187         } else {
188                 CERROR("%s: Can't find \"%s\" obj %d\n",
189                        fld->lsf_name, fld_index_name, (int)PTR_ERR(dt_obj));
190                 rc = PTR_ERR(dt_obj);
191         }
192
193         RETURN(rc);
194 }
195
196 void fld_index_fini(struct lu_server_fld *fld,
197                     const struct lu_env *env)
198 {
199         ENTRY;
200         if (fld->lsf_obj != NULL) {
201                 if (!IS_ERR(fld->lsf_obj))
202                         lu_object_put(env, &fld->lsf_obj->do_lu);
203                 fld->lsf_obj = NULL;
204         }
205         EXIT;
206 }