2 * linux/fs/sim_obd/sim_obd.c
4 * These are the only exported functions; they provide the simulated object-
9 #include <asm/uaccess.h>
10 #include <linux/sched.h>
11 #include <linux/stat.h>
12 #include <linux/string.h>
13 #include <linux/locks.h>
14 #include <linux/quotaops.h>
15 #include <linux/list.h>
16 #include <linux/file.h>
17 #include <linux/iobuf.h>
18 #include <asm/bitops.h>
19 #include <asm/byteorder.h>
20 #include <linux/obd_support.h>
21 #include <linux/obd_class.h>
24 extern struct obd_device obd_dev[MAX_OBD_DEVICES];
26 /* map connection to client */
27 struct obd_client *gen_client(int cli_id)
29 struct obd_device * obddev;
30 struct list_head * lh, * next;
31 struct obd_client * cli;
34 for (a = 0; a < MAX_OBD_DEVICES; a++) {
37 lh = next = &obddev->obd_gen_clients;
38 while ((lh = lh->next) != &obddev->obd_gen_clients) {
39 cli = list_entry(lh, struct obd_client, cli_chain);
41 if (cli->cli_id == cli_id)
51 /* a connection defines a context in which preallocation can be managed. */
52 int gen_connect (struct obd_device *obddev,
53 struct obd_conn_info * conninfo)
55 struct obd_client * cli;
57 OBD_ALLOC(cli, struct obd_client *, sizeof(struct obd_client));
59 printk("obd_connect (minor %d): no memory!\n",
64 INIT_LIST_HEAD(&cli->cli_prealloc_inodes);
65 /* this should probably spinlocked? */
66 cli->cli_id = ++obddev->obd_gen_last_id;
67 cli->cli_prealloc_quota = 0;
68 cli->cli_obd = obddev;
69 list_add(&(cli->cli_chain), obddev->obd_gen_clients.prev);
71 CDEBUG(D_IOCTL, "connect: new ID %u\n", cli->cli_id);
72 conninfo->conn_id = cli->cli_id;
74 } /* gen_obd_connect */
77 int gen_disconnect(unsigned int conn_id)
79 struct obd_client * cli;
83 if (!(cli = gen_client(conn_id))) {
84 CDEBUG(D_IOCTL, "disconnect: attempting to free "
85 "nonexistent client %u\n", conn_id);
89 list_del(&(cli->cli_chain));
90 OBD_FREE(cli, sizeof(struct obd_client));
92 CDEBUG(D_IOCTL, "disconnect: ID %u\n", conn_id);
96 } /* gen_obd_disconnect */
100 * raid1 defines a number of connections to child devices,
101 * used to make calls to these devices.
104 int gen_multi_setup(struct obd_device *obddev, int len, void *data)
107 struct obd_device *rdev = obddev->obd_multi_dev[0];
109 for (i = 0 ; i < obddev->obd_multi_count ; i++ ) {
111 struct obd_device *child = rdev + i;
112 rc = OBP(child, connect)(child, &rdev->obd_multi_conns[i]);
115 /* XXX disconnect others */
122 int gen_multi_cleanup(struct obd_device * obddev)
125 struct obd_device *rdev = obddev->obd_multi_dev[0];
127 for (i = 0 ; i < obddev->obd_multi_count ; i++ ) {
129 struct obd_device *child = rdev + i;
130 rc = OBP(child, cleanup)(child);
134 /* XXX disconnect others */
140 } /* sim_cleanup_obddev */
143 int gen_multi_attach(struct obd_device *obddev, int len, void *data)
147 struct obd_device *rdev = obddev->obd_multi_dev[0];
149 count = len/sizeof(int);
150 obddev->obd_multi_count = count;
151 for (i=0 ; i<count ; i++) {
152 rdev = &obd_dev[*((int *)data + i)];
154 CDEBUG(D_IOCTL, "OBD RAID1: replicator %d is of type %s\n", i,
155 (rdev + i)->obd_type->typ_name);
163 * remove all connections to this device
164 * close all connections to lower devices
165 * needed for forced unloads of OBD client drivers
167 int gen_multi_cleanup_device(struct obd_device *obddev)
170 struct obd_device *rdev;
172 rdev = obddev->obd_multi_dev[0];
173 for (i = 0 ; i < obddev->obd_multi_count ; i++ ) {
175 struct obd_device *child = rdev + i;
176 rc = OBP(child, disconnect)
177 (obddev->obd_multi_conns[i].conn_id);
180 printk("OBD multi cleanup dev: disconnect failure %d\n", child->obd_minor);
185 } /* gen_multi_cleanup_device */
189 * forced cleanup of the device:
190 * - remove connections from the device
191 * - cleanup the device afterwards
193 int gen_cleanup(struct obd_device * obddev)
195 struct list_head * lh, * tmp;
196 struct obd_client * cli;
200 lh = tmp = &obddev->obd_gen_clients;
201 while ((tmp = tmp->next) != lh) {
202 cli = list_entry(tmp, struct obd_client, cli_chain);
203 CDEBUG(D_IOCTL, "Disconnecting obd_connection %d, at %p\n",
205 OBP(obddev, disconnect)(cli->cli_id);
208 return OBP(obddev, cleanup_device)(obddev);
209 } /* sim_cleanup_device */