diff -Naurp a/drivers/md/dm.c b/drivers/md/dm.c --- a/drivers/md/dm.c 2006-01-14 22:16:02.000000000 -0800 +++ b/drivers/md/dm.c 2006-02-09 14:05:18.000000000 -0800 @@ -17,6 +17,7 @@ #include #include #include +#include static const char *_name = DM_NAME; @@ -223,6 +224,47 @@ static int dm_blk_close(struct inode *in return 0; } +static int dm_blk_ioctl(struct inode * inode, struct file * filp, + unsigned int cmd, unsigned long arg) +{ + struct block_device *bdev = inode->i_bdev; + struct hd_geometry __user *loc = (void __user *)arg; + struct mapped_device *md; + int diskinfo[4]; + + if (cmd == HDIO_GETGEO) { + if (!arg) + return -EINVAL; + + /* Make up some fake geometry. */ + md = bdev->bd_disk->private_data; + diskinfo[0] = 0x40; /* 1 << 6 */ + diskinfo[1] = 0x20; /* 1 << 5 */ + diskinfo[2] = md->disk->capacity >> 11; + diskinfo[3] = 0; + + /* cylinder count too big? */ + if (diskinfo[2] > 65536) { + diskinfo[0] = 255; + diskinfo[1] = 63; + diskinfo[2] = md->disk->capacity / 16065; /* 255*63 */ + } + + if (put_user(diskinfo[0], &loc->heads)) + return -EFAULT; + if (put_user(diskinfo[1], &loc->sectors)) + return -EFAULT; + if (put_user(diskinfo[2], &loc->cylinders)) + return -EFAULT; + if (put_user(diskinfo[3], &loc->start)) + return -EFAULT; + + return 0; + } + + return -ENOTTY; +} + static inline struct dm_io *alloc_io(struct mapped_device *md) { return mempool_alloc(md->io_pool, GFP_NOIO); @@ -1179,6 +1221,7 @@ int dm_suspended(struct mapped_device *m static struct block_device_operations dm_blk_dops = { .open = dm_blk_open, .release = dm_blk_close, + .ioctl = dm_blk_ioctl, .owner = THIS_MODULE };