Whamcloud - gitweb
land 0.5.20.3 b_devel onto HEAD (b_devel will remain)
[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, NULL, NULL);
75         if (rc != 0)
76                 return (rc);
77
78         rc = obd_connect (&cobd->cobd_cache, cache, &cache_uuid, NULL, NULL);
79         if (rc != 0)
80                 goto fail_0;
81
82         return (0);
83
84  fail_0:
85         obd_disconnect (&cobd->cobd_target);
86         return (rc);
87 }
88
89 static int
90 cobd_cleanup (struct obd_device *dev)
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);
99         if (rc != 0)
100                 CERROR ("error %d disconnecting cache\n", rc);
101
102         rc = obd_disconnect (&cobd->cobd_target);
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, struct recovd_obd *recovd,
112               ptlrpc_recovery_cb_t recover)
113 {
114         int rc = class_connect (conn, obd, cluuid);
115
116         CERROR ("rc %d\n", rc);
117         return (rc);
118 }
119
120 static int
121 cobd_disconnect (struct lustre_handle *conn)
122 {
123         int rc = class_disconnect (conn);
124
125         CERROR ("rc %d\n", rc);
126         return (rc);
127 }
128
129 static int
130 cobd_get_info(struct lustre_handle *conn, obd_count keylen,
131               void *key, obd_count *vallen, void **val)
132 {
133         struct obd_device *obd = class_conn2obd(conn);
134         struct cache_obd  *cobd;
135
136         if (obd == NULL) {
137                 CERROR("invalid client "LPX64"\n", conn->addr);
138                 return -EINVAL;
139         }
140
141         cobd = &obd->u.cobd;
142
143         /* intercept cache utilisation info? */
144
145         return (obd_get_info (&cobd->cobd_target,
146                               keylen, key, vallen, val));
147 }
148
149 static int
150 cobd_statfs(struct lustre_handle *conn, struct obd_statfs *osfs)
151 {
152         struct obd_device *obd = class_conn2obd(conn);
153         struct cache_obd  *cobd;
154
155         if (obd == NULL) {
156                 CERROR("invalid client "LPX64"\n", conn->addr);
157                 return -EINVAL;
158         }
159
160         cobd = &obd->u.cobd;
161         return (obd_statfs (&cobd->cobd_target, osfs));
162 }
163
164 static int
165 cobd_getattr(struct lustre_handle *conn, struct obdo *oa,
166              struct lov_stripe_md *lsm)
167 {
168         struct obd_device *obd = class_conn2obd(conn);
169         struct cache_obd  *cobd;
170
171         if (obd == NULL) {
172                 CERROR("invalid client "LPX64"\n", conn->addr);
173                 return -EINVAL;
174         }
175
176         cobd = &obd->u.cobd;
177         return (obd_getattr (&cobd->cobd_target, oa, lsm));
178 }
179
180 static int
181 cobd_open(struct lustre_handle *conn, struct obdo *oa,
182           struct lov_stripe_md *lsm, struct obd_trans_info *oti)
183 {
184         struct obd_device *obd = class_conn2obd(conn);
185         struct cache_obd  *cobd;
186
187         if (obd == NULL) {
188                 CERROR("invalid client "LPX64"\n", conn->addr);
189                 return -EINVAL;
190         }
191
192         cobd = &obd->u.cobd;
193         return (obd_open (&cobd->cobd_target, oa, lsm, oti));
194 }
195
196 static int
197 cobd_close(struct lustre_handle *conn, struct obdo *oa,
198            struct lov_stripe_md *lsm, struct obd_trans_info *oti)
199 {
200         struct obd_device *obd = class_conn2obd(conn);
201         struct cache_obd  *cobd;
202
203         if (obd == NULL) {
204                 CERROR("invalid client "LPX64"\n", conn->addr);
205                 return -EINVAL;
206         }
207
208         cobd = &obd->u.cobd;
209         return (obd_close (&cobd->cobd_target, oa, lsm, oti));
210 }
211
212 static int
213 cobd_preprw(int cmd, struct lustre_handle *conn,
214             int objcount, struct obd_ioobj *obj,
215             int niocount, struct niobuf_remote *nb,
216             struct niobuf_local *res, void **desc_private, 
217             struct obd_trans_info *oti)
218 {
219         struct obd_device *obd = class_conn2obd(conn);
220         struct cache_obd  *cobd;
221
222         if (obd == NULL) {
223                 CERROR("invalid client "LPX64"\n", conn->addr);
224                 return -EINVAL;
225         }
226
227         if ((cmd & OBD_BRW_WRITE) != 0)
228                 return -EOPNOTSUPP;
229
230         cobd = &obd->u.cobd;
231         return (obd_preprw (cmd, &cobd->cobd_target,
232                             objcount, obj,
233                             niocount, nb,
234                             res, desc_private, oti));
235 }
236
237 static int
238 cobd_commitrw(int cmd, struct lustre_handle *conn,
239               int objcount, struct obd_ioobj *obj,
240               int niocount, struct niobuf_local *local,
241               void *desc_private, struct obd_trans_info *oti)
242 {
243         struct obd_device *obd = class_conn2obd(conn);
244         struct cache_obd  *cobd;
245
246         if (obd == NULL) {
247                 CERROR("invalid client "LPX64"\n", conn->addr);
248                 return -EINVAL;
249         }
250
251         if ((cmd & OBD_BRW_WRITE) != 0)
252                 return -EOPNOTSUPP;
253
254         cobd = &obd->u.cobd;
255         return (obd_commitrw (cmd, &cobd->cobd_target,
256                               objcount, obj,
257                               niocount, local,
258                               desc_private, oti));
259 }
260
261 static inline int
262 cobd_brw(int cmd, struct lustre_handle *conn,
263          struct lov_stripe_md *lsm, obd_count oa_bufs,
264          struct brw_page *pga, struct obd_brw_set *set, 
265          struct obd_trans_info *oti)
266 {
267         struct obd_device *obd = class_conn2obd(conn);
268         struct cache_obd  *cobd;
269
270         if (obd == NULL) {
271                 CERROR("invalid client "LPX64"\n", conn->addr);
272                 return -EINVAL;
273         }
274
275         if ((cmd & OBD_BRW_WRITE) != 0)
276                 return -EOPNOTSUPP;
277
278         cobd = &obd->u.cobd;
279         return (obd_brw (cmd, &cobd->cobd_target,
280                          lsm, oa_bufs, pga, set, oti));
281 }
282
283 static int
284 cobd_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
285                void *karg, void *uarg)
286 {
287         struct obd_device *obd = class_conn2obd(conn);
288         struct cache_obd  *cobd;
289
290         if (obd == NULL) {
291                 CERROR("invalid client "LPX64"\n", conn->addr);
292                 return -EINVAL;
293         }
294
295         /* intercept? */
296
297         cobd = &obd->u.cobd;
298         return (obd_iocontrol (cmd, &cobd->cobd_target, len, karg, uarg));
299 }
300
301 static struct obd_ops cobd_ops = {
302         o_owner:                THIS_MODULE,
303         o_attach:               cobd_attach,
304         o_detach:               cobd_detach,
305
306         o_setup:                cobd_setup,
307         o_cleanup:              cobd_cleanup,
308
309         o_connect:              cobd_connect,
310         o_disconnect:           cobd_disconnect,
311
312         o_get_info:             cobd_get_info,
313         o_statfs:               cobd_statfs,
314
315         o_getattr:              cobd_getattr,
316         o_open:                 cobd_open,
317         o_close:                cobd_close,
318         o_preprw:               cobd_preprw,
319         o_commitrw:             cobd_commitrw,
320         o_brw:                  cobd_brw,
321         o_iocontrol:            cobd_iocontrol,
322 };
323
324 static int __init cobd_init(void)
325 {
326         struct lprocfs_static_vars lvars;
327         ENTRY;
328
329         printk(KERN_INFO "Lustre Caching OBD driver; info@clusterfs.com\n");
330
331         lprocfs_init_vars(&lvars);
332         RETURN(class_register_type(&cobd_ops, lvars.module_vars,
333                                    OBD_CACHE_DEVICENAME));
334 }
335
336 static void __exit cobd_exit(void)
337 {
338         class_unregister_type(OBD_CACHE_DEVICENAME);
339 }
340
341 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
342 MODULE_DESCRIPTION("Lustre Caching OBD driver");
343 MODULE_LICENSE("GPL");
344
345 module_init(cobd_init);
346 module_exit(cobd_exit);