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