Skip to content

Commit

Permalink
[PATCH] dm: support ioctls on mapped devices: fix with fake file
Browse files Browse the repository at this point in the history
The new ioctl code passes the wrong file pointer to the underlying device.
No file pointer is available so make a temporary fake one.

ioctl_by_bdev() does set_fs(KERNEL_DS) so it's for ioctls originating
within the kernel and unsuitable here.  We are processing ioctls that
originated in userspace and mapping them to different devices.  Fixing the
existing callers that pass a NULL file struct and consolidating the
fake_file users are separate matters to solve in later patches.

Signed-off-by: Milan Broz <mbroz@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Milan Broz authored and Linus Torvalds committed Oct 3, 2006
1 parent 7006f6e commit e90dae1
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 4 deletions.
8 changes: 7 additions & 1 deletion drivers/md/dm-linear.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,14 @@ static int linear_ioctl(struct dm_target *ti, struct inode *inode,
{
struct linear_c *lc = (struct linear_c *) ti->private;
struct block_device *bdev = lc->dev->bdev;
struct file fake_file = {};
struct dentry fake_dentry = {};

return blkdev_driver_ioctl(bdev->bd_inode, filp, bdev->bd_disk, cmd, arg);
fake_file.f_mode = lc->dev->mode;
fake_file.f_dentry = &fake_dentry;
fake_dentry.d_inode = bdev->bd_inode;

return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg);
}

static struct target_type linear_target = {
Expand Down
13 changes: 10 additions & 3 deletions drivers/md/dm-mpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -1273,15 +1273,22 @@ static int multipath_ioctl(struct dm_target *ti, struct inode *inode,
struct multipath *m = (struct multipath *) ti->private;
struct block_device *bdev = NULL;
unsigned long flags;
struct file fake_file = {};
struct dentry fake_dentry = {};
int r = 0;

fake_file.f_dentry = &fake_dentry;

spin_lock_irqsave(&m->lock, flags);

if (!m->current_pgpath)
__choose_pgpath(m);

if (m->current_pgpath)
if (m->current_pgpath) {
bdev = m->current_pgpath->path.dev->bdev;
fake_dentry.d_inode = bdev->bd_inode;
fake_file.f_mode = m->current_pgpath->path.dev->mode;
}

if (m->queue_io)
r = -EAGAIN;
Expand All @@ -1290,8 +1297,8 @@ static int multipath_ioctl(struct dm_target *ti, struct inode *inode,

spin_unlock_irqrestore(&m->lock, flags);

return r ? : blkdev_driver_ioctl(bdev->bd_inode, filp, bdev->bd_disk,
cmd, arg);
return r ? : blkdev_driver_ioctl(bdev->bd_inode, &fake_file,
bdev->bd_disk, cmd, arg);
}

/*-----------------------------------------------------------------
Expand Down

0 comments on commit e90dae1

Please sign in to comment.