Whamcloud - gitweb
file setup.in was initially added on branch b_unify.
[fs/lustre-release.git] / lustre / cobd / cache_obd.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (c) 2002 Cluster File Systems, Inc. <info@clusterfs.com>
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
8  *   Lustre is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Lustre is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Lustre; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #define DEBUG_SUBSYSTEM S_COBD
23
24 #include <linux/version.h>
25 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
26 #include <linux/init.h>
27 #endif
28 #include <linux/obd_support.h>
29 #include <linux/lustre_lib.h>
30 #include <linux/lustre_net.h>
31 #include <linux/lustre_idl.h>
32 #include <linux/obd_class.h>
33 #include <linux/obd_cache.h>
34
35 static int cobd_attach(struct obd_device *dev, obd_count len, void *data)
36 {
37         struct lprocfs_static_vars lvars;
38
39         lprocfs_init_vars(&lvars);
40         return lprocfs_obd_attach(dev, lvars.obd_vars);
41 }
42
43 static int cobd_detach(struct obd_device *dev)
44 {
45         return lprocfs_obd_detach(dev);
46 }
47
48 static int
49 cobd_setup (struct obd_device *dev, obd_count len, void *buf)
50 {
51         struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
52         struct cache_obd  *cobd = &dev->u.cobd;
53         struct obd_device *target;
54         struct obd_device *cache;
55         struct obd_uuid target_uuid;
56         struct obd_uuid cache_uuid;
57         int                rc;
58
59         if (data->ioc_inlbuf1 == NULL ||
60             data->ioc_inlbuf2 == NULL)
61                 return (-EINVAL);
62
63         obd_str2uuid(&target_uuid, data->ioc_inlbuf1);
64         target = class_uuid2obd (&target_uuid);
65
66         obd_str2uuid(&cache_uuid, data->ioc_inlbuf2);
67         cache  = class_uuid2obd (&cache_uuid);
68         if (target == NULL ||
69             cache == NULL)
70                 return (-EINVAL);
71
72         /* don't bother checking attached/setup;
73          * obd_connect() should, and it can change underneath us */
74         rc = obd_connect (&cobd->cobd_target, target, &target_uuid);
75         if (rc != 0)
76                 return (rc);
77
78         rc = obd_connect (&cobd->cobd_cache, cache, &cache_uuid);
79         if (rc != 0)
80                 goto fail_0;
81
82         return (0);
83
84  fail_0:
85         obd_disconnect (&cobd->cobd_target, 0 );
86         return (rc);
87 }
88
89 static int
90 cobd_cleanup (struct obd_device *dev, int force, int failover)
91 {
92         struct cache_obd  *cobd = &dev->u.cobd;
93         int                rc;
94
95         if (!list_empty (&dev->obd_exports))
96                 return (-EBUSY);
97
98         rc = obd_disconnect (&cobd->cobd_cache, failover);
99         if (rc != 0)
100                 CERROR ("error %d disconnecting cache\n", rc);
101
102         rc = obd_disconnect (&cobd->cobd_target, failover);
103         if (rc != 0)
104                 CERROR ("error %d disconnecting target\n", rc);
105
106         return (0);
107 }
108
109 static int
110 cobd_connect (struct lustre_handle *conn, struct obd_device *obd,
111               struct obd_uuid *cluuid)
112 {
113         int rc = class_connect (conn, obd, cluuid);
114
115         CERROR ("rc %d\n", rc);
116         return (rc);
117 }
118
119 static int
120 cobd_disconnect (struct lustre_handle *conn, int failover)
121 {
122         int rc = class_disconnect (conn, failover);
123
124         CERROR ("rc %d\n", rc);
125         return (rc);
126 }
127
128 static int
129 cobd_get_info(struct lustre_handle *conn, obd_count keylen,
130               void *key, __u32 *vallen, void *val)
131 {
132         struct obd_device *obd = class_conn2obd(conn);
133         struct cache_obd  *cobd;
134
135         if (obd == NULL) {
136                 CERROR("invalid client cookie "LPX64"\n", conn->cookie);
137                 return -EINVAL;
138         }
139
140         cobd = &obd->u.cobd;
141
142         /* intercept cache utilisation info? */
143
144         return obd_get_info(&cobd->cobd_target, keylen, key, vallen, val);
145 }
146
147 static int cobd_statfs(struct obd_export *exp, struct obd_statfs *osfs)
148 {
149         struct obd_export *cobd_exp;
150         int rc;
151
152         if (exp->exp_obd == NULL)
153                 return -EINVAL;
154
155         cobd_exp = class_conn2export(&exp->exp_obd->u.cobd.cobd_target);
156         rc = obd_statfs(cobd_exp, osfs);
157         class_export_put(cobd_exp);
158         return rc;
159 }
160
161 static int
162 cobd_getattr(struct lustre_handle *conn, struct obdo *oa,
163              struct lov_stripe_md *lsm)
164 {
165         struct obd_device *obd = class_conn2obd(conn);
166         struct cache_obd  *cobd;
167
168         if (obd == NULL) {
169                 CERROR("invalid client cookie "LPX64"\n", conn->cookie);
170                 return -EINVAL;
171         }
172
173         cobd = &obd->u.cobd;
174         return (obd_getattr (&cobd->cobd_target, oa, lsm));
175 }
176
177 static int
178 cobd_open(struct lustre_handle *conn, struct obdo *oa,
179           struct lov_stripe_md *lsm, struct obd_trans_info *oti,
180           struct obd_client_handle *och)
181 {
182         struct obd_device *obd = class_conn2obd(conn);
183         struct cache_obd  *cobd;
184
185         if (obd == NULL) {
186                 CERROR("invalid client cookie "LPX64"\n", conn->cookie);
187                 return -EINVAL;
188         }
189
190         cobd = &obd->u.cobd;
191         return (obd_open (&cobd->cobd_target, oa, lsm, oti, och));
192 }
193
194 static int
195 cobd_close(struct lustre_handle *conn, struct obdo *oa,
196            struct lov_stripe_md *lsm, struct obd_trans_info *oti)
197 {
198         struct obd_device *obd = class_conn2obd(conn);
199         struct cache_obd  *cobd;
200
201         if (obd == NULL) {
202                 CERROR("invalid client cookie "LPX64"\n", conn->cookie);
203                 return -EINVAL;
204         }
205
206         cobd = &obd->u.cobd;
207         return (obd_close (&cobd->cobd_target, oa, lsm, oti));
208 }
209
210 static int cobd_preprw(int cmd, struct obd_export *exp, struct obdo *obdo,
211                        int objcount, struct obd_ioobj *obj,
212                        int niocount, struct niobuf_remote *nb,
213                        struct niobuf_local *res, void **desc_private,
214                        struct obd_trans_info *oti)
215 {
216         struct obd_export *cobd_exp;
217         int rc;
218
219         if (exp->exp_obd == NULL)
220                 return -EINVAL;
221
222         if ((cmd & OBD_BRW_WRITE) != 0)
223                 return -EOPNOTSUPP;
224
225         cobd_exp = class_conn2export(&exp->exp_obd->u.cobd.cobd_target);
226         rc = obd_preprw(cmd, cobd_exp, obdo, objcount, obj, niocount, nb, res,
227                         desc_private, oti);
228         class_export_put(cobd_exp);
229         return rc;
230 }
231
232 static int cobd_commitrw(int cmd, struct obd_export *exp,
233                          int objcount, struct obd_ioobj *obj,
234                          int niocount, struct niobuf_local *local,
235                          void *desc_private, struct obd_trans_info *oti)
236 {
237         struct obd_export *cobd_exp;
238         int rc;
239
240         if (exp->exp_obd == NULL)
241                 return -EINVAL;
242
243         if ((cmd & OBD_BRW_WRITE) != 0)
244                 return -EOPNOTSUPP;
245
246         cobd_exp = class_conn2export(&exp->exp_obd->u.cobd.cobd_target);
247         rc = obd_commitrw(cmd, cobd_exp, objcount, obj, niocount, local,
248                           desc_private, oti);
249         class_export_put(cobd_exp);
250         return rc;
251 }
252
253 static inline int
254 cobd_brw(int cmd, struct lustre_handle *conn,
255          struct lov_stripe_md *lsm, obd_count oa_bufs,
256          struct brw_page *pga, struct obd_trans_info *oti)
257 {
258         struct obd_device *obd = class_conn2obd(conn);
259         struct cache_obd  *cobd;
260
261         if (obd == NULL) {
262                 CERROR("invalid client cookie "LPX64"\n", conn->cookie);
263                 return -EINVAL;
264         }
265
266         if ((cmd & OBD_BRW_WRITE) != 0)
267                 return -EOPNOTSUPP;
268
269         cobd = &obd->u.cobd;
270         return (obd_brw (cmd, &cobd->cobd_target,
271                          lsm, oa_bufs, pga, oti));
272 }
273
274 static int
275 cobd_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
276                void *karg, void *uarg)
277 {
278         struct obd_device *obd = class_conn2obd(conn);
279         struct cache_obd  *cobd;
280
281         if (obd == NULL) {
282                 CERROR("invalid client cookie "LPX64"\n", conn->cookie);
283                 return -EINVAL;
284         }
285
286         /* intercept? */
287
288         cobd = &obd->u.cobd;
289         return (obd_iocontrol (cmd, &cobd->cobd_target, len, karg, uarg));
290 }
291
292 static struct obd_ops cobd_ops = {
293         o_owner:                THIS_MODULE,
294         o_attach:               cobd_attach,
295         o_detach:               cobd_detach,
296
297         o_setup:                cobd_setup,
298         o_cleanup:              cobd_cleanup,
299
300         o_connect:              cobd_connect,
301         o_disconnect:           cobd_disconnect,
302
303         o_get_info:             cobd_get_info,
304         o_statfs:               cobd_statfs,
305
306         o_getattr:              cobd_getattr,
307         o_open:                 cobd_open,
308         o_close:                cobd_close,
309         o_preprw:               cobd_preprw,
310         o_commitrw:             cobd_commitrw,
311         o_brw:                  cobd_brw,
312         o_iocontrol:            cobd_iocontrol,
313 };
314
315 static int __init cobd_init(void)
316 {
317         struct lprocfs_static_vars lvars;
318         ENTRY;
319
320         printk(KERN_INFO "Lustre Caching OBD driver; info@clusterfs.com\n");
321
322         lprocfs_init_vars(&lvars);
323         RETURN(class_register_type(&cobd_ops, lvars.module_vars,
324                                    OBD_CACHE_DEVICENAME));
325 }
326
327 static void __exit cobd_exit(void)
328 {
329         class_unregister_type(OBD_CACHE_DEVICENAME);
330 }
331
332 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
333 MODULE_DESCRIPTION("Lustre Caching OBD driver");
334 MODULE_LICENSE("GPL");
335
336 module_init(cobd_init);
337 module_exit(cobd_exit);