View Single Post
Old 14-12-2004, 08:44   #1
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
[just for fun] loop.ko: supporto per le partizioni

Patch per il kernel 2.6.8.

Codice:
--- linux-2.6.8.1/drivers/block/loop.c.org	2004-12-13 13:00:50.000000000 +0100
+++ linux-2.6.8.1/drivers/block/loop.c	2004-12-14 09:36:02.799210096 +0100
@@ -67,9 +67,12 @@
 #include <linux/writeback.h>
 #include <linux/buffer_head.h>		/* for invalidate_bdev() */
 #include <linux/completion.h>
+#include <linux/hdreg.h>
 
 #include <asm/uaccess.h>
 
+#define MAX_LO_PART 16
+
 static int max_loop = 8;
 static struct loop_device *loop_dev;
 static struct gendisk **disks;
@@ -1010,7 +1013,10 @@
 {
 	struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
 	int err;
+	int repart = 0;
 
+	if(MINOR(inode->i_rdev)%MAX_LO_PART)
+		return -EINVAL;
 	down(&lo->lo_ctl_mutex);
 	switch (cmd) {
 	case LOOP_SET_FD:
@@ -1024,19 +1030,31 @@
 		break;
 	case LOOP_SET_STATUS:
 		err = loop_set_status_old(lo, (struct loop_info __user *) arg);
+		if(!err) repart = 1;
 		break;
 	case LOOP_GET_STATUS:
 		err = loop_get_status_old(lo, (struct loop_info __user *) arg);
 		break;
 	case LOOP_SET_STATUS64:
 		err = loop_set_status64(lo, (struct loop_info64 __user *) arg);
+		if(!err) repart = 1;
 		break;
 	case LOOP_GET_STATUS64:
 		err = loop_get_status64(lo, (struct loop_info64 __user *) arg);
 		break;
+	case HDIO_GETGEO:
+		err = lo->lo_backing_file ? lo->lo_backing_file->f_op->ioctl(
+				lo->lo_backing_file->f_mapping->host,
+				lo->lo_backing_file, cmd, arg)
+			: -EINVAL;
+		break;
 	default:
 		err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
+		if(err==-EINVAL)
+			printk("loop: Unknown ioctl %x\n", (unsigned) cmd);
 	}
+	if(repart)
+		file->f_op->ioctl(inode, file, BLKRRPART, 0);
 	up(&lo->lo_ctl_mutex);
 	return err;
 }
@@ -1137,7 +1155,7 @@
 		goto out_mem2;
 
 	for (i = 0; i < max_loop; i++) {
-		disks[i] = alloc_disk(1);
+		disks[i] = alloc_disk(MAX_LO_PART);
 		if (!disks[i])
 			goto out_mem3;
 	}
@@ -1158,7 +1176,7 @@
 		lo->lo_number = i;
 		spin_lock_init(&lo->lo_lock);
 		disk->major = LOOP_MAJOR;
-		disk->first_minor = i;
+		disk->first_minor = i*MAX_LO_PART;
 		disk->fops = &lo_fops;
 		sprintf(disk->disk_name, "loop%d", i);
 		sprintf(disk->devfs_name, "loop/%d", i);
Note:
- Con devfs: i file /dev/loop/X (X=1, 2...) sono ora _directory_ (quindi eventuali script di avvio che utilizzano il loopback non funzioneranno). Dentro queste directory ci saranno i file disc, part1, part2... Occorre usare /dev/loop/X/disc per effettuare il losetup, le partizioni verranno rilevate automaticamente.
- Con udev: verranno creati i file partizione aggiuntivi /dev/loopXpY
- fdisk e il benedetto CHS: se mettete in loopback un dispositivo a blocchi (ad es. fd0), verrà chiesto a questo dispositivo informazioni sulla geometria; altrimenti, fdisk dovrà fare le proprie assunzioni. Se si parte da un file pieno di zeri in loopback, i valori di default sono H=255 S=63 (C è calcolato in base alla capacità). Se si parte da un file immagine di un disco o floppy esistente, fdisk dovrebbe essere in grado di dedurli dalle partizioni presenti. Se create un file vuoto da utilizzare come immagine di un floppy, impostare H=2 S=18 C=80.

Non utilizzatelo su dati importanti; il disco con Windows va bene
Personalmente ho fatto questa modifica per accedere più facilmente alle immagini di qemu.

-- enjoy
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso