From patchwork Thu Apr 14 01:15:04 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yauhen Kharuzhy X-Patchwork-Id: 8830371 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 68BBA9F39A for ; Thu, 14 Apr 2016 01:16:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 46A3C202D1 for ; Thu, 14 Apr 2016 01:16:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2186D2017E for ; Thu, 14 Apr 2016 01:16:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751091AbcDNBQE (ORCPT ); Wed, 13 Apr 2016 21:16:04 -0400 Received: from mail-pf0-f193.google.com ([209.85.192.193]:33790 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750884AbcDNBQD (ORCPT ); Wed, 13 Apr 2016 21:16:03 -0400 Received: by mail-pf0-f193.google.com with SMTP id e190so5515217pfe.0 for ; Wed, 13 Apr 2016 18:16:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=iAGwTFDkh72L1xxn8AMnhaS75XCfhG7KP8AexdAC6UQ=; b=L+AbTjZZ3dbQ3e/ueHIyz1oHJaxKHtf15Mf3nc9lhErHJw3xaWEahGhfEaS1nmv9Gl 5NueR48qjZGpPdq4Y6XV4QH0LnymQwUdLtBD3wKitAFkHoVu6PrWxNTJZHJoRdoEkNpX QCudNnsevc00YkTEsdoN2dkGi36ryIX7zySqfJ9fTiwEVOgRGF084TrFbQqjnLLDuDWj OZ9OOkxvvY65bTlwdNJfxJlwAdEpkwjT2xLJYlALYH9RJtvGyAje/vupKyVyfdEaw0cx uLr7VPP8CZTV67q+fVkJp0huEZeBUuui500dPfz0Yc814JzuqFTtGDBA/cWUQFsdWH+m O2xA== X-Gm-Message-State: AOPr4FUK6SS+EU4Hn/HHJN271AoSvriBHqDpowUbD7Urt0tt+DZrnQLF9h/X9urjPZUfDg== X-Received: by 10.98.13.130 with SMTP id 2mr17270512pfn.97.1460596561586; Wed, 13 Apr 2016 18:16:01 -0700 (PDT) Received: from jek-Latitude-E7440 (sjc00ib2.hgst.com. [199.255.44.5]) by smtp.gmail.com with ESMTPSA id p189sm33238708pfb.51.2016.04.13.18.16.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 13 Apr 2016 18:16:00 -0700 (PDT) Received: from jek by jek-Latitude-E7440 with local (Exim 4.86) (envelope-from ) id 1aqVt1-0007ra-Mt; Wed, 13 Apr 2016 18:15:59 -0700 From: Yauhen Kharuzhy To: Anand Jain Cc: linux-btrfs@vger.kernel.org, Yauhen Kharuzhy Subject: [PATCH] Btrfs: Set superblock s_bdev field properly at device closing Date: Wed, 13 Apr 2016 18:15:04 -0700 Message-Id: <1460596504-30172-1-git-send-email-yauhen.kharuzhy@zavadatar.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1460470563-752-12-git-send-email-anand.jain@oracle.com> References: <1460470563-752-12-git-send-email-anand.jain@oracle.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP fs_info->sb->s_bdev field isn't set to any value at mount time but is set after device replacing or at device closing. Existing code of device_force_close() checks if current s_bdev is not equal to closing bdev and, if equal, replace it by bdev field of first btrfs_device from device list. This device may be the same as closed, and s_bdev field will be invalid. If s_bdev is not NULL but references an freed block device, kernel oopses at filesystem sync time on unmount. For multi-device FS setting of this field may be senseless, but using of it should be consistent over the all btrfs code. So, set it on mount time and select valid device at device closing time. Alternative solution may be to not set s_bdev entirely. Signed-off-by: Yauhen Kharuzhy --- fs/btrfs/super.c | 1 + fs/btrfs/volumes.c | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 3dd154e..1a2c58f 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1522,6 +1522,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, char b[BDEVNAME_SIZE]; strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); + s->s_bdev = bdev; btrfs_sb(s)->bdev_holder = fs_type; error = btrfs_fill_super(s, fs_devices, data, flags & MS_SILENT ? 1 : 0); diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 08ab116..f14f3f2 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -7132,6 +7132,7 @@ void device_force_close(struct btrfs_device *device) { struct btrfs_device *next_device; struct btrfs_fs_devices *fs_devices; + int found = 0; fs_devices = device->fs_devices; @@ -7139,13 +7140,20 @@ void device_force_close(struct btrfs_device *device) mutex_lock(&fs_devices->fs_info->chunk_mutex); spin_lock(&fs_devices->fs_info->free_chunk_lock); - next_device = list_entry(fs_devices->devices.next, - struct btrfs_device, dev_list); + list_for_each_entry(next_device, &fs_devices->devices, dev_list) { + if (next_device->bdev && next_device->bdev != device->bdev) { + found = 1; + break; + } + } + if (device->bdev == fs_devices->fs_info->sb->s_bdev) - fs_devices->fs_info->sb->s_bdev = next_device->bdev; + fs_devices->fs_info->sb->s_bdev = + found ? next_device->bdev : NULL; if (device->bdev == fs_devices->latest_bdev) - fs_devices->latest_bdev = next_device->bdev; + fs_devices->latest_bdev = + found ? next_device->bdev : NULL; if (device->bdev) fs_devices->open_devices--;