Whamcloud - gitweb
Merge b_md to HEAD for 0.5.19 release.
[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) 2001, 2002 Cluster File Systems, Inc.
5  *
6  * This code is issued under the GNU General Public License.
7  * See the file COPYING in this distribution
8  */
9
10 #define DEBUG_SUBSYSTEM S_COBD
11
12 #include <linux/obd_support.h>
13 #include <linux/lustre_lib.h>
14 #include <linux/lustre_net.h>
15 #include <linux/lustre_idl.h>
16 #include <linux/obd_class.h>
17 #include <linux/obd_cache.h>
18
19 extern struct lprocfs_vars status_var_nm_1[];
20 extern struct lprocfs_vars status_class_var[];
21
22 static int
23 cobd_attach (struct obd_device *dev, obd_count len, void *data)
24 {
25         return (lprocfs_reg_obd (dev, status_var_nm_1, dev));
26 }
27
28 static int
29 cobd_detach (struct obd_device *dev)
30 {
31         return (lprocfs_dereg_obd (dev));
32 }
33
34 static int
35 cobd_setup (struct obd_device *dev, obd_count len, void *buf)
36 {
37         struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
38         struct cache_obd  *cobd = &dev->u.cobd;
39         struct obd_device *target;
40         struct obd_device *cache;
41         int                rc;
42         
43         if (data->ioc_inlbuf1 == NULL ||
44             data->ioc_inlbuf2 == NULL)
45                 return (-EINVAL);
46         
47         target = class_uuid2obd (data->ioc_inlbuf1);
48         cache  = class_uuid2obd (data->ioc_inlbuf2);
49         if (target == NULL ||
50             cache == NULL)
51                 return (-EINVAL);
52         
53         /* don't bother checking attached/setup; 
54          * obd_connect() should, and it can change underneath us */
55
56         rc = obd_connect (&cobd->cobd_target, target, NULL, NULL, NULL);
57         if (rc != 0)
58                 return (rc);
59
60         rc = obd_connect (&cobd->cobd_cache, cache, NULL, NULL, NULL);
61         if (rc != 0)
62                 goto fail_0;
63
64         return (0);
65
66  fail_0:
67         obd_disconnect (&cobd->cobd_target);
68         return (rc);
69 }
70
71 static int
72 cobd_cleanup (struct obd_device *dev)
73 {
74         struct cache_obd  *cobd = &dev->u.cobd;
75         int                rc;
76         
77         if (!list_empty (&dev->obd_exports))
78                 return (-EBUSY);
79         
80         rc = obd_disconnect (&cobd->cobd_cache);
81         if (rc != 0)
82                 CERROR ("error %d disconnecting cache\n", rc);
83         
84         rc = obd_disconnect (&cobd->cobd_target);
85         if (rc != 0)
86                 CERROR ("error %d disconnecting target\n", rc);
87
88         return (0);
89 }
90
91 static int
92 cobd_connect (struct lustre_handle *conn, struct obd_device *obd,
93               obd_uuid_t cluuid, struct recovd_obd *recovd,
94               ptlrpc_recovery_cb_t recover)
95 {
96         int rc = class_connect (conn, obd, cluuid);
97
98         CERROR ("rc %d\n", rc);
99         return (rc);
100 }
101
102 static int
103 cobd_disconnect (struct lustre_handle *conn)
104 {
105         int rc = class_disconnect (conn);
106         
107         CERROR ("rc %d\n", rc);
108         return (rc);
109 }
110
111 static int 
112 cobd_get_info(struct lustre_handle *conn, obd_count keylen,
113               void *key, obd_count *vallen, void **val)
114 {
115         struct obd_device *obd = class_conn2obd(conn);
116         struct cache_obd  *cobd;
117
118         if (obd == NULL) {
119                 CERROR("invalid client "LPX64"\n", conn->addr);
120                 return -EINVAL;
121         }
122
123         cobd = &obd->u.cobd;
124
125         /* intercept cache utilisation info? */
126
127         return (obd_get_info (&cobd->cobd_target, 
128                               keylen, key, vallen, val));
129 }
130
131 static int 
132 cobd_statfs(struct lustre_handle *conn, struct obd_statfs *osfs)
133 {
134         struct obd_device *obd = class_conn2obd(conn);
135         struct cache_obd  *cobd;
136
137         if (obd == NULL) {
138                 CERROR("invalid client "LPX64"\n", conn->addr);
139                 return -EINVAL;
140         }
141
142         cobd = &obd->u.cobd;
143         return (obd_statfs (&cobd->cobd_target, osfs));
144 }
145
146 static int 
147 cobd_getattr(struct lustre_handle *conn, struct obdo *oa,
148              struct lov_stripe_md *lsm)
149 {
150         struct obd_device *obd = class_conn2obd(conn);
151         struct cache_obd  *cobd;
152
153         if (obd == NULL) {
154                 CERROR("invalid client "LPX64"\n", conn->addr);
155                 return -EINVAL;
156         }
157
158         cobd = &obd->u.cobd;
159         return (obd_getattr (&cobd->cobd_target, oa, lsm));
160 }
161
162 static int 
163 cobd_open(struct lustre_handle *conn, struct obdo *oa,
164           struct lov_stripe_md *lsm)
165 {
166         struct obd_device *obd = class_conn2obd(conn);
167         struct cache_obd  *cobd;
168
169         if (obd == NULL) {
170                 CERROR("invalid client "LPX64"\n", conn->addr);
171                 return -EINVAL;
172         }
173
174         cobd = &obd->u.cobd;
175         return (obd_open (&cobd->cobd_target, oa, lsm));
176 }
177
178 static int 
179 cobd_close(struct lustre_handle *conn, struct obdo *oa,
180            struct lov_stripe_md *lsm)
181 {
182         struct obd_device *obd = class_conn2obd(conn);
183         struct cache_obd  *cobd;
184
185         if (obd == NULL) {
186                 CERROR("invalid client "LPX64"\n", conn->addr);
187                 return -EINVAL;
188         }
189
190         cobd = &obd->u.cobd;
191         return (obd_close (&cobd->cobd_target, oa, lsm));
192 }
193
194 static int 
195 cobd_preprw(int cmd, struct lustre_handle *conn,
196             int objcount, struct obd_ioobj *obj,
197             int niocount, struct niobuf_remote *nb,
198             struct niobuf_local *res, void **desc_private)
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         if ((cmd & OBD_BRW_WRITE) != 0)
209                 return -EOPNOTSUPP;
210         
211         cobd = &obd->u.cobd;
212         return (obd_preprw (cmd, &cobd->cobd_target, 
213                             objcount, obj, 
214                             niocount, nb, 
215                             res, desc_private));
216 }
217
218 static int 
219 cobd_commitrw(int cmd, struct lustre_handle *conn,
220               int objcount, struct obd_ioobj *obj,
221               int niocount, struct niobuf_local *local,
222               void *desc_private)
223 {
224         struct obd_device *obd = class_conn2obd(conn);
225         struct cache_obd  *cobd;
226
227         if (obd == NULL) {
228                 CERROR("invalid client "LPX64"\n", conn->addr);
229                 return -EINVAL;
230         }
231
232         if ((cmd & OBD_BRW_WRITE) != 0)
233                 return -EOPNOTSUPP;
234         
235         cobd = &obd->u.cobd;
236         return (obd_commitrw (cmd, &cobd->cobd_target,
237                               objcount, obj,
238                               niocount, local,
239                               desc_private));
240 }
241
242 static inline int 
243 cobd_brw(int cmd, struct lustre_handle *conn,
244          struct lov_stripe_md *lsm, obd_count oa_bufs,
245          struct brw_page *pga, struct obd_brw_set *set)
246 {
247         struct obd_device *obd = class_conn2obd(conn);
248         struct cache_obd  *cobd;
249
250         if (obd == NULL) {
251                 CERROR("invalid client "LPX64"\n", conn->addr);
252                 return -EINVAL;
253         }
254
255         if ((cmd & OBD_BRW_WRITE) != 0)
256                 return -EOPNOTSUPP;
257         
258         cobd = &obd->u.cobd;
259         return (obd_brw (cmd, &cobd->cobd_target, 
260                          lsm, oa_bufs, pga, set));
261 }
262
263 static int 
264 cobd_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
265                void *karg, void *uarg)
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         /* intercept? */
276
277         cobd = &obd->u.cobd;
278         return (obd_iocontrol (cmd, &cobd->cobd_target, len, karg, uarg));
279 }
280
281 static struct obd_ops cobd_ops = {
282         o_owner:                THIS_MODULE,
283         o_attach:               cobd_attach,
284         o_detach:               cobd_detach,
285
286         o_setup:                cobd_setup,
287         o_cleanup:              cobd_cleanup,
288
289         o_connect:              cobd_connect,
290         o_disconnect:           cobd_disconnect,
291
292         o_get_info:             cobd_get_info,
293         o_statfs:               cobd_statfs,
294
295         o_getattr:              cobd_getattr,
296         o_open:                 cobd_open,
297         o_close:                cobd_close,
298         o_preprw:               cobd_preprw,
299         o_commitrw:             cobd_commitrw,
300         o_brw:                  cobd_brw,
301         o_iocontrol:            cobd_iocontrol,
302 };
303
304 static int __init
305 cobd_init (void)
306 {
307         int   rc;
308         
309         printk (KERN_INFO "Lustre Caching OBD driver\n");
310         
311         rc = class_register_type (&cobd_ops, status_class_var,
312                                   OBD_CACHE_DEVICENAME);
313         return (rc);
314 }
315
316 static void __exit
317 cobd_exit (void)
318 {
319         class_unregister_type (OBD_CACHE_DEVICENAME);
320 }
321
322 MODULE_AUTHOR("Cluster Filesystems Inc. <info@clusterfs.com>");
323 MODULE_DESCRIPTION("Lustre Caching OBD driver");
324 MODULE_LICENSE("GPL");
325
326 module_init(cobd_init);
327 module_exit(cobd_exit);
328
329