|
@@ -1228,6 +1228,20 @@ static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
|
|
|
return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit);
|
|
|
}
|
|
|
|
|
|
+static int loop_set_dio(struct loop_device *lo, unsigned long arg)
|
|
|
+{
|
|
|
+ int error = -ENXIO;
|
|
|
+ if (lo->lo_state != Lo_bound)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ __loop_update_dio(lo, !!arg);
|
|
|
+ if (lo->use_dio == !!arg)
|
|
|
+ return 0;
|
|
|
+ error = -EINVAL;
|
|
|
+ out:
|
|
|
+ return error;
|
|
|
+}
|
|
|
+
|
|
|
static int lo_ioctl(struct block_device *bdev, fmode_t mode,
|
|
|
unsigned int cmd, unsigned long arg)
|
|
|
{
|
|
@@ -1271,6 +1285,11 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
|
|
|
if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
|
|
|
err = loop_set_capacity(lo, bdev);
|
|
|
break;
|
|
|
+ case LOOP_SET_DIRECT_IO:
|
|
|
+ err = -EPERM;
|
|
|
+ if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
|
|
|
+ err = loop_set_dio(lo, arg);
|
|
|
+ break;
|
|
|
default:
|
|
|
err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
|
|
|
}
|