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 #include <linux/blk.h>
31
32 static int linear_run (int minor, struct md_dev *mddev)
33 {
34 int cur=0, i, size, dev0_size, nb_zone;
35 struct linear_data *data;
36
37 MOD_INC_USE_COUNT;
38
39 mddev->private=kmalloc (sizeof (struct linear_data), GFP_KERNEL);
40 data=(struct linear_data *) mddev->private;
41
42
43
44
45
46
47
48 data->smallest=devices[minor];
49 for (i=1; i<mddev->nb_dev; i++)
50 if (data->smallest->size > devices[minor][i].size)
51 data->smallest=devices[minor]+i;
52
53 nb_zone=data->nr_zones=
54 md_size[minor]/data->smallest->size +
55 (md_size[minor]%data->smallest->size ? 1 : 0);
56
57 data->hash_table=kmalloc (sizeof (struct linear_hash)*nb_zone, GFP_KERNEL);
58
59 size=devices[minor][cur].size;
60
61 i=0;
62 while (cur<mddev->nb_dev)
63 {
64 data->hash_table[i].dev0=devices[minor]+cur;
65
66 if (size>=data->smallest->size)
67 {
68 data->hash_table[i++].dev1=NULL;
69 size-=data->smallest->size;
70
71 if (!size)
72 {
73 if (++cur==mddev->nb_dev) continue;
74 size=devices[minor][cur].size;
75 }
76
77 continue;
78 }
79
80 if (++cur==mddev->nb_dev)
81 {
82 data->hash_table[i].dev1=NULL;
83 continue;
84 }
85
86 dev0_size=size;
87 size=devices[minor][cur].size;
88 data->hash_table[i++].dev1=devices[minor]+cur;
89 size-=(data->smallest->size - dev0_size);
90 }
91
92 return 0;
93 }
94
95 static int linear_stop (int minor, struct md_dev *mddev)
96 {
97 struct linear_data *data=(struct linear_data *) mddev->private;
98
99 kfree (data->hash_table);
100 kfree (data);
101
102 MOD_DEC_USE_COUNT;
103
104 return 0;
105 }
106
107
108 static int linear_map (int minor, struct md_dev *mddev, struct request *req)
109 {
110 struct linear_data *data=(struct linear_data *) mddev->private;
111 struct linear_hash *hash;
112 struct real_dev *tmp_dev;
113 long block, rblock;
114 struct buffer_head *bh, *bh2;
115 int queue, nblk;
116 static struct request pending[MAX_REAL]={{0, }, };
117
118 while (req->nr_sectors)
119 {
120 block=req->sector >> 1;
121 hash=data->hash_table+(block/data->smallest->size);
122
123 if (block >= (hash->dev0->size + hash->dev0->offset))
124 {
125 if (!hash->dev1)
126 printk ("linear_map : hash->dev1==NULL for block %ld\n", block);
127 tmp_dev=hash->dev1;
128 }
129 else
130 tmp_dev=hash->dev0;
131
132 if (block >= (tmp_dev->size + tmp_dev->offset) || block < tmp_dev->offset)
133 printk ("Block %ld out of bounds on dev %04x size %d offset %d\n", block, tmp_dev->dev, tmp_dev->size, tmp_dev->offset);
134
135 rblock=(block-(tmp_dev->offset));
136
137 if (req->sem)
138 {
139 req->rq_dev=tmp_dev->dev;
140 req->sector=rblock << 1;
141 add_request (blk_dev+MAJOR (tmp_dev->dev), req);
142
143 return REDIRECTED_REQ;
144 }
145
146 queue=tmp_dev - devices[minor];
147
148 for (nblk=0, bh=bh2=req->bh;
149 bh && rblock + nblk + (bh->b_size >> 10) <= tmp_dev->size;
150 nblk+=bh->b_size >> 10, bh2=bh, bh=bh->b_reqnext)
151 {
152 if (!buffer_locked(bh))
153 printk("md%d: block %ld not locked\n", minor, bh->b_blocknr);
154
155 bh->b_rdev=tmp_dev->dev;
156 }
157
158 pending[queue].rq_dev=tmp_dev->dev;
159 pending[queue].cmd=req->cmd;
160 pending[queue].sector=rblock << 1;
161 pending[queue].nr_sectors=nblk << 1;
162 pending[queue].current_nr_sectors=req->bh->b_size >> 9;
163 pending[queue].bh=req->bh;
164 pending[queue].bhtail=bh2;
165 bh2->b_reqnext=NULL;
166
167 req->bh=bh;
168 req->sector+=nblk << 1;
169 req->nr_sectors-=nblk << 1;
170 }
171
172 req->rq_status=RQ_INACTIVE;
173 wake_up (&wait_for_request);
174 make_md_request (pending, mddev->nb_dev);
175 return REDIRECTED_REQ;
176 }
177
178
179 static int linear_status (char *page, int minor, struct md_dev *mddev)
180 {
181 int sz=0;
182
183 #undef MD_DEBUG
184 #ifdef MD_DEBUG
185 int j;
186 struct linear_data *data=(struct linear_data *) mddev->private;
187
188 sz+=sprintf (page+sz, " ");
189 for (j=0; j<data->nr_zones; j++)
190 {
191 sz+=sprintf (page+sz, "[%s",
192 partition_name (data->hash_table[j].dev0->dev));
193
194 if (data->hash_table[j].dev1)
195 sz+=sprintf (page+sz, "/%s] ",
196 partition_name(data->hash_table[j].dev1->dev));
197 else
198 sz+=sprintf (page+sz, "] ");
199 }
200
201 sz+=sprintf (page+sz, "\n");
202 #endif
203 return sz;
204 }
205
206
207 static struct md_personality linear_personality=
208 {
209 "linear",
210 linear_map,
211 linear_run,
212 linear_stop,
213 linear_status,
214 NULL,
215 0
216 };
217
218
219 #ifndef MODULE
220
221 void linear_init (void)
222 {
223 register_md_personality (LINEAR, &linear_personality);
224 }
225
226 #else
227
228 int init_module (void)
229 {
230 return (register_md_personality (LINEAR, &linear_personality));
231 }
232
233 void cleanup_module (void)
234 {
235 if (MOD_IN_USE)
236 printk ("md linear : module still busy...\n");
237 else
238 unregister_md_personality (LINEAR);
239 }
240
241 #endif