From patchwork Mon Mar 5 12:34:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Holger_Hoffst=C3=A4tte?= X-Patchwork-Id: 10258851 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DCB6960365 for ; Mon, 5 Mar 2018 12:35:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CA32128930 for ; Mon, 5 Mar 2018 12:35:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B873E28A0B; Mon, 5 Mar 2018 12:35:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0477B289C4 for ; Mon, 5 Mar 2018 12:35:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932864AbeCEMe6 (ORCPT ); Mon, 5 Mar 2018 07:34:58 -0500 Received: from mail02.iobjects.de ([188.40.134.68]:45614 "EHLO mail02.iobjects.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934773AbeCEMez (ORCPT ); Mon, 5 Mar 2018 07:34:55 -0500 Received: from tux.wizards.de (p5DE2B221.dip0.t-ipconnect.de [93.226.178.33]) by mail02.iobjects.de (Postfix) with ESMTPSA id E0622416013B; Mon, 5 Mar 2018 13:34:53 +0100 (CET) Received: from [192.168.100.223] (ragnarok.applied-asynchrony.com [192.168.100.223]) by tux.wizards.de (Postfix) with ESMTP id 5A786F01588; Mon, 5 Mar 2018 13:34:53 +0100 (CET) To: linux-block , Jens Axboe From: =?UTF-8?Q?Holger_Hoffst=c3=a4tte?= Subject: loop: properly declare rotational flag of underlying device Organization: Applied Asynchrony, Inc. Message-ID: <627661e4-476f-ade0-97c0-8b4812445d93@applied-asynchrony.com> Date: Mon, 5 Mar 2018 13:34:53 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 Content-Language: en-US Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The loop driver has always declared the rotational flag of its device as rotational, even when the device of the mapped file is nonrotational, as is the case with SSDs or on tmpfs. This can confuse filesystem tools which are SSD-aware; in my case I frequently forget to tell mkfs.btrfs that my loop device on tmpfs is nonrotational, and that I really don't need any automatic metadata redundancy. The attached patch fixes this by introspecting the rotational flag of the mapped file's underlying block device, if it exists. If the mapped file's filesystem has no associated block device - as is the case on e.g. tmpfs - we assume nonrotational storage. If there is a better way to identify such non-devices I'd love to hear them. On previous submission (~2 years ago I think) Jens commented that this "changes the default". Tat's precisely the point: the default of declaring rotational behaviour unconditionally is more likely to be wrong than the other way around. To the best of my knowledge there are no byte- addressable but physically rotating media without associated block device. This is fresh against 4.16-rc4 and has been in production since 4.9, with some minor changes to accommodate initialization order in 4.14. Please consider for 4.17. Signed-off-by: Holger Hoffstätte cheers, Holger diff -rup linux-4.16-rc4/drivers/block/loop.c linux-4.16-rc4-loop/drivers/block/loop.c --- linux-4.16-rc4/drivers/block/loop.c 2018-03-04 23:54:11.000000000 +0100 +++ linux-4.16-rc4-loop/drivers/block/loop.c 2018-03-05 00:41:48.013602156 +0100 @@ -829,6 +829,24 @@ static void loop_config_discard(struct l queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); } +static void loop_update_rotational(struct loop_device *lo) +{ + struct file *file = lo->lo_backing_file; + struct inode *file_inode = file->f_mapping->host; + struct block_device *file_bdev = file_inode->i_sb->s_bdev; + struct request_queue *q = lo->lo_queue; + bool nonrot = true; + + /* not all filesystems (e.g. tmpfs) have a sb->s_bdev */ + if (file_bdev) + nonrot = blk_queue_nonrot(bdev_get_queue(file_bdev)); + + if (nonrot) + queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q); + else + queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q); +} + static void loop_unprepare_queue(struct loop_device *lo) { kthread_flush_worker(&lo->worker); @@ -929,6 +947,7 @@ static int loop_set_fd(struct loop_devic loop_update_dio(lo); set_capacity(lo->lo_disk, size); bd_set_size(bdev, size << 9); + loop_update_rotational(lo); loop_sysfs_init(lo); /* let user-space know about the new size */ kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);