block: loop: introduce ioctl command of LOOP_SET_DIRECT_IO
authorMing Lei <ming.lei@canonical.com>
Mon, 17 Aug 2015 02:31:50 +0000 (10:31 +0800)
committerJens Axboe <axboe@fb.com>
Wed, 23 Sep 2015 17:01:16 +0000 (11:01 -0600)
If loop block is mounted via 'mount -o loop', it isn't easy
to pass file descriptor opened as O_DIRECT, so this patch
introduces a new command to support direct IO for this case.

Cc: linux-api@vger.kernel.org
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@fb.com>
drivers/block/loop.c
include/uapi/linux/loop.h

index 06cad7edc0d3eed1b60d17a97f2e682226916f27..75db3b98ec2b865a31b20a1c0705f73ed700884d 100644 (file)
@@ -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;
        }
index 949851ce681f969f6dfafbb50dccdbdd44cc28bd..c8125ec1f4f2270a5a01a358832425cd57edb11a 100644 (file)
@@ -87,6 +87,7 @@ struct loop_info64 {
 #define LOOP_GET_STATUS64      0x4C05
 #define LOOP_CHANGE_FD         0x4C06
 #define LOOP_SET_CAPACITY      0x4C07
+#define LOOP_SET_DIRECT_IO     0x4C08
 
 /* /dev/loop-control interface */
 #define LOOP_CTL_ADD           0x4C80