This source file includes following definitions.
- transfer_none
- transfer_xor
- transfer_des
- figure_loop_size
- do_lo_request
- loop_set_fd
- loop_clr_fd
- loop_set_status
- loop_get_status
- lo_ioctl
- lo_open
- lo_release
- loop_init
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include <linux/module.h>
17
18 #include <linux/fs.h>
19 #include <linux/stat.h>
20 #include <linux/errno.h>
21 #include <linux/major.h>
22
23 #include <asm/segment.h>
24
25 #ifdef DES_AVAILABLE
26 #include "des.h"
27 #endif
28 #include <linux/loop.h>
29
30 #define MAJOR_NR LOOP_MAJOR
31
32 #define DEVICE_NAME "loop"
33 #define DEVICE_REQUEST do_lo_request
34 #define DEVICE_NR(device) (MINOR(device))
35 #define DEVICE_ON(device)
36 #define DEVICE_OFF(device)
37 #define DEVICE_NO_RANDOM
38 #define TIMEOUT_VALUE (6 * HZ)
39 #include <linux/blk.h>
40
41 #define MAX_LOOP 8
42 static struct loop_device loop_dev[MAX_LOOP];
43 static int loop_sizes[MAX_LOOP];
44
45
46
47
48 static int transfer_none(struct loop_device *lo, int cmd, char *raw_buf,
49 char *loop_buf, int size)
50 {
51 if (cmd == READ)
52 memcpy(loop_buf, raw_buf, size);
53 else
54 memcpy(raw_buf, loop_buf, size);
55 return 0;
56 }
57
58 static int transfer_xor(struct loop_device *lo, int cmd, char *raw_buf,
59 char *loop_buf, int size)
60 {
61 char *in, *out, *key;
62 int i, keysize;
63
64 if (cmd == READ) {
65 in = raw_buf;
66 out = loop_buf;
67 } else {
68 in = loop_buf;
69 out = raw_buf;
70 }
71 key = lo->lo_encrypt_key;
72 keysize = lo->lo_encrypt_key_size;
73 for (i=0; i < size; i++)
74 *out++ = *in++ ^ key[(i & 511) % keysize];
75 return 0;
76 }
77
78 #ifdef DES_AVAILABLE
79 static int transfer_des(struct loop_device *lo, int cmd, char *raw_buf,
80 char *loop_buf, int size)
81 {
82 unsigned long tmp[2];
83 unsigned long x0,x1,p0,p1;
84
85 if (size & 7)
86 return -EINVAL;
87 x0 = lo->lo_des_init[0];
88 x1 = lo->lo_des_init[1];
89 while (size) {
90 if (cmd == READ) {
91 tmp[0] = (p0 = ((unsigned long *) raw_buf)[0])^x0;
92 tmp[1] = (p1 = ((unsigned long *) raw_buf)[1])^x1;
93 des_ecb_encrypt((des_cblock *) tmp,(des_cblock *)
94 loop_buf,lo->lo_des_key,DES_ENCRYPT);
95 x0 = p0^((unsigned long *) loop_buf)[0];
96 x1 = p1^((unsigned long *) loop_buf)[1];
97 }
98 else {
99 p0 = ((unsigned long *) loop_buf)[0];
100 p1 = ((unsigned long *) loop_buf)[1];
101 des_ecb_encrypt((des_cblock *) loop_buf,(des_cblock *)
102 raw_buf,lo->lo_des_key,DES_DECRYPT);
103 ((unsigned long *) raw_buf)[0] ^= x0;
104 ((unsigned long *) raw_buf)[1] ^= x1;
105 x0 = p0^((unsigned long *) raw_buf)[0];
106 x1 = p1^((unsigned long *) raw_buf)[1];
107 }
108 size -= 8;
109 raw_buf += 8;
110 loop_buf += 8;
111 }
112 return 0;
113 }
114 #endif
115
116 static transfer_proc_t xfer_funcs[MAX_LOOP] = {
117 transfer_none,
118 transfer_xor,
119 #ifdef DES_AVAILABLE
120 transfer_des,
121 #else
122 NULL,
123 #endif
124 0
125 };
126
127
128 #define MAX_DISK_SIZE 1024*1024*1024
129
130
131 static void figure_loop_size(struct loop_device *lo)
132 {
133 int size;
134
135 if (S_ISREG(lo->lo_inode->i_mode))
136 size = (lo->lo_inode->i_size - lo->lo_offset) / 1024;
137 else {
138 if (blk_size[MAJOR(lo->lo_device)])
139 size = ((blk_size[MAJOR(lo->lo_device)]
140 [MINOR(lo->lo_device)]) -
141 (lo->lo_offset/1024));
142 else
143 size = MAX_DISK_SIZE;
144 }
145 loop_sizes[lo->lo_number] = size;
146 }
147
148 static void do_lo_request(void)
149 {
150 int real_block, block, offset, len, blksize, size;
151 char *dest_addr;
152 struct loop_device *lo;
153 struct buffer_head *bh;
154
155 repeat:
156 INIT_REQUEST;
157 if (MINOR(CURRENT->rq_dev) >= MAX_LOOP)
158 goto error_out;
159 lo = &loop_dev[MINOR(CURRENT->rq_dev)];
160 if (!lo->lo_inode || !lo->transfer)
161 goto error_out;
162
163 blksize = BLOCK_SIZE;
164 if (blksize_size[MAJOR(lo->lo_device)]) {
165 blksize = blksize_size[MAJOR(lo->lo_device)][MINOR(lo->lo_device)];
166 if (!blksize)
167 blksize = BLOCK_SIZE;
168 }
169
170 dest_addr = CURRENT->buffer;
171
172 if (blksize < 512) {
173 block = CURRENT->sector * (512/blksize);
174 offset = 0;
175 } else {
176 block = CURRENT->sector / (blksize >> 9);
177 offset = CURRENT->sector % (blksize >> 9);
178 }
179 block += lo->lo_offset / blksize;
180 offset += lo->lo_offset % blksize;
181 if (offset > blksize) {
182 block++;
183 offset -= blksize;
184 }
185 len = CURRENT->current_nr_sectors << 9;
186 if (CURRENT->cmd == WRITE) {
187 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
188 goto error_out;
189 } else if (CURRENT->cmd != READ) {
190 printk("unknown loop device command (%d)?!?", CURRENT->cmd);
191 goto error_out;
192 }
193 while (len > 0) {
194 real_block = block;
195 if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
196 real_block = bmap(lo->lo_inode, block);
197 if (!real_block) {
198 printk("loop: block %d not present\n", block);
199 goto error_out;
200 }
201 }
202 bh = getblk(lo->lo_device, real_block, blksize);
203 if (!bh) {
204 printk("loop: device %s: getblk(-, %d, %d) returned NULL",
205 kdevname(lo->lo_device),
206 block, blksize);
207 goto error_out;
208 }
209 if (!buffer_uptodate(bh) && ((CURRENT->cmd == READ) ||
210 (offset || (len < blksize)))) {
211 ll_rw_block(READ, 1, &bh);
212 wait_on_buffer(bh);
213 if (!buffer_uptodate(bh)) {
214 brelse(bh);
215 goto error_out;
216 }
217 }
218 size = blksize - offset;
219 if (size > len)
220 size = len;
221
222 if ((lo->transfer)(lo, CURRENT->cmd, bh->b_data + offset,
223 dest_addr, size)) {
224 printk("loop: transfer error block %d\n", block);
225 brelse(bh);
226 goto error_out;
227 }
228 if (CURRENT->cmd == WRITE)
229 mark_buffer_dirty(bh, 1);
230 brelse(bh);
231 dest_addr += size;
232 len -= size;
233 offset = 0;
234 block++;
235 }
236 end_request(1);
237 goto repeat;
238 error_out:
239 end_request(0);
240 goto repeat;
241 }
242
243 static int loop_set_fd(struct loop_device *lo, kdev_t dev, unsigned int arg)
244 {
245 struct file *file;
246 struct inode *inode;
247
248 if (arg >= NR_OPEN || !(file = current->files->fd[arg]))
249 return -EBADF;
250 if (lo->lo_inode)
251 return -EBUSY;
252 inode = file->f_inode;
253 if (!inode) {
254 printk("loop_set_fd: NULL inode?!?\n");
255 return -EINVAL;
256 }
257 if (S_ISBLK(inode->i_mode)) {
258 int error = blkdev_open(inode, file);
259 if (error)
260 return error;
261 lo->lo_device = inode->i_rdev;
262 lo->lo_flags = 0;
263 } else if (S_ISREG(inode->i_mode)) {
264 lo->lo_device = inode->i_dev;
265 lo->lo_flags = LO_FLAGS_DO_BMAP;
266 } else
267 return -EINVAL;
268
269 if (IS_RDONLY (inode) || is_read_only(lo->lo_device)) {
270 lo->lo_flags |= LO_FLAGS_READ_ONLY;
271 set_device_ro(dev, 1);
272 } else {
273 invalidate_inode_pages (inode);
274 set_device_ro(dev, 0);
275 }
276
277 lo->lo_inode = inode;
278 lo->lo_inode->i_count++;
279 lo->transfer = NULL;
280 figure_loop_size(lo);
281 MOD_INC_USE_COUNT;
282 return 0;
283 }
284
285 static int loop_clr_fd(struct loop_device *lo, kdev_t dev)
286 {
287 if (!lo->lo_inode)
288 return -ENXIO;
289 if (lo->lo_refcnt > 1)
290 return -EBUSY;
291 if (S_ISBLK(lo->lo_inode->i_mode))
292 blkdev_release (lo->lo_inode);
293 iput(lo->lo_inode);
294 lo->lo_device = 0;
295 lo->lo_inode = NULL;
296 lo->lo_encrypt_type = 0;
297 lo->lo_offset = 0;
298 lo->lo_encrypt_key_size = 0;
299 memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
300 memset(lo->lo_name, 0, LO_NAME_SIZE);
301 loop_sizes[lo->lo_number] = 0;
302 invalidate_buffers(dev);
303 MOD_DEC_USE_COUNT;
304 return 0;
305 }
306
307 static int loop_set_status(struct loop_device *lo, struct loop_info *arg)
308 {
309 struct loop_info info;
310
311 if (!lo->lo_inode)
312 return -ENXIO;
313 if (!arg)
314 return -EINVAL;
315 memcpy_fromfs(&info, arg, sizeof(info));
316 if ((unsigned int) info.lo_encrypt_key_size > LO_KEY_SIZE)
317 return -EINVAL;
318 switch (info.lo_encrypt_type) {
319 case LO_CRYPT_NONE:
320 break;
321 case LO_CRYPT_XOR:
322 if (info.lo_encrypt_key_size < 0)
323 return -EINVAL;
324 break;
325 #ifdef DES_AVAILABLE
326 case LO_CRYPT_DES:
327 if (info.lo_encrypt_key_size != 8)
328 return -EINVAL;
329 des_set_key((des_cblock *) lo->lo_encrypt_key,
330 lo->lo_des_key);
331 memcpy(lo->lo_des_init,info.lo_init,8);
332 break;
333 #endif
334 default:
335 return -EINVAL;
336 }
337 lo->lo_offset = info.lo_offset;
338 strncpy(lo->lo_name, info.lo_name, LO_NAME_SIZE);
339 lo->lo_encrypt_type = info.lo_encrypt_type;
340 lo->transfer = xfer_funcs[lo->lo_encrypt_type];
341 lo->lo_encrypt_key_size = info.lo_encrypt_key_size;
342 if (info.lo_encrypt_key_size)
343 memcpy(lo->lo_encrypt_key, info.lo_encrypt_key,
344 info.lo_encrypt_key_size);
345 figure_loop_size(lo);
346 return 0;
347 }
348
349 static int loop_get_status(struct loop_device *lo, struct loop_info *arg)
350 {
351 struct loop_info info;
352
353 if (!lo->lo_inode)
354 return -ENXIO;
355 if (!arg)
356 return -EINVAL;
357 memset(&info, 0, sizeof(info));
358 info.lo_number = lo->lo_number;
359 info.lo_device = kdev_t_to_nr(lo->lo_inode->i_dev);
360 info.lo_inode = lo->lo_inode->i_ino;
361 info.lo_rdevice = kdev_t_to_nr(lo->lo_device);
362 info.lo_offset = lo->lo_offset;
363 info.lo_flags = lo->lo_flags;
364 strncpy(info.lo_name, lo->lo_name, LO_NAME_SIZE);
365 info.lo_encrypt_type = lo->lo_encrypt_type;
366 if (lo->lo_encrypt_key_size && suser()) {
367 info.lo_encrypt_key_size = lo->lo_encrypt_key_size;
368 memcpy(info.lo_encrypt_key, lo->lo_encrypt_key,
369 lo->lo_encrypt_key_size);
370 }
371 memcpy_tofs(arg, &info, sizeof(info));
372 return 0;
373 }
374
375 static int lo_ioctl(struct inode * inode, struct file * file,
376 unsigned int cmd, unsigned long arg)
377 {
378 struct loop_device *lo;
379 int dev, err;
380
381 if (!inode)
382 return -EINVAL;
383 if (MAJOR(inode->i_rdev) != MAJOR_NR) {
384 printk("lo_ioctl: pseudo-major != %d\n", MAJOR_NR);
385 return -ENODEV;
386 }
387 dev = MINOR(inode->i_rdev);
388 if (dev >= MAX_LOOP)
389 return -ENODEV;
390 lo = &loop_dev[dev];
391 switch (cmd) {
392 case LOOP_SET_FD:
393 return loop_set_fd(lo, inode->i_rdev, arg);
394 case LOOP_CLR_FD:
395 return loop_clr_fd(lo, inode->i_rdev);
396 case LOOP_SET_STATUS:
397 return loop_set_status(lo, (struct loop_info *) arg);
398 case LOOP_GET_STATUS:
399 return loop_get_status(lo, (struct loop_info *) arg);
400 case BLKGETSIZE:
401 if (!lo->lo_inode)
402 return -ENXIO;
403 if (!arg) return -EINVAL;
404 err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
405 if (err)
406 return err;
407 put_fs_long(loop_sizes[lo->lo_number] << 1, (long *) arg);
408 return 0;
409 default:
410 return -EINVAL;
411 }
412 return 0;
413 }
414
415 static int lo_open(struct inode *inode, struct file *file)
416 {
417 struct loop_device *lo;
418 int dev;
419
420 if (!inode)
421 return -EINVAL;
422 if (MAJOR(inode->i_rdev) != MAJOR_NR) {
423 printk("lo_open: pseudo-major != %d\n", MAJOR_NR);
424 return -ENODEV;
425 }
426 dev = MINOR(inode->i_rdev);
427 if (dev >= MAX_LOOP)
428 return -ENODEV;
429 lo = &loop_dev[dev];
430 lo->lo_refcnt++;
431 MOD_INC_USE_COUNT;
432 return 0;
433 }
434
435 static void lo_release(struct inode *inode, struct file *file)
436 {
437 struct loop_device *lo;
438 int dev;
439
440 if (!inode)
441 return;
442 if (MAJOR(inode->i_rdev) != MAJOR_NR) {
443 printk("lo_release: pseudo-major != %d\n", MAJOR_NR);
444 return;
445 }
446 dev = MINOR(inode->i_rdev);
447 if (dev >= MAX_LOOP)
448 return;
449 fsync_dev(inode->i_rdev);
450 lo = &loop_dev[dev];
451 if (lo->lo_refcnt <= 0)
452 printk("lo_release: refcount(%d) <= 0\n", lo->lo_refcnt);
453 else {
454 lo->lo_refcnt--;
455 MOD_DEC_USE_COUNT;
456 }
457 }
458
459 static struct file_operations lo_fops = {
460 NULL,
461 block_read,
462 block_write,
463 NULL,
464 NULL,
465 lo_ioctl,
466 NULL,
467 lo_open,
468 lo_release
469 };
470
471
472
473
474 #ifdef MODULE
475 #define loop_init init_module
476 #endif
477
478 int
479 loop_init( void ) {
480 int i;
481
482 if (register_blkdev(MAJOR_NR, "loop", &lo_fops)) {
483 printk("Unable to get major number %d for loop device\n",
484 MAJOR_NR);
485 return -EIO;
486 }
487 #ifndef MODULE
488 printk("loop: registered device at major %d\n", MAJOR_NR);
489 #endif
490
491 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
492 for (i=0; i < MAX_LOOP; i++) {
493 memset(&loop_dev[i], 0, sizeof(struct loop_device));
494 loop_dev[i].lo_number = i;
495 }
496 memset(&loop_sizes, 0, sizeof(loop_sizes));
497 blk_size[MAJOR_NR] = loop_sizes;
498
499 return 0;
500 }
501
502 #ifdef MODULE
503 void
504 cleanup_module( void ) {
505 if (unregister_blkdev(MAJOR_NR, "loop") != 0)
506 printk("loop: cleanup_module failed\n");
507 }
508 #endif