Whamcloud - gitweb
- cleanups in cmobd and others:
[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 "LPX64"\n",
300                        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 *ea_name, int ea_namelen,
970                            unsigned int ea_size, struct ptlrpc_request **request)
971 {
972         struct obd_device *obd = class_exp2obd(exp);
973         struct obd_export *cobd_exp;
974
975         if (obd == NULL) {
976                 CERROR("invalid client cookie "LPX64"\n", 
977                        exp->exp_handle.h_cookie);
978                 return -EINVAL;
979         }
980         cobd_exp = cobd_get_exp(obd);
981         return md_getattr(cobd_exp, id, valid, ea_name, ea_namelen,
982                           ea_size, request);
983 }
984
985 static int cobd_md_req2lustre_md(struct obd_export *mdc_exp, 
986                                  struct ptlrpc_request *req,
987                                  unsigned int offset,
988                                  struct obd_export *osc_exp,
989                                  struct lustre_md *md)
990 {
991         struct obd_device *obd = class_exp2obd(mdc_exp);
992         struct obd_export *cobd_exp;
993
994         if (obd == NULL) {
995                 CERROR("invalid client cookie "LPX64"\n", 
996                        mdc_exp->exp_handle.h_cookie);
997                 return -EINVAL;
998         }
999         cobd_exp = cobd_get_exp(obd);
1000         return md_req2lustre_md(cobd_exp, req, offset, osc_exp, md);
1001 }
1002
1003 static int cobd_md_change_cbdata(struct obd_export *exp, struct lustre_id *id, 
1004                                  ldlm_iterator_t it, void *data)
1005 {
1006         struct obd_device *obd = class_exp2obd(exp);
1007         struct obd_export *cobd_exp;
1008
1009         if (obd == NULL) {
1010                 CERROR("invalid client cookie "LPX64"\n", 
1011                        exp->exp_handle.h_cookie);
1012                 return -EINVAL;
1013         }
1014         cobd_exp = cobd_get_exp(obd);
1015         return md_change_cbdata(cobd_exp, id, it, data);
1016 }
1017
1018 static int cobd_md_getattr_lock(struct obd_export *exp, struct lustre_id *id,
1019                                 char *filename, int namelen, __u64 valid,
1020                                 unsigned int ea_size, struct ptlrpc_request **request)
1021 {
1022         struct obd_device *obd = class_exp2obd(exp);
1023         struct obd_export *cobd_exp;
1024
1025         if (obd == NULL) {
1026                 CERROR("invalid client cookie "LPX64"\n", 
1027                        exp->exp_handle.h_cookie);
1028                 return -EINVAL;
1029         }
1030         cobd_exp = cobd_get_exp(obd);
1031         return md_getattr_lock(cobd_exp, id, filename, namelen, valid,
1032                                ea_size, request);
1033 }
1034
1035 static int cobd_md_create(struct obd_export *exp, struct mdc_op_data *op_data,
1036                           const void *data, int datalen, int mode, 
1037                           __u32 uid, __u32 gid, __u64 rdev, 
1038                           struct ptlrpc_request **request)
1039 {
1040         struct obd_device *obd = class_exp2obd(exp);
1041         struct obd_export *cobd_exp;
1042
1043         if (obd == NULL) {
1044                 CERROR("invalid client cookie "LPX64"\n", 
1045                        exp->exp_handle.h_cookie);
1046                 return -EINVAL;
1047         }
1048         cobd_exp = cobd_get_exp(obd);
1049         return md_create(cobd_exp, op_data, data, datalen, mode,
1050                          uid, gid, rdev, request);
1051 }
1052
1053 static int cobd_md_unlink(struct obd_export *exp,
1054                           struct mdc_op_data *data,
1055                           struct ptlrpc_request **request)
1056 {
1057         struct obd_device *obd = class_exp2obd(exp);
1058         struct obd_export *cobd_exp;
1059
1060         if (obd == NULL) {
1061                 CERROR("invalid client cookie "LPX64"\n", 
1062                        exp->exp_handle.h_cookie);
1063                 return -EINVAL;
1064         }
1065         cobd_exp = cobd_get_exp(obd);
1066         return md_unlink(cobd_exp, data, request);
1067 }
1068
1069 static int cobd_md_valid_attrs(struct obd_export *exp,
1070                                struct lustre_id *id)
1071 {
1072         struct obd_device *obd = class_exp2obd(exp);
1073         struct obd_export *cobd_exp;
1074
1075         if (obd == NULL) {
1076                 CERROR("invalid client cookie "LPX64"\n", 
1077                        exp->exp_handle.h_cookie);
1078                 return -EINVAL;
1079         }
1080         cobd_exp = cobd_get_exp(obd);
1081         return md_valid_attrs(cobd_exp, id);
1082 }
1083
1084 static int cobd_md_rename(struct obd_export *exp, struct mdc_op_data *data,
1085                           const char *old, int oldlen, const char *new, 
1086                           int newlen, struct ptlrpc_request **request)
1087 {
1088         struct obd_device *obd = class_exp2obd(exp);
1089         struct obd_export *cobd_exp;
1090
1091         if (obd == NULL) {
1092                 CERROR("invalid client cookie "LPX64"\n", 
1093                        exp->exp_handle.h_cookie);
1094                 return -EINVAL;
1095         }
1096         cobd_exp = cobd_get_exp(obd);
1097         return md_rename(cobd_exp, data, old, oldlen, new, newlen, request);
1098 }
1099
1100 static int cobd_md_link(struct obd_export *exp, struct mdc_op_data *data,
1101                         struct ptlrpc_request **request)
1102 {
1103         struct obd_device *obd = class_exp2obd(exp);
1104         struct obd_export *cobd_exp;
1105
1106         if (obd == NULL) {
1107                 CERROR("invalid client cookie "LPX64"\n", 
1108                        exp->exp_handle.h_cookie);
1109                 return -EINVAL;
1110         }
1111         cobd_exp = cobd_get_exp(obd);
1112         return md_link(cobd_exp, data, request);
1113 }
1114
1115 static int cobd_md_setattr(struct obd_export *exp, struct mdc_op_data *data,
1116                            struct iattr *iattr, void *ea, int ealen, void *ea2, 
1117                            int ea2len, struct ptlrpc_request **request)
1118 {
1119         struct obd_device *obd = class_exp2obd(exp);
1120         struct obd_export *cobd_exp;
1121
1122         if (obd == NULL) {
1123                 CERROR("invalid client cookie "LPX64"\n", 
1124                        exp->exp_handle.h_cookie);
1125                 return -EINVAL;
1126         }
1127         cobd_exp = cobd_get_exp(obd);
1128         return md_setattr(cobd_exp, data, iattr, ea,
1129                           ealen, ea2, ea2len, request);
1130 }
1131
1132 static int cobd_md_readpage(struct obd_export *exp,
1133                             struct lustre_id *mdc_id,
1134                             __u64 offset, struct page *page, 
1135                             struct ptlrpc_request **request)
1136 {
1137         struct obd_device *obd = class_exp2obd(exp);
1138         struct obd_export *cobd_exp;
1139
1140         if (obd == NULL) {
1141                 CERROR("invalid client cookie "LPX64"\n", 
1142                        exp->exp_handle.h_cookie);
1143                 return -EINVAL;
1144         }
1145         cobd_exp = cobd_get_exp(obd);
1146         return md_readpage(cobd_exp, mdc_id, offset, page, request);
1147 }
1148
1149 static int cobd_md_close(struct obd_export *exp, struct obdo *obdo,
1150                          struct obd_client_handle *och, 
1151                          struct ptlrpc_request **request)
1152 {
1153         struct obd_device *obd = class_exp2obd(exp);
1154         struct obd_export *cobd_exp;
1155
1156         if (obd == NULL) {
1157                 CERROR("invalid client cookie "LPX64"\n", 
1158                        exp->exp_handle.h_cookie);
1159                 return -EINVAL;
1160         }
1161         cobd_exp = cobd_get_exp(obd);
1162         return md_close(cobd_exp, obdo, och, request);
1163 }
1164
1165 static int cobd_md_done_writing(struct obd_export *exp,
1166                                 struct obdo *obdo)
1167 {
1168         struct obd_device *obd = class_exp2obd(exp);
1169         struct obd_export *cobd_exp;
1170
1171         if (obd == NULL) {
1172                 CERROR("invalid client cookie "LPX64"\n", 
1173                        exp->exp_handle.h_cookie);
1174                 return -EINVAL;
1175         }
1176         cobd_exp = cobd_get_exp(obd);
1177         return md_done_writing(cobd_exp, obdo);
1178 }
1179
1180 static int cobd_md_sync(struct obd_export *exp, struct lustre_id *id,
1181                         struct ptlrpc_request **request)
1182 {
1183         struct obd_device *obd = class_exp2obd(exp);
1184         struct obd_export *cobd_exp;
1185
1186         if (obd == NULL) {
1187                 CERROR("invalid client cookie "LPX64"\n", 
1188                        exp->exp_handle.h_cookie);
1189                 return -EINVAL;
1190         }
1191         cobd_exp = cobd_get_exp(obd);
1192         
1193         return md_sync(cobd_exp, id, request);
1194 }
1195
1196 static int cobd_md_set_open_replay_data(struct obd_export *exp,
1197                                         struct obd_client_handle *och,
1198                                         struct ptlrpc_request *open_req)
1199 {
1200         struct obd_device *obd = class_exp2obd(exp);
1201         struct obd_export *cobd_exp;
1202
1203         if (obd == NULL) {
1204                 CERROR("invalid client cookie "LPX64"\n", 
1205                        exp->exp_handle.h_cookie);
1206                 return -EINVAL;
1207         }
1208         cobd_exp = cobd_get_exp(obd);
1209         
1210         return md_set_open_replay_data(cobd_exp, och, open_req);
1211 }
1212
1213 static int cobd_md_clear_open_replay_data(struct obd_export *exp,
1214                                           struct obd_client_handle *och)
1215 {
1216         struct obd_device *obd = class_exp2obd(exp);
1217         struct obd_export *cobd_exp;
1218
1219         if (obd == NULL) {
1220                 CERROR("invalid client cookie "LPX64"\n", 
1221                        exp->exp_handle.h_cookie);
1222                 return -EINVAL;
1223         }
1224         cobd_exp = cobd_get_exp(obd);
1225  
1226         return md_clear_open_replay_data(cobd_exp, och);
1227 }
1228
1229 static int cobd_md_store_inode_generation(struct obd_export *exp,
1230                                           struct ptlrpc_request *req, 
1231                                           int reqoff, int repoff)
1232 {
1233         struct obd_device *obd = class_exp2obd(exp);
1234         struct obd_export *cobd_exp;
1235
1236         if (obd == NULL) {
1237                 CERROR("invalid client cookie "LPX64"\n", 
1238                        exp->exp_handle.h_cookie);
1239                 return -EINVAL;
1240         }
1241         cobd_exp = cobd_get_exp(obd);
1242
1243         return md_store_inode_generation(cobd_exp, req, reqoff, repoff);
1244 }
1245
1246 static int cobd_md_set_lock_data(struct obd_export *exp,
1247                                  __u64 *l, void *data)
1248 {
1249         struct obd_device *obd = class_exp2obd(exp);
1250         struct obd_export *cobd_exp;
1251
1252         if (obd == NULL) {
1253                 CERROR("invalid client cookie "LPX64"\n", 
1254                        exp->exp_handle.h_cookie);
1255                 return -EINVAL;
1256         }
1257         cobd_exp = cobd_get_exp(obd);
1258
1259         return md_set_lock_data(cobd_exp, l, data);
1260 }
1261
1262 static int cobd_md_enqueue(struct obd_export *exp, int lock_type,
1263                            struct lookup_intent *it, int lock_mode,
1264                            struct mdc_op_data *data, struct lustre_handle *lockh,
1265                            void *lmm, int lmmsize, 
1266                            ldlm_completion_callback cb_completion,
1267                            ldlm_blocking_callback cb_blocking, void *cb_data)
1268 {
1269         struct obd_device *obd = class_exp2obd(exp);
1270         struct obd_export *cobd_exp;
1271
1272         if (obd == NULL) {
1273                 CERROR("invalid client cookie "LPX64"\n", 
1274                        exp->exp_handle.h_cookie);
1275                 return -EINVAL;
1276         }
1277         cobd_exp = cobd_get_exp(obd);
1278         return md_enqueue(cobd_exp, lock_type, it, lock_mode, data,
1279                           lockh, lmm, lmmsize, cb_completion, cb_blocking,
1280                           cb_data);
1281 }
1282
1283 static int cobd_md_intent_lock(struct obd_export *exp, struct lustre_id *pid, 
1284                                const char *name, int len, void *lmm, int lmmsize,
1285                                struct lustre_id *cid, struct lookup_intent *it,
1286                                int lookup_flags, struct ptlrpc_request **reqp,
1287                                ldlm_blocking_callback cb_blocking)
1288 {
1289         struct obd_device *obd = class_exp2obd(exp);
1290         struct obd_export *cobd_exp;
1291
1292         if (obd == NULL) {
1293                 CERROR("invalid client cookie "LPX64"\n", 
1294                        exp->exp_handle.h_cookie);
1295                 return -EINVAL;
1296         }
1297         lookup_flags |= LOOKUP_COBD;
1298         cobd_exp = cobd_get_exp(obd);
1299         
1300         return md_intent_lock(cobd_exp, pid, name, len, lmm, lmmsize,
1301                               cid, it, lookup_flags, reqp, cb_blocking);
1302 }
1303
1304 static struct obd_device *cobd_md_get_real_obd(struct obd_export *exp,
1305                                                struct lustre_id *id)
1306 {
1307         struct obd_device *obd = class_exp2obd(exp);
1308         struct obd_export *cobd_exp;
1309
1310         if (obd == NULL) {
1311                 CERROR("invalid client cookie "LPX64"\n", 
1312                        exp->exp_handle.h_cookie);
1313                 return NULL;
1314         }
1315         cobd_exp = cobd_get_exp(obd);
1316         return md_get_real_obd(cobd_exp, id);
1317 }
1318
1319 static int cobd_md_change_cbdata_name(struct obd_export *exp,
1320                                       struct lustre_id *id, char *name,
1321                                       int namelen, struct lustre_id *id2,
1322                                       ldlm_iterator_t it, void *data)
1323 {
1324         struct obd_device *obd = class_exp2obd(exp);
1325         struct obd_export *cobd_exp;
1326
1327         if (obd == NULL) {
1328                 CERROR("invalid client cookie "LPX64"\n", 
1329                        exp->exp_handle.h_cookie);
1330                 return -EINVAL;
1331         }
1332         cobd_exp = cobd_get_exp(obd);
1333         return md_change_cbdata_name(cobd_exp, id, name, namelen,
1334                                      id2, it, data);
1335 }
1336 static struct obd_ops cobd_obd_ops = {
1337         .o_owner                  = THIS_MODULE,
1338         .o_attach                 = cobd_attach,
1339         .o_detach                 = cobd_detach,
1340         .o_setup                  = cobd_setup,
1341         .o_cleanup                = cobd_cleanup,
1342         .o_connect                = cobd_connect,
1343         .o_disconnect             = cobd_disconnect,
1344         .o_set_info               = cobd_set_info,
1345         .o_get_info               = cobd_get_info,
1346         .o_statfs                 = cobd_statfs,
1347
1348         .o_packmd                 = cobd_dt_packmd,
1349         .o_unpackmd               = cobd_dt_unpackmd,
1350         .o_create                 = cobd_dt_create,
1351         .o_destroy                = cobd_dt_destroy,
1352         .o_precleanup             = cobd_dt_precleanup,
1353         .o_getattr                = cobd_dt_getattr,
1354         .o_getattr_async          = cobd_dt_getattr_async,
1355         .o_setattr                = cobd_dt_setattr,
1356         .o_brw                    = cobd_dt_brw,
1357         .o_brw_async              = cobd_dt_brw_async,
1358         .o_prep_async_page        = cobd_dt_prep_async_page,
1359         .o_queue_async_io         = cobd_dt_queue_async_io,
1360         .o_set_async_flags        = cobd_dt_set_async_flags,
1361         .o_queue_group_io         = cobd_dt_queue_group_io,
1362         .o_trigger_group_io       = cobd_dt_trigger_group_io,
1363         .o_teardown_async_page    = cobd_dt_teardown_async_page,
1364         .o_preprw                 = cobd_dt_preprw,
1365         .o_punch                  = cobd_dt_punch,
1366         .o_sync                   = cobd_dt_sync,
1367         .o_enqueue                = cobd_dt_enqueue,
1368         .o_match                  = cobd_dt_match,
1369         .o_change_cbdata          = cobd_dt_change_cbdata,
1370         .o_cancel                 = cobd_dt_cancel,
1371         .o_cancel_unused          = cobd_dt_cancel_unused,
1372         .o_iocontrol              = cobd_dt_iocontrol,
1373         .o_commitrw               = cobd_dt_commitrw,
1374         .o_llog_init              = cobd_dt_llog_init,
1375         .o_llog_finish            = cobd_dt_llog_finish,
1376         .o_notify                 = cobd_dt_notify,
1377         .o_pin                    = cobd_dt_pin,
1378         .o_unpin                  = cobd_dt_unpin,
1379         .o_import_event           = cobd_dt_import_event,
1380         .o_init_ea_size           = cobd_dt_init_ea_size,
1381 };
1382
1383 struct md_ops cobd_md_ops = {
1384         .m_getstatus              = cobd_md_getstatus,
1385         .m_getattr                = cobd_md_getattr,
1386         .m_req2lustre_md          = cobd_md_req2lustre_md,
1387         .m_change_cbdata          = cobd_md_change_cbdata,
1388         .m_getattr_lock           = cobd_md_getattr_lock,
1389         .m_create                 = cobd_md_create,
1390         .m_unlink                 = cobd_md_unlink,
1391         .m_valid_attrs            = cobd_md_valid_attrs,
1392         .m_rename                 = cobd_md_rename,
1393         .m_link                   = cobd_md_link,
1394         .m_setattr                = cobd_md_setattr,
1395         .m_readpage               = cobd_md_readpage,
1396         .m_close                  = cobd_md_close,
1397         .m_done_writing           = cobd_md_done_writing,
1398         .m_sync                   = cobd_md_sync,
1399         .m_set_open_replay_data   = cobd_md_set_open_replay_data,
1400         .m_clear_open_replay_data = cobd_md_clear_open_replay_data,
1401         .m_store_inode_generation = cobd_md_store_inode_generation,
1402         .m_set_lock_data          = cobd_md_set_lock_data,
1403         .m_enqueue                = cobd_md_enqueue,
1404         .m_get_real_obd           = cobd_md_get_real_obd,
1405         .m_intent_lock            = cobd_md_intent_lock,
1406         .m_change_cbdata_name     = cobd_md_change_cbdata_name,
1407 };
1408
1409 static int __init cobd_init(void)
1410 {
1411         struct lprocfs_static_vars lvars;
1412         ENTRY;
1413
1414         printk(KERN_INFO "Lustre: Caching OBD driver; info@clusterfs.com\n");
1415
1416         lprocfs_init_vars(cobd, &lvars);
1417         RETURN(class_register_type(&cobd_obd_ops, &cobd_md_ops,
1418                                    lvars.module_vars, OBD_CACHE_DEVICENAME));
1419 }
1420
1421 static void /*__exit*/ cobd_exit(void)
1422 {
1423         class_unregister_type(OBD_CACHE_DEVICENAME);
1424 }
1425
1426 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
1427 MODULE_DESCRIPTION("Lustre Caching OBD driver");
1428 MODULE_LICENSE("GPL");
1429
1430 module_init(cobd_init);
1431 module_exit(cobd_exit);