Whamcloud - gitweb
- many fixes about using ENTRY, RETURN, GOTO and EXIT.
[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 #include <linux/obd_lov.h>
36
37 static int cobd_attach(struct obd_device *obd,
38                        obd_count len, void *buf)
39 {
40         struct lprocfs_static_vars lvars;
41         int rc = 0;
42         ENTRY;
43         
44         lprocfs_init_vars(cobd, &lvars);
45         rc = lprocfs_obd_attach(obd, lvars.obd_vars);
46         
47         RETURN(rc);
48 }
49
50 static int cobd_detach(struct obd_device *obd)
51 {
52         ENTRY;
53         RETURN(lprocfs_obd_detach(obd));
54 }
55
56 static int cobd_setup(struct obd_device *obd, obd_count len, void *buf)
57 {
58         struct lustre_cfg *lcfg = (struct lustre_cfg *)buf;
59         int inst_len = 0, mname_len = 0, cname_len = 0;
60         struct obd_device *master_obd, *cache_obd;
61         struct cache_obd  *cobd = &obd->u.cobd;
62         struct lustre_handle conn = { 0 };
63         int rc = 0;
64         ENTRY;
65
66         sema_init(&cobd->sem, 1);
67         
68         if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
69             lustre_cfg_buf(lcfg, 1) == NULL) {
70                 CERROR("%s: setup requires master device name\n", 
71                        obd->obd_name);
72                 RETURN(-EINVAL);
73         }
74
75         if (LUSTRE_CFG_BUFLEN(lcfg, 2) < 1 ||
76             lustre_cfg_buf(lcfg, 2) == NULL) {
77                 CERROR("%s: setup requires cache device name\n",
78                        obd->obd_name);
79                 RETURN(-EINVAL);
80         }
81         inst_len = LUSTRE_CFG_BUFLEN(lcfg, 3);
82         
83         if (inst_len) {
84                 LASSERT(lustre_cfg_buf(lcfg, 3) != NULL);
85                 mname_len = LUSTRE_CFG_BUFLEN(lcfg, 1) + inst_len;  
86                 cname_len = LUSTRE_CFG_BUFLEN(lcfg, 2) + inst_len;  
87         } else {
88                 mname_len = LUSTRE_CFG_BUFLEN(lcfg, 1);
89                 cname_len = LUSTRE_CFG_BUFLEN(lcfg, 2);
90         } 
91        
92         /* get the cache obd name and master name */
93         OBD_ALLOC(cobd->master_name, mname_len);
94         if (!cobd->master_name) 
95                 RETURN(-ENOMEM);
96         if(inst_len)
97                 sprintf(cobd->master_name, "%s-%s", lustre_cfg_string(lcfg, 1), 
98                         lustre_cfg_string(lcfg, 3));
99         else 
100                 sprintf(cobd->master_name, "%s", lustre_cfg_string(lcfg, 1));
101         
102         OBD_ALLOC(cobd->cache_name, cname_len);
103         if (!cobd->cache_name) {
104                 OBD_FREE(cobd->master_name, mname_len);
105                 RETURN(-ENOMEM);
106         } 
107         if (inst_len)
108                 sprintf(cobd->cache_name, "%s-%s", lustre_cfg_string(lcfg, 2), 
109                         lustre_cfg_string(lcfg, 3));
110         else 
111                 sprintf(cobd->cache_name, "%s", lustre_cfg_string(lcfg, 2));
112
113         CDEBUG(D_INFO, "master name %s cache name %s\n", cobd->master_name,
114                cobd->cache_name);
115         
116         /* getting master obd */
117         master_obd = class_name2obd(cobd->master_name);
118         if (!master_obd) {
119                 CERROR("can't find master obd by name %s\n",
120                        cobd->master_name);
121                 GOTO(put_names, rc = -EINVAL);
122         }
123
124         /* connecting master */
125         memset(&conn, 0, sizeof(conn));
126         rc = class_connect(&conn, master_obd, &obd->obd_uuid);
127         if (rc)
128                GOTO(put_names, rc);
129         
130         cobd->master_exp = class_conn2export(&conn);
131
132         /* getting cache obd */
133         cache_obd = class_name2obd(cobd->cache_name);
134         if (!cache_obd) {
135                 class_disconnect(cobd->master_exp, 0);
136                 CERROR("can't find cache obd by name %s\n",
137                        cobd->cache_name);
138                 GOTO(put_names, rc = -EINVAL);
139         }
140
141         /* connecting cache */
142         memset(&conn, 0, sizeof(conn));
143         rc = class_connect(&conn, cache_obd, &obd->obd_uuid);
144         if (rc) {
145                 class_disconnect(cobd->master_exp, 0);
146                 GOTO(put_names, rc);
147         }
148         cobd->cache_exp = class_conn2export(&conn);
149         
150         /* default set cache on, but nothins is realy connected yet, will be
151          * done in cobd_connect() time. */
152         cobd->cache_on = 1;
153
154         /* nothing is connected, make exports reflect this state to not confuse
155          * cobd_switch() later. */
156         cobd->cache_real_exp = NULL;
157         cobd->master_real_exp = NULL;
158         
159         EXIT;
160 put_names:
161         if (rc) {
162                 if (cobd->master_name) {
163                         OBD_FREE(cobd->master_name, LUSTRE_CFG_BUFLEN(lcfg, 1));
164                         cobd->master_name = NULL;
165                 } 
166                 if (cobd->cache_name) {
167                         OBD_FREE(cobd->cache_name, LUSTRE_CFG_BUFLEN(lcfg, 2));
168                         cobd->cache_name = NULL;
169                 }
170         }
171         return rc;
172 }
173
174 static int cobd_cleanup(struct obd_device *obd, int flags)
175 {
176         struct cache_obd  *cobd = &obd->u.cobd;
177         int rc = 0;
178         ENTRY;
179
180         if (!list_empty(&obd->obd_exports))
181                 RETURN(-EBUSY);
182
183         if (cobd->cache_name)
184                 OBD_FREE(cobd->cache_name, 
185                          strlen(cobd->cache_name) + 1);
186         if (cobd->master_name)
187                 OBD_FREE(cobd->master_name, 
188                          strlen(cobd->master_name) + 1);
189         
190         rc = class_disconnect(cobd->master_exp, flags);
191         if (rc) {
192                 CERROR("error disconnecting master, err %d\n",
193                        rc);
194         }
195         rc = class_disconnect(cobd->cache_exp, flags);
196         if (rc) {
197                 CERROR("error disconnecting master, err %d\n",
198                        rc);
199         }
200
201         RETURN(0);
202 }
203
204 static inline struct obd_export *
205 cobd_get_exp(struct obd_device *obd)
206 {
207         struct cache_obd *cobd = &obd->u.cobd;
208         ENTRY;
209         
210         if (cobd->cache_on) {
211                 CDEBUG(D_TRACE, "get cache exp %p \n", cobd->cache_exp); 
212                 if (cobd->cache_real_exp)
213                         RETURN(cobd->cache_real_exp);
214                 RETURN(cobd->cache_exp);
215         }
216         
217         CDEBUG(D_TRACE, "get master exp %p \n", cobd->master_exp);
218         if (cobd->master_real_exp)
219                 RETURN(cobd->master_real_exp); 
220         RETURN(cobd->master_exp);
221 }
222
223 static int cobd_init_dt_desc(struct obd_device *obd)
224 {
225         struct cache_obd *cobd = &obd->u.cobd;
226         struct obd_export *cobd_exp;
227         __u32 valsize;
228         int rc = 0;
229         ENTRY;
230         
231         valsize = sizeof(cobd->dt_desc);
232         memset(&cobd->dt_desc, 0, sizeof(cobd->dt_desc));
233
234         cobd_exp = cobd_get_exp(obd);
235         rc = obd_get_info(cobd_exp, strlen("lovdesc") + 1,
236                           "lovdesc", &valsize, &cobd->dt_desc);
237         RETURN(rc);
238 }
239         
240 static int cobd_init_ea_size(struct obd_device *obd)
241 {
242         int rc = 0, tgt_count, easize, cookiesize;
243         struct cache_obd *cobd = &obd->u.cobd;
244         struct obd_export *cobd_exp;
245         ENTRY;
246
247         tgt_count = cobd->dt_desc.ld_tgt_count;
248
249         /* no EA setup is needed as there is single OST with no LOV */
250         if (tgt_count == 0)
251                 RETURN(0);
252
253         cobd_exp = cobd_get_exp(obd);
254         easize = lov_mds_md_size(tgt_count);
255         cookiesize = tgt_count * sizeof(struct llog_cookie);
256         rc = obd_init_ea_size(cobd_exp, easize, cookiesize);
257         RETURN(rc);
258 }
259
260 static int
261 cobd_connect_client(struct obd_device *obd,
262                     struct obd_export *exp,
263                     struct lustre_handle *conn,
264                     struct obd_connect_data *data,
265                     unsigned long flags)
266
267         struct obd_device *cli_obd;
268         int rc = 0;
269         ENTRY;
270  
271         LASSERT(obd);
272         LASSERT(conn);
273         
274         cli_obd = class_exp2obd(exp);
275         if (cli_obd == NULL) 
276                 RETURN(-EINVAL);
277
278         rc = obd_connect(conn, cli_obd, &obd->obd_uuid,
279                          data, flags);
280         if (rc) 
281                 CERROR("error connecting err %d\n", rc);
282
283         RETURN(rc);
284 }
285
286 static int
287 cobd_disconnect_client(struct obd_device *obd,
288                        struct obd_export *exp,
289                        unsigned long flags)
290 {
291         struct obd_device *cli_obd;
292         int rc = 0;
293         ENTRY;
294
295         cli_obd = class_exp2obd(exp);
296         cli_obd->obd_no_recov = obd->obd_no_recov;
297         
298         rc = obd_disconnect(exp, flags);
299         if (rc) {
300                 CERROR("error disconnecting from %s, err %d\n",
301                        cli_obd->obd_name, rc);
302                 class_export_put(exp);
303         }
304         RETURN(rc);
305 }
306
307 #define COBD_CONNECT (1 << 0)
308 #define COBD_DISCON (1 << 1)
309 #define COBD_BOTH (1 << 2)
310
311 /* magic function for switching cobd between two exports cache and master in
312  * strong correspondence with passed @cache_on. It also may perform partial
313  * actions like only turn off old export or only turn on new one.
314  *
315  * bias == COBD_CONNECT only connect new export (used in cobd_connect())
316  * bias == COBD_DISCON only disconnect old export (used in cobd_disconnect())
317  * bias == COBD_BOTH do both (disconnect old and connect new) (used in
318  * cobd_iocontrol())
319  */
320 static int cobd_switch(struct obd_device *obd,
321                        int cache_on, int bias)
322 {
323         struct cache_obd *cobd = &obd->u.cobd;
324         struct obd_device *cli_obd = NULL;
325         struct lustre_handle conn = {0,};
326         struct obd_export *discon_exp;
327         struct obd_export *conn_exp;
328         int rc = 0;
329         ENTRY;
330
331         if (cache_on) {
332                 discon_exp = cobd->master_real_exp;
333                 conn_exp = cobd->cache_exp;
334         } else {
335                 discon_exp = cobd->cache_real_exp;
336                 conn_exp = cobd->master_exp;
337         }
338
339         /* disconnect old export */
340         if (bias == COBD_BOTH || bias == COBD_DISCON) {
341                 if (discon_exp) {
342                         rc = cobd_disconnect_client(obd, discon_exp, 0);
343                         if (rc) {
344                                 CWARN("can't disconnect export %p, err %d\n",
345                                       discon_exp, rc);
346                         }
347                 }
348                 
349                 if (cache_on)
350                         cobd->master_real_exp = NULL;
351                 else
352                         cobd->cache_real_exp = NULL; 
353         }
354
355         /* connect new export */
356         if (bias == COBD_BOTH || bias == COBD_CONNECT) {
357                 rc = cobd_connect_client(obd, conn_exp, &conn,
358                                          NULL, OBD_OPT_REAL_CLIENT);
359                 if (rc) {
360                         CERROR("can't connect export %p, err %d\n",
361                                conn_exp, rc);
362                         RETURN(rc);
363                 }
364
365                 if (cache_on) {
366                         cobd->cache_real_exp = class_conn2export(&conn);
367                         cli_obd = class_exp2obd(cobd->cache_exp);
368                 } else {
369                         cobd->master_real_exp = class_conn2export(&conn);
370                         cli_obd = class_exp2obd(cobd->master_exp);
371                 }
372         }
373
374         cobd->cache_on = cache_on;
375         
376         if (bias == COBD_BOTH || bias == COBD_CONNECT) {
377                 /* re-init EA size for new selected export. This should be done after
378                  * assigining new state to @cobd->cache_on to not call not connened
379                  * already old export. */
380                 if (obd_md_type(cli_obd)) {
381                         rc = cobd_init_dt_desc(obd);
382                         if (rc == 0) {
383                                 rc = cobd_init_ea_size(obd);
384                                 if (rc) {
385                                         CERROR("can't initialize EA size, "
386                                                "err %d\n", rc);
387                                 }
388                         } else {
389                                 /* ignore cases when we di dnot manage to init
390                                  * lovdesc. This is because some devices may not know
391                                  * "lovdesc" info command. */
392                                 rc = 0;
393                         }
394                 }
395         }
396
397         RETURN(rc);
398 }
399
400 static int
401 cobd_connect(struct lustre_handle *conn, struct obd_device *obd,
402              struct obd_uuid *cluuid, struct obd_connect_data *data,
403              unsigned long flags)
404 {
405         struct cache_obd *cobd = &obd->u.cobd;
406         struct obd_export *exp;
407         int rc = 0;
408         ENTRY;
409
410         rc = class_connect(conn, obd, cluuid);
411         if (rc)
412                 RETURN(rc);
413
414         exp = class_conn2export(conn);
415         rc = cobd_switch(obd, cobd->cache_on,
416                          COBD_CONNECT);
417         if (rc)
418                 class_disconnect(exp, 0);
419         else
420                 class_export_put(exp);
421         RETURN(rc);
422 }
423
424 static int
425 cobd_disconnect(struct obd_export *exp, unsigned long flags)
426 {
427         struct cache_obd *cobd;
428         struct obd_device *obd;
429         int rc = 0;
430         ENTRY;
431         
432         LASSERT(exp != NULL);
433         obd = class_exp2obd(exp);
434         if (obd == NULL) {
435                 CDEBUG(D_IOCTL, "invalid client cookie "
436                        LPX64"\n", exp->exp_handle.h_cookie);
437                 RETURN(-EINVAL);
438         }
439
440         /* here would be nice also to check that disconnect goes to the same
441          * export as connect did. But as now we are accepting the notion that
442          * cache should be switched after client umount this is not needed.
443          * --umka. */
444         cobd = &obd->u.cobd;
445         rc = cobd_switch(obd, cobd->cache_on, COBD_DISCON);
446         class_disconnect(exp, flags);
447
448         RETURN(rc);
449 }
450
451 static int cobd_get_info(struct obd_export *exp, __u32 keylen,
452                          void *key, __u32 *vallen, void *val)
453 {
454         struct obd_device *obd = class_exp2obd(exp);
455         struct obd_export *cobd_exp;
456         int rc = 0;
457         ENTRY;
458         
459         if (obd == NULL) {
460                 CERROR("invalid client cookie "LPX64"\n", 
461                        exp->exp_handle.h_cookie);
462                 RETURN(-EINVAL);
463         }
464         cobd_exp = cobd_get_exp(obd);
465
466         /* intercept cache utilisation info? */
467         rc = obd_get_info(cobd_exp, keylen, key, vallen, val);
468         RETURN(rc);
469 }
470
471 static int cobd_set_info(struct obd_export *exp, obd_count keylen,
472                          void *key, obd_count vallen, void *val)
473 {
474         struct obd_device *obd = class_exp2obd(exp);
475         struct obd_export *cobd_exp;
476         int rc = 0;
477         ENTRY;
478
479         if (obd == NULL) {
480                 CERROR("invalid client cookie "LPX64"\n", 
481                        exp->exp_handle.h_cookie);
482                 RETURN(-EINVAL);
483         }
484         cobd_exp = cobd_get_exp(obd);
485        
486         LASSERT(cobd_exp);
487         
488         /* intercept cache utilisation info? */
489         rc = obd_set_info(cobd_exp, keylen, key, vallen, val);
490         RETURN(rc);
491 }
492
493 static int cobd_statfs(struct obd_device *obd,
494                        struct obd_statfs *osfs,
495                        unsigned long max_age)
496 {
497         struct obd_export *cobd_exp;
498         int rc = 0;
499         ENTRY;
500
501         cobd_exp = cobd_get_exp(obd);
502         rc = obd_statfs(class_exp2obd(cobd_exp), osfs, max_age);
503         RETURN(rc);
504 }
505
506 static int cobd_iocontrol(unsigned int cmd, struct obd_export *exp,
507                           int len, void *karg, void *uarg)
508 {
509         struct obd_device *obd = class_exp2obd(exp);
510         struct cache_obd  *cobd = &obd->u.cobd;
511         struct obd_export *cobd_exp;
512         int rc = 0;
513         ENTRY;
514
515         down(&cobd->sem);
516         
517         /* here would be nice also to make sure somehow that there are no
518          * out-standing requests which go to wrong MDS after cache switch (close
519          * RPCs). But how to check that from COBD? I do not know. --umka */
520         switch (cmd) {
521         case OBD_IOC_COBD_CON:
522                 if (!cobd->cache_on)
523                         rc = cobd_switch(obd, 1, COBD_BOTH);
524                 break;
525         case OBD_IOC_COBD_COFF: 
526                 if (cobd->cache_on)
527                         rc = cobd_switch(obd, 0, COBD_BOTH);
528                 break;
529         default:
530                 cobd_exp = cobd_get_exp(obd);
531                 rc = obd_iocontrol(cmd, cobd_exp, len, karg, uarg);
532         }
533
534         up(&cobd->sem);
535         RETURN(rc);
536 }
537
538 static int cobd_dt_packmd(struct obd_export *exp,
539                           struct lov_mds_md **disk_tgt,
540                           struct lov_stripe_md *mem_src)
541 {
542         struct obd_device *obd = class_exp2obd(exp);
543         struct obd_export *cobd_exp;
544         int rc = 0;
545         ENTRY;
546
547         if (obd == NULL) {
548                 CERROR("invalid client cookie "LPX64"\n", 
549                        exp->exp_handle.h_cookie);
550                 RETURN(-EINVAL);
551         }
552         cobd_exp = cobd_get_exp(obd);
553         rc = obd_packmd(cobd_exp, disk_tgt, mem_src);
554         RETURN(rc);
555 }
556
557 static int cobd_dt_unpackmd(struct obd_export *exp,
558                             struct lov_stripe_md **mem_tgt,
559                             struct lov_mds_md *disk_src,
560                             int disk_len)
561 {
562         struct obd_device *obd = class_exp2obd(exp);
563         struct obd_export *cobd_exp;
564         int rc = 0;
565         ENTRY;
566
567         if (obd == NULL) {
568                 CERROR("invalid client cookie "LPX64"\n", 
569                        exp->exp_handle.h_cookie);
570                 RETURN(-EINVAL);
571         }
572         cobd_exp = cobd_get_exp(obd);
573         rc = obd_unpackmd(cobd_exp, mem_tgt, disk_src, disk_len);
574         RETURN(rc);
575 }
576
577 static int cobd_dt_create(struct obd_export *exp,
578                           struct obdo *obdo,
579                           void *acl, int acl_size,
580                           struct lov_stripe_md **ea,
581                           struct obd_trans_info *oti)
582 {
583         struct obd_device *obd = class_exp2obd(exp);
584         struct obd_export *cobd_exp;
585         int rc = 0;
586         ENTRY;
587
588         if (obd == NULL) {
589                 CERROR("invalid client cookie "LPX64"\n", 
590                        exp->exp_handle.h_cookie);
591                 RETURN(-EINVAL);
592         }
593         cobd_exp = cobd_get_exp(obd);
594         rc = obd_create(cobd_exp, obdo, acl, acl_size, ea, oti);
595         RETURN(rc);
596 }
597
598 static int cobd_dt_destroy(struct obd_export *exp,
599                            struct obdo *obdo,
600                            struct lov_stripe_md *ea,
601                            struct obd_trans_info *oti)
602 {
603         struct obd_device *obd = class_exp2obd(exp);
604         struct obd_export *cobd_exp;
605         int rc = 0;
606         ENTRY;
607
608         if (obd == NULL) {
609                 CERROR("invalid client cookie "LPX64"\n", 
610                        exp->exp_handle.h_cookie);
611                 RETURN(-EINVAL);
612         }
613         cobd_exp = cobd_get_exp(obd);
614         rc = obd_destroy(cobd_exp, obdo, ea, oti);
615         RETURN(rc);
616 }
617
618 static int cobd_dt_precleanup(struct obd_device *obd, int flags)
619 {
620         /* FIXME: do we need some cleanup here? */
621         ENTRY;
622         RETURN(0);
623 }
624
625 static int cobd_dt_getattr(struct obd_export *exp, struct obdo *oa,
626                            struct lov_stripe_md *ea)
627 {
628         struct obd_device *obd = class_exp2obd(exp);
629         struct obd_export *cobd_exp;
630         int rc = 0;
631         ENTRY;
632
633         if (obd == NULL) {
634                 CERROR("invalid client cookie "LPX64"\n", 
635                        exp->exp_handle.h_cookie);
636                 RETURN(-EINVAL);
637         }
638         cobd_exp = cobd_get_exp(obd);
639         rc = obd_getattr(cobd_exp, oa, ea);
640         RETURN(rc);
641 }
642
643 static int cobd_dt_getattr_async(struct obd_export *exp,
644                                  struct obdo *obdo, struct lov_stripe_md *ea,
645                                  struct ptlrpc_request_set *set)
646 {
647         struct obd_device *obd = class_exp2obd(exp);
648         struct obd_export *cobd_exp;
649         int rc = 0;
650         ENTRY;
651
652         if (obd == NULL) {
653                 CERROR("invalid client cookie "LPX64"\n", 
654                        exp->exp_handle.h_cookie);
655                 RETURN(-EINVAL);
656         }
657         cobd_exp = cobd_get_exp(obd);
658         rc = obd_getattr_async(cobd_exp, obdo, ea, set);
659         RETURN(rc);
660 }
661
662 static int cobd_dt_setattr(struct obd_export *exp, struct obdo *obdo,
663                            struct lov_stripe_md *ea,
664                            struct obd_trans_info *oti)
665 {
666         struct obd_device *obd = class_exp2obd(exp);
667         struct obd_export *cobd_exp;
668         int rc = 0;
669         ENTRY;
670
671         if (obd == NULL) {
672                 CERROR("invalid client cookie "LPX64"\n", 
673                        exp->exp_handle.h_cookie);
674                 RETURN(-EINVAL);
675         }
676         cobd_exp = cobd_get_exp(obd);
677         rc = obd_setattr(cobd_exp, obdo, ea, oti);
678         RETURN(rc);
679 }
680
681 static int cobd_dt_brw(int cmd, struct obd_export *exp, struct obdo *oa,
682                        struct lov_stripe_md *ea, obd_count oa_bufs,
683                        struct brw_page *pg, struct obd_trans_info *oti)
684 {
685         struct obd_device *obd = class_exp2obd(exp);
686         struct obd_export *cobd_exp;
687         int rc = 0;
688         ENTRY;
689
690         if (obd == NULL) {
691                 CERROR("invalid client cookie "LPX64"\n", 
692                        exp->exp_handle.h_cookie);
693                 RETURN(-EINVAL);
694         }
695         cobd_exp = cobd_get_exp(obd);
696         rc = obd_brw(cmd, cobd_exp, oa, ea, oa_bufs, pg, oti);
697         RETURN(rc);
698 }
699
700 static int cobd_dt_brw_async(int cmd, struct obd_export *exp,
701                              struct obdo *oa, struct lov_stripe_md *ea,
702                              obd_count oa_bufs, struct brw_page *pg,
703                              struct ptlrpc_request_set *set,
704                              struct obd_trans_info *oti)
705 {
706         struct obd_device *obd = class_exp2obd(exp);
707         struct obd_export *cobd_exp;
708         int rc = 0;
709         ENTRY;
710
711         if (obd == NULL) {
712                 CERROR("invalid client cookie "LPX64"\n", 
713                        exp->exp_handle.h_cookie);
714                 RETURN(-EINVAL);
715         }
716         cobd_exp = cobd_get_exp(obd);
717         rc = obd_brw_async(cmd, cobd_exp, oa, ea, oa_bufs, 
718                            pg, set, oti);
719         RETURN(rc);
720 }
721
722 static int cobd_dt_prep_async_page(struct obd_export *exp, 
723                                    struct lov_stripe_md *lsm,
724                                    struct lov_oinfo *loi, 
725                                    struct page *page, obd_off offset, 
726                                    struct obd_async_page_ops *ops, 
727                                    void *data, void **res)
728 {
729         struct obd_device *obd = class_exp2obd(exp);
730         struct obd_export *cobd_exp;
731         int rc = 0;
732         ENTRY;
733
734         if (obd == NULL) {
735                 CERROR("invalid client cookie "LPX64"\n", 
736                        exp->exp_handle.h_cookie);
737                 RETURN(-EINVAL);
738         }
739         cobd_exp = cobd_get_exp(obd);
740         rc = obd_prep_async_page(cobd_exp, lsm, loi, page,
741                                  offset, ops, data, res);
742         RETURN(rc);
743 }
744
745 static int cobd_dt_queue_async_io(struct obd_export *exp,
746                                   struct lov_stripe_md *lsm,
747                                   struct lov_oinfo *loi, void *cookie,
748                                   int cmd, obd_off off, int count,
749                                   obd_flags brw_flags, obd_flags async_flags)
750 {
751         struct obd_device *obd = class_exp2obd(exp);
752         struct obd_export *cobd_exp;
753         int rc = 0;
754         ENTRY;
755
756         if (obd == NULL) {
757                 CERROR("invalid client cookie "LPX64"\n", 
758                        exp->exp_handle.h_cookie);
759                 RETURN(-EINVAL);
760         }
761         cobd_exp = cobd_get_exp(obd);
762         rc = obd_queue_async_io(cobd_exp, lsm, loi, cookie, cmd, off,
763                                 count, brw_flags, async_flags);
764         RETURN(rc);
765 }
766
767 static int cobd_dt_set_async_flags(struct obd_export *exp,
768                                    struct lov_stripe_md *lsm,
769                                    struct lov_oinfo *loi, void *cookie,
770                                    obd_flags async_flags)
771 {
772         struct obd_device *obd = class_exp2obd(exp);
773         struct obd_export *cobd_exp;
774         int rc = 0;
775         ENTRY;
776
777         if (obd == NULL) {
778                 CERROR("invalid client cookie "LPX64"\n", 
779                        exp->exp_handle.h_cookie);
780                 RETURN(-EINVAL);
781         }
782         cobd_exp = cobd_get_exp(obd);
783         rc = obd_set_async_flags(cobd_exp, lsm, loi, cookie,
784                                  async_flags);
785         RETURN(rc);
786 }
787
788 static int cobd_dt_queue_group_io(struct obd_export *exp, 
789                                   struct lov_stripe_md *lsm, 
790                                   struct lov_oinfo *loi, 
791                                   struct obd_io_group *oig, 
792                                   void *cookie, int cmd, obd_off off, 
793                                   int count, obd_flags brw_flags,
794                                   obd_flags async_flags)
795 {
796         struct obd_device *obd = class_exp2obd(exp);
797         struct obd_export *cobd_exp;
798         int rc = 0;
799         ENTRY;
800
801         if (obd == NULL) {
802                 CERROR("invalid client cookie "LPX64"\n", 
803                        exp->exp_handle.h_cookie);
804                 RETURN(-EINVAL);
805         }
806         cobd_exp = cobd_get_exp(obd);
807         rc = obd_queue_group_io(cobd_exp, lsm, loi, oig, cookie,
808                                 cmd, off, count, brw_flags,
809                                 async_flags);
810         RETURN(rc);
811 }
812
813 static int cobd_dt_trigger_group_io(struct obd_export *exp, 
814                                     struct lov_stripe_md *lsm, 
815                                     struct lov_oinfo *loi,
816                                     struct obd_io_group *oig)
817 {
818         struct obd_device *obd = class_exp2obd(exp);
819         struct obd_export *cobd_exp;
820         int rc = 0;
821         ENTRY;
822
823         if (obd == NULL) {
824                 CERROR("invalid client cookie "LPX64"\n", 
825                        exp->exp_handle.h_cookie);
826                 RETURN(-EINVAL);
827         }
828         cobd_exp = cobd_get_exp(obd);
829         rc = obd_trigger_group_io(cobd_exp, lsm, loi, oig);
830         RETURN(rc);
831 }
832
833 static int cobd_dt_teardown_async_page(struct obd_export *exp,
834                                        struct lov_stripe_md *lsm,
835                                        struct lov_oinfo *loi,
836                                        void *cookie)
837 {
838         struct obd_device *obd = class_exp2obd(exp);
839         struct obd_export *cobd_exp;
840         int rc = 0;
841         ENTRY;
842
843         if (obd == NULL) {
844                 CERROR("invalid client cookie "LPX64"\n", 
845                        exp->exp_handle.h_cookie);
846                 RETURN(-EINVAL);
847         }
848         cobd_exp = cobd_get_exp(obd);
849         rc = obd_teardown_async_page(cobd_exp, lsm, loi, cookie);
850         RETURN(rc);
851 }
852
853 static int cobd_dt_punch(struct obd_export *exp, struct obdo *oa,
854                          struct lov_stripe_md *ea, obd_size start,
855                          obd_size end, struct obd_trans_info *oti,
856                          struct lustre_capa *capa)
857 {
858         struct obd_device *obd = class_exp2obd(exp);
859         struct obd_export *cobd_exp;
860         int rc = 0;
861         ENTRY;
862
863         if (obd == NULL) {
864                 CERROR("invalid client cookie "LPX64"\n", 
865                        exp->exp_handle.h_cookie);
866                 RETURN(-EINVAL);
867         }
868         cobd_exp = cobd_get_exp(obd);
869         rc = obd_punch(cobd_exp, oa, ea, start, end, oti, capa);
870         RETURN(rc);
871 }
872
873 static int cobd_dt_sync(struct obd_export *exp, struct obdo *oa,
874                         struct lov_stripe_md *ea, obd_size start, 
875                         obd_size end)
876 {
877         struct obd_device *obd = class_exp2obd(exp);
878         struct obd_export *cobd_exp;
879         int rc = 0;
880         ENTRY;
881
882         if (obd == NULL) {
883                 CERROR("invalid client cookie "LPX64"\n", 
884                        exp->exp_handle.h_cookie);
885                 RETURN(-EINVAL);
886         }
887         cobd_exp = cobd_get_exp(obd);
888         rc = obd_sync(cobd_exp, oa, ea, start, end);
889         RETURN(rc);
890 }
891
892 static int cobd_dt_enqueue(struct obd_export *exp, struct lov_stripe_md *ea,
893                            __u32 type, ldlm_policy_data_t *policy,
894                            __u32 mode, int *flags, void *bl_cb, void *cp_cb,
895                            void *gl_cb, void *data, __u32 lvb_len,
896                            void *lvb_swabber, struct lustre_handle *lockh)
897 {
898         struct obd_device *obd = class_exp2obd(exp);
899         struct obd_export *cobd_exp;
900         int rc = 0;
901         ENTRY;
902
903         if (obd == NULL) {
904                 CERROR("invalid client cookie "LPX64"\n", 
905                        exp->exp_handle.h_cookie);
906                 RETURN(-EINVAL);
907         }
908         cobd_exp = cobd_get_exp(obd);
909         rc = obd_enqueue(cobd_exp, ea, type, policy, mode, flags, 
910                          bl_cb, cp_cb, gl_cb, data, lvb_len,
911                          lvb_swabber, lockh);
912         RETURN(rc);
913 }
914
915 static int cobd_dt_match(struct obd_export *exp, struct lov_stripe_md *ea,
916                          __u32 type, ldlm_policy_data_t *policy, __u32 mode,
917                          int *flags, void *data, struct lustre_handle *lockh)
918 {
919         struct obd_device *obd = class_exp2obd(exp);
920         struct obd_export *cobd_exp;
921         int rc = 0;
922         ENTRY;
923
924         if (obd == NULL) {
925                 CERROR("invalid client cookie "LPX64"\n", 
926                        exp->exp_handle.h_cookie);
927                 RETURN(-EINVAL);
928         }
929         cobd_exp = cobd_get_exp(obd);
930         rc = obd_match(cobd_exp, ea, type, policy, mode, flags,
931                        data, lockh);
932         RETURN(rc);
933 }
934 static int cobd_dt_change_cbdata(struct obd_export *exp,
935                                  struct lov_stripe_md *lsm, 
936                                  ldlm_iterator_t it, void *data)
937 {
938         struct obd_device *obd = class_exp2obd(exp);
939         struct obd_export *cobd_exp;
940         int rc = 0;
941         ENTRY;
942
943         if (obd == NULL) {
944                 CERROR("invalid client cookie "LPX64"\n", 
945                        exp->exp_handle.h_cookie);
946                 RETURN(-EINVAL);
947         }
948         cobd_exp = cobd_get_exp(obd);
949         rc = obd_change_cbdata(cobd_exp, lsm, it, data);
950         RETURN(rc);
951 }
952
953 static int cobd_dt_cancel(struct obd_export *exp,
954                           struct lov_stripe_md *ea, __u32 mode,
955                           struct lustre_handle *lockh)
956 {
957         struct obd_device *obd = class_exp2obd(exp);
958         struct obd_export *cobd_exp;
959         int rc = 0;
960         ENTRY;
961
962         if (obd == NULL) {
963                 CERROR("invalid client cookie "LPX64"\n", 
964                        exp->exp_handle.h_cookie);
965                 RETURN(-EINVAL);
966         }
967         cobd_exp = cobd_get_exp(obd);
968         rc = obd_cancel(cobd_exp, ea, mode, lockh);
969         RETURN(rc);
970 }
971
972 static int cobd_dt_cancel_unused(struct obd_export *exp,
973                                  struct lov_stripe_md *ea,
974                                  int flags, void *opaque)
975 {
976         struct obd_device *obd = class_exp2obd(exp);
977         struct obd_export *cobd_exp;
978         int rc = 0;
979         ENTRY;
980         
981         if (obd == NULL) {
982                 CERROR("invalid client cookie "LPX64"\n", 
983                        exp->exp_handle.h_cookie);
984                 RETURN(-EINVAL);
985         }
986         cobd_exp = cobd_get_exp(obd);
987         rc = obd_cancel_unused(cobd_exp, ea, flags, opaque);
988         RETURN(rc);
989 }
990
991 static int cobd_dt_preprw(int cmd, struct obd_export *exp,
992                           struct obdo *oa, int objcount,
993                           struct obd_ioobj *obj, int niocount,
994                           struct niobuf_remote *nb,
995                           struct niobuf_local *res,
996                           struct obd_trans_info *oti,
997                           struct lustre_capa *capa)
998 {
999         struct obd_device *obd = class_exp2obd(exp);
1000         struct obd_export *cobd_exp;
1001         int rc = 0;
1002         ENTRY;
1003
1004         if (obd == NULL) {
1005                 CERROR("invalid client cookie "LPX64"\n", 
1006                        exp->exp_handle.h_cookie);
1007                 RETURN(-EINVAL);
1008         }
1009         cobd_exp = cobd_get_exp(obd);
1010         rc = obd_preprw(cmd, cobd_exp, oa, objcount, obj,
1011                           niocount, nb, res, oti, capa);
1012         RETURN(rc);
1013 }
1014
1015 static int cobd_dt_commitrw(int cmd, struct obd_export *exp, struct obdo *oa,
1016                             int objcount, struct obd_ioobj *obj,
1017                             int niocount, struct niobuf_local *local,
1018                             struct obd_trans_info *oti, int rc)
1019 {
1020         struct obd_device *obd = class_exp2obd(exp);
1021         struct obd_export *cobd_exp;
1022         int err = 0;
1023         ENTRY;
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         err = obd_commitrw(cmd, cobd_exp, oa, objcount, obj,
1032                            niocount, local, oti, rc);
1033         RETURN(err);
1034 }
1035
1036 static int cobd_dt_adjust_kms(struct obd_export *exp,
1037                               struct lov_stripe_md *lsm,
1038                               obd_off size, int shrink)
1039 {
1040         struct obd_device *obd = class_exp2obd(exp);
1041         struct obd_export *cobd_exp;
1042         int rc = 0;
1043         ENTRY;
1044
1045         if (obd == NULL) {
1046                 CERROR("invalid client cookie "LPX64"\n", 
1047                        exp->exp_handle.h_cookie);
1048                 RETURN(-EINVAL);
1049         }
1050         cobd_exp = cobd_get_exp(obd);
1051         rc = obd_adjust_kms(cobd_exp, lsm, size, shrink);
1052         
1053         RETURN(rc);
1054 }
1055
1056 static int cobd_dt_llog_init(struct obd_device *obd,
1057                              struct obd_llogs *llogs, 
1058                              struct obd_device *disk_obd,
1059                              int count, struct llog_catid *logid)
1060 {
1061         struct obd_export *cobd_exp;
1062         struct obd_device *cobd_obd;
1063         int rc = 0;
1064         ENTRY;
1065
1066         cobd_exp = cobd_get_exp(obd);
1067         cobd_obd = class_exp2obd(cobd_exp);
1068         
1069         rc = obd_llog_init(cobd_obd, &cobd_obd->obd_llogs, 
1070                            disk_obd, count, logid);
1071         RETURN(rc);
1072 }
1073
1074 static int cobd_dt_llog_finish(struct obd_device *obd,
1075                                struct obd_llogs *llogs, 
1076                                int count)
1077 {
1078         struct obd_export *cobd_exp;
1079         struct obd_device *cobd_obd;
1080         int rc = 0;
1081         ENTRY;
1082
1083         cobd_exp = cobd_get_exp(obd);
1084         cobd_obd = class_exp2obd(cobd_exp);
1085
1086         rc = obd_llog_finish(cobd_obd, &cobd_obd->obd_llogs, count);
1087         RETURN(rc);
1088 }
1089
1090 static int cobd_dt_notify(struct obd_device *obd, struct obd_device *watched,
1091                           int active, void *data)
1092 {
1093         struct obd_export *cobd_exp;
1094         int rc = 0;
1095         ENTRY;
1096
1097         cobd_exp = cobd_get_exp(obd);
1098         rc = obd_notify(class_exp2obd(cobd_exp), watched, active, data);
1099         RETURN(rc);
1100 }
1101
1102 static int cobd_dt_pin(struct obd_export *exp, obd_id ino, __u32 gen,
1103                        int type, struct obd_client_handle *handle,
1104                        int flag)
1105 {
1106         struct obd_device *obd = class_exp2obd(exp);
1107         struct obd_export *cobd_exp;
1108         int rc = 0;
1109         ENTRY;
1110
1111         if (obd == NULL) {
1112                 CERROR("invalid client cookie "LPX64"\n", 
1113                        exp->exp_handle.h_cookie);
1114                 RETURN(-EINVAL);
1115         }
1116         cobd_exp = cobd_get_exp(obd);
1117         rc = obd_pin(cobd_exp, ino, gen, type, handle, flag);
1118         RETURN(rc);
1119 }
1120
1121 static int cobd_dt_unpin(struct obd_export *exp,
1122                          struct obd_client_handle *handle,
1123                          int flag)
1124 {
1125         struct obd_device *obd = class_exp2obd(exp);
1126         struct obd_export *cobd_exp;
1127         int rc = 0;
1128         ENTRY;
1129
1130         if (obd == NULL) {
1131                 CERROR("invalid client cookie "LPX64"\n", 
1132                        exp->exp_handle.h_cookie);
1133                 RETURN(-EINVAL);
1134         }
1135         cobd_exp = cobd_get_exp(obd);
1136         rc = obd_unpin(cobd_exp, handle, flag);
1137         RETURN(rc);
1138 }
1139
1140 static int cobd_dt_init_ea_size(struct obd_export *exp, int easize,
1141                                 int cookiesize)
1142 {
1143         struct obd_export *cobd_exp;
1144         int rc = 0;
1145         ENTRY;
1146
1147         cobd_exp = cobd_get_exp(exp->exp_obd);
1148         rc = obd_init_ea_size(cobd_exp, easize, cookiesize);
1149         RETURN(rc);
1150 }
1151
1152 static int cobd_dt_import_event(struct obd_device *obd,
1153                                 struct obd_import *imp,
1154                                 enum obd_import_event event)
1155 {
1156         struct obd_export *cobd_exp;
1157         ENTRY;
1158
1159         cobd_exp = cobd_get_exp(obd);
1160         obd_import_event(class_exp2obd(cobd_exp), imp, event);
1161         RETURN(0); 
1162 }
1163
1164 static int cobd_md_getstatus(struct obd_export *exp,
1165                              struct lustre_id *rootid)
1166 {
1167         struct obd_device *obd = class_exp2obd(exp);
1168         struct obd_export *cobd_exp;
1169         int rc = 0;
1170         ENTRY;
1171
1172         if (obd == NULL) {
1173                 CERROR("invalid client cookie "LPX64"\n", 
1174                        exp->exp_handle.h_cookie);
1175                 RETURN(-EINVAL);
1176         }
1177         cobd_exp = cobd_get_exp(obd);
1178         rc = md_getstatus(cobd_exp, rootid);
1179         RETURN(rc);
1180 }
1181
1182 static int cobd_md_getattr(struct obd_export *exp, struct lustre_id *id,
1183                            __u64 valid, const char *xattr_name,
1184                            const void *xattr_data, unsigned int xattr_datalen,
1185                            unsigned int ea_size, struct obd_capa *ocapa,
1186                            struct ptlrpc_request **request)
1187 {
1188         struct obd_device *obd = class_exp2obd(exp);
1189         struct obd_export *cobd_exp;
1190         int rc = 0;
1191         ENTRY;
1192
1193         if (obd == NULL) {
1194                 CERROR("invalid client cookie "LPX64"\n", 
1195                        exp->exp_handle.h_cookie);
1196                 RETURN(-EINVAL);
1197         }
1198         cobd_exp = cobd_get_exp(obd);
1199         rc = md_getattr(cobd_exp, id, valid, xattr_name, xattr_data,
1200                           xattr_datalen, ea_size, ocapa, request);
1201         RETURN(rc);
1202 }
1203
1204 static int cobd_md_req2lustre_md(struct obd_export *mdc_exp, 
1205                                  struct ptlrpc_request *req,
1206                                  unsigned int offset,
1207                                  struct obd_export *osc_exp,
1208                                  struct lustre_md *md)
1209 {
1210         struct obd_device *obd = class_exp2obd(mdc_exp);
1211         struct obd_export *cobd_exp;
1212         int rc = 0;
1213         ENTRY;
1214
1215         if (obd == NULL) {
1216                 CERROR("invalid client cookie "LPX64"\n", 
1217                        mdc_exp->exp_handle.h_cookie);
1218                 RETURN(-EINVAL);
1219         }
1220         cobd_exp = cobd_get_exp(obd);
1221         rc = md_req2lustre_md(cobd_exp, req, offset, osc_exp, md);
1222         RETURN(rc);
1223 }
1224
1225 static int cobd_md_change_cbdata(struct obd_export *exp, struct lustre_id *id, 
1226                                  ldlm_iterator_t it, void *data)
1227 {
1228         struct obd_device *obd = class_exp2obd(exp);
1229         struct obd_export *cobd_exp;
1230         int rc = 0;
1231         ENTRY;
1232
1233         if (obd == NULL) {
1234                 CERROR("invalid client cookie "LPX64"\n", 
1235                        exp->exp_handle.h_cookie);
1236                 RETURN(-EINVAL);
1237         }
1238         cobd_exp = cobd_get_exp(obd);
1239         rc = md_change_cbdata(cobd_exp, id, it, data);
1240         RETURN(rc);
1241 }
1242
1243 static int cobd_md_getattr_lock(struct obd_export *exp, struct lustre_id *id,
1244                                 char *filename, int namelen, __u64 valid,
1245                                 unsigned int ea_size, struct ptlrpc_request **request)
1246 {
1247         struct obd_device *obd = class_exp2obd(exp);
1248         struct obd_export *cobd_exp;
1249         int rc = 0;
1250         ENTRY;
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         rc = md_getattr_lock(cobd_exp, id, filename, namelen,
1259                              valid, ea_size, request);
1260         RETURN(rc);
1261 }
1262
1263 static int cobd_md_create(struct obd_export *exp, struct mdc_op_data *op_data,
1264                           const void *data, int datalen, int mode, 
1265                           __u32 uid, __u32 gid, __u64 rdev, 
1266                           struct ptlrpc_request **request)
1267 {
1268         struct obd_device *obd = class_exp2obd(exp);
1269         struct obd_export *cobd_exp;
1270         int rc = 0;
1271         ENTRY;
1272
1273         if (obd == NULL) {
1274                 CERROR("invalid client cookie "LPX64"\n", 
1275                        exp->exp_handle.h_cookie);
1276                 RETURN(-EINVAL);
1277         }
1278         cobd_exp = cobd_get_exp(obd);
1279         rc = md_create(cobd_exp, op_data, data, datalen, mode,
1280                        uid, gid, rdev, request);
1281         RETURN(rc);
1282 }
1283
1284 static int cobd_md_unlink(struct obd_export *exp,
1285                           struct mdc_op_data *data,
1286                           struct ptlrpc_request **request)
1287 {
1288         struct obd_device *obd = class_exp2obd(exp);
1289         struct obd_export *cobd_exp;
1290         int rc = 0;
1291         ENTRY;
1292
1293         if (obd == NULL) {
1294                 CERROR("invalid client cookie "LPX64"\n", 
1295                        exp->exp_handle.h_cookie);
1296                 RETURN(-EINVAL);
1297         }
1298         cobd_exp = cobd_get_exp(obd);
1299         rc = md_unlink(cobd_exp, data, request);
1300         RETURN(rc);
1301 }
1302
1303 static int cobd_md_valid_attrs(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         int rc = 0;
1309         ENTRY;
1310
1311         if (obd == NULL) {
1312                 CERROR("invalid client cookie "LPX64"\n", 
1313                        exp->exp_handle.h_cookie);
1314                 RETURN(-EINVAL);
1315         }
1316         cobd_exp = cobd_get_exp(obd);
1317         rc = md_valid_attrs(cobd_exp, id);
1318         RETURN(rc);
1319 }
1320
1321 static int cobd_md_rename(struct obd_export *exp, struct mdc_op_data *data,
1322                           const char *old, int oldlen, const char *new, 
1323                           int newlen, struct ptlrpc_request **request)
1324 {
1325         struct obd_device *obd = class_exp2obd(exp);
1326         struct obd_export *cobd_exp;
1327         int rc = 0;
1328         ENTRY;
1329
1330         if (obd == NULL) {
1331                 CERROR("invalid client cookie "LPX64"\n", 
1332                        exp->exp_handle.h_cookie);
1333                 RETURN(-EINVAL);
1334         }
1335         cobd_exp = cobd_get_exp(obd);
1336         rc = md_rename(cobd_exp, data, old, oldlen, new, newlen, request);
1337         RETURN(rc);
1338 }
1339
1340 static int cobd_md_link(struct obd_export *exp, struct mdc_op_data *data,
1341                         struct ptlrpc_request **request)
1342 {
1343         struct obd_device *obd = class_exp2obd(exp);
1344         struct obd_export *cobd_exp;
1345         int rc = 0;
1346         ENTRY;
1347
1348         if (obd == NULL) {
1349                 CERROR("invalid client cookie "LPX64"\n", 
1350                        exp->exp_handle.h_cookie);
1351                 RETURN(-EINVAL);
1352         }
1353         cobd_exp = cobd_get_exp(obd);
1354         rc = md_link(cobd_exp, data, request);
1355         RETURN(rc);
1356 }
1357
1358 static int cobd_md_setattr(struct obd_export *exp, struct mdc_op_data *data,
1359                            struct iattr *iattr, void *ea, int ealen, void *ea2, 
1360                            int ea2len, void *ea3, int ea3len, 
1361                            struct ptlrpc_request **request)
1362 {
1363         struct obd_device *obd = class_exp2obd(exp);
1364         struct obd_export *cobd_exp;
1365         int rc = 0;
1366         ENTRY;
1367
1368         if (obd == NULL) {
1369                 CERROR("invalid client cookie "LPX64"\n", 
1370                        exp->exp_handle.h_cookie);
1371                 RETURN(-EINVAL);
1372         }
1373         cobd_exp = cobd_get_exp(obd);
1374         rc = md_setattr(cobd_exp, data, iattr, ea,
1375                           ealen, ea2, ea2len, ea3, ea3len, request);
1376         RETURN(rc);
1377 }
1378
1379 static int cobd_md_readpage(struct obd_export *exp,
1380                             struct lustre_id *mdc_id,
1381                             __u64 offset, struct page *page, 
1382                             struct ptlrpc_request **request)
1383 {
1384         struct obd_device *obd = class_exp2obd(exp);
1385         struct obd_export *cobd_exp;
1386         int rc = 0;
1387         ENTRY;
1388
1389         if (obd == NULL) {
1390                 CERROR("invalid client cookie "LPX64"\n", 
1391                        exp->exp_handle.h_cookie);
1392                 RETURN(-EINVAL);
1393         }
1394         cobd_exp = cobd_get_exp(obd);
1395         rc = md_readpage(cobd_exp, mdc_id, offset, page, request);
1396         RETURN(rc);
1397 }
1398
1399 static int cobd_md_close(struct obd_export *exp, struct mdc_op_data *op_data,
1400                          struct obd_client_handle *och, 
1401                          struct ptlrpc_request **request)
1402 {
1403         struct obd_device *obd = class_exp2obd(exp);
1404         struct obd_export *cobd_exp;
1405         int rc = 0;
1406         ENTRY;
1407
1408         if (obd == NULL) {
1409                 CERROR("invalid client cookie "LPX64"\n", 
1410                        exp->exp_handle.h_cookie);
1411                 RETURN(-EINVAL);
1412         }
1413         cobd_exp = cobd_get_exp(obd);
1414         rc = md_close(cobd_exp, op_data, och, request);
1415         RETURN(rc);
1416 }
1417
1418 static int cobd_md_done_writing(struct obd_export *exp,
1419                                 struct obdo *obdo)
1420 {
1421         struct obd_device *obd = class_exp2obd(exp);
1422         struct obd_export *cobd_exp;
1423         int rc = 0;
1424         ENTRY;
1425
1426         if (obd == NULL) {
1427                 CERROR("invalid client cookie "LPX64"\n", 
1428                        exp->exp_handle.h_cookie);
1429                 RETURN(-EINVAL);
1430         }
1431         cobd_exp = cobd_get_exp(obd);
1432         rc = md_done_writing(cobd_exp, obdo);
1433         RETURN(rc);
1434 }
1435
1436 static int cobd_md_sync(struct obd_export *exp, struct lustre_id *id,
1437                         struct ptlrpc_request **request)
1438 {
1439         struct obd_device *obd = class_exp2obd(exp);
1440         struct obd_export *cobd_exp;
1441         int rc = 0;
1442         ENTRY;
1443
1444         if (obd == NULL) {
1445                 CERROR("invalid client cookie "LPX64"\n", 
1446                        exp->exp_handle.h_cookie);
1447                 RETURN(-EINVAL);
1448         }
1449         cobd_exp = cobd_get_exp(obd);
1450         rc = md_sync(cobd_exp, id, request);
1451         RETURN(rc);
1452 }
1453
1454 static int cobd_md_set_open_replay_data(struct obd_export *exp,
1455                                         struct obd_client_handle *och,
1456                                         struct ptlrpc_request *open_req)
1457 {
1458         struct obd_device *obd = class_exp2obd(exp);
1459         struct obd_export *cobd_exp;
1460         int rc = 0;
1461         ENTRY;
1462
1463         if (obd == NULL) {
1464                 CERROR("invalid client cookie "LPX64"\n", 
1465                        exp->exp_handle.h_cookie);
1466                 RETURN(-EINVAL);
1467         }
1468         cobd_exp = cobd_get_exp(obd);
1469         rc = md_set_open_replay_data(cobd_exp, och, open_req);
1470         RETURN(rc);
1471 }
1472
1473 static int cobd_md_clear_open_replay_data(struct obd_export *exp,
1474                                           struct obd_client_handle *och)
1475 {
1476         struct obd_device *obd = class_exp2obd(exp);
1477         struct obd_export *cobd_exp;
1478         int rc = 0;
1479         ENTRY;
1480
1481         if (obd == NULL) {
1482                 CERROR("invalid client cookie "LPX64"\n", 
1483                        exp->exp_handle.h_cookie);
1484                 RETURN(-EINVAL);
1485         }
1486         cobd_exp = cobd_get_exp(obd);
1487         rc = md_clear_open_replay_data(cobd_exp, och);
1488         RETURN(rc);
1489 }
1490
1491 static int cobd_md_store_inode_generation(struct obd_export *exp,
1492                                           struct ptlrpc_request *req, 
1493                                           int reqoff, int repoff)
1494 {
1495         struct obd_device *obd = class_exp2obd(exp);
1496         struct obd_export *cobd_exp;
1497         int rc = 0;
1498         ENTRY;
1499
1500         if (obd == NULL) {
1501                 CERROR("invalid client cookie "LPX64"\n", 
1502                        exp->exp_handle.h_cookie);
1503                 RETURN(-EINVAL);
1504         }
1505         cobd_exp = cobd_get_exp(obd);
1506         rc = md_store_inode_generation(cobd_exp, req, reqoff, repoff);
1507         RETURN(rc);
1508 }
1509
1510 static int cobd_md_set_lock_data(struct obd_export *exp,
1511                                  __u64 *l, void *data)
1512 {
1513         struct obd_device *obd = class_exp2obd(exp);
1514         struct obd_export *cobd_exp;
1515         int rc = 0;
1516         ENTRY;
1517
1518         if (obd == NULL) {
1519                 CERROR("invalid client cookie "LPX64"\n", 
1520                        exp->exp_handle.h_cookie);
1521                 RETURN(-EINVAL);
1522         }
1523         cobd_exp = cobd_get_exp(obd);
1524         rc = md_set_lock_data(cobd_exp, l, data);
1525         RETURN(rc);
1526 }
1527
1528 static int cobd_md_enqueue(struct obd_export *exp, int lock_type,
1529                            struct lookup_intent *it, int lock_mode,
1530                            struct mdc_op_data *data, struct lustre_handle *lockh,
1531                            void *lmm, int lmmsize, 
1532                            ldlm_completion_callback cb_completion,
1533                            ldlm_blocking_callback cb_blocking, void *cb_data)
1534 {
1535         struct obd_device *obd = class_exp2obd(exp);
1536         struct obd_export *cobd_exp;
1537         int rc = 0;
1538         ENTRY;
1539
1540         if (obd == NULL) {
1541                 CERROR("invalid client cookie "LPX64"\n", 
1542                        exp->exp_handle.h_cookie);
1543                 RETURN(-EINVAL);
1544         }
1545         cobd_exp = cobd_get_exp(obd);
1546         rc = md_enqueue(cobd_exp, lock_type, it, lock_mode, data,
1547                         lockh, lmm, lmmsize, cb_completion, cb_blocking,
1548                         cb_data);
1549         RETURN(rc);
1550 }
1551
1552 static int cobd_md_intent_lock(struct obd_export *exp, struct lustre_id *pid, 
1553                                const char *name, int len, void *lmm, int lmmsize,
1554                                struct lustre_id *cid, struct lookup_intent *it,
1555                                int lookup_flags, struct ptlrpc_request **reqp,
1556                                ldlm_blocking_callback cb_blocking)
1557 {
1558         struct obd_device *obd = class_exp2obd(exp);
1559         struct obd_export *cobd_exp;
1560         int rc = 0;
1561         ENTRY;
1562
1563         if (obd == NULL) {
1564                 CERROR("invalid client cookie "LPX64"\n", 
1565                        exp->exp_handle.h_cookie);
1566                 RETURN(-EINVAL);
1567         }
1568         lookup_flags |= LOOKUP_COBD;
1569         cobd_exp = cobd_get_exp(obd);
1570         
1571         rc = md_intent_lock(cobd_exp, pid, name, len, lmm, lmmsize,
1572                             cid, it, lookup_flags, reqp, cb_blocking);
1573         RETURN(rc);
1574 }
1575
1576 static struct obd_device *cobd_md_get_real_obd(struct obd_export *exp,
1577                                                struct lustre_id *id)
1578 {
1579         struct obd_device *obd = class_exp2obd(exp);
1580         struct obd_export *cobd_exp;
1581         ENTRY;
1582
1583         if (obd == NULL) {
1584                 CERROR("invalid client cookie "LPX64"\n", 
1585                        exp->exp_handle.h_cookie);
1586                 RETURN(NULL);
1587         }
1588         cobd_exp = cobd_get_exp(obd);
1589         RETURN(md_get_real_obd(cobd_exp, id));
1590 }
1591
1592 static int cobd_md_change_cbdata_name(struct obd_export *exp,
1593                                       struct lustre_id *id, char *name,
1594                                       int namelen, struct lustre_id *id2,
1595                                       ldlm_iterator_t it, void *data)
1596 {
1597         struct obd_device *obd = class_exp2obd(exp);
1598         struct obd_export *cobd_exp;
1599         int rc = 0;
1600
1601         if (obd == NULL) {
1602                 CERROR("invalid client cookie "LPX64"\n", 
1603                        exp->exp_handle.h_cookie);
1604                 RETURN(-EINVAL);
1605         }
1606         cobd_exp = cobd_get_exp(obd);
1607         rc = md_change_cbdata_name(cobd_exp, id, name, namelen,
1608                                    id2, it, data);
1609         RETURN(rc);
1610 }
1611
1612 static struct obd_ops cobd_obd_ops = {
1613         .o_owner                  = THIS_MODULE,
1614         .o_attach                 = cobd_attach,
1615         .o_detach                 = cobd_detach,
1616         .o_setup                  = cobd_setup,
1617         .o_cleanup                = cobd_cleanup,
1618         .o_connect                = cobd_connect,
1619         .o_disconnect             = cobd_disconnect,
1620         .o_set_info               = cobd_set_info,
1621         .o_get_info               = cobd_get_info,
1622         .o_statfs                 = cobd_statfs,
1623         .o_iocontrol              = cobd_iocontrol,
1624
1625         .o_packmd                 = cobd_dt_packmd,
1626         .o_unpackmd               = cobd_dt_unpackmd,
1627         .o_create                 = cobd_dt_create,
1628         .o_destroy                = cobd_dt_destroy,
1629         .o_precleanup             = cobd_dt_precleanup,
1630         .o_getattr                = cobd_dt_getattr,
1631         .o_getattr_async          = cobd_dt_getattr_async,
1632         .o_setattr                = cobd_dt_setattr,
1633         .o_brw                    = cobd_dt_brw,
1634         .o_brw_async              = cobd_dt_brw_async,
1635         .o_prep_async_page        = cobd_dt_prep_async_page,
1636         .o_queue_async_io         = cobd_dt_queue_async_io,
1637         .o_set_async_flags        = cobd_dt_set_async_flags,
1638         .o_queue_group_io         = cobd_dt_queue_group_io,
1639         .o_trigger_group_io       = cobd_dt_trigger_group_io,
1640         .o_teardown_async_page    = cobd_dt_teardown_async_page,
1641         .o_preprw                 = cobd_dt_preprw,
1642         .o_punch                  = cobd_dt_punch,
1643         .o_sync                   = cobd_dt_sync,
1644         .o_enqueue                = cobd_dt_enqueue,
1645         .o_match                  = cobd_dt_match,
1646         .o_change_cbdata          = cobd_dt_change_cbdata,
1647         .o_cancel                 = cobd_dt_cancel,
1648         .o_cancel_unused          = cobd_dt_cancel_unused,
1649         .o_commitrw               = cobd_dt_commitrw,
1650         .o_llog_init              = cobd_dt_llog_init,
1651         .o_llog_finish            = cobd_dt_llog_finish,
1652         .o_notify                 = cobd_dt_notify,
1653         .o_pin                    = cobd_dt_pin,
1654         .o_unpin                  = cobd_dt_unpin,
1655         .o_import_event           = cobd_dt_import_event,
1656         .o_init_ea_size           = cobd_dt_init_ea_size,
1657         .o_adjust_kms             = cobd_dt_adjust_kms,
1658 };
1659
1660 struct md_ops cobd_md_ops = {
1661         .m_getstatus              = cobd_md_getstatus,
1662         .m_getattr                = cobd_md_getattr,
1663         .m_req2lustre_md          = cobd_md_req2lustre_md,
1664         .m_change_cbdata          = cobd_md_change_cbdata,
1665         .m_getattr_lock           = cobd_md_getattr_lock,
1666         .m_create                 = cobd_md_create,
1667         .m_unlink                 = cobd_md_unlink,
1668         .m_valid_attrs            = cobd_md_valid_attrs,
1669         .m_rename                 = cobd_md_rename,
1670         .m_link                   = cobd_md_link,
1671         .m_setattr                = cobd_md_setattr,
1672         .m_readpage               = cobd_md_readpage,
1673         .m_close                  = cobd_md_close,
1674         .m_done_writing           = cobd_md_done_writing,
1675         .m_sync                   = cobd_md_sync,
1676         .m_set_open_replay_data   = cobd_md_set_open_replay_data,
1677         .m_clear_open_replay_data = cobd_md_clear_open_replay_data,
1678         .m_store_inode_generation = cobd_md_store_inode_generation,
1679         .m_set_lock_data          = cobd_md_set_lock_data,
1680         .m_enqueue                = cobd_md_enqueue,
1681         .m_get_real_obd           = cobd_md_get_real_obd,
1682         .m_intent_lock            = cobd_md_intent_lock,
1683         .m_change_cbdata_name     = cobd_md_change_cbdata_name,
1684 };
1685
1686 static int __init cobd_init(void)
1687 {
1688         struct lprocfs_static_vars lvars;
1689         ENTRY;
1690
1691         printk(KERN_INFO "Lustre: Caching OBD driver; info@clusterfs.com\n");
1692
1693         lprocfs_init_vars(cobd, &lvars);
1694         RETURN(class_register_type(&cobd_obd_ops, &cobd_md_ops,
1695                                    lvars.module_vars, OBD_CACHE_DEVICENAME));
1696 }
1697
1698 static void /*__exit*/ cobd_exit(void)
1699 {
1700         class_unregister_type(OBD_CACHE_DEVICENAME);
1701 }
1702
1703 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
1704 MODULE_DESCRIPTION("Lustre Caching OBD driver");
1705 MODULE_LICENSE("GPL");
1706
1707 module_init(cobd_init);
1708 module_exit(cobd_exit);