Whamcloud - gitweb
several fixes: expiry timer adjusted.
[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 nothing 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_notify(struct obd_device *obd, struct obd_device *watched,
539                        int active, void *data)
540 {
541         struct obd_export *cobd_exp;
542         int rc = 0;
543         ENTRY;
544
545         cobd_exp = cobd_get_exp(obd);
546         rc = obd_notify(class_exp2obd(cobd_exp), watched, active, data);
547         RETURN(rc);
548 }
549
550 static int cobd_pin(struct obd_export *exp, obd_id ino, __u32 gen,
551                     int type, struct obd_client_handle *handle,
552                     int flag)
553 {
554         struct obd_device *obd = class_exp2obd(exp);
555         struct obd_export *cobd_exp;
556         int rc = 0;
557         ENTRY;
558
559         if (obd == NULL) {
560                 CERROR("invalid client cookie "LPX64"\n", 
561                        exp->exp_handle.h_cookie);
562                 RETURN(-EINVAL);
563         }
564         cobd_exp = cobd_get_exp(obd);
565         rc = obd_pin(cobd_exp, ino, gen, type, handle, flag);
566         RETURN(rc);
567 }
568
569 static int cobd_unpin(struct obd_export *exp,
570                       struct obd_client_handle *handle,
571                       int flag)
572 {
573         struct obd_device *obd = class_exp2obd(exp);
574         struct obd_export *cobd_exp;
575         int rc = 0;
576         ENTRY;
577
578         if (obd == NULL) {
579                 CERROR("invalid client cookie "LPX64"\n", 
580                        exp->exp_handle.h_cookie);
581                 RETURN(-EINVAL);
582         }
583         cobd_exp = cobd_get_exp(obd);
584         rc = obd_unpin(cobd_exp, handle, flag);
585         RETURN(rc);
586 }
587
588 /* data related stuff */
589 static int cobd_dt_packmd(struct obd_export *exp,
590                           struct lov_mds_md **disk_tgt,
591                           struct lov_stripe_md *mem_src)
592 {
593         struct obd_device *obd = class_exp2obd(exp);
594         struct obd_export *cobd_exp;
595         int rc = 0;
596         ENTRY;
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         rc = obd_packmd(cobd_exp, disk_tgt, mem_src);
605         RETURN(rc);
606 }
607
608 static int cobd_dt_unpackmd(struct obd_export *exp,
609                             struct lov_stripe_md **mem_tgt,
610                             struct lov_mds_md *disk_src,
611                             int disk_len)
612 {
613         struct obd_device *obd = class_exp2obd(exp);
614         struct obd_export *cobd_exp;
615         int rc = 0;
616         ENTRY;
617
618         if (obd == NULL) {
619                 CERROR("invalid client cookie "LPX64"\n", 
620                        exp->exp_handle.h_cookie);
621                 RETURN(-EINVAL);
622         }
623         cobd_exp = cobd_get_exp(obd);
624         rc = obd_unpackmd(cobd_exp, mem_tgt, disk_src, disk_len);
625         RETURN(rc);
626 }
627
628 static int cobd_dt_create(struct obd_export *exp,
629                           struct obdo *obdo,
630                           void *acl, int acl_size,
631                           struct lov_stripe_md **ea,
632                           struct obd_trans_info *oti)
633 {
634         struct obd_device *obd = class_exp2obd(exp);
635         struct obd_export *cobd_exp;
636         int rc = 0;
637         ENTRY;
638
639         if (obd == NULL) {
640                 CERROR("invalid client cookie "LPX64"\n", 
641                        exp->exp_handle.h_cookie);
642                 RETURN(-EINVAL);
643         }
644         cobd_exp = cobd_get_exp(obd);
645         rc = obd_create(cobd_exp, obdo, acl, acl_size, ea, oti);
646         RETURN(rc);
647 }
648
649 static int cobd_dt_destroy(struct obd_export *exp,
650                            struct obdo *obdo,
651                            struct lov_stripe_md *ea,
652                            struct obd_trans_info *oti)
653 {
654         struct obd_device *obd = class_exp2obd(exp);
655         struct obd_export *cobd_exp;
656         int rc = 0;
657         ENTRY;
658
659         if (obd == NULL) {
660                 CERROR("invalid client cookie "LPX64"\n", 
661                        exp->exp_handle.h_cookie);
662                 RETURN(-EINVAL);
663         }
664         cobd_exp = cobd_get_exp(obd);
665         rc = obd_destroy(cobd_exp, obdo, ea, oti);
666         RETURN(rc);
667 }
668
669 static int cobd_dt_precleanup(struct obd_device *obd, int flags)
670 {
671         /* FIXME: do we need some cleanup here? */
672         ENTRY;
673         RETURN(0);
674 }
675
676 static int cobd_dt_getattr(struct obd_export *exp, struct obdo *oa,
677                            struct lov_stripe_md *ea)
678 {
679         struct obd_device *obd = class_exp2obd(exp);
680         struct obd_export *cobd_exp;
681         int rc = 0;
682         ENTRY;
683
684         if (obd == NULL) {
685                 CERROR("invalid client cookie "LPX64"\n", 
686                        exp->exp_handle.h_cookie);
687                 RETURN(-EINVAL);
688         }
689         cobd_exp = cobd_get_exp(obd);
690         rc = obd_getattr(cobd_exp, oa, ea);
691         RETURN(rc);
692 }
693
694 static int cobd_dt_getattr_async(struct obd_export *exp,
695                                  struct obdo *obdo, struct lov_stripe_md *ea,
696                                  struct ptlrpc_request_set *set)
697 {
698         struct obd_device *obd = class_exp2obd(exp);
699         struct obd_export *cobd_exp;
700         int rc = 0;
701         ENTRY;
702
703         if (obd == NULL) {
704                 CERROR("invalid client cookie "LPX64"\n", 
705                        exp->exp_handle.h_cookie);
706                 RETURN(-EINVAL);
707         }
708         cobd_exp = cobd_get_exp(obd);
709         rc = obd_getattr_async(cobd_exp, obdo, ea, set);
710         RETURN(rc);
711 }
712
713 static int cobd_dt_setattr(struct obd_export *exp, struct obdo *obdo,
714                            struct lov_stripe_md *ea,
715                            struct obd_trans_info *oti,
716                            struct lustre_capa *capa)
717 {
718         struct obd_device *obd = class_exp2obd(exp);
719         struct obd_export *cobd_exp;
720         int rc = 0;
721         ENTRY;
722
723         if (obd == NULL) {
724                 CERROR("invalid client cookie "LPX64"\n", 
725                        exp->exp_handle.h_cookie);
726                 RETURN(-EINVAL);
727         }
728         cobd_exp = cobd_get_exp(obd);
729         rc = obd_setattr(cobd_exp, obdo, ea, oti, capa);
730         RETURN(rc);
731 }
732
733 static int cobd_dt_brw(int cmd, struct obd_export *exp, struct obdo *oa,
734                        struct lov_stripe_md *ea, obd_count oa_bufs,
735                        struct brw_page *pg, struct obd_trans_info *oti)
736 {
737         struct obd_device *obd = class_exp2obd(exp);
738         struct obd_export *cobd_exp;
739         int rc = 0;
740         ENTRY;
741
742         if (obd == NULL) {
743                 CERROR("invalid client cookie "LPX64"\n", 
744                        exp->exp_handle.h_cookie);
745                 RETURN(-EINVAL);
746         }
747         cobd_exp = cobd_get_exp(obd);
748         rc = obd_brw(cmd, cobd_exp, oa, ea, oa_bufs, pg, oti);
749         RETURN(rc);
750 }
751
752 static int cobd_dt_brw_async(int cmd, struct obd_export *exp,
753                              struct obdo *oa, struct lov_stripe_md *ea,
754                              obd_count oa_bufs, struct brw_page *pg,
755                              struct ptlrpc_request_set *set,
756                              struct obd_trans_info *oti)
757 {
758         struct obd_device *obd = class_exp2obd(exp);
759         struct obd_export *cobd_exp;
760         int rc = 0;
761         ENTRY;
762
763         if (obd == NULL) {
764                 CERROR("invalid client cookie "LPX64"\n", 
765                        exp->exp_handle.h_cookie);
766                 RETURN(-EINVAL);
767         }
768         cobd_exp = cobd_get_exp(obd);
769         rc = obd_brw_async(cmd, cobd_exp, oa, ea, oa_bufs, 
770                            pg, set, oti);
771         RETURN(rc);
772 }
773
774 static int cobd_dt_prep_async_page(struct obd_export *exp, 
775                                    struct lov_stripe_md *lsm,
776                                    struct lov_oinfo *loi, 
777                                    struct page *page, obd_off offset, 
778                                    struct obd_async_page_ops *ops, 
779                                    void *data, void **res)
780 {
781         struct obd_device *obd = class_exp2obd(exp);
782         struct obd_export *cobd_exp;
783         int rc = 0;
784         ENTRY;
785
786         if (obd == NULL) {
787                 CERROR("invalid client cookie "LPX64"\n", 
788                        exp->exp_handle.h_cookie);
789                 RETURN(-EINVAL);
790         }
791         cobd_exp = cobd_get_exp(obd);
792         rc = obd_prep_async_page(cobd_exp, lsm, loi, page,
793                                  offset, ops, data, res);
794         RETURN(rc);
795 }
796
797 static int cobd_dt_queue_async_io(struct obd_export *exp,
798                                   struct lov_stripe_md *lsm,
799                                   struct lov_oinfo *loi, void *cookie,
800                                   int cmd, obd_off off, int count,
801                                   obd_flags brw_flags, obd_flags async_flags)
802 {
803         struct obd_device *obd = class_exp2obd(exp);
804         struct obd_export *cobd_exp;
805         int rc = 0;
806         ENTRY;
807
808         if (obd == NULL) {
809                 CERROR("invalid client cookie "LPX64"\n", 
810                        exp->exp_handle.h_cookie);
811                 RETURN(-EINVAL);
812         }
813         cobd_exp = cobd_get_exp(obd);
814         rc = obd_queue_async_io(cobd_exp, lsm, loi, cookie, cmd, off,
815                                 count, brw_flags, async_flags);
816         RETURN(rc);
817 }
818
819 static int cobd_dt_set_async_flags(struct obd_export *exp,
820                                    struct lov_stripe_md *lsm,
821                                    struct lov_oinfo *loi, void *cookie,
822                                    obd_flags async_flags)
823 {
824         struct obd_device *obd = class_exp2obd(exp);
825         struct obd_export *cobd_exp;
826         int rc = 0;
827         ENTRY;
828
829         if (obd == NULL) {
830                 CERROR("invalid client cookie "LPX64"\n", 
831                        exp->exp_handle.h_cookie);
832                 RETURN(-EINVAL);
833         }
834         cobd_exp = cobd_get_exp(obd);
835         rc = obd_set_async_flags(cobd_exp, lsm, loi, cookie,
836                                  async_flags);
837         RETURN(rc);
838 }
839
840 static int cobd_dt_queue_group_io(struct obd_export *exp, 
841                                   struct lov_stripe_md *lsm, 
842                                   struct lov_oinfo *loi, 
843                                   struct obd_io_group *oig, 
844                                   void *cookie, int cmd, obd_off off, 
845                                   int count, obd_flags brw_flags,
846                                   obd_flags async_flags)
847 {
848         struct obd_device *obd = class_exp2obd(exp);
849         struct obd_export *cobd_exp;
850         int rc = 0;
851         ENTRY;
852
853         if (obd == NULL) {
854                 CERROR("invalid client cookie "LPX64"\n", 
855                        exp->exp_handle.h_cookie);
856                 RETURN(-EINVAL);
857         }
858         cobd_exp = cobd_get_exp(obd);
859         rc = obd_queue_group_io(cobd_exp, lsm, loi, oig, cookie,
860                                 cmd, off, count, brw_flags,
861                                 async_flags);
862         RETURN(rc);
863 }
864
865 static int cobd_dt_trigger_group_io(struct obd_export *exp, 
866                                     struct lov_stripe_md *lsm, 
867                                     struct lov_oinfo *loi,
868                                     struct obd_io_group *oig)
869 {
870         struct obd_device *obd = class_exp2obd(exp);
871         struct obd_export *cobd_exp;
872         int rc = 0;
873         ENTRY;
874
875         if (obd == NULL) {
876                 CERROR("invalid client cookie "LPX64"\n", 
877                        exp->exp_handle.h_cookie);
878                 RETURN(-EINVAL);
879         }
880         cobd_exp = cobd_get_exp(obd);
881         rc = obd_trigger_group_io(cobd_exp, lsm, loi, oig);
882         RETURN(rc);
883 }
884
885 static int cobd_dt_teardown_async_page(struct obd_export *exp,
886                                        struct lov_stripe_md *lsm,
887                                        struct lov_oinfo *loi,
888                                        void *cookie)
889 {
890         struct obd_device *obd = class_exp2obd(exp);
891         struct obd_export *cobd_exp;
892         int rc = 0;
893         ENTRY;
894
895         if (obd == NULL) {
896                 CERROR("invalid client cookie "LPX64"\n", 
897                        exp->exp_handle.h_cookie);
898                 RETURN(-EINVAL);
899         }
900         cobd_exp = cobd_get_exp(obd);
901         rc = obd_teardown_async_page(cobd_exp, lsm, loi, cookie);
902         RETURN(rc);
903 }
904
905 static int cobd_dt_punch(struct obd_export *exp, struct obdo *oa,
906                          struct lov_stripe_md *ea, obd_size start,
907                          obd_size end, struct obd_trans_info *oti,
908                          struct lustre_capa *capa)
909 {
910         struct obd_device *obd = class_exp2obd(exp);
911         struct obd_export *cobd_exp;
912         int rc = 0;
913         ENTRY;
914
915         if (obd == NULL) {
916                 CERROR("invalid client cookie "LPX64"\n", 
917                        exp->exp_handle.h_cookie);
918                 RETURN(-EINVAL);
919         }
920         cobd_exp = cobd_get_exp(obd);
921         rc = obd_punch(cobd_exp, oa, ea, start, end, oti, capa);
922         RETURN(rc);
923 }
924
925 static int cobd_dt_sync(struct obd_export *exp, struct obdo *oa,
926                         struct lov_stripe_md *ea, obd_size start, 
927                         obd_size end)
928 {
929         struct obd_device *obd = class_exp2obd(exp);
930         struct obd_export *cobd_exp;
931         int rc = 0;
932         ENTRY;
933
934         if (obd == NULL) {
935                 CERROR("invalid client cookie "LPX64"\n", 
936                        exp->exp_handle.h_cookie);
937                 RETURN(-EINVAL);
938         }
939         cobd_exp = cobd_get_exp(obd);
940         rc = obd_sync(cobd_exp, oa, ea, start, end);
941         RETURN(rc);
942 }
943
944 static int cobd_dt_enqueue(struct obd_export *exp, struct lov_stripe_md *ea,
945                            __u32 type, ldlm_policy_data_t *policy,
946                            __u32 mode, int *flags, void *bl_cb, void *cp_cb,
947                            void *gl_cb, void *data, __u32 lvb_len,
948                            void *lvb_swabber, struct lustre_handle *lockh)
949 {
950         struct obd_device *obd = class_exp2obd(exp);
951         struct obd_export *cobd_exp;
952         int rc = 0;
953         ENTRY;
954
955         if (obd == NULL) {
956                 CERROR("invalid client cookie "LPX64"\n", 
957                        exp->exp_handle.h_cookie);
958                 RETURN(-EINVAL);
959         }
960         cobd_exp = cobd_get_exp(obd);
961         rc = obd_enqueue(cobd_exp, ea, type, policy, mode, flags, 
962                          bl_cb, cp_cb, gl_cb, data, lvb_len,
963                          lvb_swabber, lockh);
964         RETURN(rc);
965 }
966
967 static int cobd_dt_match(struct obd_export *exp, struct lov_stripe_md *ea,
968                          __u32 type, ldlm_policy_data_t *policy, __u32 mode,
969                          int *flags, void *data, struct lustre_handle *lockh)
970 {
971         struct obd_device *obd = class_exp2obd(exp);
972         struct obd_export *cobd_exp;
973         int rc = 0;
974         ENTRY;
975
976         if (obd == NULL) {
977                 CERROR("invalid client cookie "LPX64"\n", 
978                        exp->exp_handle.h_cookie);
979                 RETURN(-EINVAL);
980         }
981         cobd_exp = cobd_get_exp(obd);
982         rc = obd_match(cobd_exp, ea, type, policy, mode, flags,
983                        data, lockh);
984         RETURN(rc);
985 }
986 static int cobd_dt_change_cbdata(struct obd_export *exp,
987                                  struct lov_stripe_md *lsm, 
988                                  ldlm_iterator_t it, void *data)
989 {
990         struct obd_device *obd = class_exp2obd(exp);
991         struct obd_export *cobd_exp;
992         int rc = 0;
993         ENTRY;
994
995         if (obd == NULL) {
996                 CERROR("invalid client cookie "LPX64"\n", 
997                        exp->exp_handle.h_cookie);
998                 RETURN(-EINVAL);
999         }
1000         cobd_exp = cobd_get_exp(obd);
1001         rc = obd_change_cbdata(cobd_exp, lsm, it, data);
1002         RETURN(rc);
1003 }
1004
1005 static int cobd_dt_cancel(struct obd_export *exp,
1006                           struct lov_stripe_md *ea, __u32 mode,
1007                           struct lustre_handle *lockh)
1008 {
1009         struct obd_device *obd = class_exp2obd(exp);
1010         struct obd_export *cobd_exp;
1011         int rc = 0;
1012         ENTRY;
1013
1014         if (obd == NULL) {
1015                 CERROR("invalid client cookie "LPX64"\n", 
1016                        exp->exp_handle.h_cookie);
1017                 RETURN(-EINVAL);
1018         }
1019         cobd_exp = cobd_get_exp(obd);
1020         rc = obd_cancel(cobd_exp, ea, mode, lockh);
1021         RETURN(rc);
1022 }
1023
1024 static int cobd_dt_cancel_unused(struct obd_export *exp,
1025                                  struct lov_stripe_md *ea,
1026                                  int flags, void *opaque)
1027 {
1028         struct obd_device *obd = class_exp2obd(exp);
1029         struct obd_export *cobd_exp;
1030         int rc = 0;
1031         ENTRY;
1032         
1033         if (obd == NULL) {
1034                 CERROR("invalid client cookie "LPX64"\n", 
1035                        exp->exp_handle.h_cookie);
1036                 RETURN(-EINVAL);
1037         }
1038         cobd_exp = cobd_get_exp(obd);
1039         rc = obd_cancel_unused(cobd_exp, ea, flags, opaque);
1040         RETURN(rc);
1041 }
1042
1043 static int cobd_dt_preprw(int cmd, struct obd_export *exp,
1044                           struct obdo *oa, int objcount,
1045                           struct obd_ioobj *obj, int niocount,
1046                           struct niobuf_remote *nb,
1047                           struct niobuf_local *res,
1048                           struct obd_trans_info *oti,
1049                           struct lustre_capa *capa)
1050 {
1051         struct obd_device *obd = class_exp2obd(exp);
1052         struct obd_export *cobd_exp;
1053         int rc = 0;
1054         ENTRY;
1055
1056         if (obd == NULL) {
1057                 CERROR("invalid client cookie "LPX64"\n", 
1058                        exp->exp_handle.h_cookie);
1059                 RETURN(-EINVAL);
1060         }
1061         cobd_exp = cobd_get_exp(obd);
1062         rc = obd_preprw(cmd, cobd_exp, oa, objcount, obj,
1063                           niocount, nb, res, oti, capa);
1064         RETURN(rc);
1065 }
1066
1067 static int cobd_dt_commitrw(int cmd, struct obd_export *exp, struct obdo *oa,
1068                             int objcount, struct obd_ioobj *obj,
1069                             int niocount, struct niobuf_local *local,
1070                             struct obd_trans_info *oti, int rc)
1071 {
1072         struct obd_device *obd = class_exp2obd(exp);
1073         struct obd_export *cobd_exp;
1074         int err = 0;
1075         ENTRY;
1076
1077         if (obd == NULL) {
1078                 CERROR("invalid client cookie "LPX64"\n", 
1079                        exp->exp_handle.h_cookie);
1080                 RETURN(-EINVAL);
1081         }
1082         cobd_exp = cobd_get_exp(obd);
1083         err = obd_commitrw(cmd, cobd_exp, oa, objcount, obj,
1084                            niocount, local, oti, rc);
1085         RETURN(err);
1086 }
1087
1088 static int cobd_dt_adjust_kms(struct obd_export *exp,
1089                               struct lov_stripe_md *lsm,
1090                               obd_off size, int shrink)
1091 {
1092         struct obd_device *obd = class_exp2obd(exp);
1093         struct obd_export *cobd_exp;
1094         int rc = 0;
1095         ENTRY;
1096
1097         if (obd == NULL) {
1098                 CERROR("invalid client cookie "LPX64"\n", 
1099                        exp->exp_handle.h_cookie);
1100                 RETURN(-EINVAL);
1101         }
1102         cobd_exp = cobd_get_exp(obd);
1103         rc = obd_adjust_kms(cobd_exp, lsm, size, shrink);
1104         
1105         RETURN(rc);
1106 }
1107
1108 static int cobd_dt_llog_init(struct obd_device *obd,
1109                              struct obd_llogs *llogs, 
1110                              struct obd_device *disk_obd,
1111                              int count, struct llog_catid *logid)
1112 {
1113         struct obd_export *cobd_exp;
1114         struct obd_device *cobd_obd;
1115         int rc = 0;
1116         ENTRY;
1117
1118         cobd_exp = cobd_get_exp(obd);
1119         cobd_obd = class_exp2obd(cobd_exp);
1120         
1121         rc = obd_llog_init(cobd_obd, &cobd_obd->obd_llogs, 
1122                            disk_obd, count, logid);
1123         RETURN(rc);
1124 }
1125
1126 static int cobd_dt_llog_finish(struct obd_device *obd,
1127                                struct obd_llogs *llogs, 
1128                                int count)
1129 {
1130         struct obd_export *cobd_exp;
1131         struct obd_device *cobd_obd;
1132         int rc = 0;
1133         ENTRY;
1134
1135         cobd_exp = cobd_get_exp(obd);
1136         cobd_obd = class_exp2obd(cobd_exp);
1137
1138         rc = obd_llog_finish(cobd_obd, &cobd_obd->obd_llogs, count);
1139         RETURN(rc);
1140 }
1141
1142 static int cobd_dt_init_ea_size(struct obd_export *exp, int easize,
1143                                 int cookiesize)
1144 {
1145         struct obd_export *cobd_exp;
1146         int rc = 0;
1147         ENTRY;
1148
1149         cobd_exp = cobd_get_exp(exp->exp_obd);
1150         rc = obd_init_ea_size(cobd_exp, easize, cookiesize);
1151         RETURN(rc);
1152 }
1153
1154 static int cobd_dt_import_event(struct obd_device *obd,
1155                                 struct obd_import *imp,
1156                                 enum obd_import_event event)
1157 {
1158         struct obd_export *cobd_exp;
1159         ENTRY;
1160
1161         cobd_exp = cobd_get_exp(obd);
1162         obd_import_event(class_exp2obd(cobd_exp), imp, event);
1163         RETURN(0); 
1164 }
1165
1166 /* metadata related stuff */
1167 static int cobd_md_getstatus(struct obd_export *exp,
1168                              struct lustre_id *rootid)
1169 {
1170         struct obd_device *obd = class_exp2obd(exp);
1171         struct obd_export *cobd_exp;
1172         int rc = 0;
1173         ENTRY;
1174
1175         if (obd == NULL) {
1176                 CERROR("invalid client cookie "LPX64"\n", 
1177                        exp->exp_handle.h_cookie);
1178                 RETURN(-EINVAL);
1179         }
1180         cobd_exp = cobd_get_exp(obd);
1181         rc = md_getstatus(cobd_exp, rootid);
1182         RETURN(rc);
1183 }
1184
1185 static int cobd_md_getattr(struct obd_export *exp, struct lustre_id *id,
1186                            __u64 valid, const char *xattr_name,
1187                            const void *xattr_data, unsigned int xattr_datalen,
1188                            unsigned int ea_size, struct obd_capa *ocapa,
1189                            struct ptlrpc_request **request)
1190 {
1191         struct obd_device *obd = class_exp2obd(exp);
1192         struct obd_export *cobd_exp;
1193         int rc = 0;
1194         ENTRY;
1195
1196         if (obd == NULL) {
1197                 CERROR("invalid client cookie "LPX64"\n", 
1198                        exp->exp_handle.h_cookie);
1199                 RETURN(-EINVAL);
1200         }
1201         cobd_exp = cobd_get_exp(obd);
1202         rc = md_getattr(cobd_exp, id, valid, xattr_name, xattr_data,
1203                           xattr_datalen, ea_size, ocapa, request);
1204         RETURN(rc);
1205 }
1206
1207 static int cobd_md_req2lustre_md(struct obd_export *mdc_exp, 
1208                                  struct ptlrpc_request *req,
1209                                  unsigned int offset,
1210                                  struct obd_export *osc_exp,
1211                                  struct lustre_md *md)
1212 {
1213         struct obd_device *obd = class_exp2obd(mdc_exp);
1214         struct obd_export *cobd_exp;
1215         int rc = 0;
1216         ENTRY;
1217
1218         if (obd == NULL) {
1219                 CERROR("invalid client cookie "LPX64"\n", 
1220                        mdc_exp->exp_handle.h_cookie);
1221                 RETURN(-EINVAL);
1222         }
1223         cobd_exp = cobd_get_exp(obd);
1224         rc = md_req2lustre_md(cobd_exp, req, offset, osc_exp, md);
1225         RETURN(rc);
1226 }
1227
1228 static int cobd_md_change_cbdata(struct obd_export *exp, struct lustre_id *id, 
1229                                  ldlm_iterator_t it, void *data)
1230 {
1231         struct obd_device *obd = class_exp2obd(exp);
1232         struct obd_export *cobd_exp;
1233         int rc = 0;
1234         ENTRY;
1235
1236         if (obd == NULL) {
1237                 CERROR("invalid client cookie "LPX64"\n", 
1238                        exp->exp_handle.h_cookie);
1239                 RETURN(-EINVAL);
1240         }
1241         cobd_exp = cobd_get_exp(obd);
1242         rc = md_change_cbdata(cobd_exp, id, it, data);
1243         RETURN(rc);
1244 }
1245
1246 static int cobd_md_getattr_lock(struct obd_export *exp, struct lustre_id *id,
1247                                 char *filename, int namelen, __u64 valid,
1248                                 unsigned int ea_size, struct ptlrpc_request **request)
1249 {
1250         struct obd_device *obd = class_exp2obd(exp);
1251         struct obd_export *cobd_exp;
1252         int rc = 0;
1253         ENTRY;
1254
1255         if (obd == NULL) {
1256                 CERROR("invalid client cookie "LPX64"\n", 
1257                        exp->exp_handle.h_cookie);
1258                 RETURN(-EINVAL);
1259         }
1260         cobd_exp = cobd_get_exp(obd);
1261         rc = md_getattr_lock(cobd_exp, id, filename, namelen,
1262                              valid, ea_size, request);
1263         RETURN(rc);
1264 }
1265
1266 static int cobd_md_create(struct obd_export *exp, struct mdc_op_data *op_data,
1267                           const void *data, int datalen, int mode, 
1268                           __u32 uid, __u32 gid, __u64 rdev, 
1269                           struct ptlrpc_request **request)
1270 {
1271         struct obd_device *obd = class_exp2obd(exp);
1272         struct obd_export *cobd_exp;
1273         int rc = 0;
1274         ENTRY;
1275
1276         if (obd == NULL) {
1277                 CERROR("invalid client cookie "LPX64"\n", 
1278                        exp->exp_handle.h_cookie);
1279                 RETURN(-EINVAL);
1280         }
1281         cobd_exp = cobd_get_exp(obd);
1282         rc = md_create(cobd_exp, op_data, data, datalen, mode,
1283                        uid, gid, rdev, request);
1284         RETURN(rc);
1285 }
1286
1287 static int cobd_md_unlink(struct obd_export *exp,
1288                           struct mdc_op_data *data,
1289                           struct ptlrpc_request **request)
1290 {
1291         struct obd_device *obd = class_exp2obd(exp);
1292         struct obd_export *cobd_exp;
1293         int rc = 0;
1294         ENTRY;
1295
1296         if (obd == NULL) {
1297                 CERROR("invalid client cookie "LPX64"\n", 
1298                        exp->exp_handle.h_cookie);
1299                 RETURN(-EINVAL);
1300         }
1301         cobd_exp = cobd_get_exp(obd);
1302         rc = md_unlink(cobd_exp, data, request);
1303         RETURN(rc);
1304 }
1305
1306 static int cobd_md_valid_attrs(struct obd_export *exp,
1307                                struct lustre_id *id)
1308 {
1309         struct obd_device *obd = class_exp2obd(exp);
1310         struct obd_export *cobd_exp;
1311         int rc = 0;
1312         ENTRY;
1313
1314         if (obd == NULL) {
1315                 CERROR("invalid client cookie "LPX64"\n", 
1316                        exp->exp_handle.h_cookie);
1317                 RETURN(-EINVAL);
1318         }
1319         cobd_exp = cobd_get_exp(obd);
1320         rc = md_valid_attrs(cobd_exp, id);
1321         RETURN(rc);
1322 }
1323
1324 static int cobd_md_rename(struct obd_export *exp, struct mdc_op_data *data,
1325                           const char *old, int oldlen, const char *new, 
1326                           int newlen, struct ptlrpc_request **request)
1327 {
1328         struct obd_device *obd = class_exp2obd(exp);
1329         struct obd_export *cobd_exp;
1330         int rc = 0;
1331         ENTRY;
1332
1333         if (obd == NULL) {
1334                 CERROR("invalid client cookie "LPX64"\n", 
1335                        exp->exp_handle.h_cookie);
1336                 RETURN(-EINVAL);
1337         }
1338         cobd_exp = cobd_get_exp(obd);
1339         rc = md_rename(cobd_exp, data, old, oldlen, new, newlen, request);
1340         RETURN(rc);
1341 }
1342
1343 static int cobd_md_link(struct obd_export *exp, struct mdc_op_data *data,
1344                         struct ptlrpc_request **request)
1345 {
1346         struct obd_device *obd = class_exp2obd(exp);
1347         struct obd_export *cobd_exp;
1348         int rc = 0;
1349         ENTRY;
1350
1351         if (obd == NULL) {
1352                 CERROR("invalid client cookie "LPX64"\n", 
1353                        exp->exp_handle.h_cookie);
1354                 RETURN(-EINVAL);
1355         }
1356         cobd_exp = cobd_get_exp(obd);
1357         rc = md_link(cobd_exp, data, request);
1358         RETURN(rc);
1359 }
1360
1361 static int cobd_md_setattr(struct obd_export *exp, struct mdc_op_data *data,
1362                            struct iattr *iattr, void *ea, int ealen, void *ea2, 
1363                            int ea2len, void *ea3, int ea3len, 
1364                            struct ptlrpc_request **request)
1365 {
1366         struct obd_device *obd = class_exp2obd(exp);
1367         struct obd_export *cobd_exp;
1368         int rc = 0;
1369         ENTRY;
1370
1371         if (obd == NULL) {
1372                 CERROR("invalid client cookie "LPX64"\n", 
1373                        exp->exp_handle.h_cookie);
1374                 RETURN(-EINVAL);
1375         }
1376         cobd_exp = cobd_get_exp(obd);
1377         rc = md_setattr(cobd_exp, data, iattr, ea,
1378                           ealen, ea2, ea2len, ea3, ea3len, request);
1379         RETURN(rc);
1380 }
1381
1382 static int cobd_md_readpage(struct obd_export *exp,
1383                             struct lustre_id *mdc_id,
1384                             __u64 offset, struct page *page, 
1385                             struct ptlrpc_request **request)
1386 {
1387         struct obd_device *obd = class_exp2obd(exp);
1388         struct obd_export *cobd_exp;
1389         int rc = 0;
1390         ENTRY;
1391
1392         if (obd == NULL) {
1393                 CERROR("invalid client cookie "LPX64"\n", 
1394                        exp->exp_handle.h_cookie);
1395                 RETURN(-EINVAL);
1396         }
1397         cobd_exp = cobd_get_exp(obd);
1398         rc = md_readpage(cobd_exp, mdc_id, offset, page, request);
1399         RETURN(rc);
1400 }
1401
1402 static int cobd_md_close(struct obd_export *exp, struct mdc_op_data *op_data,
1403                          struct obd_client_handle *och, 
1404                          struct ptlrpc_request **request)
1405 {
1406         struct obd_device *obd = class_exp2obd(exp);
1407         struct obd_export *cobd_exp;
1408         int rc = 0;
1409         ENTRY;
1410
1411         if (obd == NULL) {
1412                 CERROR("invalid client cookie "LPX64"\n", 
1413                        exp->exp_handle.h_cookie);
1414                 RETURN(-EINVAL);
1415         }
1416         cobd_exp = cobd_get_exp(obd);
1417         rc = md_close(cobd_exp, op_data, och, request);
1418         RETURN(rc);
1419 }
1420
1421 static int cobd_md_done_writing(struct obd_export *exp,
1422                                 struct obdo *obdo)
1423 {
1424         struct obd_device *obd = class_exp2obd(exp);
1425         struct obd_export *cobd_exp;
1426         int rc = 0;
1427         ENTRY;
1428
1429         if (obd == NULL) {
1430                 CERROR("invalid client cookie "LPX64"\n", 
1431                        exp->exp_handle.h_cookie);
1432                 RETURN(-EINVAL);
1433         }
1434         cobd_exp = cobd_get_exp(obd);
1435         rc = md_done_writing(cobd_exp, obdo);
1436         RETURN(rc);
1437 }
1438
1439 static int cobd_md_sync(struct obd_export *exp, struct lustre_id *id,
1440                         struct ptlrpc_request **request)
1441 {
1442         struct obd_device *obd = class_exp2obd(exp);
1443         struct obd_export *cobd_exp;
1444         int rc = 0;
1445         ENTRY;
1446
1447         if (obd == NULL) {
1448                 CERROR("invalid client cookie "LPX64"\n", 
1449                        exp->exp_handle.h_cookie);
1450                 RETURN(-EINVAL);
1451         }
1452         cobd_exp = cobd_get_exp(obd);
1453         rc = md_sync(cobd_exp, id, request);
1454         RETURN(rc);
1455 }
1456
1457 static int cobd_md_set_open_replay_data(struct obd_export *exp,
1458                                         struct obd_client_handle *och,
1459                                         struct ptlrpc_request *open_req)
1460 {
1461         struct obd_device *obd = class_exp2obd(exp);
1462         struct obd_export *cobd_exp;
1463         int rc = 0;
1464         ENTRY;
1465
1466         if (obd == NULL) {
1467                 CERROR("invalid client cookie "LPX64"\n", 
1468                        exp->exp_handle.h_cookie);
1469                 RETURN(-EINVAL);
1470         }
1471         cobd_exp = cobd_get_exp(obd);
1472         rc = md_set_open_replay_data(cobd_exp, och, open_req);
1473         RETURN(rc);
1474 }
1475
1476 static int cobd_md_clear_open_replay_data(struct obd_export *exp,
1477                                           struct obd_client_handle *och)
1478 {
1479         struct obd_device *obd = class_exp2obd(exp);
1480         struct obd_export *cobd_exp;
1481         int rc = 0;
1482         ENTRY;
1483
1484         if (obd == NULL) {
1485                 CERROR("invalid client cookie "LPX64"\n", 
1486                        exp->exp_handle.h_cookie);
1487                 RETURN(-EINVAL);
1488         }
1489         cobd_exp = cobd_get_exp(obd);
1490         rc = md_clear_open_replay_data(cobd_exp, och);
1491         RETURN(rc);
1492 }
1493
1494 static int cobd_md_store_inode_generation(struct obd_export *exp,
1495                                           struct ptlrpc_request *req, 
1496                                           int reqoff, int repoff)
1497 {
1498         struct obd_device *obd = class_exp2obd(exp);
1499         struct obd_export *cobd_exp;
1500         int rc = 0;
1501         ENTRY;
1502
1503         if (obd == NULL) {
1504                 CERROR("invalid client cookie "LPX64"\n", 
1505                        exp->exp_handle.h_cookie);
1506                 RETURN(-EINVAL);
1507         }
1508         cobd_exp = cobd_get_exp(obd);
1509         rc = md_store_inode_generation(cobd_exp, req, reqoff, repoff);
1510         RETURN(rc);
1511 }
1512
1513 static int cobd_md_set_lock_data(struct obd_export *exp,
1514                                  __u64 *l, void *data)
1515 {
1516         struct obd_device *obd = class_exp2obd(exp);
1517         struct obd_export *cobd_exp;
1518         int rc = 0;
1519         ENTRY;
1520
1521         if (obd == NULL) {
1522                 CERROR("invalid client cookie "LPX64"\n", 
1523                        exp->exp_handle.h_cookie);
1524                 RETURN(-EINVAL);
1525         }
1526         cobd_exp = cobd_get_exp(obd);
1527         rc = md_set_lock_data(cobd_exp, l, data);
1528         RETURN(rc);
1529 }
1530
1531 static int cobd_md_enqueue(struct obd_export *exp, int lock_type,
1532                            struct lookup_intent *it, int lock_mode,
1533                            struct mdc_op_data *data, struct lustre_handle *lockh,
1534                            void *lmm, int lmmsize, 
1535                            ldlm_completion_callback cb_completion,
1536                            ldlm_blocking_callback cb_blocking, void *cb_data)
1537 {
1538         struct obd_device *obd = class_exp2obd(exp);
1539         struct obd_export *cobd_exp;
1540         int rc = 0;
1541         ENTRY;
1542
1543         if (obd == NULL) {
1544                 CERROR("invalid client cookie "LPX64"\n", 
1545                        exp->exp_handle.h_cookie);
1546                 RETURN(-EINVAL);
1547         }
1548         cobd_exp = cobd_get_exp(obd);
1549         rc = md_enqueue(cobd_exp, lock_type, it, lock_mode, data,
1550                         lockh, lmm, lmmsize, cb_completion, cb_blocking,
1551                         cb_data);
1552         RETURN(rc);
1553 }
1554
1555 static int cobd_md_intent_lock(struct obd_export *exp, struct lustre_id *pid, 
1556                                const char *name, int len, void *lmm, int lmmsize,
1557                                struct lustre_id *cid, struct lookup_intent *it,
1558                                int lookup_flags, struct ptlrpc_request **reqp,
1559                                ldlm_blocking_callback cb_blocking)
1560 {
1561         struct obd_device *obd = class_exp2obd(exp);
1562         struct obd_export *cobd_exp;
1563         int rc = 0;
1564         ENTRY;
1565
1566         if (obd == NULL) {
1567                 CERROR("invalid client cookie "LPX64"\n", 
1568                        exp->exp_handle.h_cookie);
1569                 RETURN(-EINVAL);
1570         }
1571         lookup_flags |= LOOKUP_COBD;
1572         cobd_exp = cobd_get_exp(obd);
1573         
1574         rc = md_intent_lock(cobd_exp, pid, name, len, lmm, lmmsize,
1575                             cid, it, lookup_flags, reqp, cb_blocking);
1576         RETURN(rc);
1577 }
1578
1579 static struct obd_device *cobd_md_get_real_obd(struct obd_export *exp,
1580                                                struct lustre_id *id)
1581 {
1582         struct obd_device *obd = class_exp2obd(exp);
1583         struct obd_export *cobd_exp;
1584         ENTRY;
1585
1586         if (obd == NULL) {
1587                 CERROR("invalid client cookie "LPX64"\n", 
1588                        exp->exp_handle.h_cookie);
1589                 RETURN(NULL);
1590         }
1591         cobd_exp = cobd_get_exp(obd);
1592         RETURN(md_get_real_obd(cobd_exp, id));
1593 }
1594
1595 static int cobd_md_change_cbdata_name(struct obd_export *exp,
1596                                       struct lustre_id *id, char *name,
1597                                       int namelen, struct lustre_id *id2,
1598                                       ldlm_iterator_t it, void *data)
1599 {
1600         struct obd_device *obd = class_exp2obd(exp);
1601         struct obd_export *cobd_exp;
1602         int rc = 0;
1603
1604         if (obd == NULL) {
1605                 CERROR("invalid client cookie "LPX64"\n", 
1606                        exp->exp_handle.h_cookie);
1607                 RETURN(-EINVAL);
1608         }
1609         cobd_exp = cobd_get_exp(obd);
1610         rc = md_change_cbdata_name(cobd_exp, id, name, namelen,
1611                                    id2, it, data);
1612         RETURN(rc);
1613 }
1614
1615 static struct obd_ops cobd_obd_ops = {
1616         .o_owner                  = THIS_MODULE,
1617         .o_attach                 = cobd_attach,
1618         .o_detach                 = cobd_detach,
1619         .o_setup                  = cobd_setup,
1620         .o_cleanup                = cobd_cleanup,
1621         .o_connect                = cobd_connect,
1622         .o_disconnect             = cobd_disconnect,
1623         .o_set_info               = cobd_set_info,
1624         .o_get_info               = cobd_get_info,
1625         .o_statfs                 = cobd_statfs,
1626         .o_iocontrol              = cobd_iocontrol,
1627         .o_notify                 = cobd_notify,
1628         .o_pin                    = cobd_pin,
1629         .o_unpin                  = cobd_unpin,
1630
1631         .o_packmd                 = cobd_dt_packmd,
1632         .o_unpackmd               = cobd_dt_unpackmd,
1633         .o_create                 = cobd_dt_create,
1634         .o_destroy                = cobd_dt_destroy,
1635         .o_precleanup             = cobd_dt_precleanup,
1636         .o_getattr                = cobd_dt_getattr,
1637         .o_getattr_async          = cobd_dt_getattr_async,
1638         .o_setattr                = cobd_dt_setattr,
1639         .o_brw                    = cobd_dt_brw,
1640         .o_brw_async              = cobd_dt_brw_async,
1641         .o_prep_async_page        = cobd_dt_prep_async_page,
1642         .o_queue_async_io         = cobd_dt_queue_async_io,
1643         .o_set_async_flags        = cobd_dt_set_async_flags,
1644         .o_queue_group_io         = cobd_dt_queue_group_io,
1645         .o_trigger_group_io       = cobd_dt_trigger_group_io,
1646         .o_teardown_async_page    = cobd_dt_teardown_async_page,
1647         .o_preprw                 = cobd_dt_preprw,
1648         .o_punch                  = cobd_dt_punch,
1649         .o_sync                   = cobd_dt_sync,
1650         .o_enqueue                = cobd_dt_enqueue,
1651         .o_match                  = cobd_dt_match,
1652         .o_change_cbdata          = cobd_dt_change_cbdata,
1653         .o_cancel                 = cobd_dt_cancel,
1654         .o_cancel_unused          = cobd_dt_cancel_unused,
1655         .o_commitrw               = cobd_dt_commitrw,
1656         .o_llog_init              = cobd_dt_llog_init,
1657         .o_llog_finish            = cobd_dt_llog_finish,
1658         .o_import_event           = cobd_dt_import_event,
1659         .o_init_ea_size           = cobd_dt_init_ea_size,
1660         .o_adjust_kms             = cobd_dt_adjust_kms,
1661 };
1662
1663 struct md_ops cobd_md_ops = {
1664         .m_getstatus              = cobd_md_getstatus,
1665         .m_getattr                = cobd_md_getattr,
1666         .m_req2lustre_md          = cobd_md_req2lustre_md,
1667         .m_change_cbdata          = cobd_md_change_cbdata,
1668         .m_getattr_lock           = cobd_md_getattr_lock,
1669         .m_create                 = cobd_md_create,
1670         .m_unlink                 = cobd_md_unlink,
1671         .m_valid_attrs            = cobd_md_valid_attrs,
1672         .m_rename                 = cobd_md_rename,
1673         .m_link                   = cobd_md_link,
1674         .m_setattr                = cobd_md_setattr,
1675         .m_readpage               = cobd_md_readpage,
1676         .m_close                  = cobd_md_close,
1677         .m_done_writing           = cobd_md_done_writing,
1678         .m_sync                   = cobd_md_sync,
1679         .m_set_open_replay_data   = cobd_md_set_open_replay_data,
1680         .m_clear_open_replay_data = cobd_md_clear_open_replay_data,
1681         .m_store_inode_generation = cobd_md_store_inode_generation,
1682         .m_set_lock_data          = cobd_md_set_lock_data,
1683         .m_enqueue                = cobd_md_enqueue,
1684         .m_get_real_obd           = cobd_md_get_real_obd,
1685         .m_intent_lock            = cobd_md_intent_lock,
1686         .m_change_cbdata_name     = cobd_md_change_cbdata_name,
1687 };
1688
1689 static int __init cobd_init(void)
1690 {
1691         struct lprocfs_static_vars lvars;
1692         ENTRY;
1693
1694         printk(KERN_INFO "Lustre: Caching OBD driver; info@clusterfs.com\n");
1695
1696         lprocfs_init_vars(cobd, &lvars);
1697         RETURN(class_register_type(&cobd_obd_ops, &cobd_md_ops,
1698                                    lvars.module_vars, OBD_CACHE_DEVICENAME));
1699 }
1700
1701 static void /*__exit*/ cobd_exit(void)
1702 {
1703         class_unregister_type(OBD_CACHE_DEVICENAME);
1704 }
1705
1706 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
1707 MODULE_DESCRIPTION("Lustre Caching OBD driver");
1708 MODULE_LICENSE("GPL");
1709
1710 module_init(cobd_init);
1711 module_exit(cobd_exit);