From patchwork Thu Mar 3 23:18:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 12768271 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 13341C433EF for ; Thu, 3 Mar 2022 23:19:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236114AbiCCXUK (ORCPT ); Thu, 3 Mar 2022 18:20:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56140 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235906AbiCCXUI (ORCPT ); Thu, 3 Mar 2022 18:20:08 -0500 Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82A143BA6F for ; Thu, 3 Mar 2022 15:19:22 -0800 (PST) Received: by mail-pl1-x636.google.com with SMTP id q11so6136851pln.11 for ; Thu, 03 Mar 2022 15:19:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2dDQptnmnXM+eagiPJmnEv3pr4ajcDowzXB7b89WVcE=; b=PZZA856OEIWMR6WeVQHWYmC95MzYPoO1C1KQoM8/0r3EQKtwI1i5u+a1pYECBFzvQ0 Col1y7kfklCg2gPRlYDwdgWkp9TdUrAKoJaHeaLaWUNGgWCRRivL+/AvAHGbjCyYFG/c qJ9s+psvZszUZcXd2oXvjpkzDQ0Wt6yW8gsS92pn+yeUJcBR9iOiMDWugusub1tJm5i6 I7SrquooETfBf7i6HdTev5+1tXjULbVDpsy+dYRq0zWpQXxfZkbI64xYiAnDKTV6Nir8 PS1dR+GG2a46ngACDYcYNjCc53r9DAgX1JQYe27u6yopZe3llSaFmb6mY1GYuyX4368z JSSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2dDQptnmnXM+eagiPJmnEv3pr4ajcDowzXB7b89WVcE=; b=c8xfF0JzlkpXFvGLLAK4HZ7rHAplFSu6RKFlRaSF3btlvajhPH0ifU2NtI+44fmtyV wamKwWDJXodv1M0sIWLdkJ78xIEZp/MZW2CSsJd6e/titZfxZPJkCy+Sk4lKrn9fEzSz gp2/IPo4jkWdclLHL3h7yW1YGzosiEU+qp7xWn+Q5dXaFI2VNjgRvzgIrRQy+xCnLxLt /qbboRT39QbIJh7NswxxoFI6WU5fTXcQrddnvPmkoHZdIMC0E163y+wyER6xY06yjLX2 QcO3vnXUXnzXCgkdO8R0Aco8WzTagUR/5GSU76s9oleHjHpzE75SuzrekB7KRiAGFNBK M/gg== X-Gm-Message-State: AOAM531P7K6MaDS0pC6JKyCXnK0YRLSSJgqtGZ5bvFXLuzPbDj5nnisC JR7eQDqpjPUTKWG9hLuWq4DBjP08FCjMyg== X-Google-Smtp-Source: ABdhPJx1ousVG7WnJEGiukJCRV8u+m5HOb9KA6ULB8r4lzRGqLtlVhuNLdMZnlAjRyUCApk6Oa5mOQ== X-Received: by 2002:a17:90a:8b82:b0:1b8:9624:2bab with SMTP id z2-20020a17090a8b8200b001b896242babmr7817278pjn.177.1646349561333; Thu, 03 Mar 2022 15:19:21 -0800 (PST) Received: from relinquished.tfbnw.net ([2620:10d:c090:400::5:76ce]) by smtp.gmail.com with ESMTPSA id x7-20020a17090a1f8700b001bf1db72189sm1103507pja.23.2022.03.03.15.19.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Mar 2022 15:19:21 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 01/12] btrfs: reserve correct number of items for unlink and rmdir Date: Thu, 3 Mar 2022 15:18:51 -0800 Message-Id: <689484459053d8d48db99275dc01be8d8cf52686.1646348486.git.osandov@fb.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Omar Sandoval __btrfs_unlink_inode() calls btrfs_update_inode() on the parent directory in order to update its size and sequence number. Make sure we account for it. Signed-off-by: Omar Sandoval --- fs/btrfs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 2e7143ff5523..2fb8aa36a9ac 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4212,8 +4212,9 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir) * 1 for the dir index * 1 for the inode ref * 1 for the inode + * 1 for the parent inode */ - return btrfs_start_transaction_fallback_global_rsv(root, 5); + return btrfs_start_transaction_fallback_global_rsv(root, 6); } static int btrfs_unlink(struct inode *dir, struct dentry *dentry) From patchwork Thu Mar 3 23:18:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 12768272 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D5D34C433FE for ; Thu, 3 Mar 2022 23:19:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236280AbiCCXUK (ORCPT ); Thu, 3 Mar 2022 18:20:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56218 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235641AbiCCXUJ (ORCPT ); Thu, 3 Mar 2022 18:20:09 -0500 Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A0D03A1AA for ; Thu, 3 Mar 2022 15:19:23 -0800 (PST) Received: by mail-pl1-x62e.google.com with SMTP id ay5so6178473plb.1 for ; Thu, 03 Mar 2022 15:19:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=pcxJqW3xQG5uNguk36DKjVBeVd3Q8mLAF97DK5rZGSc=; b=Z0i4+ZXEm228gR0Mh8tLw8Ce5PwilHjpf28RnZTnFPdUg3cq6qdO4BKonJZzGbG9Lf eH9bX9NkiA18pOsGXkk6/rLl3o2UiCzJmyo00G+tFXzykLirhyirITdNu2TmZMJJvwZU d3qqZOqx6SdY8yW8/vEgL/xpu+3TDGiLUMRk+XWRvYmEcHzWa2/rpCbhete8zgN1+qxP +oWBU7wc/k4fFUYnFH+/X1FuvfimGegAdIX8v0/ujVkzHlj2rAwb4P2YAsNo3fTrwOvL 2S2TSplfjbMyxChxIt3hY1AkS4LaX80pPJX4q6nf3IdI6hXOUjSlBaOFAZ21GTDE1bjB nNPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pcxJqW3xQG5uNguk36DKjVBeVd3Q8mLAF97DK5rZGSc=; b=xYC+GFJ6/zIpKJW4uHAYIx0nbvL17hDH+ukOGzDVyoKSb0yXwmeOc/vXBsSiRajHzg 46d1xAoTZuj4WvhFFFAx9OTgJXSczZibWwwOnJCSz+XbRbHIpi1FCPIrnq9D3yMAjpjM ihloF0cZOmcUiZqNxIaPsdmmWQHvlHiIUk+XNSjjcXfbPS774kdXxjR+7V9WTop9oJEW Tf4uaOywWxrhd2iv9XxE9RArr9IIZ+7ehJpgBjrj1j8GFpRwnG20gqJBOHFDLplgs9rt 2m1xoRLbdrX5bIzObFCa7/fV08Gzjb9EUQ6582t+0qAa8kWEAydcEIoKMNYZ7ZVvSdoF oyog== X-Gm-Message-State: AOAM530H6S+AsGfwskhOiVFJe90KSkHk9IJSXOfKs5B6ohd+p5U/Hf24 AyQMx1mReN15X5BVirwEfTn2Ls7JXgK6fQ== X-Google-Smtp-Source: ABdhPJzBp5lTxJYXNHkeqfSznNUX8EfP5iSQQVGrIpJcSDsHRS88QztGHujRvBr4GIqtxsPj5JT4gw== X-Received: by 2002:a17:903:1c3:b0:151:a54b:95f4 with SMTP id e3-20020a17090301c300b00151a54b95f4mr7601353plh.10.1646349562506; Thu, 03 Mar 2022 15:19:22 -0800 (PST) Received: from relinquished.tfbnw.net ([2620:10d:c090:400::5:76ce]) by smtp.gmail.com with ESMTPSA id x7-20020a17090a1f8700b001bf1db72189sm1103507pja.23.2022.03.03.15.19.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Mar 2022 15:19:22 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 02/12] btrfs: reserve correct number of items for rename Date: Thu, 3 Mar 2022 15:18:52 -0800 Message-Id: X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Omar Sandoval btrfs_rename() and btrfs_rename_exchange() don't account for enough items. Replace the incorrect explanations with a specific breakdown of the number of items and account them accurately. Note that this glosses over RENAME_WHITEOUT because the next commit is going to rework that, too. Signed-off-by: Omar Sandoval --- fs/btrfs/inode.c | 86 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 19 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 2fb8aa36a9ac..be51630160f5 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -9058,6 +9058,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, { struct btrfs_fs_info *fs_info = btrfs_sb(old_dir->i_sb); struct btrfs_trans_handle *trans; + unsigned int trans_num_items; struct btrfs_root *root = BTRFS_I(old_dir)->root; struct btrfs_root *dest = BTRFS_I(new_dir)->root; struct inode *new_inode = new_dentry->d_inode; @@ -9089,14 +9090,37 @@ static int btrfs_rename_exchange(struct inode *old_dir, down_read(&fs_info->subvol_sem); /* - * We want to reserve the absolute worst case amount of items. So if - * both inodes are subvols and we need to unlink them then that would - * require 4 item modifications, but if they are both normal inodes it - * would require 5 item modifications, so we'll assume their normal - * inodes. So 5 * 2 is 10, plus 2 for the new links, so 12 total items - * should cover the worst case number of items we'll modify. + * For each inode: + * 1 to remove old dir item + * 1 to remove old dir index + * 1 to add new dir item + * 1 to add new dir index + * 1 to update parent inode + * + * If the parents are the same, we only need to account for one */ - trans = btrfs_start_transaction(root, 12); + trans_num_items = old_dir == new_dir ? 9 : 10; + if (old_ino == BTRFS_FIRST_FREE_OBJECTID) { + /* + * 1 to remove old root ref + * 1 to remove old root backref + * 1 to add new root ref + * 1 to add new root backref + */ + trans_num_items += 4; + } else { + /* + * 1 to update inode item + * 1 to remove old inode ref + * 1 to add new inode ref + */ + trans_num_items += 3; + } + if (new_ino == BTRFS_FIRST_FREE_OBJECTID) + trans_num_items += 4; + else + trans_num_items += 3; + trans = btrfs_start_transaction(root, trans_num_items); if (IS_ERR(trans)) { ret = PTR_ERR(trans); goto out_notrans; @@ -9375,21 +9399,45 @@ static int btrfs_rename(struct user_namespace *mnt_userns, if (new_inode && S_ISREG(old_inode->i_mode) && new_inode->i_size) filemap_flush(old_inode->i_mapping); - /* close the racy window with snapshot create/destroy ioctl */ - if (old_ino == BTRFS_FIRST_FREE_OBJECTID) + if (old_ino == BTRFS_FIRST_FREE_OBJECTID) { + /* close the racy window with snapshot create/destroy ioctl */ down_read(&fs_info->subvol_sem); + /* + * 1 to remove old root ref + * 1 to remove old root backref + * 1 to add new root ref + * 1 to add new root backref + */ + trans_num_items = 4; + } else { + /* + * 1 to update inode + * 1 to remove old inode ref + * 1 to add new inode ref + */ + trans_num_items = 3; + } /* - * We want to reserve the absolute worst case amount of items. So if - * both inodes are subvols and we need to unlink them then that would - * require 4 item modifications, but if they are both normal inodes it - * would require 5 item modifications, so we'll assume they are normal - * inodes. So 5 * 2 is 10, plus 1 for the new link, so 11 total items - * should cover the worst case number of items we'll modify. - * If our rename has the whiteout flag, we need more 5 units for the - * new inode (1 inode item, 1 inode ref, 2 dir items and 1 xattr item - * when selinux is enabled). + * 1 to remove old dir item + * 1 to remove old dir index + * 1 to update old parent inode + * 1 to add new dir item + * 1 to add new dir index + * 1 to update new parent inode (if it's not the same as the old parent) */ - trans_num_items = 11; + trans_num_items += 6; + if (new_dir != old_dir) + trans_num_items++; + if (new_inode) { + /* + * 1 to update inode + * 1 to remove inode ref + * 1 to remove dir item + * 1 to remove dir index + * 1 to possibly add orphan item + */ + trans_num_items += 5; + } if (flags & RENAME_WHITEOUT) trans_num_items += 5; trans = btrfs_start_transaction(root, trans_num_items); From patchwork Thu Mar 3 23:18:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 12768273 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2339CC433EF for ; Thu, 3 Mar 2022 23:19:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236611AbiCCXUP (ORCPT ); Thu, 3 Mar 2022 18:20:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56274 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236187AbiCCXUK (ORCPT ); Thu, 3 Mar 2022 18:20:10 -0500 Received: from mail-pg1-x52d.google.com (mail-pg1-x52d.google.com [IPv6:2607:f8b0:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 290DA3B285 for ; Thu, 3 Mar 2022 15:19:24 -0800 (PST) Received: by mail-pg1-x52d.google.com with SMTP id e6so6004417pgn.2 for ; Thu, 03 Mar 2022 15:19:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yZMRcA/nkkrjVGlPpNGs4B0U5XQyrY4BMsA0jv2oD0E=; b=BNZ9eaOO7c9FQqMFUv/9wFxXD9GlD0tCDhM4ywlOLHt0zY+5lITa1TYhZLKjSKqga8 6RIG7hOg5wgEPZqaMPjp2En+gRIArPyDcOfJyYKm0D08mxqs/SyoN5T0hIsYSzHFnFT2 pul5bjRpb/6XHtwDMdvskQAqbZiZS/rUt4ynIC9Mt0bQfhCXT64HVrAFKgaX6fIen9lm YJAnvvRh3WNkokpDr/iKG8NvtesxGgokYwUx3vtEorPKLGmuSJWrBQi6iDB8YN5gT3J+ mJ8K56LH1eJJSRyFw0SoiwP1z8MWnG3hd1cqvIYdUqgdPkosRBuesmmAlnZc/bYALZp8 dsMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yZMRcA/nkkrjVGlPpNGs4B0U5XQyrY4BMsA0jv2oD0E=; b=UrQcK16Q06XtEL/aEErFxYaPmHa0aBpuPnJyawjyo7dHDNnFYFf3ETh557cn5dFEwy vmrLdcUoFWTPH2mB3QqwRPr+oVoZeUKzpcoBK4STer+/IwdZ2EzRcdrGxz53iRAU06iI uaLsh6jYCIi+PmzbpxUDA6D19dNHHjM+ZwB5Xx7ELs5+rWXsnudH2U/zjlyFgIsagcbm Bh/fcd5q0pnhmgz2/YQ6fTC82v6PDHqdhT3l718RCaPhy9pP+QqSL0vcLxzAOhvtCsgX i42E9VXxUkWEAHdnWjEt7A9qAF8wif43WROgTzTAHppONInH0AOAfIRoqxALn+El1jV8 o01g== X-Gm-Message-State: AOAM530Ha9g0xIPKBjnTaFk3sLsI2gzRLzzyuHjh+ANTcP0puTORy46h ra70BGbTkL0i9NJSyBFvHvCd/ZW7qP5JWg== X-Google-Smtp-Source: ABdhPJxfF97yFD0RMFjwwNZZmUMi5/SMJFDobAxoOFDwyXgWZ8PBU1b6nUQF80CfBZyWocn/bcdm2Q== X-Received: by 2002:a05:6a00:15cd:b0:4f6:6895:739b with SMTP id o13-20020a056a0015cd00b004f66895739bmr6319045pfu.60.1646349563346; Thu, 03 Mar 2022 15:19:23 -0800 (PST) Received: from relinquished.tfbnw.net ([2620:10d:c090:400::5:76ce]) by smtp.gmail.com with ESMTPSA id x7-20020a17090a1f8700b001bf1db72189sm1103507pja.23.2022.03.03.15.19.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Mar 2022 15:19:23 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 03/12] btrfs: get rid of btrfs_add_nondir() Date: Thu, 3 Mar 2022 15:18:53 -0800 Message-Id: <1d1af5e40beeb1d9e67c3b78b8f97537e0c4cdc0.1646348486.git.osandov@fb.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Omar Sandoval This is a trivial wrapper around btrfs_add_link(). The only thing it does other than moving arguments around is translating a > 0 return value to -EEXIST. As far as I can tell, btrfs_add_link() won't return > 0 (and if it did, the existing callsites in, e.g., btrfs_mkdir() would be broken). The check itself dates back to commit 2c90e5d65842 ("Btrfs: still corruption hunting"), so it's probably left over from debugging. Let's just get rid of btrfs_add_nondir(). Signed-off-by: Omar Sandoval --- fs/btrfs/inode.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index be51630160f5..9c838bdd51cc 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6355,18 +6355,6 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, return ret; } -static int btrfs_add_nondir(struct btrfs_trans_handle *trans, - struct btrfs_inode *dir, struct dentry *dentry, - struct btrfs_inode *inode, int backref, u64 index) -{ - int err = btrfs_add_link(trans, dir, inode, - dentry->d_name.name, dentry->d_name.len, - backref, index); - if (err > 0) - err = -EEXIST; - return err; -} - static int btrfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) { @@ -6413,8 +6401,8 @@ static int btrfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, if (err) goto out_unlock; - err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode), - 0, index); + err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), + dentry->d_name.name, dentry->d_name.len, 0, index); if (err) goto out_unlock; @@ -6481,8 +6469,8 @@ static int btrfs_create(struct user_namespace *mnt_userns, struct inode *dir, if (err) goto out_unlock; - err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode), - 0, index); + err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), + dentry->d_name.name, dentry->d_name.len, 0, index); if (err) goto out_unlock; @@ -6541,8 +6529,8 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, ihold(inode); set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags); - err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode), - 1, index); + err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), + dentry->d_name.name, dentry->d_name.len, 1, index); if (err) { drop_inode = 1; @@ -9324,8 +9312,8 @@ static int btrfs_whiteout_for_rename(struct btrfs_trans_handle *trans, if (ret) goto out; - ret = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, - BTRFS_I(inode), 0, index); + ret = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), + dentry->d_name.name, dentry->d_name.len, 0, index); if (ret) goto out; @@ -9863,8 +9851,9 @@ static int btrfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, * elsewhere above. */ if (!err) - err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, - BTRFS_I(inode), 0, index); + err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), + dentry->d_name.name, dentry->d_name.len, 0, + index); if (err) goto out_unlock; From patchwork Thu Mar 3 23:18:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 12768276 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DDBDCC433F5 for ; Thu, 3 Mar 2022 23:19:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236581AbiCCXUQ (ORCPT ); Thu, 3 Mar 2022 18:20:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236284AbiCCXUL (ORCPT ); Thu, 3 Mar 2022 18:20:11 -0500 Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 441BA14FFDA for ; Thu, 3 Mar 2022 15:19:25 -0800 (PST) Received: by mail-pl1-x632.google.com with SMTP id t19so2596875plr.5 for ; Thu, 03 Mar 2022 15:19:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=nuKFYZLg4Yh4s47S+CVL48QhHrHOvOA9fdRSW1WoeqQ=; b=NPxC2aOTa3QfLU1t1LbjCsLf68388cScscn/uPuZNgvrB+KU0Adk+H7vQ43MVmEoQb oNAcCvqDejftWh1res5tE7efuQDvMjtU82e9NK3Hk/+Y9hxs8cO56JOITd7NjR2mKzGH 9EIA1VR9oPtrXIkk21RO+V/tFLr7LYPzdmGg89J1FcreiZOw1Ayrah0oYnB/ey2I+zvT 5mg8Tn106hqF0pO7z30ECjvKRJ7YzgNNzyGavKFMTGRjQgnQ+tk48FAVm/Pjo+P1ACTz BQvgBQU0FEB0EjiLy9VM8xIWeyldfc9rbUOQbK2tyxEMOg9v+Jnq4c2ZgJYtoo6zCMas Irlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=nuKFYZLg4Yh4s47S+CVL48QhHrHOvOA9fdRSW1WoeqQ=; b=QXnkh3HI4Kva7xUWlhQ01OZ7tIYOdUlfR1Re9EDigFTRiUWINz51j22xXFAbzD/QbF X9qw8RDNVUBwFpgyIgEWGt2M0XsDCtAr4LduqubUeRdtmEyLD4nBq+jkfZfhMAtDX26W CF94+akl3OryWAiZdQsBncjoVyOGeIdkx0Ck9x1hmO3hvXKrHjK/CAgIw3D/kJk7mfKG pS7/18nQJTiRcX2rDFkM2Y2yc42uS636qRZ7688AaHj8VzYkfUNOzgy4N2++scmQAu6B 9KnlNTchbdUGk8IkbvynK+KH+F1qLwQbljziNkmWxhXnwxnyFnmuA8UaQgTwZgLv1avF 6B4A== X-Gm-Message-State: AOAM531uSF8NLaS67vOpBTggkdSB91M9kbJahOSc19605ZrpckMNG5Xl 63sxIZ+Ut9fGcefs/nhnLEtFxsSi/mCH3w== X-Google-Smtp-Source: ABdhPJy/WgLF8CgwAjyDZ2z4dGOeDal3j5vOw81OQ5BnChO7UPFM64n9WfBNzfc1LejMrj68z8+Cyw== X-Received: by 2002:a17:90a:fa95:b0:1bc:509f:c668 with SMTP id cu21-20020a17090afa9500b001bc509fc668mr7806084pjb.189.1646349564474; Thu, 03 Mar 2022 15:19:24 -0800 (PST) Received: from relinquished.tfbnw.net ([2620:10d:c090:400::5:76ce]) by smtp.gmail.com with ESMTPSA id x7-20020a17090a1f8700b001bf1db72189sm1103507pja.23.2022.03.03.15.19.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Mar 2022 15:19:24 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 04/12] btrfs: remove unnecessary btrfs_i_size_write(0) calls Date: Thu, 3 Mar 2022 15:18:54 -0800 Message-Id: X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Omar Sandoval btrfs_new_inode() always returns an inode with i_size and disk_i_size set to 0 (via inode_init_always() and btrfs_alloc_inode(), respectively). Remove the unnecessary calls to btrfs_i_size_write() in btrfs_mkdir() and btrfs_create_subvol_root(). Signed-off-by: Omar Sandoval --- fs/btrfs/inode.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9c838bdd51cc..244e8d6ed5e4 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6606,7 +6606,6 @@ static int btrfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, if (err) goto out_fail; - btrfs_i_size_write(BTRFS_I(inode), 0); err = btrfs_update_inode(trans, root, BTRFS_I(inode)); if (err) goto out_fail; @@ -8787,7 +8786,6 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, inode->i_fop = &btrfs_dir_file_operations; set_nlink(inode, 1); - btrfs_i_size_write(BTRFS_I(inode), 0); unlock_new_inode(inode); err = btrfs_subvol_inherit_props(trans, new_root, parent_root); From patchwork Thu Mar 3 23:18:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 12768277 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 868FDC433EF for ; Thu, 3 Mar 2022 23:19:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236970AbiCCXUT (ORCPT ); Thu, 3 Mar 2022 18:20:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56554 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236472AbiCCXUN (ORCPT ); Thu, 3 Mar 2022 18:20:13 -0500 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A2FD15DB3A for ; Thu, 3 Mar 2022 15:19:26 -0800 (PST) Received: by mail-pj1-x102c.google.com with SMTP id gj15-20020a17090b108f00b001bef86c67c1so6291139pjb.3 for ; Thu, 03 Mar 2022 15:19:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tReRS13ZknTO9C24t31RpzlXcQLneIA5Zqr6TCVa0D4=; b=tuUAV6Tj0tEDhDbuowXQ84HUHAS9rakT/h8JFMtWzNmvQL7WejCXXBYkaqKCZFxgpH LvBDpb4A4Bu5MyGNH6G0d2SeEdbhDG6Z7n64/hFKxFJ+/sZa1AdhjspLMQ9QiyV39aW6 35sQRW2HC4rLMfE7hHsjuKorwXris1gy2Dw2GshGW7/JbSn/jxBTqItTcKRIyz2g0UAA 9PBLQc+3ik1ONdM50HK8JZhQRj8NP5O0bqY/Cyc7F3R3J47m8h8ZAycbKvGzJ4RygAvZ 4O/KyIWjKsbIsB7vDLwLDTkR8Tz4KwhwuZf39hsL509gBlCKRGvPwbv3FP1JsBgqFS/y QO0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tReRS13ZknTO9C24t31RpzlXcQLneIA5Zqr6TCVa0D4=; b=yrE+ck5RlockI1QNdMgx/b00PcPlYFbyw/U4f0j2lubLwlm3RuvYnu1dr8tk75xKEq czKrtJfQmAGL0r/C34QQ5peeMjV6ThkBPVhr6w5dfYw5KqrWZewCTyx6acgNRJNbjRbc 7wCB9S94E3a+zX2AVVnEFT9hG30WSSUChj96kYODwc0tdan80hmo4+tag2/+5aHiozX5 jdeK0cpnZ0+pI1Mx0Ll+c4Jj2aNUAco0BtmX4RUN3vCUEC/6EIoVklqiY2vwAnBRlJkF Ev04UQwgX5h3fI7En/XZ+f8oIYoTowd49HnbIfISpG4bx5ejQ13XsxkJbycsaEBOav2X xWmw== X-Gm-Message-State: AOAM533ZN93BAjUvFFFY1nPB5REAA2ofhoSqX2iuXxHpWe7JEvprAB8A Pddp+5lZ0jSBlDuHpdJvLewmWFo8Soo1Cg== X-Google-Smtp-Source: ABdhPJxoKaZYLPXLgl03n5Qe0cFrWwOpl14vm0hV4QhEUTGDe0km00I3Y2uy37GH3Y9U3bQ9PoinFQ== X-Received: by 2002:a17:90a:5505:b0:1b8:ebd4:d602 with SMTP id b5-20020a17090a550500b001b8ebd4d602mr7688457pji.147.1646349565504; Thu, 03 Mar 2022 15:19:25 -0800 (PST) Received: from relinquished.tfbnw.net ([2620:10d:c090:400::5:76ce]) by smtp.gmail.com with ESMTPSA id x7-20020a17090a1f8700b001bf1db72189sm1103507pja.23.2022.03.03.15.19.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Mar 2022 15:19:25 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 05/12] btrfs: remove unnecessary inode_set_bytes(0) call Date: Thu, 3 Mar 2022 15:18:55 -0800 Message-Id: X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Omar Sandoval new_inode() always returns an inode with i_blocks and i_bytes set to 0 (via inode_init_always()). Remove the unnecessary call to inode_set_bytes() in btrfs_new_inode(). Signed-off-by: Omar Sandoval --- fs/btrfs/inode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 244e8d6ed5e4..b7d54b0b2fb5 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6207,7 +6207,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, goto fail_unlock; inode_init_owner(mnt_userns, inode, dir, mode); - inode_set_bytes(inode, 0); inode->i_mtime = current_time(inode); inode->i_atime = inode->i_mtime; From patchwork Thu Mar 3 23:18:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 12768274 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8D854C4332F for ; Thu, 3 Mar 2022 23:19:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236940AbiCCXUS (ORCPT ); Thu, 3 Mar 2022 18:20:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56596 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236642AbiCCXUO (ORCPT ); Thu, 3 Mar 2022 18:20:14 -0500 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4BF5C15F090 for ; Thu, 3 Mar 2022 15:19:27 -0800 (PST) Received: by mail-pj1-x1030.google.com with SMTP id mr24-20020a17090b239800b001bf0a375440so3776171pjb.4 for ; Thu, 03 Mar 2022 15:19:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=oz1oNqIfMm4Cmy4YhvA49X206rRkGkJIw0ay+dbHTpQ=; b=uwdTwMBuKVSy7bQk5Yjr935Awtku5OyCOrUXT6Hh1QZc7DSxmMBG0c6apgCVBaO5q2 T5CJRKdF7l+Sa3GrX8YIirisnNgbsVakN7QKt6O6i71FySwhjiT8OWnEmphctYk8i7oK 2DaS+CejrYpThxPuHcpZmFkkhk1mZD/ompmMe5M8CJOnhtD0SsjMRNdZJLx5leGW7lo2 Pl7VF1bm9givr0dilnkm5sbtMENdUhJ1nV71rs4+KED/rEaITggfYmEBIxnuFsAiHw99 slOfS7XKZW30v0UMog8zEkWTS2NZYZSBI+LvfxZBH+nvKEmXWtKZBut2feVPw/UyhxVT Rmhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oz1oNqIfMm4Cmy4YhvA49X206rRkGkJIw0ay+dbHTpQ=; b=NL7t/8m2iyxeS46vS0Y3nWoNkcJGlvY42SrjGJw8zUbO2NxSm9nT0ARsBlRFc2KyC4 hg+FI7BnyAnJFs/lHnElqMIhuXuqoq79OFLnrBfn//Z1aMdDlluMNgZ79gVQPqisVtYL DPqYUNuROy2m8I3gTG2NHN5UtDnycLTuFbgolGWxYqcTWEHwPVGVnbh4lkldms7ciVCg UoVcGKPY3NzdTHrL5fEmN9e58Q30lVEfgUo5KBxzKzGau0pPGiS/XSxznB3fOda2jGyz +DiLvLSXcHl2V/D5AeOaogYfRUqYPXl8C8WSCiai/pBQKLcfAaZovT9BTRpc81eixvF9 vEgg== X-Gm-Message-State: AOAM532j9iqZ8IKq2M1N2/UpkT04te7r3ybiswxYX2hBYuLqF53TgO/w yOoMLpwz8BzMvdcNYCN29iGZw+4XRK/h7A== X-Google-Smtp-Source: ABdhPJxqMMQsJhXoo8QpA7O1O7jCx6WbOsGWu8TUAVzFRJNxeSGueXGD+LJuFNPN+vjPbIC97Wrmrw== X-Received: by 2002:a17:902:aa84:b0:150:8d6:bdec with SMTP id d4-20020a170902aa8400b0015008d6bdecmr37956806plr.118.1646349566533; Thu, 03 Mar 2022 15:19:26 -0800 (PST) Received: from relinquished.tfbnw.net ([2620:10d:c090:400::5:76ce]) by smtp.gmail.com with ESMTPSA id x7-20020a17090a1f8700b001bf1db72189sm1103507pja.23.2022.03.03.15.19.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Mar 2022 15:19:26 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 06/12] btrfs: remove unnecessary set_nlink() in btrfs_create_subvol_root() Date: Thu, 3 Mar 2022 15:18:56 -0800 Message-Id: X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Omar Sandoval btrfs_new_inode() already returns an inode with nlink set to 1 (via inode_init_always()). Get rid of the unnecessary set. Signed-off-by: Omar Sandoval --- fs/btrfs/inode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b7d54b0b2fb5..a9dabe9e5500 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -8784,7 +8784,6 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, inode->i_op = &btrfs_dir_inode_operations; inode->i_fop = &btrfs_dir_file_operations; - set_nlink(inode, 1); unlock_new_inode(inode); err = btrfs_subvol_inherit_props(trans, new_root, parent_root); From patchwork Thu Mar 3 23:18:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 12768275 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EA563C43217 for ; Thu, 3 Mar 2022 23:19:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236922AbiCCXUS (ORCPT ); Thu, 3 Mar 2022 18:20:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235932AbiCCXUO (ORCPT ); Thu, 3 Mar 2022 18:20:14 -0500 Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6E1611637DD for ; Thu, 3 Mar 2022 15:19:28 -0800 (PST) Received: by mail-pl1-x635.google.com with SMTP id z11so6149985pla.7 for ; Thu, 03 Mar 2022 15:19:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=HSocfw/j6YhN1pnIQTfafZfw9HaRlXIpVkHJDXiZ97g=; b=A13m55KRV88w+eJQjqorDcUO27NEReHmBOpptlUYmxZOis1hVc2HqkGYBO0Jze+uDq BM5YjQPStw5ThPx19z8lmWD1+jXoQK8+os/gdgsU7vxRfu7f64Mw5M3Nso42ANcbGXob AulhB1hqC7sBDMh+BgjbGYgHIBBisLaTNDUBY0L9K14M7FEmRaqu6stQ66o8l/xx4mWF L4pA3g6v981iHzy747HEsPY7yIeQmcscPa/vRSArjEYKFDGR0wCuibilbVStPgjCn3eT zfeSG7dtPzoYnR2lvUrCLgbypFWwrfpOqiagdqyUPd5yrUQJX8ApKfcG4P+g1zn2GHau yIQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=HSocfw/j6YhN1pnIQTfafZfw9HaRlXIpVkHJDXiZ97g=; b=k1M8xLN7uDp0WvSkgn2KYAlcyMZxUrq7aZ6UgaaTKEl6MH6Ssn2iHX/OPJiF1SLYYC hwBdN8oB+GrHclJpEY9W9aX3Qrc11Ov4wTir4bKhhVgZybk0jHQTXEWvsbkr2WiAKFX7 nVAukTxySX/nD9fh7ZJyvhEus8RgAVd01wgxCrkg7US6L45nS04Pm+sZHUrGCbbAwk7p UaIEIdcGSPjhuZj+IE9vkKVKHb6KMJMXAwJCTLLi4DnKitgZwbxIs/71bM83PFPdAs5s DJwH3s8EaNEbM32m6ZtGe6pjfRyVMYoLOYLUke0plMlj84PXMTQoYb7nSbJq13sKRM9M pUfg== X-Gm-Message-State: AOAM5305BaO6c9wEDsGGQ6ocOSxYtm2+cXrU2kRf7gku2tya6RJc+1SH MphcUtxNMwCuPU+nuMXaWaoCZ/u2Xe2+HA== X-Google-Smtp-Source: ABdhPJwC7q49CkV5T0wK2EKPRTEQ/8BZgF8/EPmQDuT7U+ze2pXAJ7IJ+yL+b09hZIQTqW5iVQZBPg== X-Received: by 2002:a17:902:758f:b0:14f:b5ee:cc5a with SMTP id j15-20020a170902758f00b0014fb5eecc5amr38676013pll.43.1646349567567; Thu, 03 Mar 2022 15:19:27 -0800 (PST) Received: from relinquished.tfbnw.net ([2620:10d:c090:400::5:76ce]) by smtp.gmail.com with ESMTPSA id x7-20020a17090a1f8700b001bf1db72189sm1103507pja.23.2022.03.03.15.19.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Mar 2022 15:19:27 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 07/12] btrfs: remove unused mnt_userns parameter from __btrfs_set_acl Date: Thu, 3 Mar 2022 15:18:57 -0800 Message-Id: <7317dc7ab52abf02fe0e6dcddab2a8ffc7ed372d.1646348486.git.osandov@fb.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Omar Sandoval Commit 4a8b34afa9c9 ("btrfs: handle ACLs on idmapped mounts") added this parameter but didn't use it. __btrfs_set_acl() is the low-level helper that writes an ACL to disk. The higher-level btrfs_set_acl() is the one that translates the ACL based on the user namespace. Signed-off-by: Omar Sandoval --- fs/btrfs/acl.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 0a0d0eccee4e..a6909ec9bc38 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -56,7 +56,6 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type, bool rcu) } static int __btrfs_set_acl(struct btrfs_trans_handle *trans, - struct user_namespace *mnt_userns, struct inode *inode, struct posix_acl *acl, int type) { int ret, size = 0; @@ -123,7 +122,7 @@ int btrfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, if (ret) return ret; } - ret = __btrfs_set_acl(NULL, mnt_userns, inode, acl, type); + ret = __btrfs_set_acl(NULL, inode, acl, type); if (ret) inode->i_mode = old_mode; return ret; @@ -144,14 +143,14 @@ int btrfs_init_acl(struct btrfs_trans_handle *trans, return ret; if (default_acl) { - ret = __btrfs_set_acl(trans, &init_user_ns, inode, default_acl, + ret = __btrfs_set_acl(trans, inode, default_acl, ACL_TYPE_DEFAULT); posix_acl_release(default_acl); } if (acl) { if (!ret) - ret = __btrfs_set_acl(trans, &init_user_ns, inode, acl, + ret = __btrfs_set_acl(trans, inode, acl, ACL_TYPE_ACCESS); posix_acl_release(acl); } From patchwork Thu Mar 3 23:18:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 12768278 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 433EDC433FE for ; Thu, 3 Mar 2022 23:19:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236950AbiCCXUT (ORCPT ); Thu, 3 Mar 2022 18:20:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236884AbiCCXUP (ORCPT ); Thu, 3 Mar 2022 18:20:15 -0500 Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 846633BA6E for ; Thu, 3 Mar 2022 15:19:29 -0800 (PST) Received: by mail-pj1-x1032.google.com with SMTP id mr24-20020a17090b239800b001bf0a375440so3776225pjb.4 for ; Thu, 03 Mar 2022 15:19:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fNsLLoJu73El0qniKSCwdUnuPvYFzqryV3hEiCaBQSc=; b=vCPsEiySHRk1V5PsrftqMs3w4GV1zm+TIoZqNGLxWH/vo6pHwdhokSkkDwantdAwtn V1mHeQnQiv2Mv+iJTk2SFdQ99CdQ6soVV2+ackEF+7pwiTGTJ1NIOzn03mZL5TX9kVSr 2mjXH5fyioZofSNPt+wfSU6f0+gf47n7XwpakgZa92fmpP9Q0QuFnsHoMckdGgO85nBH r5DCVeDvw/kjwInPKV1nCyaavJyBKum9BIFyXltVFBNRbgEI/ldLxWhnhcGDFeJj0d2I hLfLYGjcJ1N1HxQKrQYaswIs53h3d9qDYSllPnAg3C7+mHCfOPIz8tu1HOvmL3y/VlNu niZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fNsLLoJu73El0qniKSCwdUnuPvYFzqryV3hEiCaBQSc=; b=R5Tm9PixxRLsJUrAsB5BR1Hg8QSP345i5O5rF9WjA4MN144+lY/NvBzp/hfdWdKDiX bCW5dfi5R9DJv/XHNFBq1ronheTJc2LcIyw+FZHMZJDHXP41hMTSBLAoaHwHhnG4qfGJ SwWemPVcVFSSOvSBhmLgqVZbdH5gFBrJ3zxDzQ/6w2t1M+qPcqR3DFV12pE04NkZpiPa k21pPPWL4oWMxYebH+fmMMffrXxF/Mo4P2yJweDr9uAmq1ZnNgMQXkdWwWHl5Z1nfWj1 C9rhK4KRdZ/ORR0ORwpPFBVqbSeA7NNPjE/ZCEHfJ1o3uwDI1/mibeC8ncPnWH5132TW 3PBQ== X-Gm-Message-State: AOAM530lnwmJe0qV/jnMlIiddfgZ9YGL9XHxuXZyRICYWlSfZmEZ24Zk /gYtkSHqRAh7JBTGIsSDMGhnJHiJURKymg== X-Google-Smtp-Source: ABdhPJw9lWGTkGRdF2zDtYiiFUKtDJLEyNOdQrhbK9AKLgjWl6RworCt+KZLviskSyM90HldXIUcuA== X-Received: by 2002:a17:902:d2ce:b0:151:6781:affa with SMTP id n14-20020a170902d2ce00b001516781affamr23643418plc.168.1646349568483; Thu, 03 Mar 2022 15:19:28 -0800 (PST) Received: from relinquished.tfbnw.net ([2620:10d:c090:400::5:76ce]) by smtp.gmail.com with ESMTPSA id x7-20020a17090a1f8700b001bf1db72189sm1103507pja.23.2022.03.03.15.19.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Mar 2022 15:19:28 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 08/12] btrfs: remove redundant name and name_len parameters to create_subvol Date: Thu, 3 Mar 2022 15:18:58 -0800 Message-Id: <42d46e9d36ca960d6c5b64e14ecdea0b3cd1393b.1646348486.git.osandov@fb.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Omar Sandoval The passed dentry already contains the name. Signed-off-by: Omar Sandoval --- fs/btrfs/ioctl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 238cee5b5254..3cea5530ad83 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -546,9 +546,10 @@ int __pure btrfs_is_empty_uuid(u8 *uuid) static noinline int create_subvol(struct user_namespace *mnt_userns, struct inode *dir, struct dentry *dentry, - const char *name, int namelen, struct btrfs_qgroup_inherit *inherit) { + const char *name = dentry->d_name.name; + int namelen = dentry->d_name.len; struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); struct btrfs_trans_handle *trans; struct btrfs_key key; @@ -983,7 +984,7 @@ static noinline int btrfs_mksubvol(const struct path *parent, if (snap_src) error = create_snapshot(snap_src, dir, dentry, readonly, inherit); else - error = create_subvol(mnt_userns, dir, dentry, name, namelen, inherit); + error = create_subvol(mnt_userns, dir, dentry, inherit); if (!error) fsnotify_mkdir(dir, dentry); From patchwork Thu Mar 3 23:18:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 12768279 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C9A64C43219 for ; Thu, 3 Mar 2022 23:19:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237129AbiCCXUU (ORCPT ); Thu, 3 Mar 2022 18:20:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56780 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236562AbiCCXUQ (ORCPT ); Thu, 3 Mar 2022 18:20:16 -0500 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6367F14FFDD for ; Thu, 3 Mar 2022 15:19:30 -0800 (PST) Received: by mail-pj1-x1035.google.com with SMTP id gb21so5916597pjb.5 for ; Thu, 03 Mar 2022 15:19:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=13QpFG7i2coJtFsQrtcKk29inMBAj/dznjcFwI7nKZY=; b=yHXKRda8cisw7I/nnzcpXmlqNCOlxEMuTcbwl7It7bXupo7qdsgsJXXMUjrFhJmfx3 swRsRfjiL+X9r4cQH+uOYDMi0GK78tS/DNlIzgE9JU3cIMSjavIIecE0akpXmX3wENpp kstjZ2FJ9o4uuJUFNeZpS5wIAZrTvusrL3aS9Qgu4hRr6IuPHxR9QH1+3VSxu5Im1USB fjXd5+fb8gvYeidWAhoEz7wu5SqOGscyKSFFf0If0wubANXcGCyCgj1S4e/36qaD3Ba5 0JNoB5XmbxZHetYV31Rjqxsdtwhf+f7Aa0cypW7/gLi9+Q6hdxnn0itkQvg2yh5gGBud NY3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=13QpFG7i2coJtFsQrtcKk29inMBAj/dznjcFwI7nKZY=; b=2whaTIBVfmQzBJM3ReT5/x6DFe2WzMrAl1JVbzyy2OcKWJpyIh/azXztyITHjSaF7e ZvABnxJoCybMW+OL4GViQ0f+5xVdSDm5VRRguIUThsuesvMqCpuk7MQQJIJFLBX9lSBq +/WIHR73AcyWQGSyRRfJY8kYsQfsMZQOOYbRl52pzm5Z9b8ovWSfGELO+bX2x3Pzs6KZ k2ACRjYEmNR/a2+eYj0ZKJkpFytGdiA38pUjK9ibOZQuq+RpIu0bPZXj2WZXf/+bUyEg R1nlcYZq8q1UESzVyYUoGC//9eusHYfH6QwxVx8IwA8P/LYye2NJszJqvhqO89ukOrHp rAWw== X-Gm-Message-State: AOAM533BY9crMg+sgjQCn0FXlg5wglMeJoOS8JrpMPEAt40rHiRXB88j IGVNKmaN0NxrMKTNBubOWRV38YZRvS0clw== X-Google-Smtp-Source: ABdhPJxvpxbMMRD9GajNQhVvJ9UH+PStpvxTPEt9DJFLSdZBLPcNoJya50TGe0uOFEtkJ/4ijZLdQQ== X-Received: by 2002:a17:902:860a:b0:14b:341e:5ffb with SMTP id f10-20020a170902860a00b0014b341e5ffbmr38131239plo.6.1646349569515; Thu, 03 Mar 2022 15:19:29 -0800 (PST) Received: from relinquished.tfbnw.net ([2620:10d:c090:400::5:76ce]) by smtp.gmail.com with ESMTPSA id x7-20020a17090a1f8700b001bf1db72189sm1103507pja.23.2022.03.03.15.19.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Mar 2022 15:19:29 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 09/12] btrfs: don't pass parent objectid to btrfs_new_inode() explicitly Date: Thu, 3 Mar 2022 15:18:59 -0800 Message-Id: X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Omar Sandoval For everything other than a subvolume root inode, we get the parent objectid from the parent directory. For the subvolume root inode, the parent objectid is the same as the inode's objectid. We can find this within btrfs_new_inode() instead of passing it. Signed-off-by: Omar Sandoval --- fs/btrfs/inode.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a9dabe9e5500..9c845c67421a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6095,8 +6095,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, struct user_namespace *mnt_userns, struct inode *dir, const char *name, int name_len, - u64 ref_objectid, u64 objectid, - umode_t mode, u64 *index) + u64 objectid, umode_t mode, u64 *index) { struct btrfs_fs_info *fs_info = root->fs_info; struct inode *inode; @@ -6182,7 +6181,10 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, */ key[1].objectid = objectid; key[1].type = BTRFS_INODE_REF_KEY; - key[1].offset = ref_objectid; + if (dir) + key[1].offset = btrfs_ino(BTRFS_I(dir)); + else + key[1].offset = objectid; sizes[1] = name_len + sizeof(*ref); } @@ -6380,7 +6382,7 @@ static int btrfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, inode = btrfs_new_inode(trans, root, mnt_userns, dir, dentry->d_name.name, dentry->d_name.len, - btrfs_ino(BTRFS_I(dir)), objectid, mode, &index); + objectid, mode, &index); if (IS_ERR(inode)) { err = PTR_ERR(inode); inode = NULL; @@ -6444,7 +6446,7 @@ static int btrfs_create(struct user_namespace *mnt_userns, struct inode *dir, inode = btrfs_new_inode(trans, root, mnt_userns, dir, dentry->d_name.name, dentry->d_name.len, - btrfs_ino(BTRFS_I(dir)), objectid, mode, &index); + objectid, mode, &index); if (IS_ERR(inode)) { err = PTR_ERR(inode); inode = NULL; @@ -6589,7 +6591,7 @@ static int btrfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, inode = btrfs_new_inode(trans, root, mnt_userns, dir, dentry->d_name.name, dentry->d_name.len, - btrfs_ino(BTRFS_I(dir)), objectid, + objectid, S_IFDIR | mode, &index); if (IS_ERR(inode)) { err = PTR_ERR(inode); @@ -8776,7 +8778,7 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, return err; inode = btrfs_new_inode(trans, new_root, mnt_userns, NULL, "..", 2, - ino, ino, + ino, S_IFDIR | (~current_umask() & S_IRWXUGO), &index); if (IS_ERR(inode)) @@ -9289,7 +9291,6 @@ static int btrfs_whiteout_for_rename(struct btrfs_trans_handle *trans, inode = btrfs_new_inode(trans, root, mnt_userns, dir, dentry->d_name.name, dentry->d_name.len, - btrfs_ino(BTRFS_I(dir)), objectid, S_IFCHR | WHITEOUT_MODE, &index); @@ -9783,7 +9784,7 @@ static int btrfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, inode = btrfs_new_inode(trans, root, mnt_userns, dir, dentry->d_name.name, dentry->d_name.len, - btrfs_ino(BTRFS_I(dir)), objectid, + objectid, S_IFLNK | S_IRWXUGO, &index); if (IS_ERR(inode)) { err = PTR_ERR(inode); @@ -10134,7 +10135,7 @@ static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, goto out; inode = btrfs_new_inode(trans, root, mnt_userns, dir, NULL, 0, - btrfs_ino(BTRFS_I(dir)), objectid, mode, &index); + objectid, mode, &index); if (IS_ERR(inode)) { ret = PTR_ERR(inode); inode = NULL; From patchwork Thu Mar 3 23:19:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 12768280 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5C068C4332F for ; Thu, 3 Mar 2022 23:19:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237075AbiCCXUV (ORCPT ); Thu, 3 Mar 2022 18:20:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56832 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236284AbiCCXUR (ORCPT ); Thu, 3 Mar 2022 18:20:17 -0500 Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1FB113A1AA for ; Thu, 3 Mar 2022 15:19:31 -0800 (PST) Received: by mail-pl1-x62d.google.com with SMTP id bd1so6128720plb.13 for ; Thu, 03 Mar 2022 15:19:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KaXjNK4dXMkufXXJQqVaoztHpfljK682q4NK7Xbpr/o=; b=ns+IuSFah05ZCfPw4THwPgRCDqOWrPyN/hQR3ZcY8faNEG2cdjTHplghc3TyJFEy3Q zJ6bE3YkPAUzU+ByRUuMRXX08TZqnmbAdIEFjmRrf6YKWlTYsEOTACPrPBqJIF3sHIX9 ZPwvYZBgu5kA+xRGs/K3wRyFOL0/imnpYbkv17zAEtbuKn5aOeQgnWHVOzPL7lNMjGqp omE5ZjnHXamVvCkDawz+/INsuDIWhKjiiPE57eMFijwhYATk6Th8kKOdYEK2P8CjW94G b1fe1gvUZSDMsX6TioYE3TVZJ6U/c4ruMu18so25+MaUZMhP4sIfzJT0eoiiuvhd6+Ct vtQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=KaXjNK4dXMkufXXJQqVaoztHpfljK682q4NK7Xbpr/o=; b=r2dB0wZ8YrQvM9jhnA9MvoXuw14SVbo6/WPIJRkW/RMYn5Jthi4RYrUzFap2jRCJM0 WF+4Ohj9PEp8iHd9XG5P5mI29V4Cm+STSm4GCT6K+gfWCZ69m2q+HLs2rrlYqNzX9gVO ta3wo/T+Bk4zX+fZSfQwoGN+UpoM+ed9cZ8U149Pe/PNfflxNlc1p2tJBabUz5h0oSzZ ljrxLuA4eYN0dWSllLnhctAIt0CNMhZ8C6fg3d77mhK1OQ3TA8PCTG/56hgJZTdbAk29 30oTd/DAgMIgN91cH20KrHrIAdssnDwEzIm/Ez1dNrRChogOw5wJoPuF3eyxLfYTCjWv 3/Dg== X-Gm-Message-State: AOAM531CkgHG/FiFLd+/8pJKqIYGmOlPC6I9/kV5IMHqfTvwgMpsCcas MzDjiNu9z14ffSmd3+MNUJn4GsEbtOu/Mg== X-Google-Smtp-Source: ABdhPJziUi91l7a/FaIqtc6MIrIJ12gjzgzNQP/ye4ckToyWRFIxCDSkHnJb+ScwbGPnZKCxfp95Xg== X-Received: by 2002:a17:90b:3503:b0:1bc:5d68:e7a2 with SMTP id ls3-20020a17090b350300b001bc5d68e7a2mr7824264pjb.29.1646349570317; Thu, 03 Mar 2022 15:19:30 -0800 (PST) Received: from relinquished.tfbnw.net ([2620:10d:c090:400::5:76ce]) by smtp.gmail.com with ESMTPSA id x7-20020a17090a1f8700b001bf1db72189sm1103507pja.23.2022.03.03.15.19.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Mar 2022 15:19:30 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 10/12] btrfs: move btrfs_get_free_objectid() call into btrfs_new_inode() Date: Thu, 3 Mar 2022 15:19:00 -0800 Message-Id: <445cc006b66e4c8be60c389284e2861c1b22c84a.1646348486.git.osandov@fb.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Omar Sandoval Every call of btrfs_new_inode() is immediately preceded by a call to btrfs_get_free_objectid(). Since getting an inode number is part of creating a new inode, this is better off being moved into btrfs_new_inode(). While we're here, get rid of the comment about reclaiming inode numbers, since we only did that when using the ino cache, which was removed by commit 5297199a8bca ("btrfs: remove inode number cache feature"). Signed-off-by: Omar Sandoval --- fs/btrfs/inode.c | 58 +++++++++--------------------------------------- 1 file changed, 11 insertions(+), 47 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9c845c67421a..289bb5176e09 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6095,13 +6095,14 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, struct user_namespace *mnt_userns, struct inode *dir, const char *name, int name_len, - u64 objectid, umode_t mode, u64 *index) + umode_t mode, u64 *index) { struct btrfs_fs_info *fs_info = root->fs_info; struct inode *inode; struct btrfs_inode_item *inode_item; struct btrfs_key *location; struct btrfs_path *path; + u64 objectid; struct btrfs_inode_ref *ref; struct btrfs_key key[2]; u32 sizes[2]; @@ -6129,10 +6130,12 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, if (!name) set_nlink(inode, 0); - /* - * we have to initialize this early, so we can reclaim the inode - * number if we fail afterwards in this function. - */ + ret = btrfs_get_free_objectid(root, &objectid); + if (ret) { + btrfs_free_path(path); + iput(inode); + return ERR_PTR(ret); + } inode->i_ino = objectid; if (dir && name) { @@ -6364,7 +6367,6 @@ static int btrfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, struct btrfs_root *root = BTRFS_I(dir)->root; struct inode *inode = NULL; int err; - u64 objectid; u64 index = 0; /* @@ -6376,13 +6378,9 @@ static int btrfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, if (IS_ERR(trans)) return PTR_ERR(trans); - err = btrfs_get_free_objectid(root, &objectid); - if (err) - goto out_unlock; - inode = btrfs_new_inode(trans, root, mnt_userns, dir, dentry->d_name.name, dentry->d_name.len, - objectid, mode, &index); + mode, &index); if (IS_ERR(inode)) { err = PTR_ERR(inode); inode = NULL; @@ -6428,7 +6426,6 @@ static int btrfs_create(struct user_namespace *mnt_userns, struct inode *dir, struct btrfs_root *root = BTRFS_I(dir)->root; struct inode *inode = NULL; int err; - u64 objectid; u64 index = 0; /* @@ -6440,13 +6437,9 @@ static int btrfs_create(struct user_namespace *mnt_userns, struct inode *dir, if (IS_ERR(trans)) return PTR_ERR(trans); - err = btrfs_get_free_objectid(root, &objectid); - if (err) - goto out_unlock; - inode = btrfs_new_inode(trans, root, mnt_userns, dir, dentry->d_name.name, dentry->d_name.len, - objectid, mode, &index); + mode, &index); if (IS_ERR(inode)) { err = PTR_ERR(inode); inode = NULL; @@ -6573,7 +6566,6 @@ static int btrfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(dir)->root; int err = 0; - u64 objectid = 0; u64 index = 0; /* @@ -6585,13 +6577,8 @@ static int btrfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, if (IS_ERR(trans)) return PTR_ERR(trans); - err = btrfs_get_free_objectid(root, &objectid); - if (err) - goto out_fail; - inode = btrfs_new_inode(trans, root, mnt_userns, dir, dentry->d_name.name, dentry->d_name.len, - objectid, S_IFDIR | mode, &index); if (IS_ERR(inode)) { err = PTR_ERR(inode); @@ -8771,14 +8758,8 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, struct inode *inode; int err; u64 index = 0; - u64 ino; - - err = btrfs_get_free_objectid(new_root, &ino); - if (err < 0) - return err; inode = btrfs_new_inode(trans, new_root, mnt_userns, NULL, "..", 2, - ino, S_IFDIR | (~current_umask() & S_IRWXUGO), &index); if (IS_ERR(inode)) @@ -9281,17 +9262,11 @@ static int btrfs_whiteout_for_rename(struct btrfs_trans_handle *trans, { int ret; struct inode *inode; - u64 objectid; u64 index; - ret = btrfs_get_free_objectid(root, &objectid); - if (ret) - return ret; - inode = btrfs_new_inode(trans, root, mnt_userns, dir, dentry->d_name.name, dentry->d_name.len, - objectid, S_IFCHR | WHITEOUT_MODE, &index); @@ -9755,7 +9730,6 @@ static int btrfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, struct btrfs_key key; struct inode *inode = NULL; int err; - u64 objectid; u64 index = 0; int name_len; int datasize; @@ -9778,13 +9752,8 @@ static int btrfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, if (IS_ERR(trans)) return PTR_ERR(trans); - err = btrfs_get_free_objectid(root, &objectid); - if (err) - goto out_unlock; - inode = btrfs_new_inode(trans, root, mnt_userns, dir, dentry->d_name.name, dentry->d_name.len, - objectid, S_IFLNK | S_IRWXUGO, &index); if (IS_ERR(inode)) { err = PTR_ERR(inode); @@ -10119,7 +10088,6 @@ static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(dir)->root; struct inode *inode = NULL; - u64 objectid; u64 index; int ret = 0; @@ -10130,12 +10098,8 @@ static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, if (IS_ERR(trans)) return PTR_ERR(trans); - ret = btrfs_get_free_objectid(root, &objectid); - if (ret) - goto out; - inode = btrfs_new_inode(trans, root, mnt_userns, dir, NULL, 0, - objectid, mode, &index); + mode, &index); if (IS_ERR(inode)) { ret = PTR_ERR(inode); inode = NULL; From patchwork Thu Mar 3 23:19:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 12768281 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05105C433EF for ; Thu, 3 Mar 2022 23:19:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236284AbiCCXUV (ORCPT ); Thu, 3 Mar 2022 18:20:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236642AbiCCXUS (ORCPT ); Thu, 3 Mar 2022 18:20:18 -0500 Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 739A314FFDA for ; Thu, 3 Mar 2022 15:19:32 -0800 (PST) Received: by mail-pf1-x434.google.com with SMTP id a5so6043696pfv.9 for ; Thu, 03 Mar 2022 15:19:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tT3zKHSOw+1OA9qq/fd1n42XgS5dcWFrdiK1St0Uoys=; b=xN6Z6jtSJLMar9tZjvRImESGFromc3TTxKNyrr0FiMkcKIlLVZHH14mOYmGopN/lGV cyywiEWljXxWAvKfdpLg7QKOVjCqIqWkttJLwVtFpZHizYk61sFNWnBUmXOmIYuQ3KSk Cn49lTW1bPgVdenf3eUNtz6wh931/Cu9OgZa8hOoZpr4Hu44aXx3c9PDA29ghJ5mIuR6 0DxIZVU67FGyFBGMXoIv0ts7viC5nT3rsjwZp7f3YFKGZ6lcis9CWZjvVGztXhXpGEpc byKPQsVSwjzgMW/Ym0hmVeyJRocNh5hQY6nAlJYVEE3FUd6sSREmdbg2pS1tSprQlQ48 p67Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tT3zKHSOw+1OA9qq/fd1n42XgS5dcWFrdiK1St0Uoys=; b=rBL+vKHEYhe+kKzV9JppC0WaKF9qzAZ4CWLFxBswYEK3e15GDHic3k13p0kHBORusu RBnmlSYjQoBCmdcuPnb1zbbw2v+wTfcOEf2MUdtJEDVW/yOmmQTCu0Ukt0PTrEsY7co0 ans75wf36RUaHUs/kzp+S5px3wjbIhqKTxXlNYXVdaUQ5dgPmxeRPutlodvnLOJhmy0x f+eNDNWZ6FIOyECpJ8w5yeas7Ll2TVqhPpdPxhjBQqgKE2liuervGr7GppkelBo9i98Y oG/t7TIXDoHFeK/D+LjJ9oY78qCgT1fx1rXqG0HEQ98Dcg+ECsKzo0IvHp8FBciKeaBC VUHA== X-Gm-Message-State: AOAM530DTHVtSZ+GftggrAQ3w5K9/ZHv95PElMUzsGiBHr5bANO+lh1U ioQ2hu5DaCLYfHcyPqesYFrluMhzOWqZ3w== X-Google-Smtp-Source: ABdhPJzpQvV8FdrwgOKMv/JfzLqlVKUp0NjVSRcJBwHvIxSpx4z6Jk72IQ3egsNC+CW6GPF7DSBxWQ== X-Received: by 2002:a63:86c2:0:b0:37c:5844:a0e7 with SMTP id x185-20020a6386c2000000b0037c5844a0e7mr3911400pgd.306.1646349571386; Thu, 03 Mar 2022 15:19:31 -0800 (PST) Received: from relinquished.tfbnw.net ([2620:10d:c090:400::5:76ce]) by smtp.gmail.com with ESMTPSA id x7-20020a17090a1f8700b001bf1db72189sm1103507pja.23.2022.03.03.15.19.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Mar 2022 15:19:31 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 11/12] btrfs: set inode flags earlier in btrfs_new_inode() Date: Thu, 3 Mar 2022 15:19:01 -0800 Message-Id: <185c84ec115df2b9dca9cb9523e9006d6e225e36.1646348486.git.osandov@fb.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Omar Sandoval btrfs_new_inode() inherits the inode flags from the parent directory and the mount options _after_ we fill the inode item. This works because all of the callers of btrfs_new_inode() make further changes to the inode and then call btrfs_update_inode(). It'd be better to fully initialize the inode once to avoid the extra update, so as a first step, set the inode flags _before_ filling the inode item. Signed-off-by: Omar Sandoval --- fs/btrfs/inode.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 289bb5176e09..c47bdada2440 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6161,6 +6161,16 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, BTRFS_I(inode)->generation = trans->transid; inode->i_generation = BTRFS_I(inode)->generation; + btrfs_inherit_iflags(inode, dir); + + if (S_ISREG(mode)) { + if (btrfs_test_opt(fs_info, NODATASUM)) + BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM; + if (btrfs_test_opt(fs_info, NODATACOW)) + BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW | + BTRFS_INODE_NODATASUM; + } + /* * We could have gotten an inode number from somebody who was fsynced * and then removed in this same transaction, so let's just set full @@ -6236,16 +6246,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(path->nodes[0]); btrfs_free_path(path); - btrfs_inherit_iflags(inode, dir); - - if (S_ISREG(mode)) { - if (btrfs_test_opt(fs_info, NODATASUM)) - BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM; - if (btrfs_test_opt(fs_info, NODATACOW)) - BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW | - BTRFS_INODE_NODATASUM; - } - inode_tree_add(inode); trace_btrfs_inode_new(inode); From patchwork Thu Mar 3 23:19:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 12768282 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79DE8C433EF for ; Thu, 3 Mar 2022 23:19:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236562AbiCCXUY (ORCPT ); Thu, 3 Mar 2022 18:20:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57246 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236642AbiCCXUX (ORCPT ); Thu, 3 Mar 2022 18:20:23 -0500 Received: from mail-pj1-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1512B2DD6D for ; Thu, 3 Mar 2022 15:19:34 -0800 (PST) Received: by mail-pj1-x102a.google.com with SMTP id 15-20020a17090a098f00b001bef0376d5cso6414352pjo.5 for ; Thu, 03 Mar 2022 15:19:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CLINxLnfOwThGvK62EORK9JMWC7kPmp05dCmongQNoM=; b=Y3PzBz+0d/98ZXon/CjFF0fEP7ZbFK7M0zW1MqLx/TA1lqxlZCYXtOnq4doDt0mL3t 5reMhQgkHVMIhZmNilAwF/KSGicHvweiKCw+bWM1Ry4eg+QE4/Ylg+32SmEWxXsobAcJ pCq/nSWvRCcGe9JIt5k1S+UywvaEXXKKqz+nJh9H1ljLGiGxGRpW0dDvpKwM4zUJ2Fke IXR1I97pQIYs/qJVBWPgA+xXHPmOIJAG10Vbv+Voq6WDVlnzBO/AQ9UdfigAdGE95uax +n58dxI4UDJ1dv+Ndco5BG0xTWgakyg0DQ1A30FTf4uNYgZsu+ZsXN2RzqMEdLMUsqom BH8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CLINxLnfOwThGvK62EORK9JMWC7kPmp05dCmongQNoM=; b=CGrub7jRssvpce1mcQ53X/77vmPiXogLbZzKalD8aPEP7kcwJmR9zHieIiI6t6mP0q 4P7n/ZNlYVdRCT74X/2Aq7ZfKw694C40PFvvqWxhkbrqMoVzQVWgtt13krxrXRUJBeEw Qs5EjfV/CsBjVgz3V/x8bosJmT7J8VEcw9nFp+8nfNho6OsrDt9WYHZBuWCjWMewAcfv v2ZIsKbhMrSxkMhbMbD+EfR8v0tjO/iaDncmzpkAw1jBwX+CE8JvIzjog1nxyHDkUE5a jFXIdEKOGYGIbpup0GnR1GXq0eXwnkhQxszi1dWLCGyxtCEF0MpTztMXrIBjNupaslB0 H6tQ== X-Gm-Message-State: AOAM5324dtSCbHSuK32Lg20k84xuo3U5W3w3P3up0sigOEAQw071dJAD GoQVSQr6vqdjEdW+ULdlLkZKZsYQdXuByQ== X-Google-Smtp-Source: ABdhPJybeenfpEmUQkhzl+nomAXtkUXZVuKCUii9ZBj7Sro7wFX6YKsJPuCVjdkexmbBIlf676LJ4Q== X-Received: by 2002:a17:903:2c5:b0:14f:4a29:1f64 with SMTP id s5-20020a17090302c500b0014f4a291f64mr39228484plk.90.1646349572625; Thu, 03 Mar 2022 15:19:32 -0800 (PST) Received: from relinquished.tfbnw.net ([2620:10d:c090:400::5:76ce]) by smtp.gmail.com with ESMTPSA id x7-20020a17090a1f8700b001bf1db72189sm1103507pja.23.2022.03.03.15.19.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Mar 2022 15:19:32 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 12/12] btrfs: rework inode creation to fix several issues Date: Thu, 3 Mar 2022 15:19:02 -0800 Message-Id: X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Omar Sandoval Inode creation currently has several issues: * Parts of the creation code path are duplicated between every operation that creates an inode: create, mknod, mkdir, RENAME_WHITEOUT, symlink, O_TMPFILE, and subvolume creation. This makes it hard to fix bugs or add features to inode creation (in particular, preparatory work for fscrypt). * Subvolume creation in particular duplicates code in a way that diverges from the usual inode creation behavior when it comes to inherting flags, properties, permissions, and ACLs. * We insert an inode item first and then modify the inode and update the item again. This is a silly inefficiency. * Creation does not account for the compression property, ACLs, or the parent inode item when starting the transaction. * We can leak an inode on disk in some error cases. For example, in btrfs_create(), if btrfs_new_inode() succeeds, then we have inserted an inode item and its inode ref. However, if something after that fails (e.g., btrfs_init_inode_security()), then we end the transaction and then decrement the link count on the inode. If the transaction is committed and the system crashes before the failed inode is deleted, then we leak that inode on disk. I tried to fix these issues in their own separate patches, but they're all interconnected and much easier to fix all in one go. The solution is to unify all of the inode creation code paths into a single code path with two steps: 1. btrfs_new_inode_prepare(), which does the correct accounting and security preparations (currently POSIX ACLs, but this is where fscrypt context setup will go). 2. btrfs_create_new_inode(), which does the actual B-tree modifications for the inode and its name. This is a straightforward fix for the code duplication issue, the unnecessary inode update issue, and the accounting issue. It explicitly does _not_ change the existing non-standard subvolume behavior around flags, permissions, ACLs, etc., but it makes those differences more clear in the code and documents them so that we can discuss whether they should be changed. Finally, it fixes the inode leak issue by aborting the transaction when we can't recover more gracefully. This shouldn't be an issue now that we're accounting space correctly. Signed-off-by: Omar Sandoval --- fs/btrfs/acl.c | 36 +-- fs/btrfs/ctree.h | 39 ++- fs/btrfs/inode.c | 801 +++++++++++++++++++++++------------------------ fs/btrfs/ioctl.c | 174 +++++----- fs/btrfs/props.c | 40 +-- fs/btrfs/props.h | 4 - 6 files changed, 508 insertions(+), 586 deletions(-) diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index a6909ec9bc38..548d6a5477b4 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -55,8 +55,8 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type, bool rcu) return acl; } -static int __btrfs_set_acl(struct btrfs_trans_handle *trans, - struct inode *inode, struct posix_acl *acl, int type) +int __btrfs_set_acl(struct btrfs_trans_handle *trans, struct inode *inode, + struct posix_acl *acl, int type) { int ret, size = 0; const char *name; @@ -127,35 +127,3 @@ int btrfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, inode->i_mode = old_mode; return ret; } - -int btrfs_init_acl(struct btrfs_trans_handle *trans, - struct inode *inode, struct inode *dir) -{ - struct posix_acl *default_acl, *acl; - int ret = 0; - - /* this happens with subvols */ - if (!dir) - return 0; - - ret = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl); - if (ret) - return ret; - - if (default_acl) { - ret = __btrfs_set_acl(trans, inode, default_acl, - ACL_TYPE_DEFAULT); - posix_acl_release(default_acl); - } - - if (acl) { - if (!ret) - ret = __btrfs_set_acl(trans, inode, acl, - ACL_TYPE_ACCESS); - posix_acl_release(acl); - } - - if (!default_acl && !acl) - cache_no_acl(inode); - return ret; -} diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 4db17bd05a21..6fa63dfac573 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3254,10 +3254,30 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, long nr, int btrfs_set_extent_delalloc(struct btrfs_inode *inode, u64 start, u64 end, unsigned int extra_bits, struct extent_state **cached_state); -int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, - struct btrfs_root *new_root, - struct btrfs_root *parent_root, - struct user_namespace *mnt_userns); + +struct btrfs_new_inode_args { + /* Input */ + struct inode *dir; + struct dentry *dentry; + struct inode *inode; + bool orphan; + bool subvol; + + /* + * Output from btrfs_new_inode_prepare(), input to + * btrfs_create_new_inode(). + */ + struct posix_acl *default_acl; + struct posix_acl *acl; +}; +int btrfs_new_inode_prepare(struct btrfs_new_inode_args *args, + unsigned int *trans_num_items); +int btrfs_create_new_inode(struct btrfs_trans_handle *trans, + struct btrfs_new_inode_args *args); +void btrfs_new_inode_args_free(struct btrfs_new_inode_args *args); +struct inode *btrfs_new_subvol_inode(struct user_namespace *mnt_userns, + struct inode *dir); + void btrfs_set_delalloc_extent(struct inode *inode, struct extent_state *state, unsigned *bits); void btrfs_clear_delalloc_extent(struct inode *inode, @@ -3815,15 +3835,16 @@ static inline int __btrfs_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag) struct posix_acl *btrfs_get_acl(struct inode *inode, int type, bool rcu); int btrfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, struct posix_acl *acl, int type); -int btrfs_init_acl(struct btrfs_trans_handle *trans, - struct inode *inode, struct inode *dir); +int __btrfs_set_acl(struct btrfs_trans_handle *trans, struct inode *inode, + struct posix_acl *acl, int type); #else #define btrfs_get_acl NULL #define btrfs_set_acl NULL -static inline int btrfs_init_acl(struct btrfs_trans_handle *trans, - struct inode *inode, struct inode *dir) +static inline int __btrfs_set_acl(struct btrfs_trans_handle *trans, + struct inode *inode, struct posix_acl *acl, + int type) { - return 0; + return -EOPNOTSUPP; } #endif diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index c47bdada2440..2f17e0598664 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -223,14 +223,26 @@ static int btrfs_dirty_inode(struct inode *inode); static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir, - const struct qstr *qstr) + const struct qstr *qstr, + struct posix_acl *default_acl, + struct posix_acl *acl) { int err; - err = btrfs_init_acl(trans, inode, dir); - if (!err) - err = btrfs_xattr_security_init(trans, inode, dir, qstr); - return err; + if (default_acl) { + err = __btrfs_set_acl(trans, inode, default_acl, + ACL_TYPE_DEFAULT); + if (err) + return err; + } + if (acl) { + err = __btrfs_set_acl(trans, inode, acl, ACL_TYPE_ACCESS); + if (err) + return err; + } + if (!default_acl && !acl) + cache_no_acl(inode); + return btrfs_xattr_security_init(trans, inode, dir, qstr); } /* @@ -6059,6 +6071,49 @@ static int btrfs_insert_inode_locked(struct inode *inode) btrfs_find_actor, &args); } +int btrfs_new_inode_prepare(struct btrfs_new_inode_args *args, + unsigned int *trans_num_items) +{ + struct inode *dir = args->dir; + struct inode *inode = args->inode; + int ret; + + ret = posix_acl_create(dir, &inode->i_mode, &args->default_acl, + &args->acl); + if (ret) + return ret; + + *trans_num_items = 1; /* 1 to add inode item */ + if (BTRFS_I(dir)->prop_compress) + (*trans_num_items)++; /* 1 to add compression property */ + if (args->default_acl) + (*trans_num_items)++; /* 1 to add default ACL xattr */ + if (args->acl) + (*trans_num_items)++; /* 1 to add access ACL xattr */ +#ifdef CONFIG_SECURITY + if (dir->i_security) + (*trans_num_items)++; /* 1 to add LSM xattr */ +#endif + if (args->orphan) { + (*trans_num_items)++; /* 1 to add orphan item */ + } else { + /* + * 1 to add inode ref + * 1 to add dir item + * 1 to add dir index + * 1 to update parent inode item + */ + *trans_num_items += 4; + } + return 0; +} + +void btrfs_new_inode_args_free(struct btrfs_new_inode_args *args) +{ + posix_acl_release(args->acl); + posix_acl_release(args->default_acl); +} + /* * Inherit flags from the parent inode. * @@ -6068,9 +6123,6 @@ static void btrfs_inherit_iflags(struct inode *inode, struct inode *dir) { unsigned int flags; - if (!dir) - return; - flags = BTRFS_I(dir)->flags; if (flags & BTRFS_INODE_NOCOMPRESS) { @@ -6090,65 +6142,52 @@ static void btrfs_inherit_iflags(struct inode *inode, struct inode *dir) btrfs_sync_inode_flags_to_i_flags(inode); } -static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct user_namespace *mnt_userns, - struct inode *dir, - const char *name, int name_len, - umode_t mode, u64 *index) +int btrfs_create_new_inode(struct btrfs_trans_handle *trans, + struct btrfs_new_inode_args *args) { - struct btrfs_fs_info *fs_info = root->fs_info; - struct inode *inode; - struct btrfs_inode_item *inode_item; - struct btrfs_key *location; + struct inode *dir = args->dir; + struct inode *inode = args->inode; + const char *name = args->orphan ? NULL : args->dentry->d_name.name; + int name_len = args->orphan ? 0 : args->dentry->d_name.len; + struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); struct btrfs_path *path; u64 objectid; - struct btrfs_inode_ref *ref; + struct btrfs_key *location; + struct btrfs_root *root; struct btrfs_key key[2]; u32 sizes[2]; struct btrfs_item_batch batch; + struct btrfs_inode_item *inode_item; + struct btrfs_inode_ref *ref; unsigned long ptr; - unsigned int nofs_flag; int ret; path = btrfs_alloc_path(); if (!path) - return ERR_PTR(-ENOMEM); + return -ENOMEM; - nofs_flag = memalloc_nofs_save(); - inode = new_inode(fs_info->sb); - memalloc_nofs_restore(nofs_flag); - if (!inode) { - btrfs_free_path(path); - return ERR_PTR(-ENOMEM); - } - - /* - * O_TMPFILE, set link count to 0, so that after this point, - * we fill in an inode item with the correct link count. - */ - if (!name) - set_nlink(inode, 0); + if (!args->subvol) + BTRFS_I(inode)->root = btrfs_grab_root(BTRFS_I(dir)->root); + root = BTRFS_I(inode)->root; ret = btrfs_get_free_objectid(root, &objectid); - if (ret) { - btrfs_free_path(path); - iput(inode); - return ERR_PTR(ret); - } + if (ret) + goto out; inode->i_ino = objectid; - if (dir && name) { + if (args->orphan) { + /* + * O_TMPFILE, set link count to 0, so that after this point, we + * fill in an inode item with the correct link count. + */ + set_nlink(inode, 0); + } else { trace_btrfs_inode_request(dir); - ret = btrfs_set_inode_index(BTRFS_I(dir), index); - if (ret) { - btrfs_free_path(path); - iput(inode); - return ERR_PTR(ret); - } - } else if (dir) { - *index = 0; + ret = btrfs_set_inode_index(BTRFS_I(dir), + &BTRFS_I(inode)->dir_index); + if (ret) + goto out; } /* * index_cnt is ignored for everything but a dir, @@ -6156,14 +6195,18 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, * number */ BTRFS_I(inode)->index_cnt = 2; - BTRFS_I(inode)->dir_index = *index; - BTRFS_I(inode)->root = btrfs_grab_root(root); BTRFS_I(inode)->generation = trans->transid; inode->i_generation = BTRFS_I(inode)->generation; - btrfs_inherit_iflags(inode, dir); + /* + * Subvolumes don't inherit flags from their parent directory. + * Originally this was probably by accident, but we probably can't + * change it now. + */ + if (!args->subvol) + btrfs_inherit_iflags(inode, dir); - if (S_ISREG(mode)) { + if (S_ISREG(inode->i_mode)) { if (btrfs_test_opt(fs_info, NODATASUM)) BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM; if (btrfs_test_opt(fs_info, NODATACOW)) @@ -6171,6 +6214,57 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, BTRFS_INODE_NODATASUM; } + location = &BTRFS_I(inode)->location; + location->objectid = objectid; + location->offset = 0; + location->type = BTRFS_INODE_ITEM_KEY; + + ret = btrfs_insert_inode_locked(inode); + if (ret < 0) { + if (!args->orphan) + BTRFS_I(dir)->index_cnt--; + goto out; + } + + if (args->subvol) { + struct inode *parent; + + /* + * Subvolumes inherit properties from their parent subvolume, + * not the directory they were created in. + */ + parent = btrfs_iget(fs_info->sb, BTRFS_FIRST_FREE_OBJECTID, + BTRFS_I(dir)->root); + if (IS_ERR(parent)) { + ret = PTR_ERR(parent); + } else { + ret = btrfs_inode_inherit_props(trans, inode, parent); + iput(parent); + } + } else { + ret = btrfs_inode_inherit_props(trans, inode, dir); + } + if (ret) { + btrfs_err(fs_info, + "error inheriting props for ino %llu (root %llu): %d", + btrfs_ino(BTRFS_I(inode)), root->root_key.objectid, + ret); + } + + /* + * Subvolumes don't inherit ACLs or get passed to the LSM. This is + * probably a bug. + */ + if (!args->subvol) { + ret = btrfs_init_inode_security(trans, inode, dir, + &args->dentry->d_name, + args->default_acl, args->acl); + if (ret) { + btrfs_abort_transaction(trans, ret); + goto discard; + } + } + /* * We could have gotten an inode number from somebody who was fsynced * and then removed in this same transaction, so let's just set full @@ -6185,7 +6279,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, sizes[0] = sizeof(struct btrfs_inode_item); - if (name) { + if (!args->orphan) { /* * Start new inodes with an inode_ref. This is slightly more * efficient for small numbers of hard links since they will @@ -6194,57 +6288,61 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, */ key[1].objectid = objectid; key[1].type = BTRFS_INODE_REF_KEY; - if (dir) - key[1].offset = btrfs_ino(BTRFS_I(dir)); - else + if (args->subvol) { key[1].offset = objectid; - - sizes[1] = name_len + sizeof(*ref); - } - - location = &BTRFS_I(inode)->location; - location->objectid = objectid; - location->offset = 0; - location->type = BTRFS_INODE_ITEM_KEY; - - ret = btrfs_insert_inode_locked(inode); - if (ret < 0) { - iput(inode); - goto fail; + sizes[1] = 2 + sizeof(*ref); + } else { + key[1].offset = btrfs_ino(BTRFS_I(dir)); + sizes[1] = name_len + sizeof(*ref); + } } batch.keys = &key[0]; batch.data_sizes = &sizes[0]; - batch.total_data_size = sizes[0] + (name ? sizes[1] : 0); - batch.nr = name ? 2 : 1; + batch.total_data_size = sizes[0] + (args->orphan ? 0 : sizes[1]); + batch.nr = args->orphan ? 1 : 2; ret = btrfs_insert_empty_items(trans, root, path, &batch); - if (ret != 0) - goto fail_unlock; - - inode_init_owner(mnt_userns, inode, dir, mode); + if (ret != 0) { + btrfs_abort_transaction(trans, ret); + goto discard; + } inode->i_mtime = current_time(inode); inode->i_atime = inode->i_mtime; inode->i_ctime = inode->i_mtime; BTRFS_I(inode)->i_otime = inode->i_mtime; + /* + * We're going to fill the inode item now, so at this point the inode + * must be fully initialized. + */ + inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0], struct btrfs_inode_item); memzero_extent_buffer(path->nodes[0], (unsigned long)inode_item, sizeof(*inode_item)); fill_inode_item(trans, path->nodes[0], inode_item, inode); - if (name) { + if (!args->orphan) { ref = btrfs_item_ptr(path->nodes[0], path->slots[0] + 1, struct btrfs_inode_ref); - btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len); - btrfs_set_inode_ref_index(path->nodes[0], ref, *index); ptr = (unsigned long)(ref + 1); - write_extent_buffer(path->nodes[0], name, ptr, name_len); + if (args->subvol) { + btrfs_set_inode_ref_name_len(path->nodes[0], ref, 2); + btrfs_set_inode_ref_index(path->nodes[0], ref, 0); + write_extent_buffer(path->nodes[0], "..", ptr, 2); + } else { + btrfs_set_inode_ref_name_len(path->nodes[0], ref, + name_len); + btrfs_set_inode_ref_index(path->nodes[0], ref, + BTRFS_I(inode)->dir_index); + write_extent_buffer(path->nodes[0], name, ptr, + name_len); + } } btrfs_mark_buffer_dirty(path->nodes[0]); - btrfs_free_path(path); + btrfs_release_path(path); inode_tree_add(inode); @@ -6253,21 +6351,26 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, btrfs_update_root_times(trans, root); - ret = btrfs_inode_inherit_props(trans, inode, dir); - if (ret) - btrfs_err(fs_info, - "error inheriting props for ino %llu (root %llu): %d", - btrfs_ino(BTRFS_I(inode)), root->root_key.objectid, ret); + if (args->orphan) { + ret = btrfs_orphan_add(trans, BTRFS_I(inode)); + } else { + ret = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), name, + name_len, 0, BTRFS_I(inode)->dir_index); + } + if (ret) { + btrfs_abort_transaction(trans, ret); + goto discard; + } - return inode; + ret = 0; + goto out; -fail_unlock: +discard: + ihold(inode); discard_new_inode(inode); -fail: - if (dir && name) - BTRFS_I(dir)->index_cnt--; +out: btrfs_free_path(path); - return ERR_PTR(ret); + return ret; } /* @@ -6359,125 +6462,72 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, return ret; } +static int btrfs_create_common(struct inode *dir, struct dentry *dentry, + struct inode *inode) +{ + + struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_root *root = BTRFS_I(dir)->root; + struct btrfs_new_inode_args new_inode_args = { + .dir = dir, + .dentry = dentry, + .inode = inode, + }; + unsigned int trans_num_items; + struct btrfs_trans_handle *trans; + int ret; + + ret = btrfs_new_inode_prepare(&new_inode_args, &trans_num_items); + if (ret) + goto out_inode; + + trans = btrfs_start_transaction(root, trans_num_items); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + goto out_new_inode_args; + } + + ret = btrfs_create_new_inode(trans, &new_inode_args); + if (!ret) + d_instantiate_new(dentry, inode); + + btrfs_end_transaction(trans); + btrfs_btree_balance_dirty(fs_info); +out_new_inode_args: + btrfs_new_inode_args_free(&new_inode_args); +out_inode: + if (ret) + iput(inode); + return ret; +} + static int btrfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); - struct btrfs_trans_handle *trans; - struct btrfs_root *root = BTRFS_I(dir)->root; - struct inode *inode = NULL; - int err; - u64 index = 0; + struct inode *inode; - /* - * 2 for inode item and ref - * 2 for dir items - * 1 for xattr if selinux is on - */ - trans = btrfs_start_transaction(root, 5); - if (IS_ERR(trans)) - return PTR_ERR(trans); - - inode = btrfs_new_inode(trans, root, mnt_userns, dir, - dentry->d_name.name, dentry->d_name.len, - mode, &index); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - inode = NULL; - goto out_unlock; - } - - /* - * If the active LSM wants to access the inode during - * d_instantiate it needs these. Smack checks to see - * if the filesystem supports xattrs by looking at the - * ops vector. - */ + inode = new_inode(dir->i_sb); + if (!inode) + return -ENOMEM; + inode_init_owner(mnt_userns, inode, dir, mode); inode->i_op = &btrfs_special_inode_operations; init_special_inode(inode, inode->i_mode, rdev); - - err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); - if (err) - goto out_unlock; - - err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), - dentry->d_name.name, dentry->d_name.len, 0, index); - if (err) - goto out_unlock; - - btrfs_update_inode(trans, root, BTRFS_I(inode)); - d_instantiate_new(dentry, inode); - -out_unlock: - btrfs_end_transaction(trans); - btrfs_btree_balance_dirty(fs_info); - if (err && inode) { - inode_dec_link_count(inode); - discard_new_inode(inode); - } - return err; + return btrfs_create_common(dir, dentry, inode); } static int btrfs_create(struct user_namespace *mnt_userns, struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); - struct btrfs_trans_handle *trans; - struct btrfs_root *root = BTRFS_I(dir)->root; - struct inode *inode = NULL; - int err; - u64 index = 0; + struct inode *inode; - /* - * 2 for inode item and ref - * 2 for dir items - * 1 for xattr if selinux is on - */ - trans = btrfs_start_transaction(root, 5); - if (IS_ERR(trans)) - return PTR_ERR(trans); - - inode = btrfs_new_inode(trans, root, mnt_userns, dir, - dentry->d_name.name, dentry->d_name.len, - mode, &index); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - inode = NULL; - goto out_unlock; - } - /* - * If the active LSM wants to access the inode during - * d_instantiate it needs these. Smack checks to see - * if the filesystem supports xattrs by looking at the - * ops vector. - */ + inode = new_inode(dir->i_sb); + if (!inode) + return -ENOMEM; + inode_init_owner(mnt_userns, inode, dir, mode); inode->i_fop = &btrfs_file_operations; inode->i_op = &btrfs_file_inode_operations; inode->i_mapping->a_ops = &btrfs_aops; - - err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); - if (err) - goto out_unlock; - - err = btrfs_update_inode(trans, root, BTRFS_I(inode)); - if (err) - goto out_unlock; - - err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), - dentry->d_name.name, dentry->d_name.len, 0, index); - if (err) - goto out_unlock; - - d_instantiate_new(dentry, inode); - -out_unlock: - btrfs_end_transaction(trans); - if (err && inode) { - inode_dec_link_count(inode); - discard_new_inode(inode); - } - btrfs_btree_balance_dirty(fs_info); - return err; + return btrfs_create_common(dir, dentry, inode); } static int btrfs_link(struct dentry *old_dentry, struct inode *dir, @@ -6561,59 +6611,15 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, static int btrfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, struct dentry *dentry, umode_t mode) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); - struct inode *inode = NULL; - struct btrfs_trans_handle *trans; - struct btrfs_root *root = BTRFS_I(dir)->root; - int err = 0; - u64 index = 0; + struct inode *inode; - /* - * 2 items for inode and ref - * 2 items for dir items - * 1 for xattr if selinux is on - */ - trans = btrfs_start_transaction(root, 5); - if (IS_ERR(trans)) - return PTR_ERR(trans); - - inode = btrfs_new_inode(trans, root, mnt_userns, dir, - dentry->d_name.name, dentry->d_name.len, - S_IFDIR | mode, &index); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - inode = NULL; - goto out_fail; - } - - /* these must be set before we unlock the inode */ + inode = new_inode(dir->i_sb); + if (!inode) + return -ENOMEM; + inode_init_owner(mnt_userns, inode, dir, S_IFDIR | mode); inode->i_op = &btrfs_dir_inode_operations; inode->i_fop = &btrfs_dir_file_operations; - - err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); - if (err) - goto out_fail; - - err = btrfs_update_inode(trans, root, BTRFS_I(inode)); - if (err) - goto out_fail; - - err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), - dentry->d_name.name, - dentry->d_name.len, 0, index); - if (err) - goto out_fail; - - d_instantiate_new(dentry, inode); - -out_fail: - btrfs_end_transaction(trans); - if (err && inode) { - inode_dec_link_count(inode); - discard_new_inode(inode); - } - btrfs_btree_balance_dirty(fs_info); - return err; + return btrfs_create_common(dir, dentry, inode); } static noinline int uncompress_inline(struct btrfs_path *path, @@ -8747,38 +8753,23 @@ static int btrfs_truncate(struct inode *inode, bool skip_writeback) return ret; } -/* - * create a new subvolume directory/inode (helper for the ioctl). - */ -int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, - struct btrfs_root *new_root, - struct btrfs_root *parent_root, - struct user_namespace *mnt_userns) +struct inode *btrfs_new_subvol_inode(struct user_namespace *mnt_userns, + struct inode *dir) { struct inode *inode; - int err; - u64 index = 0; - inode = btrfs_new_inode(trans, new_root, mnt_userns, NULL, "..", 2, - S_IFDIR | (~current_umask() & S_IRWXUGO), - &index); - if (IS_ERR(inode)) - return PTR_ERR(inode); + inode = new_inode(dir->i_sb); + if (!inode) + return NULL; + /* + * Subvolumes don't inherit the sgid bit or the parent's gid if the + * parent's sgid bit is set. This is probably a bug. + */ + inode_init_owner(mnt_userns, inode, NULL, + S_IFDIR | (~current_umask() & S_IRWXUGO)); inode->i_op = &btrfs_dir_inode_operations; inode->i_fop = &btrfs_dir_file_operations; - - unlock_new_inode(inode); - - err = btrfs_subvol_inherit_props(trans, new_root, parent_root); - if (err) - btrfs_err(new_root->fs_info, - "error inheriting subvolume %llu properties: %d", - new_root->root_key.objectid, err); - - err = btrfs_update_inode(trans, new_root, BTRFS_I(inode)); - - iput(inode); - return err; + return inode; } struct inode *btrfs_alloc_inode(struct super_block *sb) @@ -9254,49 +9245,19 @@ static int btrfs_rename_exchange(struct inode *old_dir, return ret; } -static int btrfs_whiteout_for_rename(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct user_namespace *mnt_userns, - struct inode *dir, - struct dentry *dentry) +static struct inode *new_whiteout_inode(struct user_namespace *mnt_userns, + struct inode *dir) { - int ret; struct inode *inode; - u64 index; - inode = btrfs_new_inode(trans, root, mnt_userns, dir, - dentry->d_name.name, - dentry->d_name.len, - S_IFCHR | WHITEOUT_MODE, - &index); - - if (IS_ERR(inode)) { - ret = PTR_ERR(inode); - return ret; + inode = new_inode(dir->i_sb); + if (inode) { + inode_init_owner(mnt_userns, inode, dir, + S_IFCHR | WHITEOUT_MODE); + inode->i_op = &btrfs_special_inode_operations; + init_special_inode(inode, inode->i_mode, WHITEOUT_DEV); } - - inode->i_op = &btrfs_special_inode_operations; - init_special_inode(inode, inode->i_mode, - WHITEOUT_DEV); - - ret = btrfs_init_inode_security(trans, inode, dir, - &dentry->d_name); - if (ret) - goto out; - - ret = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), - dentry->d_name.name, dentry->d_name.len, 0, index); - if (ret) - goto out; - - ret = btrfs_update_inode(trans, root, BTRFS_I(inode)); -out: - unlock_new_inode(inode); - if (ret) - inode_dec_link_count(inode); - iput(inode); - - return ret; + return inode; } static int btrfs_rename(struct user_namespace *mnt_userns, @@ -9305,6 +9266,10 @@ static int btrfs_rename(struct user_namespace *mnt_userns, unsigned int flags) { struct btrfs_fs_info *fs_info = btrfs_sb(old_dir->i_sb); + struct btrfs_new_inode_args whiteout_args = { + .dir = old_dir, + .dentry = old_dentry, + }; struct btrfs_trans_handle *trans; unsigned int trans_num_items; struct btrfs_root *root = BTRFS_I(old_dir)->root; @@ -9359,6 +9324,18 @@ static int btrfs_rename(struct user_namespace *mnt_userns, if (new_inode && S_ISREG(old_inode->i_mode) && new_inode->i_size) filemap_flush(old_inode->i_mapping); + if (flags & RENAME_WHITEOUT) { + whiteout_args.inode = new_whiteout_inode(mnt_userns, old_dir); + if (!whiteout_args.inode) + return -ENOMEM; + ret = btrfs_new_inode_prepare(&whiteout_args, &trans_num_items); + if (ret) + goto out_whiteout_inode; + } else { + /* 1 to update the old parent inode. */ + trans_num_items = 1; + } + if (old_ino == BTRFS_FIRST_FREE_OBJECTID) { /* close the racy window with snapshot create/destroy ioctl */ down_read(&fs_info->subvol_sem); @@ -9368,24 +9345,25 @@ static int btrfs_rename(struct user_namespace *mnt_userns, * 1 to add new root ref * 1 to add new root backref */ - trans_num_items = 4; + trans_num_items += 4; } else { /* * 1 to update inode * 1 to remove old inode ref * 1 to add new inode ref */ - trans_num_items = 3; + trans_num_items += 3; } /* * 1 to remove old dir item * 1 to remove old dir index - * 1 to update old parent inode * 1 to add new dir item * 1 to add new dir index - * 1 to update new parent inode (if it's not the same as the old parent) */ - trans_num_items += 6; + trans_num_items += 4; + /* + * 1 to update new parent inode if it's not the same as the old parent + */ if (new_dir != old_dir) trans_num_items++; if (new_inode) { @@ -9398,8 +9376,6 @@ static int btrfs_rename(struct user_namespace *mnt_userns, */ trans_num_items += 5; } - if (flags & RENAME_WHITEOUT) - trans_num_items += 5; trans = btrfs_start_transaction(root, trans_num_items); if (IS_ERR(trans)) { ret = PTR_ERR(trans); @@ -9495,12 +9471,14 @@ static int btrfs_rename(struct user_namespace *mnt_userns, rename_ctx.index, new_dentry->d_parent); if (flags & RENAME_WHITEOUT) { - ret = btrfs_whiteout_for_rename(trans, root, mnt_userns, - old_dir, old_dentry); - + ret = btrfs_create_new_inode(trans, &whiteout_args); if (ret) { btrfs_abort_transaction(trans, ret); goto out_fail; + } else { + unlock_new_inode(whiteout_args.inode); + iput(whiteout_args.inode); + whiteout_args.inode = NULL; } } out_fail: @@ -9509,7 +9487,11 @@ static int btrfs_rename(struct user_namespace *mnt_userns, out_notrans: if (old_ino == BTRFS_FIRST_FREE_OBJECTID) up_read(&fs_info->subvol_sem); - + if (flags & RENAME_WHITEOUT) + btrfs_new_inode_args_free(&whiteout_args); +out_whiteout_inode: + if (flags & RENAME_WHITEOUT) + iput(whiteout_args.inode); return ret; } @@ -9724,13 +9706,17 @@ static int btrfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, struct dentry *dentry, const char *symname) { struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct inode *inode; + struct btrfs_new_inode_args new_inode_args = { + .dir = dir, + .dentry = dentry, + }; + unsigned int trans_num_items; struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_path *path; struct btrfs_key key; - struct inode *inode = NULL; int err; - u64 index = 0; int name_len; int datasize; unsigned long ptr; @@ -9741,44 +9727,40 @@ static int btrfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(fs_info)) return -ENAMETOOLONG; - /* - * 2 items for inode item and ref - * 2 items for dir items - * 1 item for updating parent inode item - * 1 item for the inline extent item - * 1 item for xattr if selinux is on - */ - trans = btrfs_start_transaction(root, 7); - if (IS_ERR(trans)) - return PTR_ERR(trans); + inode = new_inode(dir->i_sb); + if (!inode) + return -ENOMEM; + inode_init_owner(mnt_userns, inode, dir, S_IFLNK | S_IRWXUGO); + inode->i_op = &btrfs_symlink_inode_operations; + inode_nohighmem(inode); + inode->i_mapping->a_ops = &btrfs_aops; + btrfs_i_size_write(BTRFS_I(inode), name_len); + inode_set_bytes(inode, name_len); - inode = btrfs_new_inode(trans, root, mnt_userns, dir, - dentry->d_name.name, dentry->d_name.len, - S_IFLNK | S_IRWXUGO, &index); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - inode = NULL; - goto out_unlock; + new_inode_args.inode = inode; + err = btrfs_new_inode_prepare(&new_inode_args, &trans_num_items); + if (err) + goto out_inode; + /* 1 additional item for the inline extent */ + trans_num_items++; + + trans = btrfs_start_transaction(root, trans_num_items); + if (IS_ERR(trans)) { + err = PTR_ERR(trans); + goto out_new_inode_args; } - /* - * If the active LSM wants to access the inode during - * d_instantiate it needs these. Smack checks to see - * if the filesystem supports xattrs by looking at the - * ops vector. - */ - inode->i_fop = &btrfs_file_operations; - inode->i_op = &btrfs_file_inode_operations; - inode->i_mapping->a_ops = &btrfs_aops; - - err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); + err = btrfs_create_new_inode(trans, &new_inode_args); if (err) - goto out_unlock; + goto out; path = btrfs_alloc_path(); if (!path) { err = -ENOMEM; - goto out_unlock; + btrfs_abort_transaction(trans, err); + discard_new_inode(inode); + inode = NULL; + goto out; } key.objectid = btrfs_ino(BTRFS_I(inode)); key.offset = 0; @@ -9787,8 +9769,11 @@ static int btrfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, err = btrfs_insert_empty_item(trans, root, path, &key, datasize); if (err) { + btrfs_abort_transaction(trans, err); btrfs_free_path(path); - goto out_unlock; + discard_new_inode(inode); + inode = NULL; + goto out; } leaf = path->nodes[0]; ei = btrfs_item_ptr(leaf, path->slots[0], @@ -9806,32 +9791,16 @@ static int btrfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, btrfs_mark_buffer_dirty(leaf); btrfs_free_path(path); - inode->i_op = &btrfs_symlink_inode_operations; - inode_nohighmem(inode); - inode_set_bytes(inode, name_len); - btrfs_i_size_write(BTRFS_I(inode), name_len); - err = btrfs_update_inode(trans, root, BTRFS_I(inode)); - /* - * Last step, add directory indexes for our symlink inode. This is the - * last step to avoid extra cleanup of these indexes if an error happens - * elsewhere above. - */ - if (!err) - err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), - dentry->d_name.name, dentry->d_name.len, 0, - index); - if (err) - goto out_unlock; - d_instantiate_new(dentry, inode); - -out_unlock: + err = 0; +out: btrfs_end_transaction(trans); - if (err && inode) { - inode_dec_link_count(inode); - discard_new_inode(inode); - } btrfs_btree_balance_dirty(fs_info); +out_new_inode_args: + btrfs_new_inode_args_free(&new_inode_args); +out_inode: + if (err) + iput(inode); return err; } @@ -10085,59 +10054,61 @@ static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, struct dentry *dentry, umode_t mode) { struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); - struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(dir)->root; - struct inode *inode = NULL; - u64 index; - int ret = 0; - - /* - * 5 units required for adding orphan entry - */ - trans = btrfs_start_transaction(root, 5); - if (IS_ERR(trans)) - return PTR_ERR(trans); - - inode = btrfs_new_inode(trans, root, mnt_userns, dir, NULL, 0, - mode, &index); - if (IS_ERR(inode)) { - ret = PTR_ERR(inode); - inode = NULL; - goto out; - } + struct inode *inode; + struct btrfs_new_inode_args new_inode_args = { + .dir = dir, + .dentry = dentry, + .orphan = true, + }; + unsigned int trans_num_items; + struct btrfs_trans_handle *trans; + int ret; + inode = new_inode(dir->i_sb); + if (!inode) + return -ENOMEM; + inode_init_owner(mnt_userns, inode, dir, mode); inode->i_fop = &btrfs_file_operations; inode->i_op = &btrfs_file_inode_operations; inode->i_mapping->a_ops = &btrfs_aops; - ret = btrfs_init_inode_security(trans, inode, dir, NULL); + new_inode_args.inode = inode; + ret = btrfs_new_inode_prepare(&new_inode_args, &trans_num_items); if (ret) - goto out; + goto out_inode; - ret = btrfs_update_inode(trans, root, BTRFS_I(inode)); - if (ret) - goto out; - ret = btrfs_orphan_add(trans, BTRFS_I(inode)); - if (ret) - goto out; + trans = btrfs_start_transaction(root, trans_num_items); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + goto out_new_inode_args; + } + + ret = btrfs_create_new_inode(trans, &new_inode_args); /* - * We set number of links to 0 in btrfs_new_inode(), and here we set - * it to 1 because d_tmpfile() will issue a warning if the count is 0, - * through: + * We set number of links to 0 in btrfs_create_new_inode(), and here we + * set it to 1 because d_tmpfile() will issue a warning if the count is + * 0, through: * * d_tmpfile() -> inode_dec_link_count() -> drop_nlink() */ set_nlink(inode, 1); - d_tmpfile(dentry, inode); - unlock_new_inode(inode); - mark_inode_dirty(inode); -out: + + if (!ret) { + d_tmpfile(dentry, inode); + unlock_new_inode(inode); + mark_inode_dirty(inode); + } + btrfs_end_transaction(trans); - if (ret && inode) - discard_new_inode(inode); btrfs_btree_balance_dirty(fs_info); +out_new_inode_args: + btrfs_new_inode_args_free(&new_inode_args); +out_inode: + if (ret) + iput(inode); return ret; } diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 3cea5530ad83..4d217cff7da5 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -544,13 +544,38 @@ int __pure btrfs_is_empty_uuid(u8 *uuid) return 1; } +/* + * Calculate the number of transaction items to reserve for creating a subvolume + * or snapshot, not including the inode, directory entries, or parent directory. + */ +static unsigned int create_subvol_num_items(struct btrfs_qgroup_inherit *inherit) +{ + /* + * 1 to add root block + * 1 to add root item + * 1 to add root ref + * 1 to add root backref + * 1 to add UUID item + * 1 to add qgroup info + * 1 to add qgroup limit + * (Ideally the last two would only be accounted if qgroups are enabled, + * but that can change between now and the time we would insert them) + */ + unsigned int num_items = 7; + + if (inherit) { + /* 2 to add qgroup relations for each inherited qgroup */ + num_items += 2 * inherit->num_qgroups; + } + return num_items; +} + static noinline int create_subvol(struct user_namespace *mnt_userns, struct inode *dir, struct dentry *dentry, struct btrfs_qgroup_inherit *inherit) { - const char *name = dentry->d_name.name; - int namelen = dentry->d_name.len; struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + unsigned int trans_num_items; struct btrfs_trans_handle *trans; struct btrfs_key key; struct btrfs_root_item *root_item; @@ -560,11 +585,14 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, struct btrfs_root *new_root; struct btrfs_block_rsv block_rsv; struct timespec64 cur_time = current_time(dir); - struct inode *inode; + struct btrfs_new_inode_args new_inode_args = { + .dir = dir, + .dentry = dentry, + .subvol = true, + }; int ret; - dev_t anon_dev = 0; + dev_t anon_dev; u64 objectid; - u64 index = 0; root_item = kzalloc(sizeof(*root_item), GFP_KERNEL); if (!root_item) @@ -572,11 +600,7 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, ret = btrfs_get_free_objectid(fs_info->tree_root, &objectid); if (ret) - goto fail_free; - - ret = get_anon_bdev(&anon_dev); - if (ret < 0) - goto fail_free; + goto out_root_item; /* * Don't create subvolume whose level is not zero. Or qgroup will be @@ -584,36 +608,47 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, */ if (btrfs_qgroup_level(objectid)) { ret = -ENOSPC; - goto fail_free; + goto out_root_item; } - btrfs_init_block_rsv(&block_rsv, BTRFS_BLOCK_RSV_TEMP); - /* - * The same as the snapshot creation, please see the comment - * of create_snapshot(). - */ - ret = btrfs_subvolume_reserve_metadata(root, &block_rsv, 8, false); + ret = get_anon_bdev(&anon_dev); + if (ret < 0) + goto out_root_item; + + new_inode_args.inode = btrfs_new_subvol_inode(mnt_userns, dir); + if (!new_inode_args.inode) { + ret = -ENOMEM; + goto out_anon_dev; + } + ret = btrfs_new_inode_prepare(&new_inode_args, &trans_num_items); if (ret) - goto fail_free; + goto out_inode; + trans_num_items += create_subvol_num_items(inherit); + + btrfs_init_block_rsv(&block_rsv, BTRFS_BLOCK_RSV_TEMP); + ret = btrfs_subvolume_reserve_metadata(root, &block_rsv, + trans_num_items, false); + if (ret) + goto out_new_inode_args; trans = btrfs_start_transaction(root, 0); if (IS_ERR(trans)) { ret = PTR_ERR(trans); btrfs_subvolume_release_metadata(root, &block_rsv); - goto fail_free; + goto out_new_inode_args; } trans->block_rsv = &block_rsv; trans->bytes_reserved = block_rsv.size; ret = btrfs_qgroup_inherit(trans, 0, objectid, inherit); if (ret) - goto fail; + goto out; leaf = btrfs_alloc_tree_block(trans, root, 0, objectid, NULL, 0, 0, 0, BTRFS_NESTING_NORMAL); if (IS_ERR(leaf)) { ret = PTR_ERR(leaf); - goto fail; + goto out; } btrfs_mark_buffer_dirty(leaf); @@ -668,75 +703,47 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, btrfs_tree_unlock(leaf); btrfs_free_tree_block(trans, objectid, leaf, 0, 1); free_extent_buffer(leaf); - goto fail; + goto out; } free_extent_buffer(leaf); leaf = NULL; - key.offset = (u64)-1; new_root = btrfs_get_new_fs_root(fs_info, objectid, anon_dev); if (IS_ERR(new_root)) { - free_anon_bdev(anon_dev); ret = PTR_ERR(new_root); btrfs_abort_transaction(trans, ret); - goto fail; + goto out; } - /* Freeing will be done in btrfs_put_root() of new_root */ + /* anon_dev is owned by new_root now. */ anon_dev = 0; + BTRFS_I(new_inode_args.inode)->root = new_root; + /* ... and new_root is owned by new_inode.inode now. */ ret = btrfs_record_root_in_trans(trans, new_root); if (ret) { btrfs_put_root(new_root); btrfs_abort_transaction(trans, ret); - goto fail; - } - - ret = btrfs_create_subvol_root(trans, new_root, root, mnt_userns); - btrfs_put_root(new_root); - if (ret) { - /* We potentially lose an unused inode item here */ - btrfs_abort_transaction(trans, ret); - goto fail; - } - - /* - * insert the directory item - */ - ret = btrfs_set_inode_index(BTRFS_I(dir), &index); - if (ret) { - btrfs_abort_transaction(trans, ret); - goto fail; - } - - ret = btrfs_insert_dir_item(trans, name, namelen, BTRFS_I(dir), &key, - BTRFS_FT_DIR, index); - if (ret) { - btrfs_abort_transaction(trans, ret); - goto fail; - } - - btrfs_i_size_write(BTRFS_I(dir), dir->i_size + namelen * 2); - ret = btrfs_update_inode(trans, root, BTRFS_I(dir)); - if (ret) { - btrfs_abort_transaction(trans, ret); - goto fail; - } - - ret = btrfs_add_root_ref(trans, objectid, root->root_key.objectid, - btrfs_ino(BTRFS_I(dir)), index, name, namelen); - if (ret) { - btrfs_abort_transaction(trans, ret); - goto fail; + goto out; } ret = btrfs_uuid_tree_add(trans, root_item->uuid, BTRFS_UUID_KEY_SUBVOL, objectid); - if (ret) + if (ret) { btrfs_abort_transaction(trans, ret); + goto out; + } -fail: - kfree(root_item); + ret = btrfs_create_new_inode(trans, &new_inode_args); + if (ret) { + btrfs_abort_transaction(trans, ret); + goto out; + } + + d_instantiate_new(dentry, new_inode_args.inode); + new_inode_args.inode = NULL; + +out: trans->block_rsv = NULL; trans->bytes_reserved = 0; btrfs_subvolume_release_metadata(root, &block_rsv); @@ -745,18 +752,14 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, btrfs_end_transaction(trans); else ret = btrfs_commit_transaction(trans); - - if (!ret) { - inode = btrfs_lookup_dentry(dir, dentry); - if (IS_ERR(inode)) - return PTR_ERR(inode); - d_instantiate(dentry, inode); - } - return ret; - -fail_free: +out_new_inode_args: + btrfs_new_inode_args_free(&new_inode_args); +out_inode: + iput(new_inode_args.inode); +out_anon_dev: if (anon_dev) free_anon_bdev(anon_dev); +out_root_item: kfree(root_item); return ret; } @@ -769,6 +772,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, struct inode *inode; struct btrfs_pending_snapshot *pending_snapshot; struct btrfs_trans_handle *trans; + int trans_num_items; int ret; /* We do not support snapshotting right now. */ @@ -805,16 +809,14 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, btrfs_init_block_rsv(&pending_snapshot->block_rsv, BTRFS_BLOCK_RSV_TEMP); /* - * 1 - parent dir inode - * 2 - dir entries - * 1 - root item - * 2 - root ref/backref - * 1 - root of snapshot - * 1 - UUID item + * 1 to add dir item + * 1 to add dir index + * 1 to update parent inode item */ + trans_num_items = create_subvol_num_items(inherit) + 3; ret = btrfs_subvolume_reserve_metadata(BTRFS_I(dir)->root, - &pending_snapshot->block_rsv, 8, - false); + &pending_snapshot->block_rsv, + trans_num_items, false); if (ret) goto free_pending; diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c index 1a6d2d5b4b33..f5565c296898 100644 --- a/fs/btrfs/props.c +++ b/fs/btrfs/props.c @@ -334,9 +334,8 @@ static struct prop_handler prop_handlers[] = { }, }; -static int inherit_props(struct btrfs_trans_handle *trans, - struct inode *inode, - struct inode *parent) +int btrfs_inode_inherit_props(struct btrfs_trans_handle *trans, + struct inode *inode, struct inode *parent) { struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_fs_info *fs_info = root->fs_info; @@ -408,41 +407,6 @@ static int inherit_props(struct btrfs_trans_handle *trans, return 0; } -int btrfs_inode_inherit_props(struct btrfs_trans_handle *trans, - struct inode *inode, - struct inode *dir) -{ - if (!dir) - return 0; - - return inherit_props(trans, inode, dir); -} - -int btrfs_subvol_inherit_props(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_root *parent_root) -{ - struct super_block *sb = root->fs_info->sb; - struct inode *parent_inode, *child_inode; - int ret; - - parent_inode = btrfs_iget(sb, BTRFS_FIRST_FREE_OBJECTID, parent_root); - if (IS_ERR(parent_inode)) - return PTR_ERR(parent_inode); - - child_inode = btrfs_iget(sb, BTRFS_FIRST_FREE_OBJECTID, root); - if (IS_ERR(child_inode)) { - iput(parent_inode); - return PTR_ERR(child_inode); - } - - ret = inherit_props(trans, child_inode, parent_inode); - iput(child_inode); - iput(parent_inode); - - return ret; -} - void __init btrfs_props_init(void) { int i; diff --git a/fs/btrfs/props.h b/fs/btrfs/props.h index 40b2c65b518c..1dcd5daa3b22 100644 --- a/fs/btrfs/props.h +++ b/fs/btrfs/props.h @@ -21,8 +21,4 @@ int btrfs_inode_inherit_props(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir); -int btrfs_subvol_inherit_props(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_root *parent_root); - #endif