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