This source file includes following definitions.
- linear_run
- linear_stop
- linear_map
- linear_status
- linear_init
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <linux/module.h>
21
22 #include <linux/md.h>
23 #include <linux/linear.h>
24 #include <linux/malloc.h>
25
26 #define MAJOR_NR MD_MAJOR
27 #define MD_DRIVER
28 #define MD_PERSONALITY
29
30 static int linear_run (int minor, struct md_dev *mddev)
31 {
32 int cur=0, i, size, dev0_size, nb_zone;
33 struct linear_data *data;
34
35 MOD_INC_USE_COUNT;
36
37 mddev->private=kmalloc (sizeof (struct linear_data), GFP_KERNEL);
38 data=(struct linear_data *) mddev->private;
39
40
41
42
43
44
45
46 data->smallest=devices[minor];
47 for (i=1; i<mddev->nb_dev; i++)
48 if (data->smallest->size > devices[minor][i].size)
49 data->smallest=devices[minor]+i;
50
51 nb_zone=data->nr_zones=
52 md_size[minor]/data->smallest->size +
53 (md_size[minor]%data->smallest->size ? 1 : 0);
54
55 data->hash_table=kmalloc (sizeof (struct linear_hash)*nb_zone, GFP_KERNEL);
56
57 size=devices[minor][cur].size;
58
59 i=0;
60 while (cur<mddev->nb_dev)
61 {
62 data->hash_table[i].dev0=devices[minor]+cur;
63
64 if (size>=data->smallest->size)
65 {
66 data->hash_table[i++].dev1=NULL;
67 size-=data->smallest->size;
68
69 if (!size)
70 {
71 if (++cur==mddev->nb_dev) continue;
72 size=devices[minor][cur].size;
73 }
74
75 continue;
76 }
77
78 if (++cur==mddev->nb_dev)
79 {
80 data->hash_table[i].dev1=NULL;
81 continue;
82 }
83
84 dev0_size=size;
85 size=devices[minor][cur].size;
86 data->hash_table[i++].dev1=devices[minor]+cur;
87 size-=(data->smallest->size - dev0_size);
88 }
89
90 return 0;
91 }
92
93 static int linear_stop (int minor, struct md_dev *mddev)
94 {
95 struct linear_data *data=(struct linear_data *) mddev->private;
96
97 kfree (data->hash_table);
98 kfree (data);
99
100 MOD_DEC_USE_COUNT;
101
102 return 0;
103 }
104
105
106 static int linear_map (struct md_dev *mddev, kdev_t *rdev,
107 unsigned long *rsector, unsigned long size)
108 {
109 struct linear_data *data=(struct linear_data *) mddev->private;
110 struct linear_hash *hash;
111 struct real_dev *tmp_dev;
112 long block;
113
114 block=*rsector >> 1;
115 hash=data->hash_table+(block/data->smallest->size);
116
117 if (block >= (hash->dev0->size + hash->dev0->offset))
118 {
119 if (!hash->dev1)
120 {
121 printk ("linear_map : hash->dev1==NULL for block %ld\n", block);
122 return (-1);
123 }
124
125 tmp_dev=hash->dev1;
126 }
127 else
128 tmp_dev=hash->dev0;
129
130 if (block >= (tmp_dev->size + tmp_dev->offset) || block < tmp_dev->offset)
131 printk ("Block %ld out of bounds on dev %04x size %d offset %d\n", block, tmp_dev->dev, tmp_dev->size, tmp_dev->offset);
132
133 *rdev=tmp_dev->dev;
134 *rsector=(block-(tmp_dev->offset)) << 1;
135
136 return (0);
137 }
138
139 static int linear_status (char *page, int minor, struct md_dev *mddev)
140 {
141 int sz=0;
142
143 #undef MD_DEBUG
144 #ifdef MD_DEBUG
145 int j;
146 struct linear_data *data=(struct linear_data *) mddev->private;
147
148 sz+=sprintf (page+sz, " ");
149 for (j=0; j<data->nr_zones; j++)
150 {
151 sz+=sprintf (page+sz, "[%s",
152 partition_name (data->hash_table[j].dev0->dev));
153
154 if (data->hash_table[j].dev1)
155 sz+=sprintf (page+sz, "/%s] ",
156 partition_name(data->hash_table[j].dev1->dev));
157 else
158 sz+=sprintf (page+sz, "] ");
159 }
160
161 sz+=sprintf (page+sz, "\n");
162 #endif
163 return sz;
164 }
165
166
167 static struct md_personality linear_personality=
168 {
169 "linear",
170 linear_map,
171 linear_run,
172 linear_stop,
173 linear_status,
174 NULL,
175 0
176 };
177
178
179 #ifndef MODULE
180
181 void linear_init (void)
182 {
183 register_md_personality (LINEAR, &linear_personality);
184 }
185
186 #else
187
188 int init_module (void)
189 {
190 return (register_md_personality (LINEAR, &linear_personality));
191 }
192
193 void cleanup_module (void)
194 {
195 if (MOD_IN_USE)
196 printk ("md linear : module still busy...\n");
197 else
198 unregister_md_personality (LINEAR);
199 }
200
201 #endif