From patchwork Thu Sep 15 16:48:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarthak Kukreti X-Patchwork-Id: 12977645 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E7E0ECAAA1 for ; Thu, 15 Sep 2022 16:49:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230032AbiIOQs7 (ORCPT ); Thu, 15 Sep 2022 12:48:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229715AbiIOQsp (ORCPT ); Thu, 15 Sep 2022 12:48:45 -0400 Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [IPv6:2607:f8b0:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D19DD74366 for ; Thu, 15 Sep 2022 09:48:40 -0700 (PDT) Received: by mail-pl1-x62b.google.com with SMTP id w13so3261770plp.1 for ; Thu, 15 Sep 2022 09:48:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=eVUKjSRzP57VkDMJbmIUpe84WqTldBB8WtUi20EOq0o=; b=g0Vn0mvUgqEpeONHQxwFeclUdBsaPZdZY/loQMHufIZIYEqP3dDKGDolYhsViOFnJz mSEBlrX3OtTaCYthwbnoJlKC/1k+SIrxPQj8/lxOwDxhZ/0pnz8PlXSOIwjMH+u1VRvr paiV8k47XSqne+1soODH5p110kZdXkseUM5vg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=eVUKjSRzP57VkDMJbmIUpe84WqTldBB8WtUi20EOq0o=; b=dleIyDcWaKft2GRL6lEMrpfnIZcg/eO6vQjqEvk94fph3vl9W/xWJK0xl37T/iLe7t cwIMmn8qqjT3b91Tr4U+JBOn68bngPFz0DLK+VN3wfdCHrB5vB83xQDnBZ/GN4qROw4J domvv6Cj/gh2G/fO+mL7wPjE9b8Ml2KHb7ZBCLtuBhP3RA2OK16Zs7wyhUxYMPBFOV9W 0u/dKKgGE62OgkdJts6PPfpEEfII8/GI97WvabXGOUP1mGcnoKWFlRjwJJlPRGNWiNlp vY8bQDRCLfReNZ8ZU8zdq9zi9NcJeTIU5wd/sPXpGV4a5Ey5NXPhUa5zzRWbH6afQ5hC 4hKA== X-Gm-Message-State: ACrzQf3YXXwTHYBS6/Iav3rHXYewCkppvWkEZ9Fj6mR9z+thuCIyRch9 qE8uefLjvauHGPvNDWSE3FvzRg== X-Google-Smtp-Source: AMsMyM4zs9wHxdaBa+zcyC5s+uVhDOrEPPoce7ZcwRxnNCPypBVfVZWu5+J4XwYIDQeN48cb2oC5Dg== X-Received: by 2002:a17:902:eb82:b0:176:c0e0:55c1 with SMTP id q2-20020a170902eb8200b00176c0e055c1mr452499plg.168.1663260520248; Thu, 15 Sep 2022 09:48:40 -0700 (PDT) Received: from sarthakkukreti-glaptop.hsd1.ca.comcast.net ([2601:647:4200:b5b0:3af2:34b2:a98a:a652]) by smtp.gmail.com with ESMTPSA id o4-20020a170902bcc400b00177ee563b6dsm13174970pls.33.2022.09.15.09.48.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Sep 2022 09:48:39 -0700 (PDT) From: Sarthak Kukreti X-Google-Original-From: Sarthak Kukreti To: dm-devel@redhat.com, linux-block@vger.kernel.org, linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org Cc: Jens Axboe , "Michael S . Tsirkin" , Jason Wang , Paolo Bonzini , Stefan Hajnoczi , Alasdair Kergon , Mike Snitzer , Theodore Ts'o , Andreas Dilger , Bart Van Assche , Daniil Lunev , Evan Green , Gwendal Grignou , Sarthak Kukreti Subject: [PATCH RFC 1/8] block: Introduce provisioning primitives Date: Thu, 15 Sep 2022 09:48:19 -0700 Message-Id: <20220915164826.1396245-2-sarthakkukreti@google.com> X-Mailer: git-send-email 2.37.2.789.g6183377224-goog In-Reply-To: <20220915164826.1396245-1-sarthakkukreti@google.com> References: <20220915164826.1396245-1-sarthakkukreti@google.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org From: Sarthak Kukreti Introduce block request REQ_OP_PROVISION. The intent of this request is to request underlying storage to preallocate disk space for the given block range. Block device that support this capability will export a provision limit within their request queues. Signed-off-by: Sarthak Kukreti --- block/blk-core.c | 5 ++++ block/blk-lib.c | 55 +++++++++++++++++++++++++++++++++++++++ block/blk-merge.c | 17 ++++++++++++ block/blk-settings.c | 19 ++++++++++++++ block/blk-sysfs.c | 8 ++++++ block/bounce.c | 1 + include/linux/bio.h | 6 +++-- include/linux/blk_types.h | 5 +++- include/linux/blkdev.h | 16 ++++++++++++ 9 files changed, 129 insertions(+), 3 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index a0d1104c5590..affefbaba1cd 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -125,6 +125,7 @@ static const char *const blk_op_name[] = { REQ_OP_NAME(WRITE_ZEROES), REQ_OP_NAME(DRV_IN), REQ_OP_NAME(DRV_OUT), + REQ_OP_NAME(PROVISION) }; #undef REQ_OP_NAME @@ -776,6 +777,10 @@ void submit_bio_noacct(struct bio *bio) if (!q->limits.max_write_zeroes_sectors) goto not_supported; break; + case REQ_OP_PROVISION: + if (!q->limits.max_provision_sectors) + goto not_supported; + break; default: break; } diff --git a/block/blk-lib.c b/block/blk-lib.c index 67e6dbc1ae81..dc11ed29b523 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c @@ -338,3 +338,58 @@ int blkdev_issue_secure_erase(struct block_device *bdev, sector_t sector, return ret; } EXPORT_SYMBOL(blkdev_issue_secure_erase); + +/** + * blkdev_issue_provision - provision a block range + * @bdev: blockdev to write + * @sector: start sector + * @nr_sects: number of sectors to provision + * @gfp_mask: memory allocation flags (for bio_alloc) + * + * Description: + * Issues a provision request to the block device for the range of sectors. + * For thinly provisioned block devices, this acts as a signal for the + * underlying storage pool to allocate space for this block range. + */ +int blkdev_issue_provision(struct block_device *bdev, sector_t sector, + sector_t nr_sects, gfp_t gfp) +{ + sector_t bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1; + unsigned int max_sectors = bdev_max_provision_sectors(bdev); + struct bio *bio = NULL; + struct blk_plug plug; + int ret = 0; + + if (max_sectors == 0) + return -EOPNOTSUPP; + if ((sector | nr_sects) & bs_mask) + return -EINVAL; + if (bdev_read_only(bdev)) + return -EPERM; + + blk_start_plug(&plug); + for (;;) { + unsigned int req_sects = min_t(sector_t, nr_sects, max_sectors); + + bio = blk_next_bio(bio, bdev, 0, REQ_OP_PROVISION, gfp); + bio->bi_iter.bi_sector = sector; + bio->bi_iter.bi_size = req_sects << SECTOR_SHIFT; + bio_set_dev(bio, bdev); + bio_set_op_attrs(bio, REQ_OP_PROVISION, 0); + + sector += req_sects; + nr_sects -= req_sects; + if (!nr_sects) { + ret = submit_bio_wait(bio); + if (ret == -EOPNOTSUPP) + ret = 0; + bio_put(bio); + break; + } + cond_resched(); + } + blk_finish_plug(&plug); + + return ret; +} +EXPORT_SYMBOL(blkdev_issue_provision); diff --git a/block/blk-merge.c b/block/blk-merge.c index ff04e9290715..ee8dd07b24fe 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -156,6 +156,20 @@ static struct bio *bio_split_write_zeroes(struct bio *bio, return bio_split(bio, lim->max_write_zeroes_sectors, GFP_NOIO, bs); } +static struct bio *bio_split_provision(struct bio *bio, + struct queue_limits *lim, unsigned *nsegs, struct bio_set *bs) +{ + *nsegs = 0; + + if (!lim->max_provision_sectors) + return NULL; + + if (bio_sectors(bio) <= lim->max_provision_sectors) + return NULL; + + return bio_split(bio, lim->max_provision_sectors, GFP_NOIO, bs); +} + /* * Return the maximum number of sectors from the start of a bio that may be * submitted as a single request to a block device. If enough sectors remain, @@ -345,6 +359,9 @@ struct bio *__bio_split_to_limits(struct bio *bio, struct queue_limits *lim, case REQ_OP_WRITE_ZEROES: split = bio_split_write_zeroes(bio, lim, nr_segs, bs); break; + case REQ_OP_PROVISION: + split = bio_split_provision(bio, lim, nr_segs, bs); + break; default: split = bio_split_rw(bio, lim, nr_segs, bs, get_max_io_size(bio, lim) << SECTOR_SHIFT); diff --git a/block/blk-settings.c b/block/blk-settings.c index 8bb9eef5310e..be79ad68b330 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -57,6 +57,7 @@ void blk_set_default_limits(struct queue_limits *lim) lim->misaligned = 0; lim->zoned = BLK_ZONED_NONE; lim->zone_write_granularity = 0; + lim->max_provision_sectors = 0; } EXPORT_SYMBOL(blk_set_default_limits); @@ -81,6 +82,7 @@ void blk_set_stacking_limits(struct queue_limits *lim) lim->max_dev_sectors = UINT_MAX; lim->max_write_zeroes_sectors = UINT_MAX; lim->max_zone_append_sectors = UINT_MAX; + lim->max_provision_sectors = UINT_MAX; } EXPORT_SYMBOL(blk_set_stacking_limits); @@ -202,6 +204,20 @@ void blk_queue_max_write_zeroes_sectors(struct request_queue *q, } EXPORT_SYMBOL(blk_queue_max_write_zeroes_sectors); +/** + * blk_queue_max_provision_sectors - set max sectors for a single provision + * + * @q: the request queue for the device + * @max_provision_sectors: maximum number of sectors to provision per command + **/ + +void blk_queue_max_provision_sectors(struct request_queue *q, + unsigned int max_provision_sectors) +{ + q->limits.max_provision_sectors = max_provision_sectors; +} +EXPORT_SYMBOL(blk_queue_max_provision_sectors); + /** * blk_queue_max_zone_append_sectors - set max sectors for a single zone append * @q: the request queue for the device @@ -572,6 +588,9 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, t->max_segment_size = min_not_zero(t->max_segment_size, b->max_segment_size); + t->max_provision_sectors = min_not_zero(t->max_provision_sectors, + b->max_provision_sectors); + t->misaligned |= b->misaligned; alignment = queue_limit_alignment_offset(b, start); diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index e1f009aba6fd..912159518322 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -131,6 +131,12 @@ static ssize_t queue_max_discard_segments_show(struct request_queue *q, return queue_var_show(queue_max_discard_segments(q), page); } +static ssize_t queue_max_provision_sectors_show(struct request_queue *q, + char *page) +{ + return queue_var_show(queue_max_provision_sectors(q), (page)); +} + static ssize_t queue_max_integrity_segments_show(struct request_queue *q, char *page) { return queue_var_show(q->limits.max_integrity_segments, page); @@ -586,6 +592,7 @@ QUEUE_RO_ENTRY(queue_io_min, "minimum_io_size"); QUEUE_RO_ENTRY(queue_io_opt, "optimal_io_size"); QUEUE_RO_ENTRY(queue_max_discard_segments, "max_discard_segments"); +QUEUE_RO_ENTRY(queue_max_provision_sectors, "max_provision_sectors"); QUEUE_RO_ENTRY(queue_discard_granularity, "discard_granularity"); QUEUE_RO_ENTRY(queue_discard_max_hw, "discard_max_hw_bytes"); QUEUE_RW_ENTRY(queue_discard_max, "discard_max_bytes"); @@ -635,6 +642,7 @@ static struct attribute *queue_attrs[] = { &queue_max_sectors_entry.attr, &queue_max_segments_entry.attr, &queue_max_discard_segments_entry.attr, + &queue_max_provision_sectors_entry.attr, &queue_max_integrity_segments_entry.attr, &queue_max_segment_size_entry.attr, &elv_iosched_entry.attr, diff --git a/block/bounce.c b/block/bounce.c index 7cfcb242f9a1..ab9d8723ae64 100644 --- a/block/bounce.c +++ b/block/bounce.c @@ -176,6 +176,7 @@ static struct bio *bounce_clone_bio(struct bio *bio_src) case REQ_OP_DISCARD: case REQ_OP_SECURE_ERASE: case REQ_OP_WRITE_ZEROES: + case REQ_OP_PROVISION: break; default: bio_for_each_segment(bv, bio_src, iter) diff --git a/include/linux/bio.h b/include/linux/bio.h index ca22b06700a9..3d5af770b90a 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -55,7 +55,8 @@ static inline bool bio_has_data(struct bio *bio) bio->bi_iter.bi_size && bio_op(bio) != REQ_OP_DISCARD && bio_op(bio) != REQ_OP_SECURE_ERASE && - bio_op(bio) != REQ_OP_WRITE_ZEROES) + bio_op(bio) != REQ_OP_WRITE_ZEROES && + bio_op(bio) != REQ_OP_PROVISION) return true; return false; @@ -65,7 +66,8 @@ static inline bool bio_no_advance_iter(const struct bio *bio) { return bio_op(bio) == REQ_OP_DISCARD || bio_op(bio) == REQ_OP_SECURE_ERASE || - bio_op(bio) == REQ_OP_WRITE_ZEROES; + bio_op(bio) == REQ_OP_WRITE_ZEROES || + bio_op(bio) == REQ_OP_PROVISION; } static inline void *bio_data(struct bio *bio) diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 1ef99790f6ed..c6e9823c1542 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -386,7 +386,10 @@ enum req_op { REQ_OP_DRV_IN = (__force blk_opf_t)34, REQ_OP_DRV_OUT = (__force blk_opf_t)35, - REQ_OP_LAST = (__force blk_opf_t)36, + /* request device to provision block */ + REQ_OP_PROVISION = (__force blk_opf_t)37, + + REQ_OP_LAST = (__force blk_opf_t)38, }; enum req_flag_bits { diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 84b13fdd34a7..a58496d3f922 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -302,6 +302,7 @@ struct queue_limits { unsigned int discard_granularity; unsigned int discard_alignment; unsigned int zone_write_granularity; + unsigned int max_provision_sectors; unsigned short max_segments; unsigned short max_integrity_segments; @@ -931,6 +932,8 @@ extern void blk_queue_max_discard_sectors(struct request_queue *q, unsigned int max_discard_sectors); extern void blk_queue_max_write_zeroes_sectors(struct request_queue *q, unsigned int max_write_same_sectors); +extern void blk_queue_max_provision_sectors(struct request_queue *q, + unsigned int max_provision_sectors); extern void blk_queue_logical_block_size(struct request_queue *, unsigned int); extern void blk_queue_max_zone_append_sectors(struct request_queue *q, unsigned int max_zone_append_sectors); @@ -1071,6 +1074,9 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector, int blkdev_issue_secure_erase(struct block_device *bdev, sector_t sector, sector_t nr_sects, gfp_t gfp); +extern int blkdev_issue_provision(struct block_device *bdev, sector_t sector, + sector_t nr_sects, gfp_t gfp_mask); + #define BLKDEV_ZERO_NOUNMAP (1 << 0) /* do not free blocks */ #define BLKDEV_ZERO_NOFALLBACK (1 << 1) /* don't write explicit zeroes */ @@ -1149,6 +1155,11 @@ static inline unsigned short queue_max_discard_segments(const struct request_que return q->limits.max_discard_segments; } +static inline unsigned short queue_max_provision_sectors(const struct request_queue *q) +{ + return q->limits.max_provision_sectors; +} + static inline unsigned int queue_max_segment_size(const struct request_queue *q) { return q->limits.max_segment_size; @@ -1280,6 +1291,11 @@ static inline bool bdev_fua(struct block_device *bdev) return test_bit(QUEUE_FLAG_FUA, &bdev_get_queue(bdev)->queue_flags); } +static inline unsigned int bdev_max_provision_sectors(struct block_device *bdev) +{ + return bdev_get_queue(bdev)->limits.max_provision_sectors; +} + static inline enum blk_zoned_model bdev_zoned_model(struct block_device *bdev) { struct request_queue *q = bdev_get_queue(bdev); From patchwork Thu Sep 15 16:48:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarthak Kukreti X-Patchwork-Id: 12977644 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 36583C6FA89 for ; Thu, 15 Sep 2022 16:48:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229779AbiIOQsp (ORCPT ); Thu, 15 Sep 2022 12:48:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49528 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229644AbiIOQso (ORCPT ); Thu, 15 Sep 2022 12:48:44 -0400 Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 627015FAF2 for ; Thu, 15 Sep 2022 09:48:43 -0700 (PDT) Received: by mail-pl1-x62f.google.com with SMTP id t3so18916866ply.2 for ; Thu, 15 Sep 2022 09:48:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=5ygvmrZPI1WDIMPoH4fryGIYobUzr2vUUota+pvSXgQ=; b=OwhGbST3lN2j4BrNnqLh+crZoPJ17algWOozP9/QDV6cINmVxBuZv1MnjIOEEBVuFZ w03zVHy7wVCYe2BrUXeeMOC/7qE2nTIBh3IWd//tWn1griPA5IqsGx1fBFnIny8polm4 OTKZRylYH/i3WSS8517Mp1igJHBaaHCpQZJLs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=5ygvmrZPI1WDIMPoH4fryGIYobUzr2vUUota+pvSXgQ=; b=THM7/IccWcHgceQPRtysV0bPBGw7zzCaeN/vjNLMds9bnbNFeI20Q9gOt8QwjPDW1e qdCD2V9qCt507440cOqEj/ZxCsQcrvlKOqHOGEuvcr7HMiIPo0t9QWx9OUBwgjCvozdc bDk0wAdX6JF2bw4lGMKTdAsupSMIr15iqtvCUy3cMKRvF0bZWRvAolsRSS5Kc/skDEU0 xvuekgbKqPesBsqpIM6KpV/mHYfwqJZz0+yf3TS0VlQqlNoDa5Gi3kTHM22j/wCIhn6F KK5efORa5YRyppz4u8myi2MQ12BaDQmMsh9EE49U5OVmcN3NUKEmQCMHAs94fNlAEuAP r7Pg== X-Gm-Message-State: ACrzQf0/FaL2YppZ2rXcV8/EPyGOmb9nWzzl0n0EdFJ+doyaxHTna8Dd Lhjpa9BTCpNs4VrOYScm/AaahA== X-Google-Smtp-Source: AMsMyM7uREf6rExESlC9UOz0czMJ3vqna+akFJyuGIrevbbq1rAo01SAxEamvT9aPhybE8cjhGavpQ== X-Received: by 2002:a17:90b:4f8d:b0:202:dd39:c03a with SMTP id qe13-20020a17090b4f8d00b00202dd39c03amr11917187pjb.71.1663260522760; Thu, 15 Sep 2022 09:48:42 -0700 (PDT) Received: from sarthakkukreti-glaptop.hsd1.ca.comcast.net ([2601:647:4200:b5b0:3af2:34b2:a98a:a652]) by smtp.gmail.com with ESMTPSA id o4-20020a170902bcc400b00177ee563b6dsm13174970pls.33.2022.09.15.09.48.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Sep 2022 09:48:41 -0700 (PDT) From: Sarthak Kukreti X-Google-Original-From: Sarthak Kukreti To: dm-devel@redhat.com, linux-block@vger.kernel.org, linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org Cc: Jens Axboe , "Michael S . Tsirkin" , Jason Wang , Paolo Bonzini , Stefan Hajnoczi , Alasdair Kergon , Mike Snitzer , Theodore Ts'o , Andreas Dilger , Bart Van Assche , Daniil Lunev , Evan Green , Gwendal Grignou , Sarthak Kukreti Subject: [PATCH RFC 2/8] dm: Add support for block provisioning Date: Thu, 15 Sep 2022 09:48:20 -0700 Message-Id: <20220915164826.1396245-3-sarthakkukreti@google.com> X-Mailer: git-send-email 2.37.2.789.g6183377224-goog In-Reply-To: <20220915164826.1396245-1-sarthakkukreti@google.com> References: <20220915164826.1396245-1-sarthakkukreti@google.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org From: Sarthak Kukreti Add support to dm devices for REQ_OP_PROVISION. The default mode is to pass through the request and dm-thin will utilize it to provision blocks. Signed-off-by: Sarthak Kukreti --- drivers/md/dm-crypt.c | 4 +- drivers/md/dm-linear.c | 1 + drivers/md/dm-table.c | 17 +++++++ drivers/md/dm-thin.c | 86 +++++++++++++++++++++++++++++++++-- drivers/md/dm.c | 4 ++ include/linux/device-mapper.h | 6 +++ 6 files changed, 113 insertions(+), 5 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 159c6806c19b..357f0899cfb6 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -3081,6 +3081,8 @@ static int crypt_ctr_optional(struct dm_target *ti, unsigned int argc, char **ar if (ret) return ret; + ti->num_provision_bios = 1; + while (opt_params--) { opt_string = dm_shift_arg(&as); if (!opt_string) { @@ -3384,7 +3386,7 @@ static int crypt_map(struct dm_target *ti, struct bio *bio) * - for REQ_OP_DISCARD caller must use flush if IO ordering matters */ if (unlikely(bio->bi_opf & REQ_PREFLUSH || - bio_op(bio) == REQ_OP_DISCARD)) { + bio_op(bio) == REQ_OP_DISCARD || bio_op(bio) == REQ_OP_PROVISION)) { bio_set_dev(bio, cc->dev->bdev); if (bio_sectors(bio)) bio->bi_iter.bi_sector = cc->start + diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 3212ef6aa81b..1aa782149428 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -61,6 +61,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) ti->num_discard_bios = 1; ti->num_secure_erase_bios = 1; ti->num_write_zeroes_bios = 1; + ti->num_provision_bios = 1; ti->private = lc; return 0; diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 332f96b58252..b7f9cb66b7ba 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1853,6 +1853,18 @@ static bool dm_table_supports_write_zeroes(struct dm_table *t) return true; } +static bool dm_table_supports_provision(struct dm_table *t) +{ + for (unsigned int i = 0; i < t->num_targets; i++) { + struct dm_target *ti = dm_table_get_target(t, i); + + if (ti->num_provision_bios) + return true; + } + + return false; +} + static int device_not_nowait_capable(struct dm_target *ti, struct dm_dev *dev, sector_t start, sector_t len, void *data) { @@ -1989,6 +2001,11 @@ int dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, if (!dm_table_supports_write_zeroes(t)) q->limits.max_write_zeroes_sectors = 0; + if (dm_table_supports_provision(t)) + blk_queue_max_provision_sectors(q, UINT_MAX >> 9); + else + q->limits.max_provision_sectors = 0; + dm_table_verify_integrity(t); /* diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index e76c96c760a9..fd3eb306c823 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -908,7 +908,8 @@ static void __inc_remap_and_issue_cell(void *context, struct bio *bio; while ((bio = bio_list_pop(&cell->bios))) { - if (op_is_flush(bio->bi_opf) || bio_op(bio) == REQ_OP_DISCARD) + if (op_is_flush(bio->bi_opf) || bio_op(bio) == REQ_OP_DISCARD || + bio_op(bio) == REQ_OP_PROVISION) bio_list_add(&info->defer_bios, bio); else { inc_all_io_entry(info->tc->pool, bio); @@ -1012,6 +1013,9 @@ static void process_prepared_mapping(struct dm_thin_new_mapping *m) goto out; } + if (bio && bio_op(bio) == REQ_OP_PROVISION) + return; + /* * Release any bios held while the block was being provisioned. * If we are processing a write bio that completely covers the block, @@ -1388,6 +1392,9 @@ static void schedule_zero(struct thin_c *tc, dm_block_t virt_block, m->data_block = data_block; m->cell = cell; + if (bio && bio_op(bio) == REQ_OP_PROVISION) + m->bio = bio; + /* * If the whole block of data is being overwritten or we are not * zeroing pre-existing data, we can issue the bio immediately. @@ -1897,7 +1904,7 @@ static void provision_block(struct thin_c *tc, struct bio *bio, dm_block_t block /* * Fill read bios with zeroes and complete them immediately. */ - if (bio_data_dir(bio) == READ) { + if (bio_data_dir(bio) == READ && bio_op(bio) != REQ_OP_PROVISION) { zero_fill_bio(bio); cell_defer_no_holder(tc, cell); bio_endio(bio); @@ -1980,6 +1987,69 @@ static void process_cell(struct thin_c *tc, struct dm_bio_prison_cell *cell) } } +static void process_provision_cell(struct thin_c *tc, struct dm_bio_prison_cell *cell) +{ + int r; + struct pool *pool = tc->pool; + struct bio *bio = cell->holder; + dm_block_t begin, end; + struct dm_thin_lookup_result lookup_result; + + if (tc->requeue_mode) { + cell_requeue(pool, cell); + return; + } + + get_bio_block_range(tc, bio, &begin, &end); + + while (begin != end) { + r = ensure_next_mapping(pool); + if (r) + /* we did our best */ + return; + + r = dm_thin_find_block(tc->td, begin, 1, &lookup_result); + switch (r) { + case 0: + begin++; + break; + case -ENODATA: + provision_block(tc, bio, begin, cell); + begin++; + break; + default: + DMERR_LIMIT( + "%s: dm_thin_find_block() failed: error = %d", + __func__, r); + cell_defer_no_holder(tc, cell); + bio_io_error(bio); + begin++; + break; + } + } + bio_endio(bio); + cell_defer_no_holder(tc, cell); +} + +static void process_provision_bio(struct thin_c *tc, struct bio *bio) +{ + dm_block_t begin, end; + struct dm_cell_key virt_key; + struct dm_bio_prison_cell *virt_cell; + + get_bio_block_range(tc, bio, &begin, &end); + if (begin == end) { + bio_endio(bio); + return; + } + + build_key(tc->td, VIRTUAL, begin, end, &virt_key); + if (bio_detain(tc->pool, &virt_key, bio, &virt_cell)) + return; + + process_provision_cell(tc, virt_cell); +} + static void process_bio(struct thin_c *tc, struct bio *bio) { struct pool *pool = tc->pool; @@ -2024,7 +2094,7 @@ static void __process_bio_read_only(struct thin_c *tc, struct bio *bio, case -ENODATA: if (cell) cell_defer_no_holder(tc, cell); - if (rw != READ) { + if (rw != READ || bio_op(bio) == REQ_OP_PROVISION) { handle_unserviceable_bio(tc->pool, bio); break; } @@ -2200,6 +2270,8 @@ static void process_thin_deferred_bios(struct thin_c *tc) if (bio_op(bio) == REQ_OP_DISCARD) pool->process_discard(tc, bio); + else if (bio_op(bio) == REQ_OP_PROVISION) + process_provision_bio(tc, bio); else pool->process_bio(tc, bio); @@ -2716,7 +2788,8 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) return DM_MAPIO_SUBMITTED; } - if (op_is_flush(bio->bi_opf) || bio_op(bio) == REQ_OP_DISCARD) { + if (op_is_flush(bio->bi_opf) || bio_op(bio) == REQ_OP_DISCARD || + bio_op(bio) == REQ_OP_PROVISION) { thin_defer_bio_with_throttle(tc, bio); return DM_MAPIO_SUBMITTED; } @@ -3353,6 +3426,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) pt->low_water_blocks = low_water_blocks; pt->adjusted_pf = pt->requested_pf = pf; ti->num_flush_bios = 1; + ti->num_provision_bios = 1; /* * Only need to enable discards if the pool should pass @@ -4043,6 +4117,7 @@ static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits) blk_limits_io_opt(limits, pool->sectors_per_block << SECTOR_SHIFT); } + /* * pt->adjusted_pf is a staging area for the actual features to use. * They get transferred to the live pool in bind_control_target() @@ -4233,6 +4308,8 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) ti->num_discard_bios = 1; } + ti->num_provision_bios = 1; + mutex_unlock(&dm_thin_pool_table.mutex); spin_lock_irq(&tc->pool->lock); @@ -4447,6 +4524,7 @@ static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits) limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT; limits->max_discard_sectors = 2048 * 1024 * 16; /* 16G */ + limits->max_provision_sectors = 2048 * 1024 * 16; /* 16G */ } static struct target_type thin_target = { diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 60549b65c799..3fe524800f5a 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1600,6 +1600,7 @@ static bool is_abnormal_io(struct bio *bio) case REQ_OP_DISCARD: case REQ_OP_SECURE_ERASE: case REQ_OP_WRITE_ZEROES: + case REQ_OP_PROVISION: return true; default: break; @@ -1624,6 +1625,9 @@ static blk_status_t __process_abnormal_io(struct clone_info *ci, case REQ_OP_WRITE_ZEROES: num_bios = ti->num_write_zeroes_bios; break; + case REQ_OP_PROVISION: + num_bios = ti->num_provision_bios; + break; default: break; } diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 04c6acf7faaa..edeb47195b6f 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -333,6 +333,12 @@ struct dm_target { */ unsigned num_write_zeroes_bios; + /* + * The number of PROVISION bios that will be submitted to the target. + * The bio number can be accessed with dm_bio_get_target_bio_nr. + */ + unsigned num_provision_bios; + /* * The minimum number of extra bytes allocated in each io for the * target to use. From patchwork Thu Sep 15 16:48:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarthak Kukreti X-Patchwork-Id: 12977646 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 437ACC6FA8A for ; Thu, 15 Sep 2022 16:49:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229636AbiIOQs7 (ORCPT ); Thu, 15 Sep 2022 12:48:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49904 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229613AbiIOQs5 (ORCPT ); Thu, 15 Sep 2022 12:48:57 -0400 Received: from mail-pg1-x52b.google.com (mail-pg1-x52b.google.com [IPv6:2607:f8b0:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF9667F113 for ; Thu, 15 Sep 2022 09:48:45 -0700 (PDT) Received: by mail-pg1-x52b.google.com with SMTP id r23so9253693pgr.6 for ; Thu, 15 Sep 2022 09:48:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=8dGdE7yXwxpNJrtc0jzeOng2rxu8z4FK39IlQ5rLaw4=; b=EbErGLA/VINLfRbp4zcUbZBx85wcqmWWZ+b0wvu85Q2UUUeZQBQzI+ibcnOvQrL1/1 SpTBeWGXbbH7aJQQssASqOwJ392q4ULOBRqDM6uMUsq9W98Jxjsk1XvASOhF/X7whgnI cQc9io4mtSftKYU7SXF5cXqbt8EGpd2/X9S3E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=8dGdE7yXwxpNJrtc0jzeOng2rxu8z4FK39IlQ5rLaw4=; b=S82u6+Uy7E5SSlIGLDufq0UZTxoUEmFWJ49VdymO/lw0HnAiFaM7hrvaPDOgZnnZ+5 +xLKGM4kIsnpKgWceXhj12dYn40NXLjHafpU7WEGCfQpBQcN37wPCKqeshnNAX1O0QZq bd8q4ZOlWLmX4SEgca9TPnJxViG27xyCNCzNomqLjcUlZY//mKo5ljPWuB72X3ktuiMz kiTciKWK39PDko8l24R70X5Hm1oO1voTEeDa3dAkMWgwiYbkd+a680tzSgMhmwypiIyQ jsZMEOZEgDAtXmrjN6s3SZwDFppudBEDclk4bKGC9wz2DULtQz5wMCqxIHrYYILU/+zA efJw== X-Gm-Message-State: ACrzQf2wzNru7PazbFUnnNfVx8ePQ0UgnXEppFmzbx5+oESbHspWyKLp n64oKAJnUsZtCEHonwXglB1nRg== X-Google-Smtp-Source: AMsMyM4ZjbUOIq/Q41w/OvvKUkmXpRr0bP+C56mI+0JSOF5eLhseKC9OgxfT03jMUgCb5sBQJ9O12g== X-Received: by 2002:a63:1d25:0:b0:437:ec38:bd0e with SMTP id d37-20020a631d25000000b00437ec38bd0emr675973pgd.478.1663260525220; Thu, 15 Sep 2022 09:48:45 -0700 (PDT) Received: from sarthakkukreti-glaptop.hsd1.ca.comcast.net ([2601:647:4200:b5b0:3af2:34b2:a98a:a652]) by smtp.gmail.com with ESMTPSA id o4-20020a170902bcc400b00177ee563b6dsm13174970pls.33.2022.09.15.09.48.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Sep 2022 09:48:44 -0700 (PDT) From: Sarthak Kukreti X-Google-Original-From: Sarthak Kukreti To: dm-devel@redhat.com, linux-block@vger.kernel.org, linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org Cc: Jens Axboe , "Michael S . Tsirkin" , Jason Wang , Paolo Bonzini , Stefan Hajnoczi , Alasdair Kergon , Mike Snitzer , Theodore Ts'o , Andreas Dilger , Bart Van Assche , Daniil Lunev , Evan Green , Gwendal Grignou , Sarthak Kukreti Subject: [PATCH RFC 3/8] virtio_blk: Add support for provision requests Date: Thu, 15 Sep 2022 09:48:21 -0700 Message-Id: <20220915164826.1396245-4-sarthakkukreti@google.com> X-Mailer: git-send-email 2.37.2.789.g6183377224-goog In-Reply-To: <20220915164826.1396245-1-sarthakkukreti@google.com> References: <20220915164826.1396245-1-sarthakkukreti@google.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org From: Sarthak Kukreti Adds support for provision requests. Provision requests act like the inverse of discards. Signed-off-by: Sarthak Kukreti --- drivers/block/virtio_blk.c | 48 +++++++++++++++++++++++++++++++++ include/uapi/linux/virtio_blk.h | 9 +++++++ 2 files changed, 57 insertions(+) diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 30255fcaf181..eacc2bffe1d1 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -178,6 +178,39 @@ static int virtblk_setup_discard_write_zeroes(struct request *req, bool unmap) return 0; } +static int virtblk_setup_provision(struct request *req) +{ + unsigned short segments = blk_rq_nr_discard_segments(req); + unsigned short n = 0; + + struct virtio_blk_discard_write_zeroes *range; + struct bio *bio; + u32 flags = 0; + + range = kmalloc_array(segments, sizeof(*range), GFP_ATOMIC); + if (!range) + return -ENOMEM; + + __rq_for_each_bio(bio, req) { + u64 sector = bio->bi_iter.bi_sector; + u32 num_sectors = bio->bi_iter.bi_size >> SECTOR_SHIFT; + + range[n].flags = cpu_to_le32(flags); + range[n].num_sectors = cpu_to_le32(num_sectors); + range[n].sector = cpu_to_le64(sector); + n++; + } + + WARN_ON_ONCE(n != segments); + + req->special_vec.bv_page = virt_to_page(range); + req->special_vec.bv_offset = offset_in_page(range); + req->special_vec.bv_len = sizeof(*range) * segments; + req->rq_flags |= RQF_SPECIAL_PAYLOAD; + + return 0; +} + static void virtblk_unmap_data(struct request *req, struct virtblk_req *vbr) { if (blk_rq_nr_phys_segments(req)) @@ -243,6 +276,9 @@ static blk_status_t virtblk_setup_cmd(struct virtio_device *vdev, case REQ_OP_DRV_IN: type = VIRTIO_BLK_T_GET_ID; break; + case REQ_OP_PROVISION: + type = VIRTIO_BLK_T_PROVISION; + break; default: WARN_ON_ONCE(1); return BLK_STS_IOERR; @@ -256,6 +292,11 @@ static blk_status_t virtblk_setup_cmd(struct virtio_device *vdev, return BLK_STS_RESOURCE; } + if (type == VIRTIO_BLK_T_PROVISION) { + if (virtblk_setup_provision(req)) + return BLK_STS_RESOURCE; + } + return 0; } @@ -1075,6 +1116,12 @@ static int virtblk_probe(struct virtio_device *vdev) blk_queue_max_write_zeroes_sectors(q, v ? v : UINT_MAX); } + if (virtio_has_feature(vdev, VIRTIO_BLK_F_PROVISION)) { + virtio_cread(vdev, struct virtio_blk_config, + max_provision_sectors, &v); + q->limits.max_provision_sectors = v ? v : UINT_MAX; + } + virtblk_update_capacity(vblk, false); virtio_device_ready(vdev); @@ -1177,6 +1224,7 @@ static unsigned int features[] = { VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE, VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES, + VIRTIO_BLK_F_PROVISION, }; static struct virtio_driver virtio_blk = { diff --git a/include/uapi/linux/virtio_blk.h b/include/uapi/linux/virtio_blk.h index d888f013d9ff..184f8cf6d185 100644 --- a/include/uapi/linux/virtio_blk.h +++ b/include/uapi/linux/virtio_blk.h @@ -40,6 +40,7 @@ #define VIRTIO_BLK_F_MQ 12 /* support more than one vq */ #define VIRTIO_BLK_F_DISCARD 13 /* DISCARD is supported */ #define VIRTIO_BLK_F_WRITE_ZEROES 14 /* WRITE ZEROES is supported */ +#define VIRTIO_BLK_F_PROVISION 15 /* provision is supported */ /* Legacy feature bits */ #ifndef VIRTIO_BLK_NO_LEGACY @@ -120,6 +121,11 @@ struct virtio_blk_config { */ __u8 write_zeroes_may_unmap; + /* + * The maximum number of sectors in a provision request. + */ + __virtio32 max_provision_sectors; + __u8 unused1[3]; } __attribute__((packed)); @@ -155,6 +161,9 @@ struct virtio_blk_config { /* Write zeroes command */ #define VIRTIO_BLK_T_WRITE_ZEROES 13 +/* Provision command */ +#define VIRTIO_BLK_T_PROVISION 14 + #ifndef VIRTIO_BLK_NO_LEGACY /* Barrier before this op. */ #define VIRTIO_BLK_T_BARRIER 0x80000000 From patchwork Thu Sep 15 16:48:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarthak Kukreti X-Patchwork-Id: 12977647 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DD56CC6FA8A for ; Thu, 15 Sep 2022 16:49:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229873AbiIOQtC (ORCPT ); Thu, 15 Sep 2022 12:49:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49904 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230006AbiIOQs6 (ORCPT ); Thu, 15 Sep 2022 12:48:58 -0400 Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 46CA995ADA for ; Thu, 15 Sep 2022 09:48:48 -0700 (PDT) Received: by mail-pf1-x430.google.com with SMTP id l65so18622054pfl.8 for ; Thu, 15 Sep 2022 09:48:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=8C9PF5fV/n/yVA3OaBrI0F0iBecyk+zvR56xPQZ3IDQ=; b=j9UNt0PdafuY8eG1vCRzjZeZim0lhfvAaWOmUVbnBHmUWqdPZZ3auOQ0xlsq4Yg25G ssysjc8iJfcpwF872sxTnDKV+At5Lq1lz2NHw7y/c/HRgBxSyb3/AQ8kCSa9CzRaimvX fDowBy/9vfz+mH7HubnE6gAWlEVC/vOtMbAIU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=8C9PF5fV/n/yVA3OaBrI0F0iBecyk+zvR56xPQZ3IDQ=; b=aHzmHfSeGf5ojqKI5h0+T+lLCfOeebJm2FtVhB/p00AL64rCU8VatQNTNWlfcC7BKp mFzZp3Du0Tglc/pcbuHOntaFY99gYhRUBxwd3ioVPiZ3zVIv0fs5JrWZt7MFL8SF/rpt LOgypkLHu191ZTK7GBYnk/AzMq+72yMAOuIKI6BVL3Sy1Kvtb74WM7sK2kjI5a46JgUa byUbiiYIcCUvaLrGmad96hyb5XLwwsY9iiRliW/7UMatKsqRY0ET6dI8hW0fC94yL3BB HLBKHWqSsL+yNyi7xZc09CnRMR9hruVtuRMrAzyoMPRdD/a+5iJChFUfxMq8XWphsKkZ gm4A== X-Gm-Message-State: ACrzQf08ITCXCW5fbw8YRqs6ho/fngMtiEgCXS9ESw0TkBfX244sXpwq +XqQSJ0jcYmaK2YytrumzB4yCQ== X-Google-Smtp-Source: AMsMyM74NUJEGoCBWxXp6ovjj8HVrZVtuoYCAa5cO2wk9AivcidhyvEFeO548cRZFdt3fQKWpEtWLA== X-Received: by 2002:a05:6a00:1691:b0:53b:3f2c:3257 with SMTP id k17-20020a056a00169100b0053b3f2c3257mr882622pfc.21.1663260527748; Thu, 15 Sep 2022 09:48:47 -0700 (PDT) Received: from sarthakkukreti-glaptop.hsd1.ca.comcast.net ([2601:647:4200:b5b0:3af2:34b2:a98a:a652]) by smtp.gmail.com with ESMTPSA id o4-20020a170902bcc400b00177ee563b6dsm13174970pls.33.2022.09.15.09.48.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Sep 2022 09:48:46 -0700 (PDT) From: Sarthak Kukreti X-Google-Original-From: Sarthak Kukreti To: dm-devel@redhat.com, linux-block@vger.kernel.org, linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org Cc: Jens Axboe , "Michael S . Tsirkin" , Jason Wang , Paolo Bonzini , Stefan Hajnoczi , Alasdair Kergon , Mike Snitzer , Theodore Ts'o , Andreas Dilger , Bart Van Assche , Daniil Lunev , Evan Green , Gwendal Grignou , Sarthak Kukreti Subject: [PATCH RFC 4/8] fs: Introduce FALLOC_FL_PROVISION Date: Thu, 15 Sep 2022 09:48:22 -0700 Message-Id: <20220915164826.1396245-5-sarthakkukreti@google.com> X-Mailer: git-send-email 2.37.2.789.g6183377224-goog In-Reply-To: <20220915164826.1396245-1-sarthakkukreti@google.com> References: <20220915164826.1396245-1-sarthakkukreti@google.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org From: Sarthak Kukreti FALLOC_FL_PROVISION is a new fallocate() allocation mode that sends a hint to (supported) thinly provisioned block devices to allocate space for the given range of sectors via REQ_OP_PROVISION. Signed-off-by: Sarthak Kukreti --- block/fops.c | 7 ++++++- include/linux/falloc.h | 3 ++- include/uapi/linux/falloc.h | 8 ++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/block/fops.c b/block/fops.c index b90742595317..a436a7596508 100644 --- a/block/fops.c +++ b/block/fops.c @@ -605,7 +605,8 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) #define BLKDEV_FALLOC_FL_SUPPORTED \ (FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | \ - FALLOC_FL_ZERO_RANGE | FALLOC_FL_NO_HIDE_STALE) + FALLOC_FL_ZERO_RANGE | FALLOC_FL_NO_HIDE_STALE | \ + FALLOC_FL_PROVISION) static long blkdev_fallocate(struct file *file, int mode, loff_t start, loff_t len) @@ -661,6 +662,10 @@ static long blkdev_fallocate(struct file *file, int mode, loff_t start, error = blkdev_issue_discard(bdev, start >> SECTOR_SHIFT, len >> SECTOR_SHIFT, GFP_KERNEL); break; + case FALLOC_FL_PROVISION: + error = blkdev_issue_provision(bdev, start >> SECTOR_SHIFT, + len >> SECTOR_SHIFT, GFP_KERNEL); + break; default: error = -EOPNOTSUPP; } diff --git a/include/linux/falloc.h b/include/linux/falloc.h index f3f0b97b1675..a0e506255b20 100644 --- a/include/linux/falloc.h +++ b/include/linux/falloc.h @@ -30,7 +30,8 @@ struct space_resv { FALLOC_FL_COLLAPSE_RANGE | \ FALLOC_FL_ZERO_RANGE | \ FALLOC_FL_INSERT_RANGE | \ - FALLOC_FL_UNSHARE_RANGE) + FALLOC_FL_UNSHARE_RANGE | \ + FALLOC_FL_PROVISION) /* on ia32 l_start is on a 32-bit boundary */ #if defined(CONFIG_X86_64) diff --git a/include/uapi/linux/falloc.h b/include/uapi/linux/falloc.h index 51398fa57f6c..2d323d113eed 100644 --- a/include/uapi/linux/falloc.h +++ b/include/uapi/linux/falloc.h @@ -77,4 +77,12 @@ */ #define FALLOC_FL_UNSHARE_RANGE 0x40 +/* + * FALLOC_FL_PROVISION acts as a hint for thinly provisioned devices to allocate + * blocks for the range/EOF. + * + * FALLOC_FL_PROVISION can only be used with allocate-mode fallocate. + */ +#define FALLOC_FL_PROVISION 0x80 + #endif /* _UAPI_FALLOC_H_ */ From patchwork Thu Sep 15 16:48:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarthak Kukreti X-Patchwork-Id: 12977648 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B2A1AC6FA89 for ; Thu, 15 Sep 2022 16:49:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230095AbiIOQt0 (ORCPT ); Thu, 15 Sep 2022 12:49:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229715AbiIOQs7 (ORCPT ); Thu, 15 Sep 2022 12:48:59 -0400 Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E8DBC9DF93 for ; Thu, 15 Sep 2022 09:48:50 -0700 (PDT) Received: by mail-pl1-x62f.google.com with SMTP id t3so18917164ply.2 for ; Thu, 15 Sep 2022 09:48:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=Ez356cXmd+P7nHsJjjr+e0UneH5b2Is7vVwjmIs0dPs=; b=hf5bm+zkYxj81k0yr271q/Vk7dx9PD258+F9SK/a1tGt7tNa+NuehKD3IiLyt97euU FtXSg24Apya78hp1GXFu5BbK+vkKNo1ymR0Rwg7K+y3rnIb3ONI2XzkuntNb07Nm+r9L GJij3Ake6waJf54qKgjqFZkAvVur99qaXQO6Q= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=Ez356cXmd+P7nHsJjjr+e0UneH5b2Is7vVwjmIs0dPs=; b=ivkbDJFddzso3nWIoU6kdv1Ad6NWFf7MnaZQZw232sUiKR0FKR1fYlSatkwvQQWDkm OetQWn5nBnp5b+W79hVOpmtcaEGVUhW6L0NurtG5fzUwM2DHIW6VPXbYpTfKFBJ1ffzA t4plGflXzM9DtQAeWU44vAfpeBjoMf9LiGblojldLxlD11+1jHt+Ko5xdQt9LY//IvZy 4aCO/hq865VajNHFLLqzK3lkdH+HMb3/y5VJtZj5zZWQwzmd0fKx9ra+dfreVDmM2pGU eqvt4qrHvduFk0364SIhmgTiI2TINkgP5xF8rZfZQ2/EhkcupUkjmsoxG3+rBqjELYP3 2tlA== X-Gm-Message-State: ACrzQf2uu+NELxu35rgnk4dGXIWDma73SfOyHNK0a03PdURnUovOjbVX vAmGHeEa9eA6DVkSGeIrxkOTEj5LDG2vAA== X-Google-Smtp-Source: AMsMyM6TOx0VvMscZBFt6MT5oz7OIxc3H7dIKcJ55IvOLIdBAuHhmlUHl0xBUb5jKhe4p8X37LYvkw== X-Received: by 2002:a17:902:c106:b0:178:8cb:2762 with SMTP id 6-20020a170902c10600b0017808cb2762mr482863pli.58.1663260530537; Thu, 15 Sep 2022 09:48:50 -0700 (PDT) Received: from sarthakkukreti-glaptop.hsd1.ca.comcast.net ([2601:647:4200:b5b0:3af2:34b2:a98a:a652]) by smtp.gmail.com with ESMTPSA id o4-20020a170902bcc400b00177ee563b6dsm13174970pls.33.2022.09.15.09.48.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Sep 2022 09:48:49 -0700 (PDT) From: Sarthak Kukreti X-Google-Original-From: Sarthak Kukreti To: dm-devel@redhat.com, linux-block@vger.kernel.org, linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org Cc: Jens Axboe , "Michael S . Tsirkin" , Jason Wang , Paolo Bonzini , Stefan Hajnoczi , Alasdair Kergon , Mike Snitzer , Theodore Ts'o , Andreas Dilger , Bart Van Assche , Daniil Lunev , Evan Green , Gwendal Grignou , Sarthak Kukreti Subject: [PATCH RFC 5/8] loop: Add support for provision requests Date: Thu, 15 Sep 2022 09:48:23 -0700 Message-Id: <20220915164826.1396245-6-sarthakkukreti@google.com> X-Mailer: git-send-email 2.37.2.789.g6183377224-goog In-Reply-To: <20220915164826.1396245-1-sarthakkukreti@google.com> References: <20220915164826.1396245-1-sarthakkukreti@google.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org From: Sarthak Kukreti Add support for provision requests to loopback devices. Loop devices will configure provision support based on whether the underlying block device/file can support the provision request and upon receiving a provision bio, will map it to the backing device/storage. Signed-off-by: Sarthak Kukreti --- drivers/block/loop.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index ad92192c7d61..83f486b9bceb 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -327,6 +327,24 @@ static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos, return ret; } +static int lo_req_provision(struct loop_device *lo, struct request *rq, loff_t pos) +{ + struct file *file = lo->lo_backing_file; + struct request_queue *q = lo->lo_queue; + int ret; + + if (!q->limits.max_provision_sectors) { + ret = -EOPNOTSUPP; + goto out; + } + + ret = file->f_op->fallocate(file, FALLOC_FL_PROVISION, pos, blk_rq_bytes(rq)); + if (unlikely(ret && ret != -EINVAL && ret != -EOPNOTSUPP)) + ret = -EIO; + out: + return ret; +} + static int lo_req_flush(struct loop_device *lo, struct request *rq) { int ret = vfs_fsync(lo->lo_backing_file, 0); @@ -488,6 +506,8 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq) FALLOC_FL_PUNCH_HOLE); case REQ_OP_DISCARD: return lo_fallocate(lo, rq, pos, FALLOC_FL_PUNCH_HOLE); + case REQ_OP_PROVISION: + return lo_req_provision(lo, rq, pos); case REQ_OP_WRITE: if (cmd->use_aio) return lo_rw_aio(lo, cmd, pos, WRITE); @@ -754,6 +774,25 @@ static void loop_sysfs_exit(struct loop_device *lo) &loop_attribute_group); } +static void loop_config_provision(struct loop_device *lo) +{ + struct file *file = lo->lo_backing_file; + struct inode *inode = file->f_mapping->host; + + /* + * If the backing device is a block device, mirror its provisioning + * capability. + */ + if (S_ISBLK(inode->i_mode)) { + blk_queue_max_provision_sectors(lo->lo_queue, + bdev_max_provision_sectors(I_BDEV(inode))); + } else if (file->f_op->fallocate) { + blk_queue_max_provision_sectors(lo->lo_queue, UINT_MAX >> 9); + } else { + blk_queue_max_provision_sectors(lo->lo_queue, 0); + } +} + static void loop_config_discard(struct loop_device *lo) { struct file *file = lo->lo_backing_file; @@ -1092,6 +1131,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, blk_queue_io_min(lo->lo_queue, bsize); loop_config_discard(lo); + loop_config_provision(lo); loop_update_rotational(lo); loop_update_dio(lo); loop_sysfs_init(lo); @@ -1304,6 +1344,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) } loop_config_discard(lo); + loop_config_provision(lo); /* update dio if lo_offset or transfer is changed */ __loop_update_dio(lo, lo->use_dio); @@ -1815,6 +1856,7 @@ static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx, case REQ_OP_FLUSH: case REQ_OP_DISCARD: case REQ_OP_WRITE_ZEROES: + case REQ_OP_PROVISION: cmd->use_aio = false; break; default: From patchwork Thu Sep 15 16:48:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarthak Kukreti X-Patchwork-Id: 12977649 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 345BCC6FA89 for ; Thu, 15 Sep 2022 16:49:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229750AbiIOQtj (ORCPT ); Thu, 15 Sep 2022 12:49:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50044 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230080AbiIOQtB (ORCPT ); Thu, 15 Sep 2022 12:49:01 -0400 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 227469E697 for ; Thu, 15 Sep 2022 09:48:53 -0700 (PDT) Received: by mail-pj1-x1035.google.com with SMTP id go6so14154045pjb.2 for ; Thu, 15 Sep 2022 09:48:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=GHq7dVGm2OOxGrPIxR4jW0JwHX2wEssn4Ks1aVeah78=; b=N080U3jriplkoP0mn+6UNs5gJxyCP2n1wsAfUwiTdaLhfvKefEOQ3Jnp4joBXWoSkV PsHBuZ6zxKDriXffRGWMsJkIPwQrlz0X29bfVvN/3YJzF4V41GPn40hK7UxrsvNP/xuI 14j2sTvlzYkuFYYqjzjdseq8AKlrm90Wt6P8k= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=GHq7dVGm2OOxGrPIxR4jW0JwHX2wEssn4Ks1aVeah78=; b=mCvNiOxuDQ6+746s16NggpxRMPGt3bGsChLncSvzqpAQLbVT8S9SuOrnzWTN8F6WOE ofBv66mKK7q9nkbkD9D8x0XT7dcgP+f2iuD18Qi2aglq7xF8Bpfr70K5nXsFr86Ka57p 9a3GgVtL8R60/xH78AhyBaFQOv7AgRWkirFwuNBVai0tZ2+TnRGRBImbSur4qpj2sr+/ GfquPrgUvl2B8FuOj71wh8TupvH651mRB9xX+eYwHk5cwb8S7hfLtYVjeOZbAVyPQ/g3 Kp9fdVEHL4S8ORsn7wrja6wfeDGZ68eO6lOV1EYNa2lDyriWVU+4hQtXlZgc/gzyYOBQ dXXQ== X-Gm-Message-State: ACrzQf0whtDawZPZKXX/Ov/26VqpcYTyQfFhHV6pgi/mxORTguYHDrnn Dhg/+jeDlTEh0fQtljMz7Stbbw== X-Google-Smtp-Source: AMsMyM5ttUX80mK/xaqN8PnmPtACWbnNz3msqy9Npe8lr7jxLQP3tkGYZybEvxiT7s/KaSaMZVvSZQ== X-Received: by 2002:a17:902:dac4:b0:178:3037:680a with SMTP id q4-20020a170902dac400b001783037680amr327417plx.37.1663260532933; Thu, 15 Sep 2022 09:48:52 -0700 (PDT) Received: from sarthakkukreti-glaptop.hsd1.ca.comcast.net ([2601:647:4200:b5b0:3af2:34b2:a98a:a652]) by smtp.gmail.com with ESMTPSA id o4-20020a170902bcc400b00177ee563b6dsm13174970pls.33.2022.09.15.09.48.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Sep 2022 09:48:52 -0700 (PDT) From: Sarthak Kukreti X-Google-Original-From: Sarthak Kukreti To: dm-devel@redhat.com, linux-block@vger.kernel.org, linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org Cc: Jens Axboe , "Michael S . Tsirkin" , Jason Wang , Paolo Bonzini , Stefan Hajnoczi , Alasdair Kergon , Mike Snitzer , Theodore Ts'o , Andreas Dilger , Bart Van Assche , Daniil Lunev , Evan Green , Gwendal Grignou , Sarthak Kukreti Subject: [PATCH RFC 6/8] ext4: Add support for FALLOC_FL_PROVISION Date: Thu, 15 Sep 2022 09:48:24 -0700 Message-Id: <20220915164826.1396245-7-sarthakkukreti@google.com> X-Mailer: git-send-email 2.37.2.789.g6183377224-goog In-Reply-To: <20220915164826.1396245-1-sarthakkukreti@google.com> References: <20220915164826.1396245-1-sarthakkukreti@google.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org From: Sarthak Kukreti Once ext4 is done mapping blocks for an fallocate() request, send out an FALLOC_FL_PROVISION request to the underlying layer to ensure that the space is provisioned for the newly allocated extent or indirect blocks. Signed-off-by: Sarthak Kukreti --- fs/ext4/ext4.h | 2 ++ fs/ext4/extents.c | 15 ++++++++++++++- fs/ext4/indirect.c | 9 +++++++++ include/linux/blkdev.h | 11 +++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 9bca5565547b..ec0871e687c1 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -675,6 +675,8 @@ enum { #define EXT4_GET_BLOCKS_IO_SUBMIT 0x0400 /* Caller is in the atomic contex, find extent if it has been cached */ #define EXT4_GET_BLOCKS_CACHED_NOWAIT 0x0800 + /* Provision blocks on underlying storage */ +#define EXT4_GET_BLOCKS_PROVISION 0x1000 /* * The bit position of these flags must not overlap with any of the diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index c148bb97b527..7a096144b7f8 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4356,6 +4356,13 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, } } + /* Attempt to provision blocks on underlying storage */ + if (flags & EXT4_GET_BLOCKS_PROVISION) { + err = sb_issue_provision(inode->i_sb, pblk, ar.len, GFP_NOFS); + if (err) + goto out; + } + /* * Cache the extent and update transaction to commit on fdatasync only * when it is _not_ an unwritten extent. @@ -4690,7 +4697,7 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) /* Return error if mode is not supported */ if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE | - FALLOC_FL_INSERT_RANGE)) + FALLOC_FL_INSERT_RANGE | FALLOC_FL_PROVISION)) return -EOPNOTSUPP; inode_lock(inode); @@ -4750,6 +4757,12 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) if (ret) goto out; + /* Ensure that preallocation provisions the blocks on the underlying + * storage device. + */ + if (mode & FALLOC_FL_PROVISION) + flags |= EXT4_GET_BLOCKS_PROVISION; + ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, flags); if (ret) goto out; diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c index 860fc5119009..860a2560872b 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c @@ -640,6 +640,15 @@ int ext4_ind_map_blocks(handle_t *handle, struct inode *inode, if (err) goto cleanup; + /* Attempt to provision blocks on underlying storage */ + if (flags & EXT4_GET_BLOCKS_PROVISION) { + err = sb_issue_provision(inode->i_sb, + le32_to_cpu(chain[depth-1].key), + ar.len, GFP_NOFS); + if (err) + goto out; + } + map->m_flags |= EXT4_MAP_NEW; ext4_update_inode_fsync_trans(handle, inode, 1); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index a58496d3f922..26b41a6c12f4 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1107,6 +1107,17 @@ static inline int sb_issue_zeroout(struct super_block *sb, sector_t block, gfp_mask, 0); } +static inline int sb_issue_provision(struct super_block *sb, sector_t block, + sector_t nr_blocks, gfp_t gfp_mask) +{ + return blkdev_issue_provision(sb->s_bdev, + block << (sb->s_blocksize_bits - + SECTOR_SHIFT), + nr_blocks << (sb->s_blocksize_bits - + SECTOR_SHIFT), + gfp_mask); +} + static inline bool bdev_is_partition(struct block_device *bdev) { return bdev->bd_partno; From patchwork Thu Sep 15 16:48:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarthak Kukreti X-Patchwork-Id: 12977650 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 296FBECAAA1 for ; Thu, 15 Sep 2022 16:49:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229696AbiIOQtq (ORCPT ); Thu, 15 Sep 2022 12:49:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230021AbiIOQtZ (ORCPT ); Thu, 15 Sep 2022 12:49:25 -0400 Received: from mail-pg1-x52b.google.com (mail-pg1-x52b.google.com [IPv6:2607:f8b0:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10FEA9E6A6 for ; Thu, 15 Sep 2022 09:48:55 -0700 (PDT) Received: by mail-pg1-x52b.google.com with SMTP id 78so17797451pgb.13 for ; Thu, 15 Sep 2022 09:48:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=lepBsWytyJc7odlmE2pOVLJDHfEg/6nqSBO25R2FRqw=; b=dRYPidNB4qr/PThCP2DZvS52KW2vSmy9pm3afLiJJETIx42RmwEKAGSyFrbhz878PJ PbszA/tTAvFSMGbxN2kh3CFn+XIu17dnVbAV4wFsI8NNGMYygeWgn2PXa/4BJeXuIQVZ mJ498MmM/GTV3SCimynfUDHw4QKdTRpYJKfNI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=lepBsWytyJc7odlmE2pOVLJDHfEg/6nqSBO25R2FRqw=; b=Tqtuz5XcScpQQMCqkl6K1BT12SeO7YCIRTe91Po2AV7pJFTFhHibbezmSYTGjau7qb kkR+qz68+pN7R08sY38ja+tFZcrYvvdB5Dq0b58xx9YU5uEcmi6jDzCJOSSFmKJS5wkU /iQ54Tgll8V33Ae1Q/FbdT6vo2cpyGCRtYUy/GnGQiRiv5Le+pDBz3/6KulXONSwaqPd YHvCqZ742AvKTKmdKO7fhj7NcCCxM6c3t+bx/CsUKkYv8ErWl7burRTT/US3OWt1y1EX c//qzMSmM6inPKoLD+DHzMLneqKJHu8LKXSqTXx8rYNq8/RX7vkE1XMr9sojvjvgUEph CMUA== X-Gm-Message-State: ACrzQf3SoEqL4eRWYoS+mxpnfvM4Xprw+UBQYxU5aOvLbcMER+kfEBnQ Ga+yH0j0Ufc+l44sjoSpQ0FOyQ== X-Google-Smtp-Source: AMsMyM4mYzeO6kY8V14FHKZ6sRCrfG/b2+9U/J91HawWbKAVnfznpfZpifb9zuLeuSrNWkeoxFzUpA== X-Received: by 2002:aa7:9f0c:0:b0:546:c556:ac86 with SMTP id g12-20020aa79f0c000000b00546c556ac86mr327926pfr.55.1663260535338; Thu, 15 Sep 2022 09:48:55 -0700 (PDT) Received: from sarthakkukreti-glaptop.hsd1.ca.comcast.net ([2601:647:4200:b5b0:3af2:34b2:a98a:a652]) by smtp.gmail.com with ESMTPSA id o4-20020a170902bcc400b00177ee563b6dsm13174970pls.33.2022.09.15.09.48.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Sep 2022 09:48:54 -0700 (PDT) From: Sarthak Kukreti X-Google-Original-From: Sarthak Kukreti To: dm-devel@redhat.com, linux-block@vger.kernel.org, linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org Cc: Jens Axboe , "Michael S . Tsirkin" , Jason Wang , Paolo Bonzini , Stefan Hajnoczi , Alasdair Kergon , Mike Snitzer , Theodore Ts'o , Andreas Dilger , Bart Van Assche , Daniil Lunev , Evan Green , Gwendal Grignou , Sarthak Kukreti Subject: [PATCH RFC 7/8] ext4: Add mount option for provisioning blocks during allocations Date: Thu, 15 Sep 2022 09:48:25 -0700 Message-Id: <20220915164826.1396245-8-sarthakkukreti@google.com> X-Mailer: git-send-email 2.37.2.789.g6183377224-goog In-Reply-To: <20220915164826.1396245-1-sarthakkukreti@google.com> References: <20220915164826.1396245-1-sarthakkukreti@google.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org From: Sarthak Kukreti Add a mount option that sets the default provisioning mode for all files within the filesystem. Signed-off-by: Sarthak Kukreti --- fs/ext4/ext4.h | 1 + fs/ext4/extents.c | 7 +++++++ fs/ext4/super.c | 7 +++++++ 3 files changed, 15 insertions(+) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index ec0871e687c1..75f6e7f2f90b 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1271,6 +1271,7 @@ struct ext4_inode_info { #define EXT4_MOUNT2_MB_OPTIMIZE_SCAN 0x00000080 /* Optimize group * scanning in mballoc */ +#define EXT4_MOUNT2_PROVISION 0x00000100 /* Provision while allocating file blocks */ #define clear_opt(sb, opt) EXT4_SB(sb)->s_mount_opt &= \ ~EXT4_MOUNT_##opt diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 7a096144b7f8..746213b5ec3d 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4437,6 +4437,13 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, unsigned int credits; loff_t epos; + /* + * Attempt to provision file blocks if the mount is mounted with + * provision. + */ + if (test_opt2(inode->i_sb, PROVISION)) + flags |= EXT4_GET_BLOCKS_PROVISION; + BUG_ON(!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)); map.m_lblk = offset; map.m_len = len; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 9a66abcca1a8..5ece1868f332 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1596,6 +1596,7 @@ enum { Opt_max_dir_size_kb, Opt_nojournal_checksum, Opt_nombcache, Opt_no_prefetch_block_bitmaps, Opt_mb_optimize_scan, Opt_errors, Opt_data, Opt_data_err, Opt_jqfmt, Opt_dax_type, + Opt_provision, Opt_noprovision, #ifdef CONFIG_EXT4_DEBUG Opt_fc_debug_max_replay, Opt_fc_debug_force #endif @@ -1744,6 +1745,8 @@ static const struct fs_parameter_spec ext4_param_specs[] = { fsparam_flag ("reservation", Opt_removed), /* mount option from ext2/3 */ fsparam_flag ("noreservation", Opt_removed), /* mount option from ext2/3 */ fsparam_u32 ("journal", Opt_removed), /* mount option from ext2/3 */ + fsparam_flag ("discard", Opt_provision), + fsparam_flag ("noprovision", Opt_noprovision), {} }; @@ -1840,6 +1843,8 @@ static const struct mount_opts { {Opt_nombcache, EXT4_MOUNT_NO_MBCACHE, MOPT_SET}, {Opt_no_prefetch_block_bitmaps, EXT4_MOUNT_NO_PREFETCH_BLOCK_BITMAPS, MOPT_SET}, + {Opt_provision, EXT4_MOUNT2_PROVISION, MOPT_SET | MOPT_2}, + {Opt_noprovision, EXT4_MOUNT2_PROVISION, MOPT_CLEAR | MOPT_2}, #ifdef CONFIG_EXT4_DEBUG {Opt_fc_debug_force, EXT4_MOUNT2_JOURNAL_FAST_COMMIT, MOPT_SET | MOPT_2 | MOPT_EXT4_ONLY}, @@ -3010,6 +3015,8 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb, SEQ_OPTS_PUTS("dax=never"); } else if (test_opt2(sb, DAX_INODE)) { SEQ_OPTS_PUTS("dax=inode"); + } else if (test_opt2(sb, PROVISION)) { + SEQ_OPTS_PUTS("provision"); } if (sbi->s_groups_count >= MB_DEFAULT_LINEAR_SCAN_THRESHOLD && From patchwork Thu Sep 15 16:48:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarthak Kukreti X-Patchwork-Id: 12977651 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 78DCBC6FA89 for ; Thu, 15 Sep 2022 16:49:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230179AbiIOQt4 (ORCPT ); Thu, 15 Sep 2022 12:49:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230096AbiIOQt0 (ORCPT ); Thu, 15 Sep 2022 12:49:26 -0400 Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C29B9E6B8 for ; Thu, 15 Sep 2022 09:48:58 -0700 (PDT) Received: by mail-pl1-x62a.google.com with SMTP id w20so6843221ply.12 for ; Thu, 15 Sep 2022 09:48:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=CC2AT69XGg5wm3bSeW54GIGYiTC1rZqaZVqT6NInl68=; b=mu3+zu2fHkK18fyK8GquthMgCh0knmNuo1AuOv6/5p4XsIu5amJTOn6ebMi5f22/na PdmtAwktXThz7euWyzkdNELKrfRtOJwgowVocLAbaPOqQuLnlvONAH9Ktcv8xh5VTMrL zfixw/KKn7UoVL8Jol7k9Cf7o8+gbedJGP27U= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=CC2AT69XGg5wm3bSeW54GIGYiTC1rZqaZVqT6NInl68=; b=xPrrrlG4JVdlfs0OTYrWiQp0Bwy7oLyVeonpl9Pfj8gk7u9GIIdPno/dYll89BaQii emN641RruAE3/h2fcZOCSACmkuuT+lupDaKuxooc+I1i+gMpkKxWwfi3eaJaUWLgO7gN wvRqoh+rklxyM9LLNiQngH35N2TGB8Leiq8zMUGeg0PHNdPhUp/nMSN4+LNeljcsTemH SVqioUnDVfMm2K16+rgfYwAVLwD5hgM3eOsGulU5P7iq9bXeuOpQOvs3tTsz0Tan3MQ7 CduhpaEhVwCce/cQQx8m4yt7A+5S2qq5skYoxT9wY5/rdmsfkUwdX9I5C7MRBeCeO1st Ra1Q== X-Gm-Message-State: ACrzQf0RfZc/+xKRT39YS2u8jsvhWEglnURCKV1nv/GxNZ7J2ah2s7A8 qH7UVuMGiRQ4ms7PxoJGI3ukXw== X-Google-Smtp-Source: AMsMyM7xQDECJlshM1y7hrMSNYPc8bpR0IMtAX/vgFfB37FWYtZxA5MaaTnkclE6b1SXhntNfjnk0g== X-Received: by 2002:a17:902:b7c3:b0:176:b7e6:ae6c with SMTP id v3-20020a170902b7c300b00176b7e6ae6cmr292383plz.163.1663260537835; Thu, 15 Sep 2022 09:48:57 -0700 (PDT) Received: from sarthakkukreti-glaptop.hsd1.ca.comcast.net ([2601:647:4200:b5b0:3af2:34b2:a98a:a652]) by smtp.gmail.com with ESMTPSA id o4-20020a170902bcc400b00177ee563b6dsm13174970pls.33.2022.09.15.09.48.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Sep 2022 09:48:56 -0700 (PDT) From: Sarthak Kukreti X-Google-Original-From: Sarthak Kukreti To: dm-devel@redhat.com, linux-block@vger.kernel.org, linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org Cc: Jens Axboe , "Michael S . Tsirkin" , Jason Wang , Paolo Bonzini , Stefan Hajnoczi , Alasdair Kergon , Mike Snitzer , Theodore Ts'o , Andreas Dilger , Bart Van Assche , Daniil Lunev , Evan Green , Gwendal Grignou , Sarthak Kukreti Subject: [PATCH RFC 8/8] ext4: Add a per-file provision override xattr Date: Thu, 15 Sep 2022 09:48:26 -0700 Message-Id: <20220915164826.1396245-9-sarthakkukreti@google.com> X-Mailer: git-send-email 2.37.2.789.g6183377224-goog In-Reply-To: <20220915164826.1396245-1-sarthakkukreti@google.com> References: <20220915164826.1396245-1-sarthakkukreti@google.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org From: Sarthak Kukreti Adds a per-file provision override that allows select files to override the per-mount setting for provisioning blocks on allocation. This acts as a mechanism to allow mounts using provision to replicate the current behavior for fallocate() and only preserve space at the filesystem level. Signed-off-by: Sarthak Kukreti --- fs/ext4/extents.c | 32 ++++++++++++++++++++++++++++++++ fs/ext4/xattr.h | 1 + 2 files changed, 33 insertions(+) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 746213b5ec3d..a9ed908b2ebe 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4424,6 +4424,26 @@ int ext4_ext_truncate(handle_t *handle, struct inode *inode) return err; } +int ext4_provision_support(struct inode *inode) +{ + char provision; + int ret = + ext4_xattr_get(inode, EXT4_XATTR_INDEX_TRUSTED, + EXT4_XATTR_NAME_PROVISION_POLICY, &provision, 1); + + if (ret < 0) + return ret; + + switch (provision) { + case 'y': + return 1; + case 'n': + return 0; + default: + return -EINVAL; + } +} + static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, ext4_lblk_t len, loff_t new_size, int flags) @@ -4436,12 +4456,24 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, struct ext4_map_blocks map; unsigned int credits; loff_t epos; + bool provision = false; + int file_provision_override = -1; /* * Attempt to provision file blocks if the mount is mounted with * provision. */ if (test_opt2(inode->i_sb, PROVISION)) + provision = true; + + /* + * Use file-specific override, if available. + */ + file_provision_override = ext4_provision_support(inode); + if (file_provision_override >= 0) + provision &= file_provision_override; + + if (provision) flags |= EXT4_GET_BLOCKS_PROVISION; BUG_ON(!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)); diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index 824faf0b15a8..69e97f853b0c 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h @@ -140,6 +140,7 @@ extern const struct xattr_handler ext4_xattr_security_handler; extern const struct xattr_handler ext4_xattr_hurd_handler; #define EXT4_XATTR_NAME_ENCRYPTION_CONTEXT "c" +#define EXT4_XATTR_NAME_PROVISION_POLICY "provision" /* * The EXT4_STATE_NO_EXPAND is overloaded and used for two purposes.