From patchwork Thu Mar 6 05:55:03 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miao Xie X-Patchwork-Id: 3781451 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 01443BF540 for ; Thu, 6 Mar 2014 05:53:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 230C6201D5 for ; Thu, 6 Mar 2014 05:53:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 284EF201C7 for ; Thu, 6 Mar 2014 05:53:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751684AbaCFFxu (ORCPT ); Thu, 6 Mar 2014 00:53:50 -0500 Received: from cn.fujitsu.com ([222.73.24.84]:32696 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1751649AbaCFFxt (ORCPT ); Thu, 6 Mar 2014 00:53:49 -0500 X-IronPort-AV: E=Sophos;i="4.97,598,1389715200"; d="scan'208";a="9652950" Received: from unknown (HELO tang.cn.fujitsu.com) ([10.167.250.3]) by song.cn.fujitsu.com with ESMTP; 06 Mar 2014 13:49:55 +0800 Received: from fnstmail02.fnst.cn.fujitsu.com (tang.cn.fujitsu.com [127.0.0.1]) by tang.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id s265rRfW009842 for ; Thu, 6 Mar 2014 13:53:36 +0800 Received: from miao.fnst.cn.fujitsu.com ([10.167.226.201]) by fnstmail02.fnst.cn.fujitsu.com (Lotus Domino Release 8.5.3) with ESMTP id 2014030613505622-441853 ; Thu, 6 Mar 2014 13:50:56 +0800 From: Miao Xie To: linux-btrfs@vger.kernel.org Subject: [PATCH V2 09/10] Btrfs: fix possible empty list access when flushing the delalloc inodes Date: Thu, 6 Mar 2014 13:55:03 +0800 Message-Id: <1394085304-32589-9-git-send-email-miaox@cn.fujitsu.com> X-Mailer: git-send-email 1.8.5.3 In-Reply-To: <1394085304-32589-1-git-send-email-miaox@cn.fujitsu.com> References: <1394085304-32589-1-git-send-email-miaox@cn.fujitsu.com> X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2014/03/06 13:50:56, Serialize by Router on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2014/03/06 13:51:11, Serialize complete at 2014/03/06 13:51:11 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 We didn't have a lock to protect the access to the delalloc inodes list, that is we might access a empty delalloc inodes list if someone start flushing delalloc inodes because the delalloc inodes were moved into a other list temporarily. Fix it by wrapping the access with a lock. Signed-off-by: Miao Xie --- Changelog v1 -> v2: - New patch. --- fs/btrfs/ctree.h | 2 ++ fs/btrfs/disk-io.c | 2 ++ fs/btrfs/inode.c | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 7bae97e..ec47aa9 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1490,6 +1490,7 @@ struct btrfs_fs_info { */ struct list_head ordered_roots; + struct mutex delalloc_root_mutex; spinlock_t delalloc_root_lock; /* all fs/file tree roots that have delalloc inodes. */ struct list_head delalloc_roots; @@ -1797,6 +1798,7 @@ struct btrfs_root { spinlock_t root_item_lock; atomic_t refs; + struct mutex delalloc_mutex; spinlock_t delalloc_lock; /* * all of the inodes that have delalloc bytes. It is possible for diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 65fe26e..2bb0bbd 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1198,6 +1198,7 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, mutex_init(&root->objectid_mutex); mutex_init(&root->log_mutex); mutex_init(&root->ordered_extent_mutex); + mutex_init(&root->delalloc_mutex); init_waitqueue_head(&root->log_writer_wait); init_waitqueue_head(&root->log_commit_wait[0]); init_waitqueue_head(&root->log_commit_wait[1]); @@ -2169,6 +2170,7 @@ int open_ctree(struct super_block *sb, spin_lock_init(&fs_info->buffer_lock); rwlock_init(&fs_info->tree_mod_log_lock); mutex_init(&fs_info->reloc_mutex); + mutex_init(&fs_info->delalloc_root_mutex); seqlock_init(&fs_info->profiles_lock); init_completion(&fs_info->kobj_unregister); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4f64216..34c484c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -8429,6 +8429,7 @@ static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput, INIT_LIST_HEAD(&works); INIT_LIST_HEAD(&splice); + mutex_lock(&root->delalloc_mutex); spin_lock(&root->delalloc_lock); list_splice_init(&root->delalloc_inodes, &splice); while (!list_empty(&splice)) { @@ -8474,6 +8475,7 @@ static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput, list_splice_tail(&splice, &root->delalloc_inodes); spin_unlock(&root->delalloc_lock); } + mutex_unlock(&root->delalloc_mutex); return ret; } @@ -8515,6 +8517,7 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput, INIT_LIST_HEAD(&splice); + mutex_lock(&fs_info->delalloc_root_mutex); spin_lock(&fs_info->delalloc_root_lock); list_splice_init(&fs_info->delalloc_roots, &splice); while (!list_empty(&splice) && nr) { @@ -8554,6 +8557,7 @@ out: list_splice_tail(&splice, &fs_info->delalloc_roots); spin_unlock(&fs_info->delalloc_root_lock); } + mutex_unlock(&fs_info->delalloc_root_mutex); return ret; }