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