Whamcloud - gitweb
lu_context_key: add tags to contexts and keys to control which keys should be allocat...
[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 struct fld_thread_info {
73         __u64 fti_key;
74         __u64 fti_rec;
75 };
76
77 static void *fld_key_init(const struct lu_context *ctx,
78                           struct lu_context_key *key)
79 {
80         struct fld_thread_info *info;
81         ENTRY;
82
83         OBD_ALLOC_PTR(info);
84         if (info == NULL)
85                 info = ERR_PTR(-ENOMEM);
86         RETURN(info);
87 }
88
89 static void fld_key_fini(const struct lu_context *ctx,
90                          struct lu_context_key *key, void *data)
91 {
92         struct fld_thread_info *info = data;
93         ENTRY;
94         OBD_FREE_PTR(info);
95         EXIT;
96 }
97
98 static int fld_key_registered = 0;
99
100 static struct lu_context_key fld_thread_key = {
101         .lct_tags = LCT_MD_THREAD|LCT_DT_THREAD,
102         .lct_init = fld_key_init,
103         .lct_fini = fld_key_fini
104 };
105
106 static struct dt_key *fld_key(const struct lu_context *ctx,
107                               const seqno_t seq)
108 {
109         struct fld_thread_info *info;
110         ENTRY;
111
112         info = lu_context_key_get(ctx, &fld_thread_key);
113         LASSERT(info != NULL);
114
115         info->fti_key = cpu_to_be64(seq);
116         RETURN((void *)&info->fti_key);
117 }
118
119 static struct dt_rec *fld_rec(const struct lu_context *ctx,
120                               const mdsno_t mds)
121 {
122         struct fld_thread_info *info;
123         ENTRY;
124
125         info = lu_context_key_get(ctx, &fld_thread_key);
126         LASSERT(info != NULL);
127
128         info->fti_rec = cpu_to_be64(mds);
129         RETURN((void *)&info->fti_rec);
130 }
131
132 int fld_index_create(struct lu_server_fld *fld,
133                      const struct lu_context *ctx,
134                      seqno_t seq, mdsno_t mds)
135 {
136         struct dt_device *dt = fld->fld_dt;
137         struct dt_object *dt_obj = fld->fld_obj;
138         struct txn_param txn;
139         struct thandle *th;
140         int rc;
141         ENTRY;
142
143         /*stub here, will fix it later*/
144         txn.tp_credits = FLD_TXN_INDEX_INSERT_CREDITS;
145
146         th = dt->dd_ops->dt_trans_start(ctx, dt, &txn);
147         if (!IS_ERR(th)) {
148                 rc = dt_obj->do_index_ops->dio_insert(ctx, dt_obj,
149                                                       fld_rec(ctx, mds),
150                                                       fld_key(ctx, seq), th);
151                 dt->dd_ops->dt_trans_stop(ctx, th);
152         } else
153                 rc = PTR_ERR(th);
154         RETURN(rc);
155 }
156
157 int fld_index_delete(struct lu_server_fld *fld,
158                      const struct lu_context *ctx,
159                      seqno_t seq)
160 {
161         struct dt_device *dt = fld->fld_dt;
162         struct dt_object *dt_obj = fld->fld_obj;
163         struct txn_param txn;
164         struct thandle *th;
165         int rc;
166         ENTRY;
167
168         txn.tp_credits = FLD_TXN_INDEX_DELETE_CREDITS;
169         th = dt->dd_ops->dt_trans_start(ctx, dt, &txn);
170         if (!IS_ERR(th)) {
171                 rc = dt_obj->do_index_ops->dio_delete(ctx, dt_obj,
172                                                       fld_key(ctx, seq), th);
173                 dt->dd_ops->dt_trans_stop(ctx, th);
174         } else
175                 rc = PTR_ERR(th);
176         RETURN(rc);
177 }
178
179 int fld_index_lookup(struct lu_server_fld *fld,
180                      const struct lu_context *ctx,
181                      seqno_t seq, mdsno_t *mds)
182 {
183         struct dt_object *dt_obj = fld->fld_obj;
184         struct dt_rec    *rec = fld_rec(ctx, 0);
185         int rc;
186         ENTRY;
187
188         rc = dt_obj->do_index_ops->dio_lookup(ctx, dt_obj, rec,
189                                               fld_key(ctx, seq));
190         if (rc == 0)
191                 *mds = be64_to_cpu(*(__u64 *)rec);
192         RETURN(rc);
193 }
194
195 int fld_index_init(struct lu_server_fld *fld,
196                    const struct lu_context *ctx)
197 {
198         struct dt_device *dt = fld->fld_dt;
199         struct dt_object *dt_obj;
200         int rc;
201         ENTRY;
202
203         if (fld_key_registered == 0) {
204                 rc = lu_context_key_register(&fld_thread_key);
205                 if (rc != 0)
206                         RETURN(rc);
207         }
208         fld_key_registered++;
209
210         /*
211          * lu_context_key has to be registered before threads are started,
212          * check this.
213          */
214         LASSERT(fld->fld_service == NULL);
215
216         dt_obj = dt_store_open(ctx, dt, fld_index_name, &fld->fld_fid);
217         if (!IS_ERR(dt_obj)) {
218                 fld->fld_obj = dt_obj;
219                 rc = dt_obj->do_ops->do_object_index_try(ctx, dt_obj,
220                                                          &fld_index_features);
221                 if (rc == 0)
222                         LASSERT(dt_obj->do_index_ops != NULL);
223                 else
224                         CERROR("\"%s\" is not an index!\n", fld_index_name);
225         } else {
226                 CERROR("cannot find \"%s\" obj %d\n",
227                        fld_index_name, (int)PTR_ERR(dt_obj));
228                 rc = PTR_ERR(dt_obj);
229         }
230
231         RETURN(rc);
232 }
233
234 void fld_index_fini(struct lu_server_fld *fld,
235                     const struct lu_context *ctx)
236 {
237         ENTRY;
238         if (fld->fld_obj != NULL) {
239                 lu_object_put(ctx, &fld->fld_obj->do_lu);
240                 fld->fld_obj = NULL;
241         }
242         if (fld_key_registered > 0) {
243                 if (--fld_key_registered == 0)
244                         lu_context_key_degister(&fld_thread_key);
245         }
246         EXIT;
247 }