Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S946059AbcJaTiJ (ORCPT ); Mon, 31 Oct 2016 15:38:09 -0400 Received: from mx2.suse.de ([195.135.220.15]:38742 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S945975AbcJaTiF (ORCPT ); Mon, 31 Oct 2016 15:38:05 -0400 From: Hannes Reinecke To: Jens Axboe Cc: Christoph Hellwig , Alexander Graf , Ming@suse.de, "Lei Subject: [PATCH 4/4] loop: Pass logical blocksize in 'lo_init[0]' ioctl field Date: Mon, 31 Oct 2016 20:37:19 +0100 Message-Id: <1477942639-109971-5-git-send-email-hare@suse.de> X-Mailer: git-send-email 1.8.5.6 In-Reply-To: <1477942639-109971-1-git-send-email-hare@suse.de> References: <1477942639-109971-1-git-send-email-hare@suse.de> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2586 Lines: 71 The current LOOP_SET_STATUS64 ioctl has two unused fields 'init[2]', which can be used in conjunction with the LO_FLAGS_BLOCKSIZE flag to pass in the new logical blocksize. Signed-off-by: Hannes Reinecke --- drivers/block/loop.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index a863667..9ad56bf 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -221,7 +221,8 @@ static void __loop_update_dio(struct loop_device *lo, bool dio) } static int -figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit) +figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit, + loff_t logical_blocksize) { loff_t size = get_size(offset, sizelimit, lo->lo_backing_file); sector_t x = (sector_t)size; @@ -234,6 +235,7 @@ figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit) if (lo->lo_sizelimit != sizelimit) lo->lo_sizelimit = sizelimit; if (lo->lo_flags & LO_FLAGS_BLOCKSIZE) { + lo->lo_logical_blocksize = logical_blocksize; blk_queue_physical_block_size(lo->lo_queue, lo->lo_blocksize); blk_queue_logical_block_size(lo->lo_queue, lo->lo_logical_blocksize); @@ -1124,13 +1126,24 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) if (err) return err; - if (info->lo_flags & LO_FLAGS_BLOCKSIZE) + if (info->lo_flags & LO_FLAGS_BLOCKSIZE) { lo->lo_flags |= LO_FLAGS_BLOCKSIZE; + if ((info->lo_init[0] != 512) && + (info->lo_init[0] != 1024) && + (info->lo_init[0] != 2048) && + (info->lo_init[0] != 4096)) + return -EINVAL; + if (info->lo_init[0] > lo->lo_blocksize) + return -EINVAL; + } if (lo->lo_offset != info->lo_offset || lo->lo_sizelimit != info->lo_sizelimit || - lo->lo_flags != lo_flags) - if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) + lo->lo_flags != lo_flags || + ((lo->lo_flags & LO_FLAGS_BLOCKSIZE) && + (lo->lo_logical_blocksize != info->lo_init[0]))) + if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit, + info->lo_init[0])) return -EFBIG; loop_config_discard(lo); @@ -1315,7 +1328,8 @@ static int loop_set_capacity(struct loop_device *lo) if (unlikely(lo->lo_state != Lo_bound)) return -ENXIO; - return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit); + return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit, + lo->lo_logical_blocksize); } static int loop_set_dio(struct loop_device *lo, unsigned long arg) -- 2.6.6