ilsensine
14-12-2004, 08:44
Patch per il kernel 2.6.8.
--- 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 :p
Personalmente ho fatto questa modifica per accedere più facilmente alle immagini di qemu.
-- enjoy
--- 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 :p
Personalmente ho fatto questa modifica per accedere più facilmente alle immagini di qemu.
-- enjoy