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