aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMing Lei <ming.lei@canonical.com>2015-08-16 22:31:50 -0400
committerJens Axboe <axboe@fb.com>2015-09-23 13:01:16 -0400
commitab1cb278bc7027663adbfb0b81404f8398437e11 (patch)
tree9406e09aeb44e5caa2ee816a93124f966812f4f5
parent2e5ab5f379f96a6207c45be40c357ebb1beb8ef3 (diff)
block: loop: introduce ioctl command of LOOP_SET_DIRECT_IO
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>
-rw-r--r--drivers/block/loop.c19
-rw-r--r--include/uapi/linux/loop.h1
2 files changed, 20 insertions, 0 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 06cad7edc0d3..75db3b98ec2b 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1228,6 +1228,20 @@ static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
1228 return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit); 1228 return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit);
1229} 1229}
1230 1230
1231static int loop_set_dio(struct loop_device *lo, unsigned long arg)
1232{
1233 int error = -ENXIO;
1234 if (lo->lo_state != Lo_bound)
1235 goto out;
1236
1237 __loop_update_dio(lo, !!arg);
1238 if (lo->use_dio == !!arg)
1239 return 0;
1240 error = -EINVAL;
1241 out:
1242 return error;
1243}
1244
1231static int lo_ioctl(struct block_device *bdev, fmode_t mode, 1245static int lo_ioctl(struct block_device *bdev, fmode_t mode,
1232 unsigned int cmd, unsigned long arg) 1246 unsigned int cmd, unsigned long arg)
1233{ 1247{
@@ -1271,6 +1285,11 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
1271 if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) 1285 if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
1272 err = loop_set_capacity(lo, bdev); 1286 err = loop_set_capacity(lo, bdev);
1273 break; 1287 break;
1288 case LOOP_SET_DIRECT_IO:
1289 err = -EPERM;
1290 if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
1291 err = loop_set_dio(lo, arg);
1292 break;
1274 default: 1293 default:
1275 err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; 1294 err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
1276 } 1295 }
diff --git a/include/uapi/linux/loop.h b/include/uapi/linux/loop.h
index 949851ce681f..c8125ec1f4f2 100644
--- a/include/uapi/linux/loop.h
+++ b/include/uapi/linux/loop.h
@@ -87,6 +87,7 @@ struct loop_info64 {
87#define LOOP_GET_STATUS64 0x4C05 87#define LOOP_GET_STATUS64 0x4C05
88#define LOOP_CHANGE_FD 0x4C06 88#define LOOP_CHANGE_FD 0x4C06
89#define LOOP_SET_CAPACITY 0x4C07 89#define LOOP_SET_CAPACITY 0x4C07
90#define LOOP_SET_DIRECT_IO 0x4C08
90 91
91/* /dev/loop-control interface */ 92/* /dev/loop-control interface */
92#define LOOP_CTL_ADD 0x4C80 93#define LOOP_CTL_ADD 0x4C80