1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2002 Cluster File Systems, Inc. <info@clusterfs.com>
6 * This file is part of Lustre, http://www.lustre.org.
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.
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.
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.
22 #define DEBUG_SUBSYSTEM S_COBD
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/obd_class.h>
31 #include <linux/obd_cache.h>
33 static int cobd_attach(struct obd_device *dev, obd_count len, void *data)
35 struct lprocfs_static_vars lvars;
37 lprocfs_init_vars(cobd, &lvars);
38 return lprocfs_obd_attach(dev, lvars.obd_vars);
41 static int cobd_detach(struct obd_device *dev)
43 return lprocfs_obd_detach(dev);
47 cobd_setup (struct obd_device *dev, obd_count len, void *buf)
49 struct lustre_cfg *lcfg = (struct lustre_cfg *)buf;
50 struct cache_obd *cobd = &dev->u.cobd;
51 struct obd_device *target;
52 struct obd_device *cache;
53 struct obd_uuid target_uuid;
54 struct obd_uuid cache_uuid;
55 struct lustre_handle target_conn = {0,}, cache_conn = {0,};
58 if (lcfg->lcfg_inlbuf1 == NULL ||
59 lcfg->lcfg_inlbuf2 == NULL)
62 obd_str2uuid(&target_uuid, lcfg->lcfg_inlbuf1);
63 target = class_uuid2obd (&target_uuid);
65 obd_str2uuid(&cache_uuid, lcfg->lcfg_inlbuf2);
66 cache = class_uuid2obd (&cache_uuid);
71 /* don't bother checking attached/setup;
72 * obd_connect() should, and it can change underneath us */
73 rc = obd_connect(&target_conn, target, &target_uuid);
76 cobd->cobd_target_exp = class_conn2export(&target_conn);
78 rc = obd_connect(&cache_conn, cache, &cache_uuid);
80 obd_disconnect(cobd->cobd_target_exp, 0);
83 cobd->cobd_cache_exp = class_conn2export(&cache_conn);
88 static int cobd_cleanup(struct obd_device *dev, int flags)
90 struct cache_obd *cobd = &dev->u.cobd;
93 if (!list_empty(&dev->obd_exports))
96 rc = obd_disconnect(cobd->cobd_cache_exp, flags);
98 CERROR ("error %d disconnecting cache\n", rc);
100 rc = obd_disconnect(cobd->cobd_target_exp, flags);
102 CERROR ("error %d disconnecting target\n", rc);
108 cobd_connect (struct lustre_handle *conn, struct obd_device *obd,
109 struct obd_uuid *cluuid)
111 int rc = class_connect (conn, obd, cluuid);
113 CERROR ("rc %d\n", rc);
117 static int cobd_disconnect(struct obd_export *exp, int flags)
119 int rc = class_disconnect(exp, flags);
121 CERROR ("rc %d\n", rc);
125 static int cobd_get_info(struct obd_export *exp, obd_count keylen,
126 void *key, __u32 *vallen, void *val)
128 struct obd_device *obd = class_exp2obd(exp);
129 struct cache_obd *cobd;
132 CERROR("invalid client cookie "LPX64"\n",
133 exp->exp_handle.h_cookie);
139 /* intercept cache utilisation info? */
141 return obd_get_info(cobd->cobd_target_exp, keylen, key, vallen, val);
144 static int cobd_statfs(struct obd_device *obd, struct obd_statfs *osfs,
145 unsigned long max_age)
147 return obd_statfs(class_exp2obd(obd->u.cobd.cobd_target_exp), osfs,
151 static int cobd_getattr(struct obd_export *exp, struct obdo *oa,
152 struct lov_stripe_md *lsm)
154 struct obd_device *obd = class_exp2obd(exp);
155 struct cache_obd *cobd;
158 CERROR("invalid client cookie "LPX64"\n",
159 exp->exp_handle.h_cookie);
164 return obd_getattr(cobd->cobd_target_exp, oa, lsm);
167 static int cobd_preprw(int cmd, struct obd_export *exp, struct obdo *oa,
168 int objcount, struct obd_ioobj *obj,
169 int niocount, struct niobuf_remote *nb,
170 struct niobuf_local *res, struct obd_trans_info *oti)
172 struct obd_export *cobd_exp;
175 if (exp->exp_obd == NULL)
178 if ((cmd & OBD_BRW_WRITE) != 0)
181 cobd_exp = exp->exp_obd->u.cobd.cobd_target_exp;
182 rc = obd_preprw(cmd, cobd_exp, oa, objcount, obj, niocount, nb, res,
188 static int cobd_commitrw(int cmd, struct obd_export *exp, struct obdo *oa,
189 int objcount, struct obd_ioobj *obj,
190 int niocount, struct niobuf_local *local,
191 struct obd_trans_info *oti, int rc)
193 struct obd_export *cobd_exp;
195 if (exp->exp_obd == NULL)
198 if ((cmd & OBD_BRW_WRITE) != 0)
201 cobd_exp = exp->exp_obd->u.cobd.cobd_target_exp;
202 rc = obd_commitrw(cmd, cobd_exp, oa, objcount, obj, niocount, local,
207 static int cobd_brw(int cmd, struct obd_export *exp, struct obdo *oa,
208 struct lov_stripe_md *lsm, obd_count oa_bufs,
209 struct brw_page *pga, struct obd_trans_info *oti)
211 struct obd_device *obd = class_exp2obd(exp);
212 struct cache_obd *cobd;
215 CERROR("invalid client cookie "LPX64"\n",
216 exp->exp_handle.h_cookie);
220 if ((cmd & OBD_BRW_WRITE) != 0)
224 return obd_brw(cmd, cobd->cobd_target_exp, oa, lsm, oa_bufs, pga, oti);
227 static int cobd_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
228 void *karg, void *uarg)
230 struct obd_device *obd = class_exp2obd(exp);
231 struct cache_obd *cobd;
234 CERROR("invalid client cookie "LPX64"\n",
235 exp->exp_handle.h_cookie);
242 return obd_iocontrol(cmd, cobd->cobd_target_exp, len, karg, uarg);
245 static struct obd_ops cobd_ops = {
246 o_owner: THIS_MODULE,
247 o_attach: cobd_attach,
248 o_detach: cobd_detach,
251 o_cleanup: cobd_cleanup,
253 o_connect: cobd_connect,
254 o_disconnect: cobd_disconnect,
256 o_get_info: cobd_get_info,
257 o_statfs: cobd_statfs,
259 o_getattr: cobd_getattr,
260 o_preprw: cobd_preprw,
261 o_commitrw: cobd_commitrw,
263 o_iocontrol: cobd_iocontrol,
266 static int __init cobd_init(void)
268 struct lprocfs_static_vars lvars;
271 printk(KERN_INFO "Lustre: Caching OBD driver; info@clusterfs.com\n");
273 lprocfs_init_vars(cobd, &lvars);
274 RETURN(class_register_type(&cobd_ops, lvars.module_vars,
275 OBD_CACHE_DEVICENAME));
278 static void /*__exit*/ cobd_exit(void)
280 class_unregister_type(OBD_CACHE_DEVICENAME);
283 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
284 MODULE_DESCRIPTION("Lustre Caching OBD driver");
285 MODULE_LICENSE("GPL");
287 module_init(cobd_init);
288 module_exit(cobd_exit);