From patchwork Thu Mar 28 20:39:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13609601 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C0AA13A879 for ; Thu, 28 Mar 2024 20:39:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658392; cv=none; b=EUYaNcss7MwNrGn6M41xgJrgiayf7RJveIjdDqozflsNH6/7XScHYGfDeDaKFdzVwRRPr2wjfaUqq3DOCKsv+jvfzlfqalDyR4wQEz7/bck/1EXDyuMqAxjc4X12qFqswU+5nqFhh/WYqm4jrvvKM/0toR9/8bG02JfC4ALzXdc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658392; c=relaxed/simple; bh=Z/9BALdmqq/q3tmjj2QgJEd4wnfZA9Ii706QeBSvW/w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OP7/qXmP4+oay8DazXwVvCCkuUJF9p5Vy18cFKDPeGAmupgCmwcDTL/oktW6sM8L2a4qMRvHri11UprAw6XTM7FRlU3CUXt+q9SA7gh2papT6XYJTwjt96/CToNeDy+eJlkErz0PjwGNsebCkRCpX+OhQlLYb1TXhbhhOVndobg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=QEZ1G5FZ; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="QEZ1G5FZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1711658390; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ifdaXHJafNhgJEodv1uxro7ZmRQAOz8+u7BNkXOalBo=; b=QEZ1G5FZ2vWF9jfR84zg1Rvli180LBl1uvUGYmw5BbSAGIQvdphmUSZUiJOnQFok0DweJB autHHgHYoPl8HVi8ooQuWy/uLT9FqAf1p76ymFeiWxMCKKVwCIqRFxXf8eERfxccchhnLX 4FYv46cyIND5SRki7Gzvvk7hR473rFI= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-492-EC1kfjvMNx-NTQDJ-Tmc6A-1; Thu, 28 Mar 2024 16:39:46 -0400 X-MC-Unique: EC1kfjvMNx-NTQDJ-Tmc6A-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id CAC9A1C2CDF2; Thu, 28 Mar 2024 20:39:45 +0000 (UTC) Received: from localhost (unknown [10.39.194.117]) by smtp.corp.redhat.com (Postfix) with ESMTP id C12A3492BDA; Thu, 28 Mar 2024 20:39:44 +0000 (UTC) From: Stefan Hajnoczi To: linux-block@vger.kernel.org Cc: linux-kernel@vger.kernel.org, eblake@redhat.com, Alasdair Kergon , Mikulas Patocka , dm-devel@lists.linux.dev, David Teigland , Mike Snitzer , Jens Axboe , Christoph Hellwig , Joe Thornber , Stefan Hajnoczi Subject: [RFC 1/9] block: add llseek(SEEK_HOLE/SEEK_DATA) support Date: Thu, 28 Mar 2024 16:39:02 -0400 Message-ID: <20240328203910.2370087-2-stefanha@redhat.com> In-Reply-To: <20240328203910.2370087-1-stefanha@redhat.com> References: <20240328203910.2370087-1-stefanha@redhat.com> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.10 The SEEK_HOLE/SEEK_DATA interface is used by userspace applications to detect sparseness. This makes copying and backup applications faster and reduces space consumption because only ranges that do not contain data can be skipped. Handle SEEK_HOLE/SEEK_DATA for block devices. No block drivers implement the new callback yet so the entire block device will appear to contain data. Later patches will add support to drivers so this actually becomes useful. Signed-off-by: Stefan Hajnoczi --- include/linux/blkdev.h | 7 +++++++ block/fops.c | 43 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index c3e8f7cf96be9..eecfbf9c27fc4 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -332,6 +332,9 @@ int blkdev_zone_mgmt(struct block_device *bdev, enum req_op op, int blk_revalidate_disk_zones(struct gendisk *disk, void (*update_driver_data)(struct gendisk *disk)); +loff_t blkdev_seek_hole_data(struct block_device *bdev, loff_t offset, + int whence); + /* * Independent access ranges: struct blk_independent_access_range describes * a range of contiguous sectors that can be accessed using device command @@ -1432,6 +1435,10 @@ struct block_device_operations { * driver. */ int (*alternative_gpt_sector)(struct gendisk *disk, sector_t *sector); + + /* Like llseek(SEEK_HOLE/SEEK_DATA). This callback may be NULL. */ + loff_t (*seek_hole_data)(struct block_device *bdev, loff_t offset, + int whence); }; #ifdef CONFIG_COMPAT diff --git a/block/fops.c b/block/fops.c index 679d9b752fe82..8ffbfec6b4c25 100644 --- a/block/fops.c +++ b/block/fops.c @@ -523,6 +523,43 @@ const struct address_space_operations def_blk_aops = { }; #endif /* CONFIG_BUFFER_HEAD */ +/* Like llseek(SEEK_HOLE/SEEK_DATA) */ +loff_t blkdev_seek_hole_data(struct block_device *bdev, loff_t offset, + int whence) +{ + const struct block_device_operations *fops = bdev->bd_disk->fops; + loff_t size; + + if (fops->seek_hole_data) + return fops->seek_hole_data(bdev, offset, whence); + + size = bdev_nr_bytes(bdev); + + switch (whence) { + case SEEK_DATA: + if ((unsigned long long)offset >= size) + return -ENXIO; + return offset; + case SEEK_HOLE: + if ((unsigned long long)offset >= size) + return -ENXIO; + return size; + default: + return -EINVAL; + } +} + +static loff_t blkdev_llseek_hole_data(struct file *file, loff_t offset, + int whence) +{ + struct block_device *bdev = file_bdev(file); + + offset = blkdev_seek_hole_data(bdev, offset, whence); + if (offset >= 0) + offset = vfs_setpos(file, offset, bdev_nr_bytes(bdev)); + return offset; +} + /* * for a block special file file_inode(file)->i_size is zero * so we compute the size by hand (just as in block_read/write above) @@ -533,7 +570,11 @@ static loff_t blkdev_llseek(struct file *file, loff_t offset, int whence) loff_t retval; inode_lock(bd_inode); - retval = fixed_size_llseek(file, offset, whence, i_size_read(bd_inode)); + if (whence == SEEK_HOLE || whence == SEEK_DATA) + retval = blkdev_llseek_hole_data(file, offset, whence); + else + retval = fixed_size_llseek(file, offset, whence, + i_size_read(bd_inode)); inode_unlock(bd_inode); return retval; } From patchwork Thu Mar 28 20:39:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13609602 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5B38A13A250 for ; Thu, 28 Mar 2024 20:39:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658400; cv=none; b=SZn3YxTcf3VbtrgiKHaVT+c2r2xGOfKLA91neywKa4XCC4q6bZ7JXxaGtayxcOIcJQ5I9p+cVhekhGZqXUbON5yjnfmOr1RqGE2gSsukmFQGB+I0br6Lawooi1rN1ko3AACArpnrKWML87s/B5gGRqUXfEVv1L2UESjQuZUtzRA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658400; c=relaxed/simple; bh=9TzmnhsUKTbqm3MBDZcbvUahak/Gsv0zqkL0N7t7Zn8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EJ/5NSYRtgBTZFnEIpvKaUnUoLpkx7lo+UONfXzfD/GLXgOwLer7n8KMrtyEtM3WH1GR5QU+rqLwbiLFYwWG1niM+4a4BzPmtirpUVR1chVHqZbX2bfoIQpmRUgwrZqv5grJ92W1wv9IIOeHEyhIt3li/dW2Jq3H598j/Xd4Zi4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=ilbJisdy; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="ilbJisdy" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1711658397; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=g4rLC5S75oEgMAlRnRiGxyXHyD4Dy8z12uj2IyMw9Nc=; b=ilbJisdy4NpmxD3zqpl77476xQADEaJ/CT0ytc/wYAJ+razz4XqMF+LCQU57e8FWpar90H Bm4V62gxSTwIkkE/Ds1ymJj3URd0py1af0Ck4+12DbMfLsCejQtw02HpavdMGi3nsRtYZV ScBcgSimNoiEPWDjx/Gb2S6V5JYk+a0= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-642-TPsvWD4yNkqI23cHGTHb_Q-1; Thu, 28 Mar 2024 16:39:52 -0400 X-MC-Unique: TPsvWD4yNkqI23cHGTHb_Q-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5D8DF185A786; Thu, 28 Mar 2024 20:39:52 +0000 (UTC) Received: from localhost (unknown [10.39.194.117]) by smtp.corp.redhat.com (Postfix) with ESMTP id B501E1C060DC; Thu, 28 Mar 2024 20:39:50 +0000 (UTC) From: Stefan Hajnoczi To: linux-block@vger.kernel.org Cc: linux-kernel@vger.kernel.org, eblake@redhat.com, Alasdair Kergon , Mikulas Patocka , dm-devel@lists.linux.dev, David Teigland , Mike Snitzer , Jens Axboe , Christoph Hellwig , Joe Thornber , Stefan Hajnoczi Subject: [RFC 2/9] loop: add llseek(SEEK_HOLE/SEEK_DATA) support Date: Thu, 28 Mar 2024 16:39:03 -0400 Message-ID: <20240328203910.2370087-3-stefanha@redhat.com> In-Reply-To: <20240328203910.2370087-1-stefanha@redhat.com> References: <20240328203910.2370087-1-stefanha@redhat.com> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 Signed-off-by: Stefan Hajnoczi --- Open issues: - The file offset is updated on both the blkdev file and the backing file. Is there a way to avoid updating the backing file offset so the file opened by userspace is not affected? - Should this run in the worker or use the cgroups? --- drivers/block/loop.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 28a95fd366fea..6a89375de82e8 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -750,6 +750,29 @@ static void loop_sysfs_exit(struct loop_device *lo) &loop_attribute_group); } +static loff_t lo_seek_hole_data(struct block_device *bdev, loff_t offset, + int whence) +{ + /* TODO need to activate cgroups or use worker? */ + /* TODO locking? */ + struct loop_device *lo = bdev->bd_disk->private_data; + struct file *file = lo->lo_backing_file; + + if (lo->lo_offset > 0) + offset += lo->lo_offset; /* TODO underflow/overflow? */ + + /* TODO backing file offset is modified! */ + offset = vfs_llseek(file, offset, whence); + if (offset < 0) + return offset; + + if (lo->lo_offset > 0) + offset -= lo->lo_offset; /* TODO underflow/overflow? */ + if (lo->lo_sizelimit > 0 && offset > lo->lo_sizelimit) + offset = lo->lo_sizelimit; + return offset; +} + static void loop_config_discard(struct loop_device *lo, struct queue_limits *lim) { @@ -1751,13 +1774,14 @@ static void lo_free_disk(struct gendisk *disk) } static const struct block_device_operations lo_fops = { - .owner = THIS_MODULE, - .release = lo_release, - .ioctl = lo_ioctl, + .owner = THIS_MODULE, + .release = lo_release, + .ioctl = lo_ioctl, #ifdef CONFIG_COMPAT - .compat_ioctl = lo_compat_ioctl, + .compat_ioctl = lo_compat_ioctl, #endif - .free_disk = lo_free_disk, + .free_disk = lo_free_disk, + .seek_hole_data = lo_seek_hole_data, }; /* @@ -2140,7 +2164,7 @@ static int loop_control_remove(int idx) pr_warn_once("deleting an unspecified loop device is not supported.\n"); return -EINVAL; } - + /* Hide this loop device for serialization. */ ret = mutex_lock_killable(&loop_ctl_mutex); if (ret) From patchwork Thu Mar 28 20:39:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13609603 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B7D1A13A3F5 for ; Thu, 28 Mar 2024 20:40:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658405; cv=none; b=PJGvRvkmCjvH1xDyipXO7Oc3HDp5c825ntovBWqTRpewAEXkx0jtfXSgEk3Qd7Vi/ThrfvbXGHTblasa58vwy0AY/h2rI25sK4xLgYxH6TJo/THP9JL1b4XddUaZhGSSVyMMgIroADWMtFAo8p09odaSCIdkkiD3+YPQPVVMaeE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658405; c=relaxed/simple; bh=Rp9w8RwSy/4Z0Y7bMy5x7qlp6KJE9aJoHoyuWIitvzQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cfh05CcoVf4xSiI6uNiXEEcXLHfeSnzdvFb96uMLigQi9ATL/xzf9wRLDrILXdrjX+zPe9y7LOssKmKb4+xQLT3XRmBmQKdBmsqcOpL1+hJsDebi7516y8B3cO3gpKACeEryEU3uVEPxRvIPBXBlzu4yrTkWjsnRlLu+FWITyko= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=icZCihKX; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="icZCihKX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1711658402; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sjBz1KrK98sVajIv7PgdUWh+8H9rTGPZ9ES9DnhFZf8=; b=icZCihKXUCLbOBK7p5WjkaN6kskc/xrNuHxkWnRA6QTVaClRo2xyadpRAFKv0vQAHmnGqH 3jrcmJ+Hskquzo4Y+xPbDF1yK62emEt0cFGZw/gUtgdBDWk+hz+h24gnaQYmh7AYBOEsh7 wX2AvpddsDIFO4CTZe0cvRCEWUrlDBw= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-63-wEWhjZfMPkOYk_YV6Rw3gw-1; Thu, 28 Mar 2024 16:39:59 -0400 X-MC-Unique: wEWhjZfMPkOYk_YV6Rw3gw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id E4D0085A58B; Thu, 28 Mar 2024 20:39:58 +0000 (UTC) Received: from localhost (unknown [10.39.194.117]) by smtp.corp.redhat.com (Postfix) with ESMTP id C2C792166B35; Thu, 28 Mar 2024 20:39:57 +0000 (UTC) From: Stefan Hajnoczi To: linux-block@vger.kernel.org Cc: linux-kernel@vger.kernel.org, eblake@redhat.com, Alasdair Kergon , Mikulas Patocka , dm-devel@lists.linux.dev, David Teigland , Mike Snitzer , Jens Axboe , Christoph Hellwig , Joe Thornber , Stefan Hajnoczi Subject: [RFC 3/9] selftests: block_seek_hole: add loop block driver tests Date: Thu, 28 Mar 2024 16:39:04 -0400 Message-ID: <20240328203910.2370087-4-stefanha@redhat.com> In-Reply-To: <20240328203910.2370087-1-stefanha@redhat.com> References: <20240328203910.2370087-1-stefanha@redhat.com> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.6 Run the tests with: $ make TARGETS=block_seek_hole -C tools/selftests run_tests Signed-off-by: Stefan Hajnoczi --- tools/testing/selftests/Makefile | 1 + .../selftests/block_seek_hole/Makefile | 17 +++ .../testing/selftests/block_seek_hole/config | 1 + .../selftests/block_seek_hole/map_holes.py | 37 +++++++ .../testing/selftests/block_seek_hole/test.py | 103 ++++++++++++++++++ 5 files changed, 159 insertions(+) create mode 100644 tools/testing/selftests/block_seek_hole/Makefile create mode 100644 tools/testing/selftests/block_seek_hole/config create mode 100755 tools/testing/selftests/block_seek_hole/map_holes.py create mode 100755 tools/testing/selftests/block_seek_hole/test.py diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index e1504833654db..8a21d6031b940 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -2,6 +2,7 @@ TARGETS += alsa TARGETS += amd-pstate TARGETS += arm64 +TARGETS += block_seek_hole TARGETS += bpf TARGETS += breakpoints TARGETS += cachestat diff --git a/tools/testing/selftests/block_seek_hole/Makefile b/tools/testing/selftests/block_seek_hole/Makefile new file mode 100644 index 0000000000000..3f4bbd52db29f --- /dev/null +++ b/tools/testing/selftests/block_seek_hole/Makefile @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0-only +PY3 = $(shell which python3 2>/dev/null) + +ifneq ($(PY3),) + +TEST_PROGS := test.py + +include ../lib.mk + +else + +all: no_py3_warning + +no_py3_warning: + @echo "Missing python3. This test will be skipped." + +endif diff --git a/tools/testing/selftests/block_seek_hole/config b/tools/testing/selftests/block_seek_hole/config new file mode 100644 index 0000000000000..72437e0c0fc1c --- /dev/null +++ b/tools/testing/selftests/block_seek_hole/config @@ -0,0 +1 @@ +CONFIG_BLK_DEV_LOOP=m diff --git a/tools/testing/selftests/block_seek_hole/map_holes.py b/tools/testing/selftests/block_seek_hole/map_holes.py new file mode 100755 index 0000000000000..9477ec5d69d3a --- /dev/null +++ b/tools/testing/selftests/block_seek_hole/map_holes.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-only +# +# map_holes.py +# +# Print the holes and data ranges in a file. + +import errno +import os +import sys + +def map_holes(fd): + end = os.lseek(fd, 0, os.SEEK_END) + offset = 0 + + print('TYPE START END SIZE') + + while offset < end: + contents = 'DATA' + new_offset = os.lseek(fd, offset, os.SEEK_HOLE) + if new_offset == offset: + contents = 'HOLE' + try: + new_offset = os.lseek(fd, offset, os.SEEK_DATA) + except OSError as err: + if err.errno == errno.ENXIO: + new_offset = end + else: + raise err + assert new_offset != offset + print(f'{contents} {offset} {new_offset} {new_offset - offset}') + offset = new_offset + +if __name__ == '__main__': + with open(sys.argv[1], 'rb') as f: + fd = f.fileno() + map_holes(fd) diff --git a/tools/testing/selftests/block_seek_hole/test.py b/tools/testing/selftests/block_seek_hole/test.py new file mode 100755 index 0000000000000..4f7c2d01ab3d3 --- /dev/null +++ b/tools/testing/selftests/block_seek_hole/test.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-only +# +# test.py +# +# Test SEEK_HOLE/SEEK_DATA support in block drivers + +import os +import subprocess +import sys +from contextlib import contextmanager + +KB = 1024 +MB = 1024 * KB + +def run(args): + try: + cmd = subprocess.run(args, check=True, capture_output=True) + except subprocess.CalledProcessError as e: + print(e) + print(e.stderr.decode('utf-8').strip()) + sys.exit(1) + return cmd + +@contextmanager +def test_file(layout_fn, prefix='test'): + '''A context manager that creates a test file and produces its path''' + path = f'{prefix}-{os.getpid()}' + with open(path, 'w+b') as f: + layout_fn(f) + + try: + yield path + finally: + os.unlink(path) + +@contextmanager +def loop_device(file_path): + '''A context manager that attaches a loop device for a given file and produces the path of the loop device''' + cmd = run(['losetup', '--show', '-f', file_path]) + loop_path = os.fsdecode(cmd.stdout.strip()) + + try: + yield loop_path + finally: + run(['losetup', '-d', loop_path]) + +def test(layout, dev_context_manager): + with test_file(layout) as file_path, dev_context_manager(file_path) as dev_path: + cmd = run(['./map_holes.py', file_path]) + file_output = cmd.stdout.decode('utf-8').strip() + + cmd = run(['./map_holes.py', dev_path]) + dev_output = cmd.stdout.decode('utf-8').strip() + + if file_output != dev_output: + print(f'FAIL {dev_context_manager.__name__} {layout.__name__}') + print('File output:') + print(file_output) + print('Does not match device output:') + print(dev_output) + sys.exit(1) + +def test_all(layouts, dev_context_managers): + for dev_context_manager in dev_context_managers: + for layout in layouts: + test(layout, dev_context_manager) + +# Different data layouts to test + +def data_at_beginning_and_end(f): + f.write(b'A' * 4 * KB) + f.seek(256 * MB) + + f.write(b'B' * 64 * KB) + + f.seek(1024 * MB - KB) + f.write(b'C' * KB) + +def holes_at_beginning_and_end(f): + f.seek(128 * MB) + f.write(b'A' * 4 * KB) + + f.seek(512 * MB) + f.write(b'B' * 64 * KB) + + f.truncate(1024 * MB) + +def no_holes(f): + # Just 1 MB so test file generation is quick + mb = b'A' * MB + f.write(mb) + +def empty_file(f): + f.truncate(1024 * MB) + +if __name__ == '__main__': + layouts = [data_at_beginning_and_end, + holes_at_beginning_and_end, + no_holes, + empty_file] + dev_context_managers = [loop_device] + test_all(layouts, dev_context_managers) From patchwork Thu Mar 28 20:39:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13609604 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7346B13B5AD for ; Thu, 28 Mar 2024 20:40:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658411; cv=none; b=FYACGsStYdFHyDDQM3LUD5IFc0b1+PVRhIIZfosF0RzDRcpee9EPM6Qe5kcOhQjrj0NKwcbdwlTVyZQCqXoA2KciZTinggtpU6i1mpdoXy8PXwrtHV8pYzA5AbBKLPng4w4QCYEnfwDv+DIsBKTFClhH+7BOyD2+fe0FMNbBauI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658411; c=relaxed/simple; bh=5/XIIKiTB1kK6mCedHSlUjddeWaCgNaGwQ7W/dFaZPQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VDgX8xwzJu0a4VTcs9OLp6qnImPIIIEb+4lLj9gx10/9gzx5Mkw4Fmo6gr37g83R89N3JnsBDgMlpq0CbAvw+eIgJvG3X19NPt6z8uOQ29RW3y4fJvT/RDSFRpyD3fu9r2vEYRDf2BxFei+8KUQ7aDJqKON3HsFezmzxl1UTqT4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=RlVvCpUn; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="RlVvCpUn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1711658408; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=O2S5dlufkY7ji1jTEmuLexd5aljX5StH7MYrMWEnyTc=; b=RlVvCpUn3mqmI+KgqWey/npCb7ke2TrnIIgN/k7i5PydkoFZvmWSF1IJNRX5o4AfkcjKp9 ErWjcV2Br6Ykc5iYjEn8yW4exLi2UWlUWo3mdDoIpLo2otOVbE/8YW/2WQz3TpASy/65dx cWBkClT9T92k61KQfChYQ+0N6lyORz4= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-582-8_4MxpuOPVm5kw_6Dhr1YQ-1; Thu, 28 Mar 2024 16:40:06 -0400 X-MC-Unique: 8_4MxpuOPVm5kw_6Dhr1YQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C38E1185A781; Thu, 28 Mar 2024 20:40:05 +0000 (UTC) Received: from localhost (unknown [10.39.194.117]) by smtp.corp.redhat.com (Postfix) with ESMTP id D1E612166B35; Thu, 28 Mar 2024 20:40:04 +0000 (UTC) From: Stefan Hajnoczi To: linux-block@vger.kernel.org Cc: linux-kernel@vger.kernel.org, eblake@redhat.com, Alasdair Kergon , Mikulas Patocka , dm-devel@lists.linux.dev, David Teigland , Mike Snitzer , Jens Axboe , Christoph Hellwig , Joe Thornber , Stefan Hajnoczi Subject: [RFC 4/9] dm: add llseek(SEEK_HOLE/SEEK_DATA) support Date: Thu, 28 Mar 2024 16:39:05 -0400 Message-ID: <20240328203910.2370087-5-stefanha@redhat.com> In-Reply-To: <20240328203910.2370087-1-stefanha@redhat.com> References: <20240328203910.2370087-1-stefanha@redhat.com> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.6 Delegate SEEK_HOLE/SEEK_DATA to device-mapper targets. The new dm_seek_hole_data() callback allows target types to customize behavior. The default implementation treats the target as all data with no holes. Signed-off-by: Stefan Hajnoczi --- include/linux/device-mapper.h | 5 +++ drivers/md/dm.c | 68 +++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 82b2195efaca7..e89ebaab6507a 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -161,6 +161,10 @@ typedef int (*dm_dax_zero_page_range_fn)(struct dm_target *ti, pgoff_t pgoff, typedef size_t (*dm_dax_recovery_write_fn)(struct dm_target *ti, pgoff_t pgoff, void *addr, size_t bytes, struct iov_iter *i); +/* Like llseek(SEEK_HOLE/SEEK_DATA) */ +typedef loff_t (*dm_seek_hole_data)(struct dm_target *ti, loff_t offset, + int whence); + void dm_error(const char *message); struct dm_dev { @@ -210,6 +214,7 @@ struct target_type { dm_dax_direct_access_fn direct_access; dm_dax_zero_page_range_fn dax_zero_page_range; dm_dax_recovery_write_fn dax_recovery_write; + dm_seek_hole_data seek_hole_data; /* For internal device-mapper use. */ struct list_head list; diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 56aa2a8b9d715..3c921bdbd17fc 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -3167,6 +3167,72 @@ void dm_free_md_mempools(struct dm_md_mempools *pools) kfree(pools); } +/* Default implementation for targets that do not implement the callback */ +static loff_t dm_blk_seek_hole_data_default(loff_t offset, int whence, + loff_t size) +{ + switch (whence) { + case SEEK_DATA: + if ((unsigned long long)offset >= size) + return -ENXIO; + return offset; + case SEEK_HOLE: + if ((unsigned long long)offset >= size) + return -ENXIO; + return size; + default: + return -EINVAL; + } +} + +static loff_t dm_blk_do_seek_hole_data(struct dm_table *table, loff_t offset, + int whence) +{ + struct dm_target *ti; + loff_t end; + + /* Loop when the end of a target is reached */ + do { + ti = dm_table_find_target(table, offset >> SECTOR_SHIFT); + if (!ti) + return whence == SEEK_DATA ? -ENXIO : offset; + + end = (ti->begin + ti->len) << SECTOR_SHIFT; + + if (ti->type->seek_hole_data) + offset = ti->type->seek_hole_data(ti, offset, whence); + else + offset = dm_blk_seek_hole_data_default(offset, whence, end); + + if (whence == SEEK_DATA && offset == -ENXIO) + offset = end; + } while (offset == end); + + return offset; +} + +static loff_t dm_blk_seek_hole_data(struct block_device *bdev, loff_t offset, + int whence) +{ + struct mapped_device *md = bdev->bd_disk->private_data; + struct dm_table *table; + int srcu_idx; + loff_t ret; + + if (dm_suspended_md(md)) + return -EAGAIN; + + table = dm_get_live_table(md, &srcu_idx); + if (!table) + return -EIO; + + ret = dm_blk_do_seek_hole_data(table, offset, whence); + + dm_put_live_table(md, srcu_idx); + + return ret; +} + struct dm_pr { u64 old_key; u64 new_key; @@ -3493,6 +3559,7 @@ static const struct block_device_operations dm_blk_dops = { .getgeo = dm_blk_getgeo, .report_zones = dm_blk_report_zones, .pr_ops = &dm_pr_ops, + .seek_hole_data = dm_blk_seek_hole_data, .owner = THIS_MODULE }; @@ -3502,6 +3569,7 @@ static const struct block_device_operations dm_rq_blk_dops = { .ioctl = dm_blk_ioctl, .getgeo = dm_blk_getgeo, .pr_ops = &dm_pr_ops, + .seek_hole_data = dm_blk_seek_hole_data, .owner = THIS_MODULE }; From patchwork Thu Mar 28 20:39:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13609605 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AC2B013AA2D for ; Thu, 28 Mar 2024 20:40:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658419; cv=none; b=lz8UUcFSucDZv3y5oPIzzGgtQwT4WiED+YA8IgXGNsdYWdPm3mkHiWI8ZlZx62U3F6CqMCu3Lteb4fN/p9Cl8PQ8bZkP+9IPNGHWVnMOrG8IAxWgqyeOYEjnvYkh+aZ0ZRiI6mauuuVGVi53+8o8kHNca6CwjRI33dHc3Lm4dJY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658419; c=relaxed/simple; bh=FlivA4yfGfFdJLo5ECHK0IC8x6gx23qUTsMI8w0FX6A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tmzaikw5IjsmheWCTdZcVeBeAfQmhjRUv0nL+cFcBf/Y7CaZxWXAxDUrwb8RqkCbvAmZT5/gQZ9ktFxgLVk82qnvXe2gPIDYh6ptyjuWag5IHBdYJ+fgi5ObJ4eGIUpaIsY/XRGA4msY6edJ2cL+amY6K7pfrLreWh0c1B8l+8c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=FELyqegE; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="FELyqegE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1711658416; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pLyw7KMUSkZphXtYRA9aQyoROjVXRJ0JkZ6RNSfd43U=; b=FELyqegEbVpa0uH5JmewyaPisuuqMOt2GyVSisJB1iEJKre8dCXWLzZBuSJIb+Ti5iZI5a y5WF54hmtVttuLtxAuX3Y4ij4GA87b1mjNr/16NQ+0aHiylB8ztOwMXpV6ydqJ4m1Pb/8j HxA+HFGrc9WbDDUVqPOFWZ38IL5BSjU= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-327-01rxHV2tPM2OivYrAooexw-1; Thu, 28 Mar 2024 16:40:13 -0400 X-MC-Unique: 01rxHV2tPM2OivYrAooexw-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id EB8B788905A; Thu, 28 Mar 2024 20:40:12 +0000 (UTC) Received: from localhost (unknown [10.39.194.117]) by smtp.corp.redhat.com (Postfix) with ESMTP id C87C7492BC8; Thu, 28 Mar 2024 20:40:11 +0000 (UTC) From: Stefan Hajnoczi To: linux-block@vger.kernel.org Cc: linux-kernel@vger.kernel.org, eblake@redhat.com, Alasdair Kergon , Mikulas Patocka , dm-devel@lists.linux.dev, David Teigland , Mike Snitzer , Jens Axboe , Christoph Hellwig , Joe Thornber , Stefan Hajnoczi Subject: [RFC 5/9] selftests: block_seek_hole: add dm-zero test Date: Thu, 28 Mar 2024 16:39:06 -0400 Message-ID: <20240328203910.2370087-6-stefanha@redhat.com> In-Reply-To: <20240328203910.2370087-1-stefanha@redhat.com> References: <20240328203910.2370087-1-stefanha@redhat.com> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.9 Signed-off-by: Stefan Hajnoczi --- .../selftests/block_seek_hole/Makefile | 2 +- .../testing/selftests/block_seek_hole/config | 2 ++ .../selftests/block_seek_hole/dm_zero.sh | 31 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100755 tools/testing/selftests/block_seek_hole/dm_zero.sh diff --git a/tools/testing/selftests/block_seek_hole/Makefile b/tools/testing/selftests/block_seek_hole/Makefile index 3f4bbd52db29f..1bd9e748b2acc 100644 --- a/tools/testing/selftests/block_seek_hole/Makefile +++ b/tools/testing/selftests/block_seek_hole/Makefile @@ -3,7 +3,7 @@ PY3 = $(shell which python3 2>/dev/null) ifneq ($(PY3),) -TEST_PROGS := test.py +TEST_PROGS := test.py dm_zero.sh include ../lib.mk diff --git a/tools/testing/selftests/block_seek_hole/config b/tools/testing/selftests/block_seek_hole/config index 72437e0c0fc1c..bfd59f1d98769 100644 --- a/tools/testing/selftests/block_seek_hole/config +++ b/tools/testing/selftests/block_seek_hole/config @@ -1 +1,3 @@ CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_ZERO=m diff --git a/tools/testing/selftests/block_seek_hole/dm_zero.sh b/tools/testing/selftests/block_seek_hole/dm_zero.sh new file mode 100755 index 0000000000000..20836a566fcc8 --- /dev/null +++ b/tools/testing/selftests/block_seek_hole/dm_zero.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# +# dm_zero.sh +# +# Test that dm-zero reports data because it does not have a custom +# SEEK_HOLE/SEEK_DATA implementation. + +set -e + +dev_name=test-$$ +size=$((1024 * 1024 * 1024 / 512)) # 1 GB + +cleanup() { + dmsetup remove $dev_name +} +trap cleanup EXIT + +dmsetup create $dev_name --table "0 $size zero" + +output=$(./map_holes.py /dev/mapper/$dev_name) +expected='TYPE START END SIZE +DATA 0 1073741824 1073741824' + +if [ "$output" != "$expected" ]; then + echo 'FAIL expected:' + echo "$expected" + echo 'Does not match device output:' + echo "$output" + exit 1 +fi From patchwork Thu Mar 28 20:39:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13609606 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 367CF13AA48 for ; Thu, 28 Mar 2024 20:40:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658426; cv=none; b=PMtpX7JeZZWcPcKCqRXRb7qPqrt3XArnv6ZtlJN+7bkvvYcNpXvNwSnojo0eA+Cr0Z9euSwY0UYLdewWD1/sRJ+aSJ8eT7AhymFZzNmAc14qrkxYVKkCWv2Z4guwl2mCyxfdV11q7oQARa/AkP5hjFKHYvJ6kWKOq5X9kbyw7Rw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658426; c=relaxed/simple; bh=9Z6YD6FPCzBTKeIPm1fHe9GnkbXDhxoo7eDcvyUvuCs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JwwcVYaNileKZAEXDK09ujiq3h4sF9MbeFPG3CALqqdYVfw7HLINB+mSLZyzK3yZNu3M2hRfS7UxxVSYqY/9pAIRP5BTgc+LFu5++FwgjkB4oeF3MY8Xndx8eQt9d0MX3ZOTZ3DtO3BAyNiDUnHpjtzSNJfqDKw4awEtPcFlIfU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Y9YL/Hgj; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Y9YL/Hgj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1711658424; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NXXER/zigpP/1IR48CBo1zF8A1UxNQTU4ClNAQkl164=; b=Y9YL/HgjjPxfYCZDl767fff+NePAiuupg5PsmF7Ynm8ttbtCXYySJ4Z005lxl7O6AL8iqR n4B+Hd+hDFuS+tckyouIuNXd1Wes+Ayz1UqIrh2Kc7K7OLjjUMqt2CusYxW0qXyeRgqlux 4dOcioqxI6qTGV4uvXdYdkWsb9w/T0Y= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-595-5C6a797YMhSPfEhO_58Kmg-1; Thu, 28 Mar 2024 16:40:20 -0400 X-MC-Unique: 5C6a797YMhSPfEhO_58Kmg-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 50E4888905E; Thu, 28 Mar 2024 20:40:20 +0000 (UTC) Received: from localhost (unknown [10.39.194.117]) by smtp.corp.redhat.com (Postfix) with ESMTP id 474F3C1576F; Thu, 28 Mar 2024 20:40:18 +0000 (UTC) From: Stefan Hajnoczi To: linux-block@vger.kernel.org Cc: linux-kernel@vger.kernel.org, eblake@redhat.com, Alasdair Kergon , Mikulas Patocka , dm-devel@lists.linux.dev, David Teigland , Mike Snitzer , Jens Axboe , Christoph Hellwig , Joe Thornber , Stefan Hajnoczi Subject: [RFC 6/9] dm-linear: add llseek(SEEK_HOLE/SEEK_DATA) support Date: Thu, 28 Mar 2024 16:39:07 -0400 Message-ID: <20240328203910.2370087-7-stefanha@redhat.com> In-Reply-To: <20240328203910.2370087-1-stefanha@redhat.com> References: <20240328203910.2370087-1-stefanha@redhat.com> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.8 Signed-off-by: Stefan Hajnoczi --- drivers/md/dm-linear.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 2d3e186ca87e3..9b6cdfa4f951d 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -147,6 +147,30 @@ static int linear_report_zones(struct dm_target *ti, #define linear_report_zones NULL #endif +static loff_t linear_seek_hole_data(struct dm_target *ti, loff_t offset, + int whence) +{ + struct linear_c *lc = ti->private; + loff_t ti_begin = ti->begin << SECTOR_SHIFT; + loff_t ti_len = ti->len << SECTOR_SHIFT; + loff_t bdev_start = lc->start << SECTOR_SHIFT; + loff_t bdev_offset; + + /* TODO underflow/overflow? */ + bdev_offset = offset - ti_begin + bdev_start; + + bdev_offset = blkdev_seek_hole_data(lc->dev->bdev, bdev_offset, + whence); + if (bdev_offset < 0) + return bdev_offset; + + offset = bdev_offset - bdev_start; + if (offset >= ti_len) + return whence == SEEK_DATA ? -ENXIO : ti_begin + ti_len; + + return offset + ti_begin; +} + static int linear_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) { @@ -212,6 +236,7 @@ static struct target_type linear_target = { .direct_access = linear_dax_direct_access, .dax_zero_page_range = linear_dax_zero_page_range, .dax_recovery_write = linear_dax_recovery_write, + .seek_hole_data = linear_seek_hole_data, }; int __init dm_linear_init(void) From patchwork Thu Mar 28 20:39:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13609607 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0981D13A879 for ; Thu, 28 Mar 2024 20:40:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658431; cv=none; b=GRQLKPSCqRtGWCt8qPqPZ/j0LwnyiaFX+L3ZuVd4b1Irh2l/QPscRCwcZu0W3900/eKbB9kfnOhnBIJteVotXgBKdiCo50WCicH+naVtNdPNIH+nFqo+9F2weBrRIgYw1t6tNZOCa4qzinc2PVMi8k6S+NelP3veZ4/HZBvSONQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658431; c=relaxed/simple; bh=FebcY8GW4qSxZjt6PKBKn/4SmoqAJZOlJIPy8dlvqF0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ljQuGajRRdi3pS2FhIVOR0QVOoSMm6zPOmNiDKeHvh5RmGQmHvE7haGSeA9ZL47HxbSNo6EsyCawcOoQRyKDTEvaPwdUCdCKg3eASpWekVceaN59I2qL/8TjTUxwohMlP1WYLBMtSXTsatmDHekfbvaNbFAOeQf/lv1Hc9NjhJ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=L4A91fs0; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="L4A91fs0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1711658429; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Nu/r5NDd0Gy6+JgiI/0jpbuTZcHkzRRhPWBk6MBfw3I=; b=L4A91fs0QJcFnyulQLl0CQqxB6teXzvIu7xR+hfhUS/Wims1LP6g20fDELYt8FpTPBHEdn apvAxWGhZocjLVBpRe77XoFiUcNt2UEuwDl9ZK3hq8GsdOxSDTZgTxB0uKXmsC+Ue6654M mYj6Eaj0s6Siq15vg/J9rCxOIkhJCQg= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-507-IncmixdjM7iaA-qSd38v7g-1; Thu, 28 Mar 2024 16:40:26 -0400 X-MC-Unique: IncmixdjM7iaA-qSd38v7g-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5E2142802267; Thu, 28 Mar 2024 20:40:26 +0000 (UTC) Received: from localhost (unknown [10.39.194.117]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5233FC1576F; Thu, 28 Mar 2024 20:40:25 +0000 (UTC) From: Stefan Hajnoczi To: linux-block@vger.kernel.org Cc: linux-kernel@vger.kernel.org, eblake@redhat.com, Alasdair Kergon , Mikulas Patocka , dm-devel@lists.linux.dev, David Teigland , Mike Snitzer , Jens Axboe , Christoph Hellwig , Joe Thornber , Stefan Hajnoczi Subject: [RFC 7/9] selftests: block_seek_hole: add dm-linear test Date: Thu, 28 Mar 2024 16:39:08 -0400 Message-ID: <20240328203910.2370087-8-stefanha@redhat.com> In-Reply-To: <20240328203910.2370087-1-stefanha@redhat.com> References: <20240328203910.2370087-1-stefanha@redhat.com> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.8 The dm-linear linear target passes through SEEK_HOLE/SEEK_DATA. Extend the test case to check that the same holes/data are reported as for the underlying file. Signed-off-by: Stefan Hajnoczi --- tools/testing/selftests/block_seek_hole/test.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/block_seek_hole/test.py b/tools/testing/selftests/block_seek_hole/test.py index 4f7c2d01ab3d3..6360b72aee338 100755 --- a/tools/testing/selftests/block_seek_hole/test.py +++ b/tools/testing/selftests/block_seek_hole/test.py @@ -45,6 +45,20 @@ def loop_device(file_path): finally: run(['losetup', '-d', loop_path]) +@contextmanager +def dm_linear(file_path): + file_size = os.path.getsize(file_path) + + with loop_device(file_path) as loop_path: + dm_name = f'test-{os.getpid()}' + run(['dmsetup', 'create', dm_name, '--table', + f'0 {file_size // 512} linear {loop_path} 0']) + + try: + yield f'/dev/mapper/{dm_name}' + finally: + run(['dmsetup', 'remove', dm_name]) + def test(layout, dev_context_manager): with test_file(layout) as file_path, dev_context_manager(file_path) as dev_path: cmd = run(['./map_holes.py', file_path]) @@ -99,5 +113,5 @@ if __name__ == '__main__': holes_at_beginning_and_end, no_holes, empty_file] - dev_context_managers = [loop_device] + dev_context_managers = [loop_device, dm_linear] test_all(layouts, dev_context_managers) From patchwork Thu Mar 28 20:39:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13609608 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D14A13AD2E for ; Thu, 28 Mar 2024 20:40:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658440; cv=none; b=NGWmPWmANXCCLsWv7fE0inExh60PzVBw6jE8HurEUzs1wGAC63ORgYc1v/EgfHq9snY5/mw1E5W35eFMF3lh/pHlwxNLbBDQ5BLqRJxQioEJPIFh1kE9uBNSLrG4ktdE0FEpgbGXRRg9CGD0+RK24UPhXsDX0G1QXAOH03CJiRc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658440; c=relaxed/simple; bh=SI9EyP15CZh3jJTeMjwpu+Zr17yZzGKirE/DIG97dXw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fSFGBmk+lse28oZouqxnvgerfnFN9phe4G88ba1c3CFsgPYUAfeY/vOr7701BU5JXCiMaT/u0OwC6XoonEsWzIXBKS3EN4E4I1UFKftEcp6atrCUvPr8qDhCAskWKkXXSxLgBMYlOSvGXo+MLsIo+kXfLWUGPqu4eeRDL9HVyQ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=WRQm6aIn; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="WRQm6aIn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1711658438; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lf6jghLGdSH/W25WTkrfJgf1lvUf+tFV6p9B6mZYK3I=; b=WRQm6aInDL7jIuBtCrX9rT6nrEuF09ISH1vw2iRYjEQJRSv9yiTc7TtiYqiRCsJ6Dmp3CS hffwA7pA3raFKlR7bBLH6eQOssm4pAYLlRhi51mHmc0s+N0JN6d8q234M3frpq3VAAOfTZ m2VtO1ndiJICDUj846KCx82du4cNGkc= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-688-SH43pzrSOta28V_OS728qA-1; Thu, 28 Mar 2024 16:40:33 -0400 X-MC-Unique: SH43pzrSOta28V_OS728qA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 6CE073C025B1; Thu, 28 Mar 2024 20:40:33 +0000 (UTC) Received: from localhost (unknown [10.39.194.117]) by smtp.corp.redhat.com (Postfix) with ESMTP id 484432166B31; Thu, 28 Mar 2024 20:40:31 +0000 (UTC) From: Stefan Hajnoczi To: linux-block@vger.kernel.org Cc: linux-kernel@vger.kernel.org, eblake@redhat.com, Alasdair Kergon , Mikulas Patocka , dm-devel@lists.linux.dev, David Teigland , Mike Snitzer , Jens Axboe , Christoph Hellwig , Joe Thornber , Stefan Hajnoczi Subject: [RFC 8/9] dm thin: add llseek(SEEK_HOLE/SEEK_DATA) support Date: Thu, 28 Mar 2024 16:39:09 -0400 Message-ID: <20240328203910.2370087-9-stefanha@redhat.com> In-Reply-To: <20240328203910.2370087-1-stefanha@redhat.com> References: <20240328203910.2370087-1-stefanha@redhat.com> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.6 Signed-off-by: Stefan Hajnoczi --- Open issues: - Locking? - thin_seek_hole_data() does not run as a bio or request. This patch assumes dm_thin_find_mapped_range() synchronously performs I/O if metadata needs to be loaded from disk. Is that a valid assumption? --- drivers/md/dm-thin.c | 77 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 4793ad2aa1f7e..3c5dc4f0fe8a3 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -4501,6 +4501,82 @@ static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits) } } +static dm_block_t loff_to_block(struct pool *pool, loff_t offset) +{ + sector_t offset_sectors = offset >> SECTOR_SHIFT; + dm_block_t ret; + + if (block_size_is_power_of_two(pool)) + ret = offset_sectors >> pool->sectors_per_block_shift; + else { + ret = offset_sectors; + (void) sector_div(ret, pool->sectors_per_block); + } + + return ret; +} + +static loff_t block_to_loff(struct pool *pool, dm_block_t block) +{ + return block_to_sectors(pool, block) << SECTOR_SHIFT; +} + +static loff_t thin_seek_hole_data(struct dm_target *ti, loff_t offset, + int whence) +{ + struct thin_c *tc = ti->private; + struct dm_thin_device *td = tc->td; + struct pool *pool = tc->pool; + dm_block_t begin; + dm_block_t end; + dm_block_t mapped_begin; + dm_block_t mapped_end; + dm_block_t pool_begin; + bool maybe_shared; + int ret; + + /* TODO locking? */ + + if (block_size_is_power_of_two(pool)) + end = ti->len >> pool->sectors_per_block_shift; + else { + end = ti->len; + (void) sector_div(end, pool->sectors_per_block); + } + + offset -= ti->begin << SECTOR_SHIFT; + + while (true) { + begin = loff_to_block(pool, offset); + ret = dm_thin_find_mapped_range(td, begin, end, + &mapped_begin, &mapped_end, + &pool_begin, &maybe_shared); + if (ret == -ENODATA) { + if (whence == SEEK_DATA) + return -ENXIO; + break; + } else if (ret < 0) { + /* TODO handle EWOULDBLOCK? */ + return -ENXIO; + } + + /* SEEK_DATA finishes here... */ + if (whence == SEEK_DATA) { + if (mapped_begin != begin) + offset = block_to_loff(pool, mapped_begin); + break; + } + + /* ...while SEEK_HOLE may need to look further */ + if (mapped_begin != begin) + break; /* offset is in a hole */ + + offset = block_to_loff(pool, mapped_end); + } + + return offset + (ti->begin << SECTOR_SHIFT); +} + static struct target_type thin_target = { .name = "thin", .version = {1, 23, 0}, @@ -4515,6 +4591,7 @@ static struct target_type thin_target = { .status = thin_status, .iterate_devices = thin_iterate_devices, .io_hints = thin_io_hints, + .seek_hole_data = thin_seek_hole_data, }; /*----------------------------------------------------------------*/ From patchwork Thu Mar 28 20:39:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13609609 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 203BB13A3E7 for ; Thu, 28 Mar 2024 20:41:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658464; cv=none; b=IFiO9wqyezaROpCECgsT6n7DJNLc5u8iSuH+Sgxgo8S9b+pYEoqpe6vHKYfMMwPRE6qGz10+Fcc+lJBpTv2p94cBqQMS/66hTUmA17FRPJGevYSbv9XgvyFA/Ahmx8CDXl1A2FWQinENsYqd+2thg73qWMMC2AJEdso9o82eV4E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711658464; c=relaxed/simple; bh=4LVr4XIyTxfxImYgjXFnrBvXpjmjemBkyYv51+FUVj0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Bzd8uAk1HsfcnsPnC5p9SPbQYKz3FBjoIW7HcDJtoS3e0zAdmAMEMQ0MN0fByMegvrDD1zEh7Z15k/4LBGuf40h37pFJgPCxO+buI5Nn1u6liCb2tWMuvI+FhEjdUyCaEQki9Ukx0g6F/Mr5hqF5uHaNvJL9LG+L3RgS167jZEU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=WkeU1nLy; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="WkeU1nLy" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1711658460; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=y4QwQ4LobXpOZeMcmZtW4ftxyW2t074qf+BN+wufuQA=; b=WkeU1nLyZwpjusMGdTH8N7QNbPk1F7C7Q9lF2HmqjBKle6zFMIuGpfG/1ps70H/eFr6uOz cjOCQLV3z2z+OSYacIsIfXRSwCuldg0QareOS8jaQK5kl8xWBobFEfqJ/aDV8tID7+K8eo Jq/nMox66h5/LImMEl9UyXMlSyTdKe8= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-631-FGHnscCFOt2rRDtvRy7V4Q-1; Thu, 28 Mar 2024 16:40:56 -0400 X-MC-Unique: FGHnscCFOt2rRDtvRy7V4Q-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4C74A8007A7; Thu, 28 Mar 2024 20:40:56 +0000 (UTC) Received: from localhost (unknown [10.39.194.117]) by smtp.corp.redhat.com (Postfix) with ESMTP id B0F5B3C54; Thu, 28 Mar 2024 20:40:54 +0000 (UTC) From: Stefan Hajnoczi To: linux-block@vger.kernel.org Cc: linux-kernel@vger.kernel.org, eblake@redhat.com, Alasdair Kergon , Mikulas Patocka , dm-devel@lists.linux.dev, David Teigland , Mike Snitzer , Jens Axboe , Christoph Hellwig , Joe Thornber , Stefan Hajnoczi Subject: [RFC 9/9] selftests: block_seek_hole: add dm-thin test Date: Thu, 28 Mar 2024 16:39:10 -0400 Message-ID: <20240328203910.2370087-10-stefanha@redhat.com> In-Reply-To: <20240328203910.2370087-1-stefanha@redhat.com> References: <20240328203910.2370087-1-stefanha@redhat.com> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.1 Signed-off-by: Stefan Hajnoczi --- .../selftests/block_seek_hole/Makefile | 2 +- .../selftests/block_seek_hole/dm_thin.sh | 80 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100755 tools/testing/selftests/block_seek_hole/dm_thin.sh diff --git a/tools/testing/selftests/block_seek_hole/Makefile b/tools/testing/selftests/block_seek_hole/Makefile index 1bd9e748b2acc..3b4ee1b1fb6e7 100644 --- a/tools/testing/selftests/block_seek_hole/Makefile +++ b/tools/testing/selftests/block_seek_hole/Makefile @@ -3,7 +3,7 @@ PY3 = $(shell which python3 2>/dev/null) ifneq ($(PY3),) -TEST_PROGS := test.py dm_zero.sh +TEST_PROGS := test.py dm_zero.sh dm_thin.sh include ../lib.mk diff --git a/tools/testing/selftests/block_seek_hole/dm_thin.sh b/tools/testing/selftests/block_seek_hole/dm_thin.sh new file mode 100755 index 0000000000000..a379b7c875f28 --- /dev/null +++ b/tools/testing/selftests/block_seek_hole/dm_thin.sh @@ -0,0 +1,80 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# +# dm_thin.sh +# +# Test that dm-thin supports SEEK_HOLE/SEEK_DATA. + +set -e + +# check +# Check that the actual output matches the expected output. +check() { + if [ "$1" != "$2" ]; then + echo 'FAIL expected:' + echo "$2" + echo 'Does not match device output:' + echo "$1" + exit 1 + fi +} + +cleanup() { + if [ -n "$thin_name" ]; then + dmsetup remove $thin_name + fi + if [ -n "$pool_name" ]; then + dmsetup remove $pool_name + fi + if [ -n "$metadata_path" ]; then + losetup --detach "$metadata_path" + fi + if [ -n "$data_path" ]; then + losetup --detach "$data_path" + fi + rm -f pool-metadata pool-data +} +trap cleanup EXIT + +rm -f pool-metadata pool-data +truncate -s 256M pool-metadata +truncate -s 1G pool-data + +size_sectors=$((1024 * 1024 * 1024 / 512)) # 1 GB +metadata_path=$(losetup --show --find pool-metadata) +data_path=$(losetup --show --find pool-data) +pool_name=pool-$$ +thin_name=thin-$$ + +dmsetup create $pool_name \ + --table "0 $size_sectors thin-pool $metadata_path $data_path 128 $size_sectors" +dmsetup message /dev/mapper/$pool_name 0 'create_thin 0' +dmsetup create $thin_name --table "0 $size_sectors thin /dev/mapper/$pool_name 0" + +# Verify that the device is empty +check "$(./map_holes.py /dev/mapper/$thin_name)" 'TYPE START END SIZE +HOLE 0 1073741824 1073741824' + +# Write 4k at offset 128M but dm-thin will actually map an entire 64k block +dd if=/dev/urandom of=/dev/mapper/$thin_name bs=4k count=1 seek=32768 status=none +check "$(./map_holes.py /dev/mapper/$thin_name)" 'TYPE START END SIZE +HOLE 0 134217728 134217728 +DATA 134217728 134283264 65536 +HOLE 134283264 1073741824 939458560' + +# Write at the beginning of the device +dd if=/dev/urandom of=/dev/mapper/$thin_name bs=4k count=1 status=none +check "$(./map_holes.py /dev/mapper/$thin_name)" 'TYPE START END SIZE +DATA 0 65536 65536 +HOLE 65536 134217728 134152192 +DATA 134217728 134283264 65536 +HOLE 134283264 1073741824 939458560' + +# Write at the end of the device +dd if=/dev/urandom of=/dev/mapper/$thin_name bs=4k count=1 seek=262143 status=none +check "$(./map_holes.py /dev/mapper/$thin_name)" 'TYPE START END SIZE +DATA 0 65536 65536 +HOLE 65536 134217728 134152192 +DATA 134217728 134283264 65536 +HOLE 134283264 1073676288 939393024 +DATA 1073676288 1073741824 65536'