Whamcloud - gitweb
f4072ebcedf70d31c55ce2573bc2f9f81528c7e6
[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 //        struct lustre_handle real_conn = {0,}, cache_conn = {0,};
70         struct lustre_handle  cache_conn = {0,};
71         struct obd_device *real;
72         struct obd_device *cache;
73         int rc;
74         ENTRY;
75
76         if (lcfg->lcfg_inllen1 == 0 || lcfg->lcfg_inlbuf1 == NULL) {
77                 CERROR("%s: setup requires real device name\n", 
78                        obd->obd_name);
79                 RETURN(-EINVAL);
80         }
81
82         real = class_name2obd(lcfg->lcfg_inlbuf1);
83         if (real == NULL) {
84                 CERROR("%s: unable to find a client for real: %s\n",
85                        obd->obd_name, lcfg->lcfg_inlbuf1);
86                 RETURN(-EINVAL);
87         }
88
89         if (lcfg->lcfg_inllen2 == 0 || lcfg->lcfg_inlbuf2 == NULL) {
90                 CERROR("%s: setup requires cache device name\n", obd->obd_name);
91                 RETURN(-EINVAL);
92         }
93
94         cache  = class_name2obd(lcfg->lcfg_inlbuf2);
95         if (cache == NULL) {
96                 CERROR("%s: unable to find a client for cache: %s\n",
97                        obd->obd_name, lcfg->lcfg_inlbuf2);
98                 RETURN(-EINVAL);
99         }
100
101         OBD_ALLOC(cobd->cobd_real_name, strlen(lcfg->lcfg_inlbuf1) + 1);
102         if (!cobd->cobd_real_name) 
103                 GOTO(exit, rc = -ENOMEM);
104         memcpy(cobd->cobd_real_name, lcfg->lcfg_inlbuf1, 
105                strlen(lcfg->lcfg_inlbuf1));
106         
107         OBD_ALLOC(cobd->cobd_cache_name, strlen(lcfg->lcfg_inlbuf2) + 1);
108         if (!cobd->cobd_cache_name) 
109                 GOTO(exit, rc = -ENOMEM);
110         memcpy(cobd->cobd_cache_name, lcfg->lcfg_inlbuf2, 
111                strlen(lcfg->lcfg_inlbuf2));
112
113 #if 0        
114         /* don't bother checking attached/setup;
115          * obd_connect() should, and it can change underneath us */
116         rc = connect_to_obd(cobd->cobd_real_name, &real_conn);
117         if (rc != 0)
118                 GOTO(exit, rc);
119         cobd->cobd_real_exp = class_conn2export(&real_conn);
120 #endif        
121         rc = connect_to_obd(cobd->cobd_cache_name, &cache_conn);
122         if (rc != 0) {
123                 obd_disconnect(cobd->cobd_cache_exp, 0);
124                 GOTO(exit, rc);
125         }
126         cobd->cobd_cache_exp = class_conn2export(&cache_conn);
127         
128         cobd->cache_on = 1;
129         if (!strcmp(real->obd_type->typ_name, LUSTRE_MDC_NAME)) {
130                 /* set mds_num for lustre */
131                 int mds_num;
132                 mds_num = REAL_MDS_NUMBER;
133                 obd_set_info(cobd->cobd_real_exp, strlen("mds_num"),
134                              "mds_num", sizeof(mds_num), &mds_num);
135                 mds_num = CACHE_MDS_NUMBER;
136                 obd_set_info(cobd->cobd_cache_exp, strlen("mds_num"),
137                              "mds_num", sizeof(mds_num), &mds_num);
138         }
139         /*default write to real obd*/
140 exit:
141         if (rc) {
142                 if (cobd->cobd_cache_name)
143                         OBD_FREE(cobd->cobd_cache_name, 
144                                  strlen(cobd->cobd_cache_name) + 1);
145                 if (cobd->cobd_real_name)
146                         OBD_FREE(cobd->cobd_real_name, 
147                                  strlen(cobd->cobd_real_name) + 1);
148         }
149         RETURN(rc);
150 }
151
152 static int cobd_cleanup(struct obd_device *obd, int flags)
153 {
154         struct cache_obd  *cobd = &obd->u.cobd;
155         int                rc;
156
157         if (!list_empty(&obd->obd_exports))
158                 return (-EBUSY);
159         
160         if (cobd->cobd_cache_name)
161                 OBD_FREE(cobd->cobd_cache_name, 
162                          strlen(cobd->cobd_cache_name) + 1);
163         if (cobd->cobd_real_name)
164                 OBD_FREE(cobd->cobd_real_name, 
165                          strlen(cobd->cobd_real_name) + 1);
166         if (cobd->cache_on) { 
167                 rc = obd_disconnect(cobd->cobd_cache_exp, flags);
168                 if (rc != 0)
169                         CERROR("error %d disconnecting cache\n", rc);
170         }
171         rc = obd_disconnect(cobd->cobd_real_exp, flags);
172         if (rc != 0)
173                 CERROR("error %d disconnecting real\n", rc);
174         
175         return (rc);
176 }
177
178 struct obd_export *cobd_get_exp(struct obd_device *obd)
179 {
180         struct cache_obd  *cobd = &obd->u.cobd;
181         
182         if (cobd->cache_on)  
183                 return cobd->cobd_cache_exp;
184         else
185                 return cobd->cobd_real_exp;
186 }
187
188 static int
189 cobd_connect(struct lustre_handle *conn, struct obd_device *obd,
190              struct obd_uuid *cluuid, unsigned long connect_flags)
191 {
192         int rc;
193         rc = class_connect(conn, obd, cluuid);
194         return rc; 
195 }
196
197 static int cobd_disconnect(struct obd_export *exp, int flags)
198 {
199         int rc;
200         rc = class_disconnect(exp, 0);
201         return rc; 
202 }
203
204 static int cobd_get_info(struct obd_export *exp, obd_count keylen,
205                          void *key, __u32 *vallen, void *val)
206 {
207         struct obd_device *obd = class_exp2obd(exp);
208         struct obd_export *cobd_exp;
209         if (obd == NULL) {
210                 CERROR("invalid client cookie "LPX64"\n", 
211                        exp->exp_handle.h_cookie);
212                 return -EINVAL;
213         }
214         cobd_exp = cobd_get_exp(obd);
215         /* intercept cache utilisation info? */
216
217         return obd_get_info(cobd_exp, keylen, key, vallen, val);
218 }
219
220 static int cobd_set_info(struct obd_export *exp, obd_count keylen,
221                          void *key, obd_count vallen, void *val)
222 {
223         struct obd_device *obd = class_exp2obd(exp);
224         struct obd_export *cobd_exp;
225
226         if (obd == NULL) {
227                 CERROR("invalid client cookie "LPX64"\n", 
228                        exp->exp_handle.h_cookie);
229                 return -EINVAL;
230         }
231         cobd_exp = cobd_get_exp(obd);
232         /* intercept cache utilisation info? */
233
234         return obd_set_info(cobd_exp, keylen, key, vallen, val);
235 }
236
237 static int cobd_statfs(struct obd_device *obd, struct obd_statfs *osfs,
238                        unsigned long max_age)
239 {
240         struct obd_export *cobd_exp;
241
242         cobd_exp = cobd_get_exp(obd);
243
244         return obd_statfs(class_exp2obd(cobd_exp), osfs, max_age);
245 }
246
247 static int cobd_packmd(struct obd_export *exp,
248                        struct lov_mds_md **disk_tgt,
249                        struct lov_stripe_md *mem_src)
250 {
251         struct obd_device *obd = class_exp2obd(exp);
252         struct obd_export *cobd_exp;
253
254         if (obd == NULL) {
255                 CERROR("invalid client cookie "LPX64"\n", 
256                        exp->exp_handle.h_cookie);
257                 return -EINVAL;
258         }
259         cobd_exp = cobd_get_exp(obd);
260         return obd_packmd(cobd_exp, disk_tgt, mem_src);
261 }
262
263 static int cobd_unpackmd(struct obd_export *exp,
264                          struct lov_stripe_md **mem_tgt,
265                          struct lov_mds_md *disk_src,
266                          int disk_len)
267 {
268         struct obd_device *obd = class_exp2obd(exp);
269         struct obd_export *cobd_exp;
270
271         if (obd == NULL) {
272                 CERROR("invalid client cookie "LPX64"\n", 
273                        exp->exp_handle.h_cookie);
274                 return -EINVAL;
275         }
276         cobd_exp = cobd_get_exp(obd);
277         return obd_unpackmd(cobd_exp, mem_tgt, disk_src, disk_len);
278 }
279
280 static int cobd_create(struct obd_export *exp, struct obdo *obdo,
281                        struct lov_stripe_md **ea,
282                        struct obd_trans_info *oti)
283 {
284         struct obd_device *obd = class_exp2obd(exp);
285         struct obd_export *cobd_exp;
286
287         if (obd == NULL) {
288                 CERROR("invalid client cookie "LPX64"\n", 
289                        exp->exp_handle.h_cookie);
290                 return -EINVAL;
291         }
292         cobd_exp = cobd_get_exp(obd);
293         return obd_create(cobd_exp, obdo, ea, oti); 
294 }
295
296 static int cobd_destroy(struct obd_export *exp, struct obdo *obdo,
297                         struct lov_stripe_md *ea,
298                         struct obd_trans_info *oti)
299 {
300         struct obd_device *obd = class_exp2obd(exp);
301         struct obd_export *cobd_exp;
302
303         if (obd == NULL) {
304                 CERROR("invalid client cookie "LPX64"\n", 
305                        exp->exp_handle.h_cookie);
306                 return -EINVAL;
307         }
308         cobd_exp = cobd_get_exp(obd);
309         return obd_destroy(cobd_exp, obdo, ea, oti); 
310 }
311
312 static int cobd_precleanup(struct obd_device *obd, int flags)
313 {
314         /*FIXME Do we need some cleanup here?*/
315         return 0;
316 }
317
318 static int cobd_getattr(struct obd_export *exp, struct obdo *oa,
319                         struct lov_stripe_md *lsm)
320 {
321         struct obd_device *obd = class_exp2obd(exp);
322         struct obd_export *cobd_exp;
323
324         if (obd == NULL) {
325                 CERROR("invalid client cookie "LPX64"\n", 
326                        exp->exp_handle.h_cookie);
327                 return -EINVAL;
328         }
329         cobd_exp = cobd_get_exp(obd);
330         return obd_getattr(cobd_exp, oa, lsm);
331 }
332
333 static int cobd_getattr_async(struct obd_export *exp,
334                              struct obdo *obdo, struct lov_stripe_md *ea,
335                              struct ptlrpc_request_set *set)
336 {
337         struct obd_device *obd = class_exp2obd(exp);
338         struct obd_export *cobd_exp;
339
340         if (obd == NULL) {
341                 CERROR("invalid client cookie "LPX64"\n", 
342                        exp->exp_handle.h_cookie);
343                 return -EINVAL;
344         }
345         cobd_exp = cobd_get_exp(obd);
346         return obd_getattr_async(cobd_exp, obdo, ea, set);
347 }
348
349 static int cobd_setattr(struct obd_export *exp, struct obdo *obdo,
350                         struct lov_stripe_md *ea,
351                         struct obd_trans_info *oti)
352 {
353         struct obd_device *obd = class_exp2obd(exp);
354         struct obd_export *cobd_exp;
355
356         if (obd == NULL) {
357                 CERROR("invalid client cookie "LPX64"\n", 
358                        exp->exp_handle.h_cookie);
359                 return -EINVAL;
360         }
361         cobd_exp = cobd_get_exp(obd);
362         return obd_setattr(cobd_exp, obdo, ea, oti);
363 }
364
365 static int cobd_md_getstatus(struct obd_export *exp, struct ll_fid *rootfid)
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, rootfid);
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_flag brw_flags, obd_flag 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_flag 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_flag brw_flags,
476                                obd_flag 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 
679         *to the real device */
680         return 0; 
681 }
682
683 static int cobd_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
684                           void *karg, void *uarg)
685 {
686         struct obd_device *obd = class_exp2obd(exp);
687         struct cache_obd  *cobd = &obd->u.cobd;
688         struct obd_device *real_dev = NULL;
689         struct obd_export *cobd_exp;
690         int rc = 0;
691  
692         switch (cmd) {
693         case OBD_IOC_COBD_CON:
694                 if (!cobd->cache_on) {
695                         struct lustre_handle cache_conn = {0,};
696                         
697                         rc = obd_disconnect(cobd->cobd_real_exp, 0);
698                         if (rc != 0)
699                                 CERROR("error %d disconnecting real\n", rc);
700                         rc = connect_to_obd(cobd->cobd_cache_name, &cache_conn);
701                         if (rc != 0)
702                                 RETURN(rc); 
703                         cobd->cobd_cache_exp = class_conn2export(&cache_conn);
704                         
705                         cobd->cache_on = 1;
706                 }
707                 break;
708         case OBD_IOC_COBD_COFF: 
709                 if (cobd->cache_on) {
710                         struct lustre_handle real_conn = {0,};
711                         struct obd_device *cache_dev = NULL;
712                         int m_easize, m_cooksize;
713
714                         cache_dev = class_exp2obd(cobd->cobd_cache_exp); 
715                         m_easize = cache_dev->u.cli.cl_max_mds_easize; 
716                         m_cooksize = cache_dev->u.cli.cl_max_mds_cookiesize; 
717                         rc = obd_disconnect(cobd->cobd_cache_exp, 0);
718                         if (rc != 0)
719                                 CERROR("error %d disconnecting real\n", rc);
720
721                         /*FIXME, should read from real_dev*/
722                         
723                         rc = connect_to_obd(cobd->cobd_real_name, &real_conn);
724                         if (rc != 0)
725                                 RETURN(rc); 
726                         cobd->cobd_real_exp = class_conn2export(&real_conn);
727                         real_dev = class_exp2obd(cobd->cobd_real_exp);
728                         real_dev->u.cli.cl_max_mds_easize = m_easize;
729                         real_dev->u.cli.cl_max_mds_cookiesize = m_cooksize;
730                         cobd->cache_on = 0;
731                 }
732                 break;
733         case OBD_IOC_COBD_CFLUSH:
734                 if (cobd->cache_on) {
735                         cobd->cache_on = 0;
736                         cobd_flush(obd);
737                 }
738                 break;
739         default:
740                 cobd_exp = cobd_get_exp(obd);
741                 rc = obd_iocontrol(cmd, cobd_exp, len, karg, uarg);
742         }
743         
744         return rc;
745 }
746
747 static int cobd_llog_init(struct obd_device *obd, struct obd_llogs *llogs, 
748                           struct obd_device *disk_obd, int count, 
749                           struct llog_catid *logid)
750 {
751         struct obd_export *cobd_exp;
752         struct obd_device *cobd_obd;
753
754         cobd_exp = cobd_get_exp(obd);
755         cobd_obd = class_exp2obd(cobd_exp);
756         
757         return obd_llog_init(cobd_obd, &cobd_obd->obd_llogs, 
758                              disk_obd, count, logid);
759 }
760
761 static int cobd_llog_finish(struct obd_device *obd, struct obd_llogs *llogs, 
762                             int count)
763 {
764         struct obd_export *cobd_exp;
765         struct obd_device *cobd_obd;
766
767         cobd_exp = cobd_get_exp(obd);
768         cobd_obd = class_exp2obd(cobd_exp);
769
770         return obd_llog_finish(cobd_obd, &cobd_obd->obd_llogs, count);
771 }
772
773 static int cobd_notify(struct obd_device *obd, struct obd_device *watched,
774                        int active, void *data)
775 {
776         struct obd_export *cobd_exp;
777
778         cobd_exp = cobd_get_exp(obd);
779
780         return obd_notify(class_exp2obd(cobd_exp), watched, active, data);
781 }
782
783 static int cobd_pin(struct obd_export *exp, obd_id ino, __u32 gen,
784                     int type, struct obd_client_handle *handle, int flag)
785 {
786         struct obd_device *obd = class_exp2obd(exp);
787         struct obd_export *cobd_exp;
788
789         if (obd == NULL) {
790                 CERROR("invalid client cookie "LPX64"\n", 
791                        exp->exp_handle.h_cookie);
792                 return -EINVAL;
793         }
794         cobd_exp = cobd_get_exp(obd);
795
796         return obd_pin(cobd_exp, ino, gen, type, handle, flag);
797 }
798
799 static int cobd_unpin(struct obd_export *exp,
800                       struct obd_client_handle *handle, int flag)
801 {
802         struct obd_device *obd = class_exp2obd(exp);
803         struct obd_export *cobd_exp;
804
805         if (obd == NULL) {
806                 CERROR("invalid client cookie "LPX64"\n", 
807                        exp->exp_handle.h_cookie);
808                 return -EINVAL;
809         }
810         cobd_exp = cobd_get_exp(obd);
811
812         return obd_unpin(cobd_exp, handle, flag);
813 }
814
815 static int cobd_init_ea_size(struct obd_export *exp, int easize, int cookiesize)
816 {
817         struct obd_export *cobd_exp;
818
819         cobd_exp = cobd_get_exp(exp->exp_obd);
820         return obd_init_ea_size(cobd_exp, easize, cookiesize);
821 }
822
823 static int  cobd_import_event(struct obd_device *obd,
824                               struct obd_import *imp,
825                               enum obd_import_event event)
826 {
827         struct obd_export *cobd_exp;
828
829         cobd_exp = cobd_get_exp(obd);
830
831         obd_import_event(class_exp2obd(cobd_exp), imp, event);
832         
833         return 0; 
834 }
835
836 static int cobd_md_getattr(struct obd_export *exp, struct ll_fid *fid,
837                            unsigned long valid, unsigned int ea_size,
838                            struct ptlrpc_request **request)
839 {
840         struct obd_device *obd = class_exp2obd(exp);
841         struct obd_export *cobd_exp;
842
843         if (obd == NULL) {
844                 CERROR("invalid client cookie "LPX64"\n", 
845                        exp->exp_handle.h_cookie);
846                 return -EINVAL;
847         }
848         cobd_exp = cobd_get_exp(obd);
849         return md_getattr(cobd_exp, fid, valid, ea_size, request);
850 }
851
852 static int cobd_md_req2lustre_md (struct obd_export *mdc_exp, 
853                                   struct ptlrpc_request *req, unsigned int offset,
854                                   struct obd_export *osc_exp, struct lustre_md *md)
855 {
856         struct obd_device *obd = class_exp2obd(mdc_exp);
857         struct obd_export *cobd_exp;
858
859         if (obd == NULL) {
860                 CERROR("invalid client cookie "LPX64"\n", 
861                        mdc_exp->exp_handle.h_cookie);
862                 return -EINVAL;
863         }
864         cobd_exp = cobd_get_exp(obd);
865         return md_req2lustre_md(cobd_exp, req, offset, osc_exp, md);
866 }
867
868 static int cobd_md_change_cbdata(struct obd_export *exp, struct ll_fid *fid, 
869                                  ldlm_iterator_t it, void *data)
870 {
871         struct obd_device *obd = class_exp2obd(exp);
872         struct obd_export *cobd_exp;
873
874         if (obd == NULL) {
875                 CERROR("invalid client cookie "LPX64"\n", 
876                        exp->exp_handle.h_cookie);
877                 return -EINVAL;
878         }
879         cobd_exp = cobd_get_exp(obd);
880         return md_change_cbdata(cobd_exp, fid, it, data);
881 }
882
883 static int cobd_md_getattr_name(struct obd_export *exp, struct ll_fid *fid,
884                                 char *filename, int namelen, 
885                                 unsigned long valid,
886                                 unsigned int ea_size, 
887                                 struct ptlrpc_request **request)
888 {
889         struct obd_device *obd = class_exp2obd(exp);
890         struct obd_export *cobd_exp;
891
892         if (obd == NULL) {
893                 CERROR("invalid client cookie "LPX64"\n", 
894                        exp->exp_handle.h_cookie);
895                 return -EINVAL;
896         }
897         cobd_exp = cobd_get_exp(obd);
898         return md_getattr_name(cobd_exp, fid, filename, namelen, valid,
899                                ea_size, request);
900 }
901
902 static int cobd_md_create(struct obd_export *exp, struct mdc_op_data *op_data,
903                           const void *data, int datalen, int mode, 
904                           __u32 uid, __u32 gid, __u64 rdev, 
905                           struct ptlrpc_request **request)
906 {
907         struct obd_device *obd = class_exp2obd(exp);
908         struct obd_export *cobd_exp;
909
910         if (obd == NULL) {
911                 CERROR("invalid client cookie "LPX64"\n", 
912                        exp->exp_handle.h_cookie);
913                 return -EINVAL;
914         }
915         cobd_exp = cobd_get_exp(obd);
916         return md_create(cobd_exp, op_data, data, datalen, mode,
917                          uid, gid, rdev, request);
918 }
919
920 static int cobd_md_unlink(struct obd_export *exp, struct mdc_op_data *data,
921                           struct ptlrpc_request **request)
922 {
923         struct obd_device *obd = class_exp2obd(exp);
924         struct obd_export *cobd_exp;
925
926         if (obd == NULL) {
927                 CERROR("invalid client cookie "LPX64"\n", 
928                        exp->exp_handle.h_cookie);
929                 return -EINVAL;
930         }
931         cobd_exp = cobd_get_exp(obd);
932         return md_unlink(cobd_exp, data, request);
933 }
934
935 static int cobd_md_valid_attrs(struct obd_export *exp, struct ll_fid *fid)
936 {
937         struct obd_device *obd = class_exp2obd(exp);
938         struct obd_export *cobd_exp;
939
940         if (obd == NULL) {
941                 CERROR("invalid client cookie "LPX64"\n", 
942                        exp->exp_handle.h_cookie);
943                 return -EINVAL;
944         }
945         cobd_exp = cobd_get_exp(obd);
946         return md_valid_attrs(cobd_exp, fid);
947 }
948
949 static int cobd_md_rename(struct obd_export *exp, struct mdc_op_data *data,
950                           const char *old, int oldlen, const char *new, 
951                           int newlen, struct ptlrpc_request **request)
952 {
953         struct obd_device *obd = class_exp2obd(exp);
954         struct obd_export *cobd_exp;
955
956         if (obd == NULL) {
957                 CERROR("invalid client cookie "LPX64"\n", 
958                        exp->exp_handle.h_cookie);
959                 return -EINVAL;
960         }
961         cobd_exp = cobd_get_exp(obd);
962         return md_rename(cobd_exp, data, old, oldlen, new, newlen, request);
963 }
964
965 static int cobd_md_link(struct obd_export *exp, struct mdc_op_data *data,
966                         struct ptlrpc_request **request)
967 {
968         struct obd_device *obd = class_exp2obd(exp);
969         struct obd_export *cobd_exp;
970
971         if (obd == NULL) {
972                 CERROR("invalid client cookie "LPX64"\n", 
973                        exp->exp_handle.h_cookie);
974                 return -EINVAL;
975         }
976         cobd_exp = cobd_get_exp(obd);
977         return md_link(cobd_exp, data, request);
978 }
979
980 static int cobd_md_setattr(struct obd_export *exp, struct mdc_op_data *data,
981                            struct iattr *iattr, void *ea, int ealen, void *ea2, 
982                            int ea2len, struct ptlrpc_request **request)
983 {
984         struct obd_device *obd = class_exp2obd(exp);
985         struct obd_export *cobd_exp;
986
987         if (obd == NULL) {
988                 CERROR("invalid client cookie "LPX64"\n", 
989                        exp->exp_handle.h_cookie);
990                 return -EINVAL;
991         }
992         cobd_exp = cobd_get_exp(obd);
993         return md_setattr(cobd_exp, data, iattr, ea, ealen, ea2, ea2len, request);
994 }
995
996 static int cobd_md_readpage(struct obd_export *exp, struct ll_fid *mdc_fid,
997                             __u64 offset, struct page *page, 
998                             struct ptlrpc_request **request)
999 {
1000         struct obd_device *obd = class_exp2obd(exp);
1001         struct obd_export *cobd_exp;
1002
1003         if (obd == NULL) {
1004                 CERROR("invalid client cookie "LPX64"\n", 
1005                        exp->exp_handle.h_cookie);
1006                 return -EINVAL;
1007         }
1008         cobd_exp = cobd_get_exp(obd);
1009         return md_readpage(cobd_exp, mdc_fid, offset, page, request);
1010 }
1011
1012 static int cobd_md_close(struct obd_export *exp, struct obdo *obdo,
1013                          struct obd_client_handle *och, 
1014                          struct ptlrpc_request **request)
1015 {
1016         struct obd_device *obd = class_exp2obd(exp);
1017         struct obd_export *cobd_exp;
1018
1019         if (obd == NULL) {
1020                 CERROR("invalid client cookie "LPX64"\n", 
1021                        exp->exp_handle.h_cookie);
1022                 return -EINVAL;
1023         }
1024         cobd_exp = cobd_get_exp(obd);
1025         return md_close(cobd_exp, obdo, och, request);
1026 }
1027
1028 static int cobd_md_done_writing(struct obd_export *exp, struct obdo *obdo)
1029 {
1030         struct obd_device *obd = class_exp2obd(exp);
1031         struct obd_export *cobd_exp;
1032
1033         if (obd == NULL) {
1034                 CERROR("invalid client cookie "LPX64"\n", 
1035                        exp->exp_handle.h_cookie);
1036                 return -EINVAL;
1037         }
1038         cobd_exp = cobd_get_exp(obd);
1039         return md_done_writing(cobd_exp, obdo);
1040 }
1041
1042 static int cobd_md_sync(struct obd_export *exp, struct ll_fid *fid,
1043                         struct ptlrpc_request **request)
1044 {
1045         struct obd_device *obd = class_exp2obd(exp);
1046         struct obd_export *cobd_exp;
1047
1048         if (obd == NULL) {
1049                 CERROR("invalid client cookie "LPX64"\n", 
1050                        exp->exp_handle.h_cookie);
1051                 return -EINVAL;
1052         }
1053         cobd_exp = cobd_get_exp(obd);
1054         
1055         return md_sync(cobd_exp, fid, request);
1056 }
1057
1058 static int cobd_md_set_open_replay_data(struct obd_export *exp,
1059                                         struct obd_client_handle *och,
1060                                         struct ptlrpc_request *open_req)
1061 {
1062         struct obd_device *obd = class_exp2obd(exp);
1063         struct obd_export *cobd_exp;
1064
1065         if (obd == NULL) {
1066                 CERROR("invalid client cookie "LPX64"\n", 
1067                        exp->exp_handle.h_cookie);
1068                 return -EINVAL;
1069         }
1070         cobd_exp = cobd_get_exp(obd);
1071         
1072         return md_set_open_replay_data(cobd_exp, och, open_req);
1073 }
1074
1075 static int cobd_md_clear_open_replay_data(struct obd_export *exp,
1076                                           struct obd_client_handle *och)
1077 {
1078         struct obd_device *obd = class_exp2obd(exp);
1079         struct obd_export *cobd_exp;
1080
1081         if (obd == NULL) {
1082                 CERROR("invalid client cookie "LPX64"\n", 
1083                        exp->exp_handle.h_cookie);
1084                 return -EINVAL;
1085         }
1086         cobd_exp = cobd_get_exp(obd);
1087  
1088         return md_clear_open_replay_data(cobd_exp, och);
1089 }
1090
1091 static int cobd_md_store_inode_generation(struct obd_export *exp,
1092                                           struct ptlrpc_request *req, 
1093                                           int reqoff, int repoff)
1094 {
1095         struct obd_device *obd = class_exp2obd(exp);
1096         struct obd_export *cobd_exp;
1097
1098         if (obd == NULL) {
1099                 CERROR("invalid client cookie "LPX64"\n", 
1100                        exp->exp_handle.h_cookie);
1101                 return -EINVAL;
1102         }
1103         cobd_exp = cobd_get_exp(obd);
1104
1105         return md_store_inode_generation(cobd_exp, req, reqoff, repoff);
1106 }
1107
1108 static int cobd_md_set_lock_data(struct obd_export *exp, __u64 *l, void *data)
1109 {
1110         struct obd_device *obd = class_exp2obd(exp);
1111         struct obd_export *cobd_exp;
1112
1113         if (obd == NULL) {
1114                 CERROR("invalid client cookie "LPX64"\n", 
1115                        exp->exp_handle.h_cookie);
1116                 return -EINVAL;
1117         }
1118         cobd_exp = cobd_get_exp(obd);
1119
1120         return md_set_lock_data(cobd_exp, l, data);
1121 }
1122
1123 static int cobd_md_enqueue(struct obd_export *exp, int lock_type,
1124                            struct lookup_intent *it, int lock_mode,
1125                            struct mdc_op_data *data, struct lustre_handle *lockh,
1126                            void *lmm, int lmmsize, 
1127                            ldlm_completion_callback cb_completion,
1128                            ldlm_blocking_callback cb_blocking, void *cb_data)
1129 {
1130         struct obd_device *obd = class_exp2obd(exp);
1131         struct obd_export *cobd_exp;
1132
1133         if (obd == NULL) {
1134                 CERROR("invalid client cookie "LPX64"\n", 
1135                        exp->exp_handle.h_cookie);
1136                 return -EINVAL;
1137         }
1138         cobd_exp = cobd_get_exp(obd);
1139         return md_enqueue(cobd_exp, lock_type, it, lock_mode, data,
1140                           lockh, lmm, lmmsize, cb_completion, cb_blocking,
1141                           cb_data);
1142 }
1143
1144 static int cobd_md_intent_lock(struct obd_export *exp,
1145                                struct ll_fid *pfid, const char *name, int len,
1146                                void *lmm, int lmmsize,
1147                                struct ll_fid *cfid, struct lookup_intent *it,
1148                                int lookup_flags, struct ptlrpc_request **reqp,
1149                                ldlm_blocking_callback cb_blocking)
1150 {
1151         struct obd_device *obd = class_exp2obd(exp);
1152         struct obd_export *cobd_exp;
1153
1154         if (obd == NULL) {
1155                 CERROR("invalid client cookie "LPX64"\n", 
1156                        exp->exp_handle.h_cookie);
1157                 return -EINVAL;
1158         }
1159         cobd_exp = cobd_get_exp(obd);
1160         return md_intent_lock(cobd_exp, pfid, name, len, lmm, lmmsize,
1161                               cfid, it, lookup_flags, reqp, cb_blocking);
1162 }
1163
1164 static struct obd_device * cobd_md_get_real_obd(struct obd_export *exp,
1165                                                 char *name, int len)
1166 {
1167         struct obd_device *obd = class_exp2obd(exp);
1168         struct obd_export *cobd_exp;
1169
1170         if (obd == NULL) {
1171                 CERROR("invalid client cookie "LPX64"\n", 
1172                        exp->exp_handle.h_cookie);
1173                 return NULL;
1174         }
1175         cobd_exp = cobd_get_exp(obd);
1176         return md_get_real_obd(cobd_exp, name, len);
1177 }
1178
1179 static int cobd_md_change_cbdata_name(struct obd_export *exp,
1180                                       struct ll_fid *fid, char *name,
1181                                       int namelen, struct ll_fid *fid2,
1182                                       ldlm_iterator_t it, void *data)
1183 {
1184         struct obd_device *obd = class_exp2obd(exp);
1185         struct obd_export *cobd_exp;
1186
1187         if (obd == NULL) {
1188                 CERROR("invalid client cookie "LPX64"\n", 
1189                        exp->exp_handle.h_cookie);
1190                 return -EINVAL;
1191         }
1192         cobd_exp = cobd_get_exp(obd);
1193         return md_change_cbdata_name(cobd_exp, fid, name, namelen, fid2, it, 
1194                                      data);
1195 }
1196 static struct obd_ops cobd_obd_ops = {
1197         .o_owner                = THIS_MODULE,
1198         .o_attach               = cobd_attach,
1199         .o_detach               = cobd_detach,
1200         .o_setup                = cobd_setup,
1201         .o_cleanup              = cobd_cleanup,
1202         .o_connect              = cobd_connect,
1203         .o_disconnect           = cobd_disconnect,
1204         .o_set_info             = cobd_set_info,
1205         .o_get_info             = cobd_get_info,
1206         .o_statfs               = cobd_statfs,
1207
1208         .o_packmd               = cobd_packmd,
1209         .o_unpackmd             = cobd_unpackmd,
1210         .o_create               = cobd_create,
1211         .o_destroy              = cobd_destroy,
1212         .o_precleanup           = cobd_precleanup,
1213         .o_getattr              = cobd_getattr,
1214         .o_getattr_async        = cobd_getattr_async,
1215         .o_setattr              = cobd_setattr,
1216
1217         .o_brw                  = cobd_brw,
1218         .o_brw_async            = cobd_brw_async,
1219         .o_prep_async_page      = cobd_prep_async_page,
1220         .o_queue_async_io       = cobd_queue_async_io,
1221         .o_set_async_flags      = cobd_set_async_flags,
1222         .o_queue_group_io       = cobd_queue_group_io,
1223         .o_trigger_group_io     = cobd_trigger_group_io,
1224         .o_teardown_async_page  = cobd_teardown_async_page,
1225         .o_preprw               = cobd_preprw,
1226         .o_punch                = cobd_punch,
1227         .o_sync                 = cobd_sync,
1228         .o_enqueue              = cobd_enqueue,
1229         .o_match                = cobd_match,
1230         .o_change_cbdata        = cobd_change_cbdata,
1231         .o_cancel               = cobd_cancel,
1232         .o_cancel_unused        = cobd_cancel_unused,
1233         .o_iocontrol            = cobd_iocontrol,
1234         .o_commitrw             = cobd_commitrw,
1235         .o_llog_init            = cobd_llog_init,
1236         .o_llog_finish          = cobd_llog_finish,
1237         .o_notify               = cobd_notify,
1238         .o_pin                  = cobd_pin,
1239         .o_unpin                = cobd_unpin,
1240         .o_import_event         = cobd_import_event,
1241         .o_init_ea_size         = cobd_init_ea_size,
1242 };
1243
1244 struct md_ops cobd_md_ops = {
1245         .m_getstatus            = cobd_md_getstatus,
1246         .m_getattr              = cobd_md_getattr,
1247         .m_req2lustre_md        = cobd_md_req2lustre_md,
1248         .m_change_cbdata        = cobd_md_change_cbdata,
1249         .m_getattr_name         = cobd_md_getattr_name,
1250         .m_create               = cobd_md_create,
1251         .m_unlink               = cobd_md_unlink,
1252         .m_valid_attrs          = cobd_md_valid_attrs,
1253         .m_rename               = cobd_md_rename,
1254         .m_link                 = cobd_md_link,
1255         .m_setattr              = cobd_md_setattr,
1256         .m_readpage             = cobd_md_readpage,
1257         .m_close                = cobd_md_close,
1258         .m_done_writing         = cobd_md_done_writing,
1259         .m_sync                 = cobd_md_sync,
1260         .m_set_open_replay_data = cobd_md_set_open_replay_data,
1261         .m_clear_open_replay_data = cobd_md_clear_open_replay_data,
1262         .m_store_inode_generation = cobd_md_store_inode_generation,
1263         .m_set_lock_data        = cobd_md_set_lock_data,
1264         .m_enqueue              = cobd_md_enqueue,
1265         .m_get_real_obd         = cobd_md_get_real_obd,
1266         .m_intent_lock          = cobd_md_intent_lock,
1267         .m_change_cbdata_name   = cobd_md_change_cbdata_name,
1268 };
1269
1270 static int __init cobd_init(void)
1271 {
1272         struct lprocfs_static_vars lvars;
1273         ENTRY;
1274
1275         printk(KERN_INFO "Lustre: Caching OBD driver; info@clusterfs.com\n");
1276
1277         lprocfs_init_vars(cobd, &lvars);
1278         RETURN(class_register_type(&cobd_obd_ops, &cobd_md_ops,
1279                                    lvars.module_vars, OBD_CACHE_DEVICENAME));
1280 }
1281
1282 static void /*__exit*/ cobd_exit(void)
1283 {
1284         class_unregister_type(OBD_CACHE_DEVICENAME);
1285 }
1286
1287 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
1288 MODULE_DESCRIPTION("Lustre Caching OBD driver");
1289 MODULE_LICENSE("GPL");
1290
1291 module_init(cobd_init);
1292 module_exit(cobd_exit);