Whamcloud - gitweb
- changes about @flags in m_disconnect(). It should be cohenernt with m_connect(),
[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 #include <linux/init.h>
26 #include <linux/obd_support.h>
27 #include <linux/lustre_lib.h>
28 #include <linux/lustre_net.h>
29 #include <linux/lustre_idl.h>
30 #include <linux/lustre_log.h>
31 #include <linux/lustre_mds.h>
32 #include <linux/obd_class.h>
33 #include <linux/obd_cache.h>
34
35 static int cobd_attach(struct obd_device *obd, obd_count len, void *buf)
36 {
37         struct lprocfs_static_vars lvars;
38         
39         lprocfs_init_vars(cobd, &lvars);
40         return lprocfs_obd_attach(obd, lvars.obd_vars);
41 }
42
43 static int cobd_detach(struct obd_device *obd)
44 {
45         return lprocfs_obd_detach(obd);
46 }
47
48 static int connect_to_obd(char *name, struct lustre_handle *conn)
49
50         struct obd_uuid   obd_uuid;
51         struct obd_device *obd;
52         int    rc = 0;
53         ENTRY;
54  
55         obd = class_name2obd(name);
56         if (obd == NULL) {
57                 CERROR("%s: unable to find a client for obd: %s\n",
58                        obd->obd_name, name);
59                 RETURN(-EINVAL);
60         }
61         rc = obd_connect(conn, obd, &obd_uuid, 0);
62         RETURN(rc);
63 }
64
65 static int cobd_setup(struct obd_device *obd, obd_count len, void *buf)
66 {
67         struct lustre_cfg *lcfg = (struct lustre_cfg *)buf;
68         struct cache_obd  *cobd = &obd->u.cobd;
69 #if 0
70         struct lustre_handle master_conn = {0,};
71 #endif
72         struct lustre_handle cache_conn = {0,};
73         struct obd_device *master;
74         struct obd_device *cache;
75         int rc;
76         ENTRY;
77
78         if (lcfg->lcfg_inllen1 == 0 || lcfg->lcfg_inlbuf1 == NULL) {
79                 CERROR("%s: setup requires master device name\n", 
80                        obd->obd_name);
81                 RETURN(-EINVAL);
82         }
83
84         master = class_name2obd(lcfg->lcfg_inlbuf1);
85         if (master == NULL) {
86                 CERROR("%s: unable to find a client for master: %s\n",
87                        obd->obd_name, lcfg->lcfg_inlbuf1);
88                 RETURN(-EINVAL);
89         }
90
91         if (lcfg->lcfg_inllen2 == 0 || lcfg->lcfg_inlbuf2 == NULL) {
92                 CERROR("%s: setup requires cache device name\n", obd->obd_name);
93                 RETURN(-EINVAL);
94         }
95
96         cache = class_name2obd(lcfg->lcfg_inlbuf2);
97         if (cache == NULL) {
98                 CERROR("%s: unable to find a client for cache: %s\n",
99                        obd->obd_name, lcfg->lcfg_inlbuf2);
100                 RETURN(-EINVAL);
101         }
102
103         OBD_ALLOC(cobd->master_name, strlen(lcfg->lcfg_inlbuf1) + 1);
104         if (!cobd->master_name) 
105                 GOTO(exit, rc = -ENOMEM);
106         memcpy(cobd->master_name, lcfg->lcfg_inlbuf1, 
107                strlen(lcfg->lcfg_inlbuf1));
108         
109         OBD_ALLOC(cobd->cache_name, strlen(lcfg->lcfg_inlbuf2) + 1);
110         if (!cobd->cache_name) 
111                 GOTO(exit, rc = -ENOMEM);
112         memcpy(cobd->cache_name, lcfg->lcfg_inlbuf2, 
113                strlen(lcfg->lcfg_inlbuf2));
114
115 #if 0        
116         /* don't bother checking attached/setup; obd_connect() should, and it
117          * can change underneath us */
118         rc = connect_to_obd(cobd->master_name, &master_conn);
119         if (rc != 0)
120                 GOTO(exit, rc);
121         cobd->master_exp = class_conn2export(&master_conn);
122 #endif        
123         rc = connect_to_obd(cobd->cache_name, &cache_conn);
124         if (rc != 0) {
125                 obd_disconnect(cobd->cache_exp, 0);
126                 GOTO(exit, rc);
127         }
128         cobd->cache_exp = class_conn2export(&cache_conn);
129         cobd->cache_on = 1;
130
131         if (!strcmp(master->obd_type->typ_name, LUSTRE_MDC_NAME)) {
132                 int mds_type;
133                 
134                 mds_type = MDS_MASTER_OBD;
135                 obd_set_info(cobd->master_exp, strlen("mds_type"),
136                              "mds_type", sizeof(mds_type), &mds_type);
137                 
138                 mds_type = MDS_CACHE_OBD;
139                 obd_set_info(cobd->cache_exp, strlen("mds_type"),
140                              "mds_type", sizeof(mds_type), &mds_type);
141         }
142 exit:
143         if (rc) {
144                 if (cobd->cache_name)
145                         OBD_FREE(cobd->cache_name, 
146                                  strlen(cobd->cache_name) + 1);
147                 if (cobd->master_name)
148                         OBD_FREE(cobd->master_name, 
149                                  strlen(cobd->master_name) + 1);
150         }
151         RETURN(rc);
152 }
153
154 static int cobd_cleanup(struct obd_device *obd, int flags)
155 {
156         struct cache_obd  *cobd = &obd->u.cobd;
157         int                rc;
158
159         if (!list_empty(&obd->obd_exports))
160                 return (-EBUSY);
161         
162         if (cobd->cache_name)
163                 OBD_FREE(cobd->cache_name, 
164                          strlen(cobd->cache_name) + 1);
165         if (cobd->master_name)
166                 OBD_FREE(cobd->master_name, 
167                          strlen(cobd->master_name) + 1);
168         if (cobd->cache_on) { 
169                 rc = obd_disconnect(cobd->cache_exp, flags);
170                 if (rc != 0)
171                         CERROR("error %d disconnecting cache\n", rc);
172         }
173         rc = obd_disconnect(cobd->master_exp, flags);
174         if (rc != 0)
175                 CERROR("error %d disconnecting master\n", rc);
176         
177         return (rc);
178 }
179
180 struct obd_export *cobd_get_exp(struct obd_device *obd)
181 {
182         struct cache_obd  *cobd = &obd->u.cobd;
183         
184         if (cobd->cache_on)  
185                 return cobd->cache_exp;
186         else
187                 return cobd->master_exp;
188 }
189
190 static int
191 cobd_connect(struct lustre_handle *conn, struct obd_device *obd,
192              struct obd_uuid *cluuid, unsigned long connect_flags)
193 {
194         return class_connect(conn, obd, cluuid);
195 }
196
197 static int cobd_disconnect(struct obd_export *exp, unsigned long flags)
198 {
199         return class_disconnect(exp, flags);
200 }
201
202 static int cobd_get_info(struct obd_export *exp, obd_count keylen,
203                          void *key, __u32 *vallen, void *val)
204 {
205         struct obd_device *obd = class_exp2obd(exp);
206         struct obd_export *cobd_exp;
207         
208         if (obd == NULL) {
209                 CERROR("invalid client cookie "LPX64"\n", 
210                        exp->exp_handle.h_cookie);
211                 return -EINVAL;
212         }
213         cobd_exp = cobd_get_exp(obd);
214
215         /* intercept cache utilisation info? */
216         return obd_get_info(cobd_exp, keylen, key, vallen, val);
217 }
218
219 static int cobd_set_info(struct obd_export *exp, obd_count keylen,
220                          void *key, obd_count vallen, void *val)
221 {
222         struct obd_device *obd = class_exp2obd(exp);
223         struct obd_export *cobd_exp;
224
225         if (obd == NULL) {
226                 CERROR("invalid client cookie "LPX64"\n", 
227                        exp->exp_handle.h_cookie);
228                 return -EINVAL;
229         }
230         cobd_exp = cobd_get_exp(obd);
231         
232         /* intercept cache utilisation info? */
233         return obd_set_info(cobd_exp, keylen, key, vallen, val);
234 }
235
236 static int cobd_statfs(struct obd_device *obd, struct obd_statfs *osfs,
237                        unsigned long max_age)
238 {
239         struct obd_export *cobd_exp;
240
241         cobd_exp = cobd_get_exp(obd);
242
243         return obd_statfs(class_exp2obd(cobd_exp), osfs, max_age);
244 }
245
246 static int cobd_packmd(struct obd_export *exp,
247                        struct lov_mds_md **disk_tgt,
248                        struct lov_stripe_md *mem_src)
249 {
250         struct obd_device *obd = class_exp2obd(exp);
251         struct obd_export *cobd_exp;
252
253         if (obd == NULL) {
254                 CERROR("invalid client cookie "LPX64"\n", 
255                        exp->exp_handle.h_cookie);
256                 return -EINVAL;
257         }
258         cobd_exp = cobd_get_exp(obd);
259         return obd_packmd(cobd_exp, disk_tgt, mem_src);
260 }
261
262 static int cobd_unpackmd(struct obd_export *exp,
263                          struct lov_stripe_md **mem_tgt,
264                          struct lov_mds_md *disk_src,
265                          int disk_len)
266 {
267         struct obd_device *obd = class_exp2obd(exp);
268         struct obd_export *cobd_exp;
269
270         if (obd == NULL) {
271                 CERROR("invalid client cookie "LPX64"\n", 
272                        exp->exp_handle.h_cookie);
273                 return -EINVAL;
274         }
275         cobd_exp = cobd_get_exp(obd);
276         return obd_unpackmd(cobd_exp, mem_tgt, disk_src, disk_len);
277 }
278
279 static int cobd_create(struct obd_export *exp, struct obdo *obdo,
280                        struct lov_stripe_md **ea,
281                        struct obd_trans_info *oti)
282 {
283         struct obd_device *obd = class_exp2obd(exp);
284         struct obd_export *cobd_exp;
285
286         if (obd == NULL) {
287                 CERROR("invalid client cookie "LPX64"\n", 
288                        exp->exp_handle.h_cookie);
289                 return -EINVAL;
290         }
291         cobd_exp = cobd_get_exp(obd);
292         return obd_create(cobd_exp, obdo, ea, oti); 
293 }
294
295 static int cobd_destroy(struct obd_export *exp, struct obdo *obdo,
296                         struct lov_stripe_md *ea,
297                         struct obd_trans_info *oti)
298 {
299         struct obd_device *obd = class_exp2obd(exp);
300         struct obd_export *cobd_exp;
301
302         if (obd == NULL) {
303                 CERROR("invalid client cookie "LPX64"\n", 
304                        exp->exp_handle.h_cookie);
305                 return -EINVAL;
306         }
307         cobd_exp = cobd_get_exp(obd);
308         return obd_destroy(cobd_exp, obdo, ea, oti); 
309 }
310
311 static int cobd_precleanup(struct obd_device *obd, int flags)
312 {
313         /* FIXME-WANGDI: do we need some cleanup here? */
314         return 0;
315 }
316
317 static int cobd_getattr(struct obd_export *exp, struct obdo *oa,
318                         struct lov_stripe_md *lsm)
319 {
320         struct obd_device *obd = class_exp2obd(exp);
321         struct obd_export *cobd_exp;
322
323         if (obd == NULL) {
324                 CERROR("invalid client cookie "LPX64"\n", 
325                        exp->exp_handle.h_cookie);
326                 return -EINVAL;
327         }
328         cobd_exp = cobd_get_exp(obd);
329         return obd_getattr(cobd_exp, oa, lsm);
330 }
331
332 static int cobd_getattr_async(struct obd_export *exp,
333                               struct obdo *obdo, struct lov_stripe_md *ea,
334                               struct ptlrpc_request_set *set)
335 {
336         struct obd_device *obd = class_exp2obd(exp);
337         struct obd_export *cobd_exp;
338
339         if (obd == NULL) {
340                 CERROR("invalid client cookie "LPX64"\n", 
341                        exp->exp_handle.h_cookie);
342                 return -EINVAL;
343         }
344         cobd_exp = cobd_get_exp(obd);
345         return obd_getattr_async(cobd_exp, obdo, ea, set);
346 }
347
348 static int cobd_setattr(struct obd_export *exp, struct obdo *obdo,
349                         struct lov_stripe_md *ea,
350                         struct obd_trans_info *oti)
351 {
352         struct obd_device *obd = class_exp2obd(exp);
353         struct obd_export *cobd_exp;
354
355         if (obd == NULL) {
356                 CERROR("invalid client cookie "LPX64"\n", 
357                        exp->exp_handle.h_cookie);
358                 return -EINVAL;
359         }
360         cobd_exp = cobd_get_exp(obd);
361         return obd_setattr(cobd_exp, obdo, ea, oti);
362 }
363
364 static int cobd_md_getstatus(struct obd_export *exp,
365                              struct lustre_id *rootid)
366 {
367         struct obd_device *obd = class_exp2obd(exp);
368         struct obd_export *cobd_exp;
369
370         if (obd == NULL) {
371                 CERROR("invalid client cookie "LPX64"\n", 
372                        exp->exp_handle.h_cookie);
373                 return -EINVAL;
374         }
375         cobd_exp = cobd_get_exp(obd);
376         return md_getstatus(cobd_exp, rootid);
377 }
378
379 static int cobd_brw(int cmd, struct obd_export *exp, struct obdo *oa,
380                     struct lov_stripe_md *ea, obd_count oa_bufs,
381                     struct brw_page *pg, struct obd_trans_info *oti)
382 {
383         struct obd_device *obd = class_exp2obd(exp);
384         struct obd_export *cobd_exp;
385
386         if (obd == NULL) {
387                 CERROR("invalid client cookie "LPX64"\n", 
388                        exp->exp_handle.h_cookie);
389                 return -EINVAL;
390         }
391         cobd_exp = cobd_get_exp(obd);
392         return obd_brw(cmd, cobd_exp, oa, ea, oa_bufs, pg, oti);
393 }
394
395 static int cobd_brw_async(int cmd, struct obd_export *exp,
396                           struct obdo *oa, struct lov_stripe_md *ea,
397                           obd_count oa_bufs, struct brw_page *pg,
398                           struct ptlrpc_request_set *set,
399                           struct obd_trans_info *oti)
400 {
401         struct obd_device *obd = class_exp2obd(exp);
402         struct obd_export *cobd_exp;
403
404         if (obd == NULL) {
405                 CERROR("invalid client cookie "LPX64"\n", 
406                        exp->exp_handle.h_cookie);
407                 return -EINVAL;
408         }
409         cobd_exp = cobd_get_exp(obd);
410         return obd_brw_async(cmd, cobd_exp, oa, ea, oa_bufs, 
411                              pg, set, oti);
412 }
413
414 static int cobd_prep_async_page(struct obd_export *exp, 
415                                 struct lov_stripe_md *lsm,
416                                 struct lov_oinfo *loi, 
417                                 struct page *page, obd_off offset, 
418                                 struct obd_async_page_ops *ops, 
419                                 void *data, void **res)
420 {
421         struct obd_device *obd = class_exp2obd(exp);
422         struct obd_export *cobd_exp;
423
424         if (obd == NULL) {
425                 CERROR("invalid client cookie "LPX64"\n", 
426                        exp->exp_handle.h_cookie);
427                 return -EINVAL;
428         }
429         cobd_exp = cobd_get_exp(obd);
430         return obd_prep_async_page(cobd_exp, lsm, loi, page, offset,
431                                    ops, data, res);
432 }
433
434 static int cobd_queue_async_io(struct obd_export *exp,
435                                struct lov_stripe_md *lsm,
436                                struct lov_oinfo *loi, void *cookie,
437                                int cmd, obd_off off, int count,
438                                obd_flags brw_flags, obd_flags async_flags)
439 {
440         struct obd_device *obd = class_exp2obd(exp);
441         struct obd_export *cobd_exp;
442
443         if (obd == NULL) {
444                 CERROR("invalid client cookie "LPX64"\n", 
445                        exp->exp_handle.h_cookie);
446                 return -EINVAL;
447         }
448         cobd_exp = cobd_get_exp(obd);
449         return obd_queue_async_io(cobd_exp, lsm, loi, cookie, cmd, off, count,
450                                   brw_flags, async_flags);
451 }
452
453 static int cobd_set_async_flags(struct obd_export *exp,
454                                struct lov_stripe_md *lsm,
455                                struct lov_oinfo *loi, void *cookie,
456                                obd_flags async_flags)
457 {
458         struct obd_device *obd = class_exp2obd(exp);
459         struct obd_export *cobd_exp;
460
461         if (obd == NULL) {
462                 CERROR("invalid client cookie "LPX64"\n", 
463                        exp->exp_handle.h_cookie);
464                 return -EINVAL;
465         }
466         cobd_exp = cobd_get_exp(obd);
467         return obd_set_async_flags(cobd_exp, lsm, loi, cookie, async_flags);
468 }
469
470 static int cobd_queue_group_io(struct obd_export *exp, 
471                                struct lov_stripe_md *lsm, 
472                                struct lov_oinfo *loi, 
473                                struct obd_io_group *oig, 
474                                void *cookie, int cmd, obd_off off, 
475                                int count, obd_flags brw_flags,
476                                obd_flags async_flags)
477 {
478         struct obd_device *obd = class_exp2obd(exp);
479         struct obd_export *cobd_exp;
480
481         if (obd == NULL) {
482                 CERROR("invalid client cookie "LPX64"\n", 
483                        exp->exp_handle.h_cookie);
484                 return -EINVAL;
485         }
486         cobd_exp = cobd_get_exp(obd);
487         return obd_queue_group_io(cobd_exp, lsm, loi, oig, cookie,
488                                   cmd, off, count, brw_flags, async_flags);
489 }
490
491 static int cobd_trigger_group_io(struct obd_export *exp, 
492                                  struct lov_stripe_md *lsm, 
493                                  struct lov_oinfo *loi,
494                                  struct obd_io_group *oig)
495 {
496         struct obd_device *obd = class_exp2obd(exp);
497         struct obd_export *cobd_exp;
498
499         if (obd == NULL) {
500                 CERROR("invalid client cookie "LPX64"\n", 
501                        exp->exp_handle.h_cookie);
502                 return -EINVAL;
503         }
504         cobd_exp = cobd_get_exp(obd);
505         return obd_trigger_group_io(cobd_exp, lsm, loi, oig); 
506 }
507
508 static int cobd_teardown_async_page(struct obd_export *exp,
509                                     struct lov_stripe_md *lsm,
510                                     struct lov_oinfo *loi, void *cookie)
511 {
512         struct obd_device *obd = class_exp2obd(exp);
513         struct obd_export *cobd_exp;
514
515         if (obd == NULL) {
516                 CERROR("invalid client cookie "LPX64"\n", 
517                        exp->exp_handle.h_cookie);
518                 return -EINVAL;
519         }
520         cobd_exp = cobd_get_exp(obd);
521         return obd_teardown_async_page(cobd_exp, lsm, loi, cookie);
522 }
523
524 static int cobd_punch(struct obd_export *exp, struct obdo *oa,
525                       struct lov_stripe_md *ea, obd_size start,
526                       obd_size end, struct obd_trans_info *oti)
527 {
528         struct obd_device *obd = class_exp2obd(exp);
529         struct obd_export *cobd_exp;
530
531         if (obd == NULL) {
532                 CERROR("invalid client cookie "LPX64"\n", 
533                        exp->exp_handle.h_cookie);
534                 return -EINVAL;
535         }
536         cobd_exp = cobd_get_exp(obd);
537         return obd_punch(cobd_exp, oa, ea, start, end, oti);
538 }
539
540 static int cobd_sync(struct obd_export *exp, struct obdo *oa,
541                      struct lov_stripe_md *ea, obd_size start, 
542                      obd_size end)
543 {
544         struct obd_device *obd = class_exp2obd(exp);
545         struct obd_export *cobd_exp;
546
547         if (obd == NULL) {
548                 CERROR("invalid client cookie "LPX64"\n", 
549                        exp->exp_handle.h_cookie);
550                 return -EINVAL;
551         }
552         cobd_exp = cobd_get_exp(obd);
553         return obd_sync(cobd_exp, oa, ea, start, end);
554 }
555
556 static int cobd_enqueue(struct obd_export *exp, struct lov_stripe_md *ea,
557                         __u32 type, ldlm_policy_data_t *policy,
558                         __u32 mode, int *flags, void *bl_cb, void *cp_cb,
559                         void *gl_cb, void *data, __u32 lvb_len,
560                         void *lvb_swabber, struct lustre_handle *lockh)
561 {
562         struct obd_device *obd = class_exp2obd(exp);
563         struct obd_export *cobd_exp;
564
565         if (obd == NULL) {
566                 CERROR("invalid client cookie "LPX64"\n", 
567                        exp->exp_handle.h_cookie);
568                 return -EINVAL;
569         }
570         cobd_exp = cobd_get_exp(obd);
571         return obd_enqueue(cobd_exp, ea, type, policy, mode, flags, 
572                            bl_cb, cp_cb, gl_cb, data, lvb_len,
573                            lvb_swabber, lockh);
574 }
575
576 static int cobd_match(struct obd_export *exp, struct lov_stripe_md *ea,
577                       __u32 type, ldlm_policy_data_t *policy, __u32 mode,
578                       int *flags, void *data, struct lustre_handle *lockh)
579 {
580         struct obd_device *obd = class_exp2obd(exp);
581         struct obd_export *cobd_exp;
582
583         if (obd == NULL) {
584                 CERROR("invalid client cookie "LPX64"\n", 
585                        exp->exp_handle.h_cookie);
586                 return -EINVAL;
587         }
588         cobd_exp = cobd_get_exp(obd);
589         return obd_match(cobd_exp, ea, type, policy, mode, flags, data,
590                          lockh); 
591 }
592 static int cobd_change_cbdata(struct obd_export *exp,
593                               struct lov_stripe_md *lsm, 
594                               ldlm_iterator_t it, void *data)
595 {
596         struct obd_device *obd = class_exp2obd(exp);
597         struct obd_export *cobd_exp;
598
599         if (obd == NULL) {
600                 CERROR("invalid client cookie "LPX64"\n", 
601                        exp->exp_handle.h_cookie);
602                 return -EINVAL;
603         }
604         cobd_exp = cobd_get_exp(obd);
605         return obd_change_cbdata(cobd_exp, lsm, it, data);
606 }
607
608 static int cobd_cancel(struct obd_export *exp,
609                        struct lov_stripe_md *ea, __u32 mode,
610                        struct lustre_handle *lockh)
611 {
612         struct obd_device *obd = class_exp2obd(exp);
613         struct obd_export *cobd_exp;
614
615         if (obd == NULL) {
616                 CERROR("invalid client cookie "LPX64"\n", 
617                        exp->exp_handle.h_cookie);
618                 return -EINVAL;
619         }
620         cobd_exp = cobd_get_exp(obd);
621         return obd_cancel(cobd_exp, ea, mode, lockh);
622 }
623
624 static int cobd_cancel_unused(struct obd_export *exp,
625                               struct lov_stripe_md *ea, int flags,
626                               void *opaque)
627 {
628         struct obd_device *obd = class_exp2obd(exp);
629         struct obd_export *cobd_exp;
630
631         if (obd == NULL) {
632                 CERROR("invalid client cookie "LPX64"\n", 
633                        exp->exp_handle.h_cookie);
634                 return -EINVAL;
635         }
636         cobd_exp = cobd_get_exp(obd);
637         return obd_cancel_unused(cobd_exp, ea, flags, opaque);
638 }
639
640 static int cobd_preprw(int cmd, struct obd_export *exp, struct obdo *oa,
641                        int objcount, struct obd_ioobj *obj,
642                        int niocount, struct niobuf_remote *nb,
643                        struct niobuf_local *res, struct obd_trans_info *oti)
644 {
645         struct obd_device *obd = class_exp2obd(exp);
646         struct obd_export *cobd_exp;
647
648         if (obd == NULL) {
649                 CERROR("invalid client cookie "LPX64"\n", 
650                        exp->exp_handle.h_cookie);
651                 return -EINVAL;
652         }
653         cobd_exp = cobd_get_exp(obd);
654         return obd_preprw(cmd, cobd_exp, oa, objcount, obj, niocount, nb, 
655                           res, oti);
656 }
657
658 static int cobd_commitrw(int cmd, struct obd_export *exp, struct obdo *oa,
659                          int objcount, struct obd_ioobj *obj,
660                          int niocount, struct niobuf_local *local,
661                          struct obd_trans_info *oti, int rc)
662 {
663         struct obd_device *obd = class_exp2obd(exp);
664         struct obd_export *cobd_exp;
665
666         if (obd == NULL) {
667                 CERROR("invalid client cookie "LPX64"\n", 
668                        exp->exp_handle.h_cookie);
669                 return -EINVAL;
670         }
671         cobd_exp = cobd_get_exp(obd);
672         return obd_commitrw(cmd, cobd_exp, oa, objcount, obj, niocount, 
673                             local, oti, rc);
674 }
675
676 static int cobd_flush(struct obd_device *obd)
677 {
678         /* flush the filesystem from the cache to the real device. */
679         return 0; 
680 }
681
682 static int cobd_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
683                           void *karg, void *uarg)
684 {
685         struct obd_device *obd = class_exp2obd(exp);
686         struct cache_obd  *cobd = &obd->u.cobd;
687         struct obd_device *master_dev = NULL;
688         struct obd_export *cobd_exp;
689         int rc = 0;
690  
691         switch (cmd) {
692         case OBD_IOC_COBD_CON:
693                 if (!cobd->cache_on) {
694                         struct lustre_handle cache_conn = {0,};
695                         
696                         rc = obd_disconnect(cobd->master_exp, 0);
697                         if (rc != 0)
698                                 CERROR("error %d disconnecting master\n", rc);
699                         rc = connect_to_obd(cobd->cache_name, &cache_conn);
700                         if (rc != 0)
701                                 RETURN(rc); 
702                         cobd->cache_exp = class_conn2export(&cache_conn);
703                         
704                         cobd->cache_on = 1;
705                 }
706                 break;
707         case OBD_IOC_COBD_COFF: 
708                 if (cobd->cache_on) {
709                         struct lustre_handle master_conn = {0,};
710                         struct obd_device *cache_dev = NULL;
711                         int m_easize, m_cooksize;
712
713                         cache_dev = class_exp2obd(cobd->cache_exp); 
714                         m_easize = cache_dev->u.cli.cl_max_mds_easize; 
715                         m_cooksize = cache_dev->u.cli.cl_max_mds_cookiesize; 
716                         rc = obd_disconnect(cobd->cache_exp, 0);
717                         if (rc != 0)
718                                 CERROR("error %d disconnecting master\n", rc);
719
720                         /* FIXME-WANGDI: should we read from master_dev? */
721                         
722                         rc = connect_to_obd(cobd->master_name, &master_conn);
723                         if (rc != 0)
724                                 RETURN(rc); 
725                         cobd->master_exp = class_conn2export(&master_conn);
726                         master_dev = class_exp2obd(cobd->master_exp);
727                         master_dev->u.cli.cl_max_mds_easize = m_easize;
728                         master_dev->u.cli.cl_max_mds_cookiesize = m_cooksize;
729                         cobd->cache_on = 0;
730                 }
731                 break;
732         case OBD_IOC_COBD_CFLUSH:
733                 if (cobd->cache_on) {
734                         cobd->cache_on = 0;
735                         cobd_flush(obd);
736                 }
737                 break;
738         default:
739                 cobd_exp = cobd_get_exp(obd);
740                 rc = obd_iocontrol(cmd, cobd_exp, len, karg, uarg);
741         }
742         
743         return rc;
744 }
745
746 static int cobd_llog_init(struct obd_device *obd, struct obd_llogs *llogs, 
747                           struct obd_device *disk_obd, int count, 
748                           struct llog_catid *logid)
749 {
750         struct obd_export *cobd_exp;
751         struct obd_device *cobd_obd;
752
753         cobd_exp = cobd_get_exp(obd);
754         cobd_obd = class_exp2obd(cobd_exp);
755         
756         return obd_llog_init(cobd_obd, &cobd_obd->obd_llogs, 
757                              disk_obd, count, logid);
758 }
759
760 static int cobd_llog_finish(struct obd_device *obd, struct obd_llogs *llogs, 
761                             int count)
762 {
763         struct obd_export *cobd_exp;
764         struct obd_device *cobd_obd;
765
766         cobd_exp = cobd_get_exp(obd);
767         cobd_obd = class_exp2obd(cobd_exp);
768
769         return obd_llog_finish(cobd_obd, &cobd_obd->obd_llogs, count);
770 }
771
772 static int cobd_notify(struct obd_device *obd, struct obd_device *watched,
773                        int active, void *data)
774 {
775         struct obd_export *cobd_exp;
776
777         cobd_exp = cobd_get_exp(obd);
778
779         return obd_notify(class_exp2obd(cobd_exp), watched, active, data);
780 }
781
782 static int cobd_pin(struct obd_export *exp, obd_id ino, __u32 gen,
783                     int type, struct obd_client_handle *handle, int flag)
784 {
785         struct obd_device *obd = class_exp2obd(exp);
786         struct obd_export *cobd_exp;
787
788         if (obd == NULL) {
789                 CERROR("invalid client cookie "LPX64"\n", 
790                        exp->exp_handle.h_cookie);
791                 return -EINVAL;
792         }
793         cobd_exp = cobd_get_exp(obd);
794
795         return obd_pin(cobd_exp, ino, gen, type, handle, flag);
796 }
797
798 static int cobd_unpin(struct obd_export *exp,
799                       struct obd_client_handle *handle, int flag)
800 {
801         struct obd_device *obd = class_exp2obd(exp);
802         struct obd_export *cobd_exp;
803
804         if (obd == NULL) {
805                 CERROR("invalid client cookie "LPX64"\n", 
806                        exp->exp_handle.h_cookie);
807                 return -EINVAL;
808         }
809         cobd_exp = cobd_get_exp(obd);
810
811         return obd_unpin(cobd_exp, handle, flag);
812 }
813
814 static int cobd_init_ea_size(struct obd_export *exp, int easize, int cookiesize)
815 {
816         struct obd_export *cobd_exp;
817
818         cobd_exp = cobd_get_exp(exp->exp_obd);
819         return obd_init_ea_size(cobd_exp, easize, cookiesize);
820 }
821
822 static int  cobd_import_event(struct obd_device *obd,
823                               struct obd_import *imp,
824                               enum obd_import_event event)
825 {
826         struct obd_export *cobd_exp;
827
828         cobd_exp = cobd_get_exp(obd);
829
830         obd_import_event(class_exp2obd(cobd_exp), imp, event);
831         
832         return 0; 
833 }
834
835 static int cobd_md_getattr(struct obd_export *exp, struct lustre_id *id,
836                            __u64 valid, unsigned int ea_size,
837                            struct ptlrpc_request **request)
838 {
839         struct obd_device *obd = class_exp2obd(exp);
840         struct obd_export *cobd_exp;
841
842         if (obd == NULL) {
843                 CERROR("invalid client cookie "LPX64"\n", 
844                        exp->exp_handle.h_cookie);
845                 return -EINVAL;
846         }
847         cobd_exp = cobd_get_exp(obd);
848         return md_getattr(cobd_exp, id, valid, ea_size, request);
849 }
850
851 static int cobd_md_req2lustre_md (struct obd_export *mdc_exp, 
852                                   struct ptlrpc_request *req, unsigned int offset,
853                                   struct obd_export *osc_exp, struct lustre_md *md)
854 {
855         struct obd_device *obd = class_exp2obd(mdc_exp);
856         struct obd_export *cobd_exp;
857
858         if (obd == NULL) {
859                 CERROR("invalid client cookie "LPX64"\n", 
860                        mdc_exp->exp_handle.h_cookie);
861                 return -EINVAL;
862         }
863         cobd_exp = cobd_get_exp(obd);
864         return md_req2lustre_md(cobd_exp, req, offset, osc_exp, md);
865 }
866
867 static int cobd_md_change_cbdata(struct obd_export *exp, struct lustre_id *id, 
868                                  ldlm_iterator_t it, void *data)
869 {
870         struct obd_device *obd = class_exp2obd(exp);
871         struct obd_export *cobd_exp;
872
873         if (obd == NULL) {
874                 CERROR("invalid client cookie "LPX64"\n", 
875                        exp->exp_handle.h_cookie);
876                 return -EINVAL;
877         }
878         cobd_exp = cobd_get_exp(obd);
879         return md_change_cbdata(cobd_exp, id, it, data);
880 }
881
882 static int cobd_md_getattr_lock(struct obd_export *exp, struct lustre_id *id,
883                                 char *filename, int namelen, __u64 valid,
884                                 unsigned int ea_size, struct ptlrpc_request **request)
885 {
886         struct obd_device *obd = class_exp2obd(exp);
887         struct obd_export *cobd_exp;
888
889         if (obd == NULL) {
890                 CERROR("invalid client cookie "LPX64"\n", 
891                        exp->exp_handle.h_cookie);
892                 return -EINVAL;
893         }
894         cobd_exp = cobd_get_exp(obd);
895         return md_getattr_lock(cobd_exp, id, filename, namelen, valid,
896                                ea_size, request);
897 }
898
899 static int cobd_md_create(struct obd_export *exp, struct mdc_op_data *op_data,
900                           const void *data, int datalen, int mode, 
901                           __u32 uid, __u32 gid, __u64 rdev, 
902                           struct ptlrpc_request **request)
903 {
904         struct obd_device *obd = class_exp2obd(exp);
905         struct obd_export *cobd_exp;
906
907         if (obd == NULL) {
908                 CERROR("invalid client cookie "LPX64"\n", 
909                        exp->exp_handle.h_cookie);
910                 return -EINVAL;
911         }
912         cobd_exp = cobd_get_exp(obd);
913         return md_create(cobd_exp, op_data, data, datalen, mode,
914                          uid, gid, rdev, request);
915 }
916
917 static int cobd_md_unlink(struct obd_export *exp, struct mdc_op_data *data,
918                           struct ptlrpc_request **request)
919 {
920         struct obd_device *obd = class_exp2obd(exp);
921         struct obd_export *cobd_exp;
922
923         if (obd == NULL) {
924                 CERROR("invalid client cookie "LPX64"\n", 
925                        exp->exp_handle.h_cookie);
926                 return -EINVAL;
927         }
928         cobd_exp = cobd_get_exp(obd);
929         return md_unlink(cobd_exp, data, request);
930 }
931
932 static int cobd_md_valid_attrs(struct obd_export *exp,
933                                struct lustre_id *id)
934 {
935         struct obd_device *obd = class_exp2obd(exp);
936         struct obd_export *cobd_exp;
937
938         if (obd == NULL) {
939                 CERROR("invalid client cookie "LPX64"\n", 
940                        exp->exp_handle.h_cookie);
941                 return -EINVAL;
942         }
943         cobd_exp = cobd_get_exp(obd);
944         return md_valid_attrs(cobd_exp, id);
945 }
946
947 static int cobd_md_rename(struct obd_export *exp, struct mdc_op_data *data,
948                           const char *old, int oldlen, const char *new, 
949                           int newlen, struct ptlrpc_request **request)
950 {
951         struct obd_device *obd = class_exp2obd(exp);
952         struct obd_export *cobd_exp;
953
954         if (obd == NULL) {
955                 CERROR("invalid client cookie "LPX64"\n", 
956                        exp->exp_handle.h_cookie);
957                 return -EINVAL;
958         }
959         cobd_exp = cobd_get_exp(obd);
960         return md_rename(cobd_exp, data, old, oldlen, new, newlen, request);
961 }
962
963 static int cobd_md_link(struct obd_export *exp, struct mdc_op_data *data,
964                         struct ptlrpc_request **request)
965 {
966         struct obd_device *obd = class_exp2obd(exp);
967         struct obd_export *cobd_exp;
968
969         if (obd == NULL) {
970                 CERROR("invalid client cookie "LPX64"\n", 
971                        exp->exp_handle.h_cookie);
972                 return -EINVAL;
973         }
974         cobd_exp = cobd_get_exp(obd);
975         return md_link(cobd_exp, data, request);
976 }
977
978 static int cobd_md_setattr(struct obd_export *exp, struct mdc_op_data *data,
979                            struct iattr *iattr, void *ea, int ealen, void *ea2, 
980                            int ea2len, struct ptlrpc_request **request)
981 {
982         struct obd_device *obd = class_exp2obd(exp);
983         struct obd_export *cobd_exp;
984
985         if (obd == NULL) {
986                 CERROR("invalid client cookie "LPX64"\n", 
987                        exp->exp_handle.h_cookie);
988                 return -EINVAL;
989         }
990         cobd_exp = cobd_get_exp(obd);
991         return md_setattr(cobd_exp, data, iattr, ea, ealen, ea2, ea2len, request);
992 }
993
994 static int cobd_md_readpage(struct obd_export *exp,
995                             struct lustre_id *mdc_id,
996                             __u64 offset, struct page *page, 
997                             struct ptlrpc_request **request)
998 {
999         struct obd_device *obd = class_exp2obd(exp);
1000         struct obd_export *cobd_exp;
1001
1002         if (obd == NULL) {
1003                 CERROR("invalid client cookie "LPX64"\n", 
1004                        exp->exp_handle.h_cookie);
1005                 return -EINVAL;
1006         }
1007         cobd_exp = cobd_get_exp(obd);
1008         return md_readpage(cobd_exp, mdc_id, offset, page, request);
1009 }
1010
1011 static int cobd_md_close(struct obd_export *exp, struct obdo *obdo,
1012                          struct obd_client_handle *och, 
1013                          struct ptlrpc_request **request)
1014 {
1015         struct obd_device *obd = class_exp2obd(exp);
1016         struct obd_export *cobd_exp;
1017
1018         if (obd == NULL) {
1019                 CERROR("invalid client cookie "LPX64"\n", 
1020                        exp->exp_handle.h_cookie);
1021                 return -EINVAL;
1022         }
1023         cobd_exp = cobd_get_exp(obd);
1024         return md_close(cobd_exp, obdo, och, request);
1025 }
1026
1027 static int cobd_md_done_writing(struct obd_export *exp, struct obdo *obdo)
1028 {
1029         struct obd_device *obd = class_exp2obd(exp);
1030         struct obd_export *cobd_exp;
1031
1032         if (obd == NULL) {
1033                 CERROR("invalid client cookie "LPX64"\n", 
1034                        exp->exp_handle.h_cookie);
1035                 return -EINVAL;
1036         }
1037         cobd_exp = cobd_get_exp(obd);
1038         return md_done_writing(cobd_exp, obdo);
1039 }
1040
1041 static int cobd_md_sync(struct obd_export *exp, struct lustre_id *id,
1042                         struct ptlrpc_request **request)
1043 {
1044         struct obd_device *obd = class_exp2obd(exp);
1045         struct obd_export *cobd_exp;
1046
1047         if (obd == NULL) {
1048                 CERROR("invalid client cookie "LPX64"\n", 
1049                        exp->exp_handle.h_cookie);
1050                 return -EINVAL;
1051         }
1052         cobd_exp = cobd_get_exp(obd);
1053         
1054         return md_sync(cobd_exp, id, request);
1055 }
1056
1057 static int cobd_md_set_open_replay_data(struct obd_export *exp,
1058                                         struct obd_client_handle *och,
1059                                         struct ptlrpc_request *open_req)
1060 {
1061         struct obd_device *obd = class_exp2obd(exp);
1062         struct obd_export *cobd_exp;
1063
1064         if (obd == NULL) {
1065                 CERROR("invalid client cookie "LPX64"\n", 
1066                        exp->exp_handle.h_cookie);
1067                 return -EINVAL;
1068         }
1069         cobd_exp = cobd_get_exp(obd);
1070         
1071         return md_set_open_replay_data(cobd_exp, och, open_req);
1072 }
1073
1074 static int cobd_md_clear_open_replay_data(struct obd_export *exp,
1075                                           struct obd_client_handle *och)
1076 {
1077         struct obd_device *obd = class_exp2obd(exp);
1078         struct obd_export *cobd_exp;
1079
1080         if (obd == NULL) {
1081                 CERROR("invalid client cookie "LPX64"\n", 
1082                        exp->exp_handle.h_cookie);
1083                 return -EINVAL;
1084         }
1085         cobd_exp = cobd_get_exp(obd);
1086  
1087         return md_clear_open_replay_data(cobd_exp, och);
1088 }
1089
1090 static int cobd_md_store_inode_generation(struct obd_export *exp,
1091                                           struct ptlrpc_request *req, 
1092                                           int reqoff, int repoff)
1093 {
1094         struct obd_device *obd = class_exp2obd(exp);
1095         struct obd_export *cobd_exp;
1096
1097         if (obd == NULL) {
1098                 CERROR("invalid client cookie "LPX64"\n", 
1099                        exp->exp_handle.h_cookie);
1100                 return -EINVAL;
1101         }
1102         cobd_exp = cobd_get_exp(obd);
1103
1104         return md_store_inode_generation(cobd_exp, req, reqoff, repoff);
1105 }
1106
1107 static int cobd_md_set_lock_data(struct obd_export *exp, __u64 *l, void *data)
1108 {
1109         struct obd_device *obd = class_exp2obd(exp);
1110         struct obd_export *cobd_exp;
1111
1112         if (obd == NULL) {
1113                 CERROR("invalid client cookie "LPX64"\n", 
1114                        exp->exp_handle.h_cookie);
1115                 return -EINVAL;
1116         }
1117         cobd_exp = cobd_get_exp(obd);
1118
1119         return md_set_lock_data(cobd_exp, l, data);
1120 }
1121
1122 static int cobd_md_enqueue(struct obd_export *exp, int lock_type,
1123                            struct lookup_intent *it, int lock_mode,
1124                            struct mdc_op_data *data, struct lustre_handle *lockh,
1125                            void *lmm, int lmmsize, 
1126                            ldlm_completion_callback cb_completion,
1127                            ldlm_blocking_callback cb_blocking, void *cb_data)
1128 {
1129         struct obd_device *obd = class_exp2obd(exp);
1130         struct obd_export *cobd_exp;
1131
1132         if (obd == NULL) {
1133                 CERROR("invalid client cookie "LPX64"\n", 
1134                        exp->exp_handle.h_cookie);
1135                 return -EINVAL;
1136         }
1137         cobd_exp = cobd_get_exp(obd);
1138         return md_enqueue(cobd_exp, lock_type, it, lock_mode, data,
1139                           lockh, lmm, lmmsize, cb_completion, cb_blocking,
1140                           cb_data);
1141 }
1142
1143 static int cobd_md_intent_lock(struct obd_export *exp, struct lustre_id *pid, 
1144                                const char *name, int len, void *lmm, int lmmsize,
1145                                struct lustre_id *cid, struct lookup_intent *it,
1146                                int lookup_flags, struct ptlrpc_request **reqp,
1147                                ldlm_blocking_callback cb_blocking)
1148 {
1149         struct obd_device *obd = class_exp2obd(exp);
1150         struct obd_export *cobd_exp;
1151
1152         if (obd == NULL) {
1153                 CERROR("invalid client cookie "LPX64"\n", 
1154                        exp->exp_handle.h_cookie);
1155                 return -EINVAL;
1156         }
1157         cobd_exp = cobd_get_exp(obd);
1158         return md_intent_lock(cobd_exp, pid, name, len, lmm, lmmsize,
1159                               cid, it, lookup_flags, reqp, cb_blocking);
1160 }
1161
1162 static struct obd_device *cobd_md_get_real_obd(struct obd_export *exp,
1163                                                char *name, int len)
1164 {
1165         struct obd_device *obd = class_exp2obd(exp);
1166         struct obd_export *cobd_exp;
1167
1168         if (obd == NULL) {
1169                 CERROR("invalid client cookie "LPX64"\n", 
1170                        exp->exp_handle.h_cookie);
1171                 return NULL;
1172         }
1173         cobd_exp = cobd_get_exp(obd);
1174         return md_get_real_obd(cobd_exp, name, len);
1175 }
1176
1177 static int cobd_md_change_cbdata_name(struct obd_export *exp,
1178                                       struct lustre_id *id, char *name,
1179                                       int namelen, struct lustre_id *id2,
1180                                       ldlm_iterator_t it, void *data)
1181 {
1182         struct obd_device *obd = class_exp2obd(exp);
1183         struct obd_export *cobd_exp;
1184
1185         if (obd == NULL) {
1186                 CERROR("invalid client cookie "LPX64"\n", 
1187                        exp->exp_handle.h_cookie);
1188                 return -EINVAL;
1189         }
1190         cobd_exp = cobd_get_exp(obd);
1191         return md_change_cbdata_name(cobd_exp, id, name, namelen,
1192                                      id2, it, data);
1193 }
1194 static struct obd_ops cobd_obd_ops = {
1195         .o_owner                = THIS_MODULE,
1196         .o_attach               = cobd_attach,
1197         .o_detach               = cobd_detach,
1198         .o_setup                = cobd_setup,
1199         .o_cleanup              = cobd_cleanup,
1200         .o_connect              = cobd_connect,
1201         .o_disconnect           = cobd_disconnect,
1202         .o_set_info             = cobd_set_info,
1203         .o_get_info             = cobd_get_info,
1204         .o_statfs               = cobd_statfs,
1205
1206         .o_packmd               = cobd_packmd,
1207         .o_unpackmd             = cobd_unpackmd,
1208         .o_create               = cobd_create,
1209         .o_destroy              = cobd_destroy,
1210         .o_precleanup           = cobd_precleanup,
1211         .o_getattr              = cobd_getattr,
1212         .o_getattr_async        = cobd_getattr_async,
1213         .o_setattr              = cobd_setattr,
1214
1215         .o_brw                  = cobd_brw,
1216         .o_brw_async            = cobd_brw_async,
1217         .o_prep_async_page      = cobd_prep_async_page,
1218         .o_queue_async_io       = cobd_queue_async_io,
1219         .o_set_async_flags      = cobd_set_async_flags,
1220         .o_queue_group_io       = cobd_queue_group_io,
1221         .o_trigger_group_io     = cobd_trigger_group_io,
1222         .o_teardown_async_page  = cobd_teardown_async_page,
1223         .o_preprw               = cobd_preprw,
1224         .o_punch                = cobd_punch,
1225         .o_sync                 = cobd_sync,
1226         .o_enqueue              = cobd_enqueue,
1227         .o_match                = cobd_match,
1228         .o_change_cbdata        = cobd_change_cbdata,
1229         .o_cancel               = cobd_cancel,
1230         .o_cancel_unused        = cobd_cancel_unused,
1231         .o_iocontrol            = cobd_iocontrol,
1232         .o_commitrw             = cobd_commitrw,
1233         .o_llog_init            = cobd_llog_init,
1234         .o_llog_finish          = cobd_llog_finish,
1235         .o_notify               = cobd_notify,
1236         .o_pin                  = cobd_pin,
1237         .o_unpin                = cobd_unpin,
1238         .o_import_event         = cobd_import_event,
1239         .o_init_ea_size         = cobd_init_ea_size,
1240 };
1241
1242 struct md_ops cobd_md_ops = {
1243         .m_getstatus            = cobd_md_getstatus,
1244         .m_getattr              = cobd_md_getattr,
1245         .m_req2lustre_md        = cobd_md_req2lustre_md,
1246         .m_change_cbdata        = cobd_md_change_cbdata,
1247         .m_getattr_lock         = cobd_md_getattr_lock,
1248         .m_create               = cobd_md_create,
1249         .m_unlink               = cobd_md_unlink,
1250         .m_valid_attrs          = cobd_md_valid_attrs,
1251         .m_rename               = cobd_md_rename,
1252         .m_link                 = cobd_md_link,
1253         .m_setattr              = cobd_md_setattr,
1254         .m_readpage             = cobd_md_readpage,
1255         .m_close                = cobd_md_close,
1256         .m_done_writing         = cobd_md_done_writing,
1257         .m_sync                 = cobd_md_sync,
1258         .m_set_open_replay_data = cobd_md_set_open_replay_data,
1259         .m_clear_open_replay_data = cobd_md_clear_open_replay_data,
1260         .m_store_inode_generation = cobd_md_store_inode_generation,
1261         .m_set_lock_data        = cobd_md_set_lock_data,
1262         .m_enqueue              = cobd_md_enqueue,
1263         .m_get_real_obd         = cobd_md_get_real_obd,
1264         .m_intent_lock          = cobd_md_intent_lock,
1265         .m_change_cbdata_name   = cobd_md_change_cbdata_name,
1266 };
1267
1268 static int __init cobd_init(void)
1269 {
1270         struct lprocfs_static_vars lvars;
1271         ENTRY;
1272
1273         printk(KERN_INFO "Lustre: Caching OBD driver; info@clusterfs.com\n");
1274
1275         lprocfs_init_vars(cobd, &lvars);
1276         RETURN(class_register_type(&cobd_obd_ops, &cobd_md_ops,
1277                                    lvars.module_vars, OBD_CACHE_DEVICENAME));
1278 }
1279
1280 static void /*__exit*/ cobd_exit(void)
1281 {
1282         class_unregister_type(OBD_CACHE_DEVICENAME);
1283 }
1284
1285 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
1286 MODULE_DESCRIPTION("Lustre Caching OBD driver");
1287 MODULE_LICENSE("GPL");
1288
1289 module_init(cobd_init);
1290 module_exit(cobd_exit);