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