From patchwork Wed Feb 21 20:19:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Mahoney X-Patchwork-Id: 10233907 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 BFAC1602A7 for ; Wed, 21 Feb 2018 20:19:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF33127D4D for ; Wed, 21 Feb 2018 20:19:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A11E4284BD; Wed, 21 Feb 2018 20:19:30 +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 1C82F27D4D for ; Wed, 21 Feb 2018 20:19:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751228AbeBUUT2 (ORCPT ); Wed, 21 Feb 2018 15:19:28 -0500 Received: from mx2.suse.de ([195.135.220.15]:50751 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750752AbeBUUT1 (ORCPT ); Wed, 21 Feb 2018 15:19:27 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id CBE85ADBD for ; Wed, 21 Feb 2018 20:19:25 +0000 (UTC) Received: from starscream.home.jeffm.io (starscream-1.home.jeffm.io [IPv6:2001:559:c0d4::1fe]) by mail.home.jeffm.io (Postfix) with ESMTPS id 0A27F81AD3E5; Wed, 21 Feb 2018 15:19:05 -0500 (EST) Received: by starscream.home.jeffm.io (Postfix, from userid 1000) id DFB5680363; Wed, 21 Feb 2018 15:19:23 -0500 (EST) From: jeffm@suse.com To: linux-btrfs@vger.kernel.org Cc: Jeff Mahoney Subject: [PATCH] btrfs: qgroups, properly handle no reservations Date: Wed, 21 Feb 2018 15:19:21 -0500 Message-Id: <20180221201921.17944-1-jeffm@suse.com> X-Mailer: git-send-email 2.15.1 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Jeff Mahoney There are several places where we call btrfs_qgroup_reserve_meta and assume that a return value of 0 means that the reservation was successful. Later, we use the original bytes value passed to that call to free bytes during error handling or to pass the number of bytes reserved to the caller. This patch returns -ENODATA when we don't perform a reservation so that callers can make the distinction. This also lets call sites not necessarily care whether qgroups are enabled. Signed-off-by: Jeff Mahoney --- fs/btrfs/extent-tree.c | 33 ++++++++++++++++----------------- fs/btrfs/qgroup.c | 4 ++-- fs/btrfs/transaction.c | 5 ++++- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index c1618ab9fecf..2d5e963fae88 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -5988,20 +5988,18 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root, u64 *qgroup_reserved, bool use_global_rsv) { - u64 num_bytes; int ret; struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv; + /* One for parent inode, two for dir entries */ + u64 num_bytes = 3 * fs_info->nodesize; - if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) { - /* One for parent inode, two for dir entries */ - num_bytes = 3 * fs_info->nodesize; - ret = btrfs_qgroup_reserve_meta(root, num_bytes, true); - if (ret) - return ret; - } else { + ret = btrfs_qgroup_reserve_meta(root, num_bytes, true); + if (ret == -ENODATA) { num_bytes = 0; - } + ret = 0; + } else if (ret) + return ret; *qgroup_reserved = num_bytes; @@ -6057,6 +6055,7 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes) enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_ALL; int ret = 0; bool delalloc_lock = true; + u64 qgroup_reserved; /* If we are a free space inode we need to not flush since we will be in * the middle of a transaction commit. We also don't need the delalloc @@ -6090,17 +6089,17 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes) btrfs_calculate_inode_block_rsv_size(fs_info, inode); spin_unlock(&inode->lock); - if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) { - ret = btrfs_qgroup_reserve_meta(root, - nr_extents * fs_info->nodesize, true); - if (ret) - goto out_fail; - } + qgroup_reserved = nr_extents * fs_info->nodesize; + ret = btrfs_qgroup_reserve_meta(root, qgroup_reserved, true); + if (ret == -ENODATA) { + ret = 0; + qgroup_reserved = 0; + } if (ret) + goto out_fail; ret = btrfs_inode_rsv_refill(inode, flush); if (unlikely(ret)) { - btrfs_qgroup_free_meta(root, - nr_extents * fs_info->nodesize); + btrfs_qgroup_free_meta(root, qgroup_reserved); goto out_fail; } diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index aa259d6986e1..5d9e011243c6 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -3025,7 +3025,7 @@ int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) || !is_fstree(root->objectid) || num_bytes == 0) - return 0; + return -ENODATA; BUG_ON(num_bytes != round_down(num_bytes, fs_info->nodesize)); trace_qgroup_meta_reserve(root, (s64)num_bytes); @@ -3057,7 +3057,7 @@ void btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes) struct btrfs_fs_info *fs_info = root->fs_info; if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) || - !is_fstree(root->objectid)) + !is_fstree(root->objectid) || num_bytes == 0) return; BUG_ON(num_bytes != round_down(num_bytes, fs_info->nodesize)); diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 04f07144b45c..ab67b73bd7fa 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -510,7 +510,10 @@ start_transaction(struct btrfs_root *root, unsigned int num_items, qgroup_reserved = num_items * fs_info->nodesize; ret = btrfs_qgroup_reserve_meta(root, qgroup_reserved, enforce_qgroups); - if (ret) + if (ret == -ENODATA) { + ret = 0; + qgroup_reserved = 0; + } else if (ret) return ERR_PTR(ret); num_bytes = btrfs_calc_trans_metadata_size(fs_info, num_items);