From nobody Fri Apr 3 06:53:22 2026 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 D1019C6FA89 for ; Thu, 15 Sep 2022 16:48:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229846AbiIOQsw (ORCPT ); Thu, 15 Sep 2022 12:48:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229462AbiIOQsn (ORCPT ); Thu, 15 Sep 2022 12:48:43 -0400 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D342476958 for ; Thu, 15 Sep 2022 09:48:40 -0700 (PDT) Received: by mail-pj1-x1031.google.com with SMTP id m10-20020a17090a730a00b001fa986fd8eeso22987502pjk.0 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=qBKQWiMWsq8lRWggJ43oaQpjPlD6g92SIPsWNDQAuHggsojj0S9Z5zw4j9358Fmjqj /l+S377a1hY161DToOWntpZ+Z8MJchHqO6NgTFVRbgge/501bg13r11AXS1M2UxHfyHb MKkpqnzkopKljFd0VVI7/diBCFoLoWgb/nXI2VtcyIZJkbj49fWsPcya4syVQiTUMhJf IeUI+4/qCeEfRWcvWb5VNkdlPKJ9C0/fgcCFnuXm2QZd8EVLKETAGDydix492LPxqViD irNe32B+awM8KI3s65gyduX9P6QFVjMkQBq1LlkoJwDjqB2yscGf+vfG5HZbECv4mYmm Tlbg== X-Gm-Message-State: ACrzQf0rLiKUnNARoipk8g1whMouD22mq2VsNC8szFDr/K8aXGSzXVQA lsMZEGTjGnkL7RT0t8JKCuMnwg== 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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[] =3D { REQ_OP_NAME(WRITE_ZEROES), REQ_OP_NAME(DRV_IN), REQ_OP_NAME(DRV_OUT), + REQ_OP_NAME(PROVISION) }; #undef REQ_OP_NAME =20 @@ -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 *bde= v, 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 sector= s. + * 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 =3D (bdev_logical_block_size(bdev) >> 9) - 1; + unsigned int max_sectors =3D bdev_max_provision_sectors(bdev); + struct bio *bio =3D NULL; + struct blk_plug plug; + int ret =3D 0; + + if (max_sectors =3D=3D 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 =3D min_t(sector_t, nr_sects, max_sectors); + + bio =3D blk_next_bio(bio, bdev, 0, REQ_OP_PROVISION, gfp); + bio->bi_iter.bi_sector =3D sector; + bio->bi_iter.bi_size =3D req_sects << SECTOR_SHIFT; + bio_set_dev(bio, bdev); + bio_set_op_attrs(bio, REQ_OP_PROVISION, 0); + + sector +=3D req_sects; + nr_sects -=3D req_sects; + if (!nr_sects) { + ret =3D submit_bio_wait(bio); + if (ret =3D=3D -EOPNOTSUPP) + ret =3D 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); } =20 +static struct bio *bio_split_provision(struct bio *bio, + struct queue_limits *lim, unsigned *nsegs, struct bio_set *bs) +{ + *nsegs =3D 0; + + if (!lim->max_provision_sectors) + return NULL; + + if (bio_sectors(bio) <=3D 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 rema= in, @@ -345,6 +359,9 @@ struct bio *__bio_split_to_limits(struct bio *bio, stru= ct queue_limits *lim, case REQ_OP_WRITE_ZEROES: split =3D bio_split_write_zeroes(bio, lim, nr_segs, bs); break; + case REQ_OP_PROVISION: + split =3D bio_split_provision(bio, lim, nr_segs, bs); + break; default: split =3D 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 =3D 0; lim->zoned =3D BLK_ZONED_NONE; lim->zone_write_granularity =3D 0; + lim->max_provision_sectors =3D 0; } EXPORT_SYMBOL(blk_set_default_limits); =20 @@ -81,6 +82,7 @@ void blk_set_stacking_limits(struct queue_limits *lim) lim->max_dev_sectors =3D UINT_MAX; lim->max_write_zeroes_sectors =3D UINT_MAX; lim->max_zone_append_sectors =3D UINT_MAX; + lim->max_provision_sectors =3D UINT_MAX; } EXPORT_SYMBOL(blk_set_stacking_limits); =20 @@ -202,6 +204,20 @@ void blk_queue_max_write_zeroes_sectors(struct request= _queue *q, } EXPORT_SYMBOL(blk_queue_max_write_zeroes_sectors); =20 +/** + * 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 comm= and + **/ + +void blk_queue_max_provision_sectors(struct request_queue *q, + unsigned int max_provision_sectors) +{ + q->limits.max_provision_sectors =3D max_provision_sectors; +} +EXPORT_SYMBOL(blk_queue_max_provision_sectors); + /** * blk_queue_max_zone_append_sectors - set max sectors for a single zone a= ppend * @q: the request queue for the device @@ -572,6 +588,9 @@ int blk_stack_limits(struct queue_limits *t, struct que= ue_limits *b, t->max_segment_size =3D min_not_zero(t->max_segment_size, b->max_segment_size); =20 + t->max_provision_sectors =3D min_not_zero(t->max_provision_sectors, + b->max_provision_sectors); + t->misaligned |=3D b->misaligned; =20 alignment =3D 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); } =20 +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"); =20 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[] =3D { &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) !=3D REQ_OP_DISCARD && bio_op(bio) !=3D REQ_OP_SECURE_ERASE && - bio_op(bio) !=3D REQ_OP_WRITE_ZEROES) + bio_op(bio) !=3D REQ_OP_WRITE_ZEROES && + bio_op(bio) !=3D REQ_OP_PROVISION) return true; =20 return false; @@ -65,7 +66,8 @@ static inline bool bio_no_advance_iter(const struct bio *= bio) { return bio_op(bio) =3D=3D REQ_OP_DISCARD || bio_op(bio) =3D=3D REQ_OP_SECURE_ERASE || - bio_op(bio) =3D=3D REQ_OP_WRITE_ZEROES; + bio_op(bio) =3D=3D REQ_OP_WRITE_ZEROES || + bio_op(bio) =3D=3D REQ_OP_PROVISION; } =20 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 =3D (__force blk_opf_t)34, REQ_OP_DRV_OUT =3D (__force blk_opf_t)35, =20 - REQ_OP_LAST =3D (__force blk_opf_t)36, + /* request device to provision block */ + REQ_OP_PROVISION =3D (__force blk_opf_t)37, + + REQ_OP_LAST =3D (__force blk_opf_t)38, }; =20 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; =20 unsigned short max_segments; unsigned short max_integrity_segments; @@ -931,6 +932,8 @@ extern void blk_queue_max_discard_sectors(struct reques= t_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); =20 +extern int blkdev_issue_provision(struct block_device *bdev, sector_t sect= or, + 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 */ =20 @@ -1149,6 +1155,11 @@ static inline unsigned short queue_max_discard_segme= nts(const struct request_que return q->limits.max_discard_segments; } =20 +static inline unsigned short queue_max_provision_sectors(const struct requ= est_queue *q) +{ + return q->limits.max_provision_sectors; +} + static inline unsigned int queue_max_segment_size(const struct request_que= ue *q) { return q->limits.max_segment_size; @@ -1280,6 +1291,11 @@ static inline bool bdev_fua(struct block_device *bde= v) return test_bit(QUEUE_FLAG_FUA, &bdev_get_queue(bdev)->queue_flags); } =20 +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 *b= dev) { struct request_queue *q =3D bdev_get_queue(bdev); --=20 2.31.0 From nobody Fri Apr 3 06:53:22 2026 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 53B0BC6FA89 for ; Thu, 15 Sep 2022 16:49:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230073AbiIOQtB (ORCPT ); Thu, 15 Sep 2022 12:49:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49550 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229712AbiIOQsp (ORCPT ); Thu, 15 Sep 2022 12:48:45 -0400 Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6BF7C61D9C for ; Thu, 15 Sep 2022 09:48:43 -0700 (PDT) Received: by mail-pl1-x631.google.com with SMTP id l10so18895148plb.10 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=Vp4zgE8r8+tqsET9zkzCpxmzjt6R4BMcDYJ8vjteu1wg5XqJj7b0eti89S/hP9QU0Z gGmmmQbbamNRp14YGnNo3YkoO3AhmKpkZafySw1Jq1+3x7wVg2J7BNza7aUShvsQoO0b 9i9Wof9NEDmTcNEgGhKKuhY4SsZzT/kt0R678z5q1w60VALYhHTjyD2Sax+iU2Swdmxu 6zoC7fug7aBR2nZj7RD5vzEAYVSMZlu1em5O6WmjBNJF8FCcoGsE1g0hgQUqtOHJX38u NVvJaeMHFA1cJX/0LC+pbNPsFFpzhx1E9Ttmbx4a/DCRkG7L1CrEjYHv1VuUa5wPJIk3 IYAg== X-Gm-Message-State: ACrzQf2+NWlh6qy9uLed4nWF8fBujNRIuJQLOCsPqtNq04jj6brGSUSj XJJiQSNW14VUfjF+j6jVP5fyYA== 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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, u= nsigned int argc, char **ar if (ret) return ret; =20 + ti->num_provision_bios =3D 1; + while (opt_params--) { opt_string =3D 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) =3D=3D REQ_OP_DISCARD)) { + bio_op(bio) =3D=3D REQ_OP_DISCARD || bio_op(bio) =3D=3D REQ_OP_PROVIS= ION)) { bio_set_dev(bio, cc->dev->bdev); if (bio_sectors(bio)) bio->bi_iter.bi_sector =3D 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 =3D 1; ti->num_secure_erase_bios =3D 1; ti->num_write_zeroes_bios =3D 1; + ti->num_provision_bios =3D 1; ti->private =3D lc; return 0; =20 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; } =20 +static bool dm_table_supports_provision(struct dm_table *t) +{ + for (unsigned int i =3D 0; i < t->num_targets; i++) { + struct dm_target *ti =3D 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, st= ruct request_queue *q, if (!dm_table_supports_write_zeroes(t)) q->limits.max_write_zeroes_sectors =3D 0; =20 + if (dm_table_supports_provision(t)) + blk_queue_max_provision_sectors(q, UINT_MAX >> 9); + else + q->limits.max_provision_sectors =3D 0; + dm_table_verify_integrity(t); =20 /* 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; =20 while ((bio =3D bio_list_pop(&cell->bios))) { - if (op_is_flush(bio->bi_opf) || bio_op(bio) =3D=3D REQ_OP_DISCARD) + if (op_is_flush(bio->bi_opf) || bio_op(bio) =3D=3D REQ_OP_DISCARD || + bio_op(bio) =3D=3D 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_n= ew_mapping *m) goto out; } =20 + if (bio && bio_op(bio) =3D=3D 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 =3D data_block; m->cell =3D cell; =20 + if (bio && bio_op(bio) =3D=3D REQ_OP_PROVISION) + m->bio =3D 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) =3D=3D READ) { + if (bio_data_dir(bio) =3D=3D READ && bio_op(bio) !=3D 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 d= m_bio_prison_cell *cell) } } =20 +static void process_provision_cell(struct thin_c *tc, struct dm_bio_prison= _cell *cell) +{ + int r; + struct pool *pool =3D tc->pool; + struct bio *bio =3D 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 !=3D end) { + r =3D ensure_next_mapping(pool); + if (r) + /* we did our best */ + return; + + r =3D 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 =3D %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 =3D=3D 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 =3D 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 !=3D READ) { + if (rw !=3D READ || bio_op(bio) =3D=3D REQ_OP_PROVISION) { handle_unserviceable_bio(tc->pool, bio); break; } @@ -2200,6 +2270,8 @@ static void process_thin_deferred_bios(struct thin_c = *tc) =20 if (bio_op(bio) =3D=3D REQ_OP_DISCARD) pool->process_discard(tc, bio); + else if (bio_op(bio) =3D=3D REQ_OP_PROVISION) + process_provision_bio(tc, bio); else pool->process_bio(tc, bio); =20 @@ -2716,7 +2788,8 @@ static int thin_bio_map(struct dm_target *ti, struct = bio *bio) return DM_MAPIO_SUBMITTED; } =20 - if (op_is_flush(bio->bi_opf) || bio_op(bio) =3D=3D REQ_OP_DISCARD) { + if (op_is_flush(bio->bi_opf) || bio_op(bio) =3D=3D REQ_OP_DISCARD || + bio_op(bio) =3D=3D 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 ar= gc, char **argv) pt->low_water_blocks =3D low_water_blocks; pt->adjusted_pf =3D pt->requested_pf =3D pf; ti->num_flush_bios =3D 1; + ti->num_provision_bios =3D 1; =20 /* * Only need to enable discards if the pool should pass @@ -4043,6 +4117,7 @@ static void pool_io_hints(struct dm_target *ti, struc= t queue_limits *limits) blk_limits_io_opt(limits, pool->sectors_per_block << SECTOR_SHIFT); } =20 + /* * 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 ar= gc, char **argv) ti->num_discard_bios =3D 1; } =20 + ti->num_provision_bios =3D 1; + mutex_unlock(&dm_thin_pool_table.mutex); =20 spin_lock_irq(&tc->pool->lock); @@ -4447,6 +4524,7 @@ static void thin_io_hints(struct dm_target *ti, struc= t queue_limits *limits) =20 limits->discard_granularity =3D pool->sectors_per_block << SECTOR_SHIFT; limits->max_discard_sectors =3D 2048 * 1024 * 16; /* 16G */ + limits->max_provision_sectors =3D 2048 * 1024 * 16; /* 16G */ } =20 static struct target_type thin_target =3D { 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 clon= e_info *ci, case REQ_OP_WRITE_ZEROES: num_bios =3D ti->num_write_zeroes_bios; break; + case REQ_OP_PROVISION: + num_bios =3D 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; =20 + /* + * 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. --=20 2.31.0 From nobody Fri Apr 3 06:53:22 2026 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 E1576ECAAA1 for ; Thu, 15 Sep 2022 16:49:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229953AbiIOQtF (ORCPT ); Thu, 15 Sep 2022 12:49:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229881AbiIOQs6 (ORCPT ); Thu, 15 Sep 2022 12:48:58 -0400 Received: from mail-pg1-x52a.google.com (mail-pg1-x52a.google.com [IPv6:2607:f8b0:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 037947FF88 for ; Thu, 15 Sep 2022 09:48:45 -0700 (PDT) Received: by mail-pg1-x52a.google.com with SMTP id g4so17877748pgc.0 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=czYaXjn5EhMhDQ9pxNA2F4JE9Ah8TyAU69Cq+Pnfeww6VzXtibSg+I5as/1/WoIUqg vzdfQMLOOuerzHL1WC9gU0TCEbXrqYkSGY6rDCKjpP1kXGOdYV/wjTmKfnMWjwdikzMc 6ISAOvv8ftV+IBWG/qfywxpXyZOCl9YPpmaoU0Sd2j664I6PKLrLg8ppkdOsWSqsvegR AIvZr/y6DtNEw5EVfm1T9E8BdkfN5lYWwsNmecmDtEVO6yTbTJzMzKqNGSivqdv2bM0T RB9dIjlCBtRFTUInDBgfqIencEtIHDzuBv72FaG03sDIteck0lNrAovkMlEawVy+OHE3 dhrA== X-Gm-Message-State: ACrzQf2SRysYvwafcAfo7szTUlhxpKjtmNHrlHQpITKasx2ZpgqQKDOx 6IF7eAaQpI8EQBd/mFaOEkKyAw== 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 r= equest *req, bool unmap) return 0; } =20 +static int virtblk_setup_provision(struct request *req) +{ + unsigned short segments =3D blk_rq_nr_discard_segments(req); + unsigned short n =3D 0; + + struct virtio_blk_discard_write_zeroes *range; + struct bio *bio; + u32 flags =3D 0; + + range =3D kmalloc_array(segments, sizeof(*range), GFP_ATOMIC); + if (!range) + return -ENOMEM; + + __rq_for_each_bio(bio, req) { + u64 sector =3D bio->bi_iter.bi_sector; + u32 num_sectors =3D bio->bi_iter.bi_size >> SECTOR_SHIFT; + + range[n].flags =3D cpu_to_le32(flags); + range[n].num_sectors =3D cpu_to_le32(num_sectors); + range[n].sector =3D cpu_to_le64(sector); + n++; + } + + WARN_ON_ONCE(n !=3D segments); + + req->special_vec.bv_page =3D virt_to_page(range); + req->special_vec.bv_offset =3D offset_in_page(range); + req->special_vec.bv_len =3D sizeof(*range) * segments; + req->rq_flags |=3D RQF_SPECIAL_PAYLOAD; + + return 0; +} + static void virtblk_unmap_data(struct request *req, struct virtblk_req *vb= r) { if (blk_rq_nr_phys_segments(req)) @@ -243,6 +276,9 @@ static blk_status_t virtblk_setup_cmd(struct virtio_dev= ice *vdev, case REQ_OP_DRV_IN: type =3D VIRTIO_BLK_T_GET_ID; break; + case REQ_OP_PROVISION: + type =3D 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_de= vice *vdev, return BLK_STS_RESOURCE; } =20 + if (type =3D=3D VIRTIO_BLK_T_PROVISION) { + if (virtblk_setup_provision(req)) + return BLK_STS_RESOURCE; + } + return 0; } =20 @@ -1075,6 +1116,12 @@ static int virtblk_probe(struct virtio_device *vdev) blk_queue_max_write_zeroes_sectors(q, v ? v : UINT_MAX); } =20 + 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 =3D v ? v : UINT_MAX; + } + virtblk_update_capacity(vblk, false); virtio_device_ready(vdev); =20 @@ -1177,6 +1224,7 @@ static unsigned int features[] =3D { 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, }; =20 static struct virtio_driver virtio_blk =3D { diff --git a/include/uapi/linux/virtio_blk.h b/include/uapi/linux/virtio_bl= k.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 */ =20 /* Legacy feature bits */ #ifndef VIRTIO_BLK_NO_LEGACY @@ -120,6 +121,11 @@ struct virtio_blk_config { */ __u8 write_zeroes_may_unmap; =20 + /* + * The maximum number of sectors in a provision request. + */ + __virtio32 max_provision_sectors; + __u8 unused1[3]; } __attribute__((packed)); =20 @@ -155,6 +161,9 @@ struct virtio_blk_config { /* Write zeroes command */ #define VIRTIO_BLK_T_WRITE_ZEROES 13 =20 +/* Provision command */ +#define VIRTIO_BLK_T_PROVISION 14 + #ifndef VIRTIO_BLK_NO_LEGACY /* Barrier before this op. */ #define VIRTIO_BLK_T_BARRIER 0x80000000 --=20 2.31.0 From nobody Fri Apr 3 06:53:22 2026 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 F278CECAAA1 for ; Thu, 15 Sep 2022 16:49:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229947AbiIOQtX (ORCPT ); Thu, 15 Sep 2022 12:49:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49942 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230021AbiIOQs6 (ORCPT ); Thu, 15 Sep 2022 12:48:58 -0400 Received: from mail-pf1-x432.google.com (mail-pf1-x432.google.com [IPv6:2607:f8b0:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5DFAE9836A for ; Thu, 15 Sep 2022 09:48:48 -0700 (PDT) Received: by mail-pf1-x432.google.com with SMTP id c198so18623916pfc.13 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=ezsmBKlRFr4LeLYaiuMOUbxBDhLFs5HwyZbxQC5zAj7W/LvUmhfhyAP69v5r5RdLuu elfl521XM8DRMCyHXtim3ImQ4DstEUwnaVVQ4ngZJcnPCFkt9i+IlIf+/F1rOLJdcG7b mVacK3S4iWQ/7UOj9ppO6DQjSjx0PUEeu7+CowOcwnXehGv2FWdT8vijZrLgjtbh1+N2 P57Bn7quHylVx3Tw8vfXg04z4Cz/NRqk0sWbKc3VYhn3AKHJs7HSGie6aiHKdtvW+4NV s+21Y6E0eHw847PgyZ5L5RoUdHj9yzFV+mUYtygxbpGQc5qyguHWQ8/2OAHbHlzzdCCu 6oGQ== X-Gm-Message-State: ACrzQf1yPCochew+jealI1bUjRkm6xhPvDY5aUF13ZHEP8fWZwOoxaAt Lp+0K1dDh17cVFQtCZDF3JA1jA== 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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, str= uct iov_iter *to) =20 #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) =20 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 mo= de, loff_t start, error =3D blkdev_issue_discard(bdev, start >> SECTOR_SHIFT, len >> SECTOR_SHIFT, GFP_KERNEL); break; + case FALLOC_FL_PROVISION: + error =3D blkdev_issue_provision(bdev, start >> SECTOR_SHIFT, + len >> SECTOR_SHIFT, GFP_KERNEL); + break; default: error =3D -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) =20 /* 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 =20 +/* + * FALLOC_FL_PROVISION acts as a hint for thinly provisioned devices to al= locate + * 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_ */ --=20 2.31.0 From nobody Fri Apr 3 06:53:22 2026 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 884BBECAAA1 for ; Thu, 15 Sep 2022 16:49:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230076AbiIOQt3 (ORCPT ); Thu, 15 Sep 2022 12:49:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230046AbiIOQs7 (ORCPT ); Thu, 15 Sep 2022 12:48:59 -0400 Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2D8A19E136 for ; Thu, 15 Sep 2022 09:48:51 -0700 (PDT) Received: by mail-pj1-x1032.google.com with SMTP id n23-20020a17090a091700b00202a51cc78bso16694797pjn.2 for ; Thu, 15 Sep 2022 09:48:51 -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=R2amWx2M0vFDEYjPobcFaivyESRf2dH+cu5RZMNd8MwGCkGN3z6vHFxFrSN3k0vPuV PHmVirA0VSneVHpF4IKbHZjtKfcPQXYbPEZAr4gq2Zy4ioJx6uBsNBBJ6J9+HhGqdI5p vy1xpqOtaAB3RssXaOAi9k8vz2f6zfaQjBBhKCQSB7BJYq9GSTJBGZZXKxU9x/u1FJeH /A0GXUhEvsvRUpZfp1g5K5nNJ168EmR585Xv38NwuJw95e5aonrdj4smcN0MIjqVvU8h pYgZpBz4H8c23HAE7mJH0PO7ssY9q79lLRR32fnzjCppKDWmMq/OWFzXjapbkxXljNCO pw1Q== X-Gm-Message-State: ACrzQf1hGyF5+ItCMg6DkWGXTKAeXs+WjnVupqaY+yaLeBNNXs0SvpPO qnK6vES42uGy4CWhmR7ttEFA1Q== 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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; } =20 +static int lo_req_provision(struct loop_device *lo, struct request *rq, lo= ff_t pos) +{ + struct file *file =3D lo->lo_backing_file; + struct request_queue *q =3D lo->lo_queue; + int ret; + + if (!q->limits.max_provision_sectors) { + ret =3D -EOPNOTSUPP; + goto out; + } + + ret =3D file->f_op->fallocate(file, FALLOC_FL_PROVISION, pos, blk_rq_byte= s(rq)); + if (unlikely(ret && ret !=3D -EINVAL && ret !=3D -EOPNOTSUPP)) + ret =3D -EIO; + out: + return ret; +} + static int lo_req_flush(struct loop_device *lo, struct request *rq) { int ret =3D vfs_fsync(lo->lo_backing_file, 0); @@ -488,6 +506,8 @@ static int do_req_filebacked(struct loop_device *lo, st= ruct 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); } =20 +static void loop_config_provision(struct loop_device *lo) +{ + struct file *file =3D lo->lo_backing_file; + struct inode *inode =3D 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 =3D lo->lo_backing_file; @@ -1092,6 +1131,7 @@ static int loop_configure(struct loop_device *lo, fmo= de_t mode, blk_queue_io_min(lo->lo_queue, bsize); =20 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) } =20 loop_config_discard(lo); + loop_config_provision(lo); =20 /* 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_ct= x *hctx, case REQ_OP_FLUSH: case REQ_OP_DISCARD: case REQ_OP_WRITE_ZEROES: + case REQ_OP_PROVISION: cmd->use_aio =3D false; break; default: --=20 2.31.0 From nobody Fri Apr 3 06:53:22 2026 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 89B62C6FA89 for ; Thu, 15 Sep 2022 16:49:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229731AbiIOQto (ORCPT ); Thu, 15 Sep 2022 12:49:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50626 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229872AbiIOQtY (ORCPT ); Thu, 15 Sep 2022 12:49:24 -0400 Received: from mail-pj1-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 08D129E691 for ; Thu, 15 Sep 2022 09:48:53 -0700 (PDT) Received: by mail-pj1-x102a.google.com with SMTP id j6-20020a17090a694600b00200bba67dadso17976691pjm.5 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=1PMK27tSXMhveRsbCUiQM7oUFwS2E88GHTucUteidubgCwlgZtHxuAIAfVCRaL6HiF AcHZOaGPnx8Ql5qrFavQVtIfUk0RTALnAAOQX7NjqLpr9da2uhCtHWITqZIl/HCHj++1 NW9TbhCeC3CFrTZqSLOYViO83GoJBlY2VahKpKM8koZikscUEXLhlcV9jaEMF9AKCEBl 9kOZL1c3U8bTksI26YGH/NHsHnT0Dyw2fFsl0t70huwp86qGu6KY4KCPZnAeRHqDXaH+ dL2mtoCtl9DurLC35Sl5CYw4hIoWaDmCjn269v4oTiZb1lYiCFFC1jHWqgkaF7qPYv3B k5kQ== X-Gm-Message-State: ACrzQf00N888FCcChE/cj4nmgukUbexfqnqRrm6Nwd1AeNMV1C2GZcpf vHpxUMNrzKD6wdx7XJUDBiO0oQ== 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 =20 /* * 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 ino= de *inode, } } =20 + /* Attempt to provision blocks on underlying storage */ + if (flags & EXT4_GET_BLOCKS_PROVISION) { + err =3D 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; =20 inode_lock(inode); @@ -4750,6 +4757,12 @@ long ext4_fallocate(struct file *file, int mode, lof= f_t offset, loff_t len) if (ret) goto out; =20 + /* Ensure that preallocation provisions the blocks on the underlying + * storage device. + */ + if (mode & FALLOC_FL_PROVISION) + flags |=3D EXT4_GET_BLOCKS_PROVISION; + ret =3D 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; =20 + /* Attempt to provision blocks on underlying storage */ + if (flags & EXT4_GET_BLOCKS_PROVISION) { + err =3D sb_issue_provision(inode->i_sb, + le32_to_cpu(chain[depth-1].key), + ar.len, GFP_NOFS); + if (err) + goto out; + } + map->m_flags |=3D EXT4_MAP_NEW; =20 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_bloc= k *sb, sector_t block, gfp_mask, 0); } =20 +static inline int sb_issue_provision(struct super_block *sb, sector_t bloc= k, + 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; --=20 2.31.0 From nobody Fri Apr 3 06:53:22 2026 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 C7D43C6FA8B for ; Thu, 15 Sep 2022 16:49:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230193AbiIOQt5 (ORCPT ); Thu, 15 Sep 2022 12:49:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49978 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230081AbiIOQtZ (ORCPT ); Thu, 15 Sep 2022 12:49:25 -0400 Received: from mail-pg1-x52e.google.com (mail-pg1-x52e.google.com [IPv6:2607:f8b0:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10C1C9E6A1 for ; Thu, 15 Sep 2022 09:48:55 -0700 (PDT) Received: by mail-pg1-x52e.google.com with SMTP id q9so8714616pgq.8 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=0S1tP6OVMeiieJ1yO4pD+Sz7QUJeLd7sht3D5eTPxjvM1yVFykzpmsooD4HX45bnyM v8IPNLmtRaJpSgLml4VHM7GU/C7iMqJ+aAy+W726c5rj6A4f6f4bKqgfEvO/rsc4iK+7 F268Yj5KqaAuExn+WEpWbDLHR4s8Wt2H7J9kjSxz4eLyWlc4H0TVl93MZ1A6wFYO++yO S6vHoFCM0GflnUWR5nc1RWpDGpTDbnaolHSyUCn62QfouBG5TyFKvtFTmLUPYCbIDbfx qglOxJxt+etEGDVkTblNt5EyaLibClZxS9Rv+AGAKXj+aOy7HqBg7PsGCecegnVdv0FV CpDA== X-Gm-Message-State: ACrzQf2mIlnaea40kNcwNy1+2w2fCxUnF+VtKVrAMAVv6hl7vKUdenTW 3ko5NVNNPjMyu4o5cbIFjEN0Ag== 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 fi= le blocks */ =20 #define clear_opt(sb, opt) EXT4_SB(sb)->s_mount_opt &=3D \ ~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; =20 + /* + * Attempt to provision file blocks if the mount is mounted with + * provision. + */ + if (test_opt2(inode->i_sb, PROVISION)) + flags |=3D EXT4_GET_BLOCKS_PROVISION; + BUG_ON(!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)); map.m_lblk =3D offset; map.m_len =3D 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_spec= s[] =3D { 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), {} }; =20 @@ -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, s= truct super_block *sb, SEQ_OPTS_PUTS("dax=3Dnever"); } else if (test_opt2(sb, DAX_INODE)) { SEQ_OPTS_PUTS("dax=3Dinode"); + } else if (test_opt2(sb, PROVISION)) { + SEQ_OPTS_PUTS("provision"); } =20 if (sbi->s_groups_count >=3D MB_DEFAULT_LINEAR_SCAN_THRESHOLD && --=20 2.31.0 From nobody Fri Apr 3 06:53:22 2026 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 EAB5EECAAA1 for ; Thu, 15 Sep 2022 16:50:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230111AbiIOQuB (ORCPT ); Thu, 15 Sep 2022 12:50:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49988 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230088AbiIOQt0 (ORCPT ); Thu, 15 Sep 2022 12:49:26 -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 27CAD74366 for ; Thu, 15 Sep 2022 09:48:58 -0700 (PDT) Received: by mail-pj1-x1035.google.com with SMTP id go6so14154303pjb.2 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=CqPOCQl70cJRSB+wk4yjcRU39VmxOlga53OuRNb9vAp2i8724YD15n1E417S3ciEXV M2Yk/BK2mySv7izQOUXYgstyzUSIlYRbPF0rQuQUzAIAG/hgWs58F1/wg1iv50QDvGg+ aWC1pXg5TDNX6xMAJllB66gbVTxbSI8aLIlMvGv6HqaW7fJSsMavi8LwyMT9emfCVMrA c0dISwkNy6MCtlNvPD19tNDvBZpk7Jq4urVSOVJfzPNvgwMeQ+akAvifTQ5WmPAu2jyg o9aiBGF2Jek3zJPbv/J/FH/1QnzxB8YNi3u9OZiaZaqK7PJ9QYLBCxsp9iAtopytIUw5 79IQ== X-Gm-Message-State: ACrzQf3wD9TxQJyBFKQSAR/gJHug8fDVi0FaR0mwzIup34HRflBK2rFk J+EQqs3tiZWKyBe9ECwSgcyk9A== 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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; } =20 +int ext4_provision_support(struct inode *inode) +{ + char provision; + int ret =3D + 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 =3D false; + int file_provision_override =3D -1; =20 /* * Attempt to provision file blocks if the mount is mounted with * provision. */ if (test_opt2(inode->i_sb, PROVISION)) + provision =3D true; + + /* + * Use file-specific override, if available. + */ + file_provision_override =3D ext4_provision_support(inode); + if (file_provision_override >=3D 0) + provision &=3D file_provision_override; + + if (provision) flags |=3D EXT4_GET_BLOCKS_PROVISION; =20 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_h= andler; extern const struct xattr_handler ext4_xattr_hurd_handler; =20 #define EXT4_XATTR_NAME_ENCRYPTION_CONTEXT "c" +#define EXT4_XATTR_NAME_PROVISION_POLICY "provision" =20 /* * The EXT4_STATE_NO_EXPAND is overloaded and used for two purposes. --=20 2.31.0