From patchwork Wed Aug 23 14:32:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362624 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 8DDD8EE49A0 for ; Wed, 23 Aug 2023 14:33:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236465AbjHWOdZ (ORCPT ); Wed, 23 Aug 2023 10:33:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33238 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231590AbjHWOdZ (ORCPT ); Wed, 23 Aug 2023 10:33:25 -0400 Received: from mail-yb1-xb34.google.com (mail-yb1-xb34.google.com [IPv6:2607:f8b0:4864:20::b34]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 913C2E69 for ; Wed, 23 Aug 2023 07:33:10 -0700 (PDT) Received: by mail-yb1-xb34.google.com with SMTP id 3f1490d57ef6-d71dd633f33so5599356276.2 for ; Wed, 23 Aug 2023 07:33:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801189; x=1693405989; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ZuaRbraIK7esAjwYzoHLtLR2lLxKYrV6Kvo/Tba5jPc=; b=ThLsCW/dQHTwSI96w5JAMbTzC11qNkC0XP6i9w6w5QUV4Z/E3MbOR0V2RxlxsJ9A0n YdBkueb38HpIpKprrhRrRxQKSApk5ws1BASnH2Rty+uU7bxPUcjenaT/xUnhBQzlDaul s/C8lJqDGewMAEstLkD1LEb5h+jWY9jbDe9UAECa16jmbkKFoJ+rjv+ybGfTHFwD14pW D/aI2O+albNGEUr7OXAezD7SsN/TyOlwDln0XRxPmQvSnS+Jzoq2+wdKvZNB3WowOQrC LOPOEKvY1IGPf0OYELYm5dbCZimJGXZ8bvbmV6Pe49KYSgrnKjZjUXuKqkoxYc5IBi1j HGnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801189; x=1693405989; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZuaRbraIK7esAjwYzoHLtLR2lLxKYrV6Kvo/Tba5jPc=; b=gwKNkKjz2eFLPcE+hb8brEjUyF57oyNsazYMGLUYPrTPpujsp720zhFJhex4yJpdrr qAyO18xlW2BIt11D9d7wTHIahhZweun0Duo3IUhY543DVR8BiHD+2YSsYNoaoZb8eW5w krZ4hYtW0y1aG4wQuL6g0/tVDYPxC0g5qSboBmGFGwEO7RXzr7T1M2TpJd5pG1IZhAf/ UIuNDc7OF7KazjiOHyE34zh5hOBcvrD68ALbVzK71oZQmafdK7UtP4UPZ3PAn7ma09N4 Wn+CI2fHOOSzARMHvmnSGjoiFjGxfc7s2SGwkkD8wMT2Y5YRaaJ4yKmQ1c1t12KCfgU1 ZRzQ== X-Gm-Message-State: AOJu0YxHNy//n8Q7QRwpcljLT8Kpl5HyColCTq45ASJLRcEmnsdiW2hG OYnK376vJfrZl8iTvAvzhMzS3J9bcICRM6dWuz0= X-Google-Smtp-Source: AGHT+IEKJ2vXkiVfPgW1KPj7s/BYJyEyIFLjuz4KJ+8NRhivMX0ewNt8GH9puwQr56+7DtCQ0BJbvQ== X-Received: by 2002:a25:a28e:0:b0:d6c:cd45:73b4 with SMTP id c14-20020a25a28e000000b00d6ccd4573b4mr11812367ybi.54.1692801189694; Wed, 23 Aug 2023 07:33:09 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id h186-20020a2521c3000000b00d1d0841d911sm2851121ybh.17.2023.08.23.07.33.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:09 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 01/38] btrfs-progs: stop using add_root_to_dirty_list in check Date: Wed, 23 Aug 2023 10:32:27 -0400 Message-ID: <1ca99898312945fad777d436de277df359de0076.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This is used to make sure the root is updated in the tree_root when we re-init the root, however this function is static in the kernel and doesn't need to be exported for any reason. Simply update the root item and then update it in the tree_root instead of adding it to the dirty list. Signed-off-by: Josef Bacik --- check/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/check/main.c b/check/main.c index 4565b367..d992b9f8 100644 --- a/check/main.c +++ b/check/main.c @@ -9163,8 +9163,12 @@ static int btrfs_fsck_reinit_root(struct btrfs_trans_handle *trans, free_extent_buffer(root->node); root->node = c; - add_root_to_dirty_list(root); - return 0; + + btrfs_set_root_bytenr(&root->root_item, c->start); + btrfs_set_root_generation(&root->root_item, trans->transid); + + return btrfs_update_root(trans, gfs_info->tree_root, &root->root_key, + &root->root_item); } static int reset_block_groups(void) From patchwork Wed Aug 23 14:32:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362626 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 CF176EE49B5 for ; Wed, 23 Aug 2023 14:33:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236472AbjHWOd1 (ORCPT ); Wed, 23 Aug 2023 10:33:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33274 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236463AbjHWOdZ (ORCPT ); Wed, 23 Aug 2023 10:33:25 -0400 Received: from mail-yw1-x1133.google.com (mail-yw1-x1133.google.com [IPv6:2607:f8b0:4864:20::1133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C79CBE6A for ; Wed, 23 Aug 2023 07:33:11 -0700 (PDT) Received: by mail-yw1-x1133.google.com with SMTP id 00721157ae682-58df8cab1f2so60460987b3.3 for ; Wed, 23 Aug 2023 07:33:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801191; x=1693405991; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=g3WjlWJTqtg9G6UZScCYtaSBsl+hxchuVIWEshBORPw=; b=ZUUjIUNo6VQNgpq1MiepagRrEbi4xdBUhHftd1wD6aOaKmUbE6RWZHZsxkZd6MJM5E hvUFY2wiWS96C8273HLxfs59X1MnoVEGi2YPyVsLc/f1Hgp8JDLyYYkrku7TD9H/u0EK IzPy1StIa+a8+DzQzkc1hE1G01dDyjANU98rSLSVfPm6YxiVFmqUyfZ7I3sryCAhpJCi AVQQBOQ2IwOq96xQ9tJrWHOAERhYeYvoBmCq9Q1EApyLXogfbp7OLrRoWIvYjTXAO7Z7 ZlFExdcygPBME+iVYfc24GgiP4xizq2SlIC90Gh4oK5IcnUQT/LuvkdIbGtYFli3wkbQ dzdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801191; x=1693405991; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=g3WjlWJTqtg9G6UZScCYtaSBsl+hxchuVIWEshBORPw=; b=YvpeE4EzW2jgqivZ9Bk2nTAJM4V5yk137nWMi8piv/MXv/kFSnFfS71vMskLihokVS JluyRRxVdQuTA/Zr0ph3fbMqSPmzJH0WCDmn7Sz4zQouvQXltIto5kSFsHAduqLQrid4 Zc35dsAqvlea1natw/7Cahfpjquh4Sid7YBzYNSO7Ay6Mbk3ZHw4g3mBO/aCReizco1f XnjrENAH6L20u5C7FhuYXsXrpbboMZpe/OsQIeh/JE5FqSe07PVrTTXJwvhgr/SW3X4k L5l2F9AFZOZOv5Rg2w2VLWBHTut1vpDREqI7LbpDb8hYmBDLgRVhWaAa3KCnpa2eyA89 4G8w== X-Gm-Message-State: AOJu0Yz0JxWizbP5yIZ6bErtkR9CNtD+xsG/dLIojZDP9bfZMf49uoSN PGDTMMpraHEXrxSSq4CQOXHZYe3N99WEfE4/9m0= X-Google-Smtp-Source: AGHT+IGmGz90btFb+LEpiZ6jDn9kI7wemxx8EictlhNzW+anINsrTJLlCCJRaLnah2WeOMR31PmdBw== X-Received: by 2002:a81:478b:0:b0:589:d617:e7c4 with SMTP id u133-20020a81478b000000b00589d617e7c4mr12314788ywa.16.1692801190834; Wed, 23 Aug 2023 07:33:10 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id k125-20020a819383000000b0057a8de72338sm3339966ywg.68.2023.08.23.07.33.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:10 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 02/38] btrfs-progs: remove useless add_root_to_dirty_list call in mkfs Date: Wed, 23 Aug 2023 10:32:28 -0400 Message-ID: <34ac8f222d475d692faa8d325cf63b5196912644.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org We are calling this when creating the UUID tree, however when we create the tree it inserts the root item into the tree_root, so this call is superfluous. Signed-off-by: Josef Bacik --- mkfs/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mkfs/main.c b/mkfs/main.c index 1c5d668e..1b917f55 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -789,7 +789,6 @@ static int create_uuid_tree(struct btrfs_trans_handle *trans) goto out; } - add_root_to_dirty_list(root); fs_info->uuid_root = root; ret = btrfs_uuid_tree_add(trans, fs_info->fs_root->root_item.uuid, BTRFS_UUID_KEY_SUBVOL, From patchwork Wed Aug 23 14:32:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362628 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 AD0A5EE49B2 for ; Wed, 23 Aug 2023 14:33:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236457AbjHWOd0 (ORCPT ); Wed, 23 Aug 2023 10:33:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33276 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236461AbjHWOdZ (ORCPT ); Wed, 23 Aug 2023 10:33:25 -0400 Received: from mail-ot1-x335.google.com (mail-ot1-x335.google.com [IPv6:2607:f8b0:4864:20::335]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EF893E77 for ; Wed, 23 Aug 2023 07:33:12 -0700 (PDT) Received: by mail-ot1-x335.google.com with SMTP id 46e09a7af769-6bca5d6dcedso4364767a34.1 for ; Wed, 23 Aug 2023 07:33:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801192; x=1693405992; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=gzhoi3X8eNVANHEyatN34UIapOSXaoRN4o4V10+WQeo=; b=cUbHvJxnWpjDrspGtNqaHl6DLbj79RKbLHLfJuo6XaRGrrsz5EMypajylDIczo6yF2 nBZ7QJXA86HEhDmwQ1++B8L0YW/iZUvSBjtkbhlVkxn2iFv34ieb3qjAzCUA1xF4AW3/ Un541ZFf3EfrTpKB6W+8tpCsD48NyFf0P3V9qQlZkG9kRhVvGiQuoYPTUcJS4g6MIwEZ S+LKMBKWqIyQgD1PFztUiWivOu8YIkQHTg8HGMykQKXY5u1VZYniUZeaIkjb69eIiUem mGpb1gwM1+Zrz2NdIR6SeLhCcvrW72zNAFw/P8x6gc9tgdRgCBBxSd8sw0n0g6fgpXmq FZ7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801192; x=1693405992; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gzhoi3X8eNVANHEyatN34UIapOSXaoRN4o4V10+WQeo=; b=jeilgTlvGk2RHKDgv7S88llCkzAJL1G+MYWSmP717m43O7tAslso7pUbocqiiTuePD TkUwDFYOAM160xiEBygMwt3N+naJWSNmUK9FF5Bo+uI/pltYkQIypaPQJIQN9SYAt/Zy jWoYLmEqgJh7CTtSXWl8NTblU9vOuZW7+l5tsGWSBaQgk5CWSNfh3lZlmSWsPWA/snTY GEcXvi7D8G9C4YPu8LGPnc5Q8D/9mYXqw3XaTHPer7bU4AFcAq7DteSIFUUMLTMWEcf0 30z+SXRSIwD8MVm/aSaqvsimJh7stIy/PAVh4S+AUGSljVCD3rmB7+3sPv2stQLQWbSF beVQ== X-Gm-Message-State: AOJu0YxtocBFhN7Zp6oojOhrCS9+B8phxUYCM6ojU2pZTdM0cNaDAgRF hPJ3rLoVWuz23mZX9ydkbuxCuhdRaAKr0QTlhoU= X-Google-Smtp-Source: AGHT+IFreGwYoFaTvY4ESOpAiWL8bEPyCHeDRqCVjnU6+0t49/Gxb3dZd9EPagcowUr7lzyBt12UGA== X-Received: by 2002:a05:6358:2791:b0:139:c7cb:77d4 with SMTP id l17-20020a056358279100b00139c7cb77d4mr11859680rwb.24.1692801191991; Wed, 23 Aug 2023 07:33:11 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id v14-20020a81a54e000000b00579e5c4982fsm3377201ywg.36.2023.08.23.07.33.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:11 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 03/38] btrfs-progs: remove add_root_to_dirty_list call when creating free space tree Date: Wed, 23 Aug 2023 10:32:29 -0400 Message-ID: <0fb703b5ba71157cf5fb4cb18174538a49b036d9.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Since we insert the free space tree item into the tree_root when we create the tree we don't need to call add_root_to_dirty_list. Signed-off-by: Josef Bacik --- kernel-shared/free-space-tree.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel-shared/free-space-tree.c b/kernel-shared/free-space-tree.c index a2a3663d..34a19464 100644 --- a/kernel-shared/free-space-tree.c +++ b/kernel-shared/free-space-tree.c @@ -1522,7 +1522,6 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info) ret = btrfs_global_root_insert(fs_info, free_space_root); if (ret) goto abort; - add_root_to_dirty_list(free_space_root); do { block_group = btrfs_lookup_first_block_group(fs_info, start); From patchwork Wed Aug 23 14:32:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362627 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 37950EE49A3 for ; Wed, 23 Aug 2023 14:33:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236473AbjHWOd1 (ORCPT ); Wed, 23 Aug 2023 10:33:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236464AbjHWOdZ (ORCPT ); Wed, 23 Aug 2023 10:33:25 -0400 Received: from mail-yw1-x1132.google.com (mail-yw1-x1132.google.com [IPv6:2607:f8b0:4864:20::1132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 20CAAE78 for ; Wed, 23 Aug 2023 07:33:14 -0700 (PDT) Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-58c92a2c52dso61783237b3.2 for ; Wed, 23 Aug 2023 07:33:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801193; x=1693405993; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=OCyZHB34BZce4FZ4PGz6ESIQhV8F8G7pmPqidbHJmNY=; b=nEIuoiS1OAJmKLZa24Qh0uFikFT/lQ2sduHsG141eswSFsQZ13sarxFuYj3CYz8k0Z S71PvVLP+RCJ+rmNtoE7CZWj2UiIZaXIdXd22RwSCwFpF6ID0/LQhTN46UETv3CN4qFb JJkIM73UdZbsde7wJCfjr/ywS0+Epp2Rr1CcvKL0UsgvLV+jLVXAkkU5xx3fGnn5zRL5 Md67Sea/N4P91gqrlIjp4BlOAMxdElTuOjirvpxaawaK+btO1wgaJo+dVVl+nqi97E2C /Zx1aHB+ZLhSzLWIb8Jr5+E+nCv5oulD0Mf1a90YzhuAd0X230OLAdkHE7s5poWkzR89 ulOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801193; x=1693405993; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=OCyZHB34BZce4FZ4PGz6ESIQhV8F8G7pmPqidbHJmNY=; b=hpsh0/gg9Rjskwm+3v4YlzxfquQQv6/ReTUn5RtLniZATYRziLi8ige4DCMdNQGLnj JCxdkbQPIjmyhWBBFN4DT0ZcqZitYwpk4CLBpwmQ+y+ENVO+njXOdvZAHgd/03+2GUKq 8Rd6Q0oXZ5LuSMmeAITySCjHQOT4UUIjwBUXQDGqkFbRr/fJkJ8Tnko4zH7/P76PoT6z 3ItJetsEvwDZJgyWYFcNDVL1jlnkXMAyjeh/P1yNznJd58Cm7guoPyLFU1vdnYngyDOx Q0lTn16hTYN+3mhLZ6bm5j2QfrMIl2tt2PMf/agqfc4OIHqFchuLPfN1zsKrwYXxM4Hu vjlA== X-Gm-Message-State: AOJu0YyM/APm+53vZrTU3KjU/aqzoLfKOM0AjfnB0SAejeK8waBk6glo Eivgu6jT64omiHFmzH8K9Ah4rXO6/TwhLEIWiIA= X-Google-Smtp-Source: AGHT+IHymjphZsvWDdq2bwBXtYIzfq8s+u86tz5BSBKYdCgiBNF0lXl82YU8drs93fbwRwwX/WpH1w== X-Received: by 2002:a81:8402:0:b0:586:a684:e7b6 with SMTP id u2-20020a818402000000b00586a684e7b6mr13298678ywf.9.1692801193228; Wed, 23 Aug 2023 07:33:13 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id i80-20020a816d53000000b00570599de9a5sm3357294ywc.88.2023.08.23.07.33.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:12 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 04/38] btrfs-progs: make add_root_to_dirty_list static and unexport it Date: Wed, 23 Aug 2023 10:32:30 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Now that there are no users of this helper outside of ctree.c, unexport it and make it static. Signed-off-by: Josef Bacik --- kernel-shared/ctree.c | 2 +- kernel-shared/ctree.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 51b126c6..6e88b4a9 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -262,7 +262,7 @@ bool __cold abort_should_print_stack(int errno) return true; } -void add_root_to_dirty_list(struct btrfs_root *root) +static void add_root_to_dirty_list(struct btrfs_root *root) { if (test_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state) && list_empty(&root->dirty_list)) { diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 59533879..15ac310e 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -989,7 +989,6 @@ int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path, u64 iobjectid, u64 ioff, u8 key_type, struct btrfs_key *found_key); void btrfs_release_path(struct btrfs_path *p); -void add_root_to_dirty_list(struct btrfs_root *root); struct btrfs_path *btrfs_alloc_path(void); void btrfs_free_path(struct btrfs_path *p); void btrfs_init_path(struct btrfs_path *p); From patchwork Wed Aug 23 14:32:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362630 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 065C4EE49A0 for ; Wed, 23 Aug 2023 14:33:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236477AbjHWOd3 (ORCPT ); Wed, 23 Aug 2023 10:33:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33316 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236467AbjHWOd0 (ORCPT ); Wed, 23 Aug 2023 10:33:26 -0400 Received: from mail-yb1-xb32.google.com (mail-yb1-xb32.google.com [IPv6:2607:f8b0:4864:20::b32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4ECFFE79 for ; Wed, 23 Aug 2023 07:33:15 -0700 (PDT) Received: by mail-yb1-xb32.google.com with SMTP id 3f1490d57ef6-d71c3a32e1aso5300350276.3 for ; Wed, 23 Aug 2023 07:33:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801194; x=1693405994; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=e1wMhu87fj8yCR2Ff3q/jizxT4irK1HD29PxYua+r/A=; b=PzywyVbCvrOtHsdVb6mi6Br7IIa8Wg59OxEKlZaoPU1v77ENAeL8ToEnV/Ar3im0Kj 2KB9NnVcLLw2ZGC/QG1seGzb0Ry1eWAo//2RUm5gXLx4gL0Hyr5zLik7ECEUJLdqvpa7 h2eeOhLejdvs11Oc9V596V0JZhesMHhGQYejWBtRgyBLpFcF8HYljehM+uN3RvH5x5ZE nm9SLlyUiWXJZtuyqhKLiRG5eqfkPaGigsFHnauI7/rGc8QFB9RAjMzh6cFMUPlfZh5C Ok8aYELlAAaz1rKqpqrtM64K+/oLqE0lZOF4sY7icf6PX7VQ6aHKy35T6rsOLUpB4hgL qHrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801194; x=1693405994; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=e1wMhu87fj8yCR2Ff3q/jizxT4irK1HD29PxYua+r/A=; b=QMASbMidVOzM+NVVxLaZrGofzEgEXHfBAwCjoZpZTnqrooYl4me4kQv73Cl9vL4PQP mOIMRTxcrcSvb9TvvTKHtR1OJcrR/EuMgpHe0XAsfrnOjoZDYpctK2gRwOAlOXvT0yWX g5If7sVCHhQSW9Q+JogYphS8AHhqgb67MASAr6pfv09/6qwXPiK560cKXFe44ADYnhpm OkHl4HU6+Ig0JYUuQ1W6zEnVRBfgeTzaMqUqkzuwh3Y5FmlLX3bMSRjI/voKOyYGF0NZ 4Ho89nkxwAhlEccNc+tdGscoY9Ez0XCsAmH7x7o7VjcUhskEb8AX/g4qqERt7iNLmHte ybFw== X-Gm-Message-State: AOJu0YzP5ylHivG3OoMp0+SL7F+2MYdNBihwfaC/hO2ogjO9lBp3vqgE acO5mAc7oxZQdG5kcAg8xCCD8DYdLXRJu0Ndi9Q= X-Google-Smtp-Source: AGHT+IF+ifNJdwDotM5yA4ylXn5hm22d+PyFAAev3G2L63ImiP83hqkcV6q1c55/2t1qaiaN656zJw== X-Received: by 2002:a25:bccb:0:b0:d50:60a4:a1b6 with SMTP id l11-20020a25bccb000000b00d5060a4a1b6mr11218388ybm.63.1692801194331; Wed, 23 Aug 2023 07:33:14 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id y127-20020a253285000000b00d74c43dad49sm1495108yby.48.2023.08.23.07.33.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:14 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 05/38] btrfs-progs: pass btrfs_trans_handle through btrfs_clear_buffer_dirty Date: Wed, 23 Aug 2023 10:32:31 -0400 Message-ID: <7bb1e13416572388567f149591690ab8b80b6d1d.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This is the calling convention in the kernel because we track dirty blocks per transaction instead of globally in the fs_info. Simply mirror what we do in the kernel to make it easier to sync ctree.c locally. Signed-off-by: Josef Bacik --- cmds/rescue.c | 2 +- kernel-shared/ctree.c | 12 ++++++------ kernel-shared/disk-io.c | 2 +- kernel-shared/extent-tree.c | 2 +- kernel-shared/extent_io.c | 3 ++- kernel-shared/extent_io.h | 4 +++- kernel-shared/transaction.c | 4 ++-- 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/cmds/rescue.c b/cmds/rescue.c index e244d1af..cf39edd3 100644 --- a/cmds/rescue.c +++ b/cmds/rescue.c @@ -340,7 +340,7 @@ static int clear_uuid_tree(struct btrfs_fs_info *fs_info) if (ret < 0) goto out; list_del(&uuid_root->dirty_list); - ret = btrfs_clear_buffer_dirty(uuid_root->node); + ret = btrfs_clear_buffer_dirty(trans, uuid_root->node); if (ret < 0) goto out; ret = btrfs_free_tree_block(trans, btrfs_root_id(uuid_root), diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 6e88b4a9..a87a79b2 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -571,7 +571,7 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ret = btrfs_dec_ref(trans, root, buf, 1); BUG_ON(ret); } - btrfs_clear_buffer_dirty(buf); + btrfs_clear_buffer_dirty(trans, buf); } return 0; } @@ -917,7 +917,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, root->node = child; add_root_to_dirty_list(root); path->nodes[level] = NULL; - btrfs_clear_buffer_dirty(mid); + btrfs_clear_buffer_dirty(trans, mid); /* once for the path */ free_extent_buffer(mid); @@ -971,7 +971,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, u64 bytenr = right->start; u32 blocksize = right->len; - btrfs_clear_buffer_dirty(right); + btrfs_clear_buffer_dirty(trans, right); free_extent_buffer(right); right = NULL; wret = btrfs_del_ptr(root, path, level + 1, pslot + 1); @@ -1018,7 +1018,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, /* we've managed to empty the middle node, drop it */ u64 bytenr = mid->start; u32 blocksize = mid->len; - btrfs_clear_buffer_dirty(mid); + btrfs_clear_buffer_dirty(trans, mid); free_extent_buffer(mid); mid = NULL; wret = btrfs_del_ptr(root, path, level + 1, pslot); @@ -2982,7 +2982,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, if (leaf == root->node) { btrfs_set_header_level(leaf, 0); } else { - btrfs_clear_buffer_dirty(leaf); + btrfs_clear_buffer_dirty(trans, leaf); wret = btrfs_del_leaf(trans, root, path, leaf); BUG_ON(ret); if (wret) @@ -3018,7 +3018,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, } if (btrfs_header_nritems(leaf) == 0) { - btrfs_clear_buffer_dirty(leaf); + btrfs_clear_buffer_dirty(trans, leaf); path->slots[1] = slot; ret = btrfs_del_leaf(trans, root, path, leaf); BUG_ON(ret); diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c index 6a3178a8..35b6cde9 100644 --- a/kernel-shared/disk-io.c +++ b/kernel-shared/disk-io.c @@ -2289,7 +2289,7 @@ int btrfs_delete_and_free_root(struct btrfs_trans_handle *trans, return ret; list_del(&root->dirty_list); - ret = btrfs_clear_buffer_dirty(root->node); + ret = btrfs_clear_buffer_dirty(trans, root->node); if (ret) return ret; ret = btrfs_free_tree_block(trans, btrfs_root_id(root), root->node, 0, 1); diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c index 91dd7ca1..8c7dab3f 100644 --- a/kernel-shared/extent-tree.c +++ b/kernel-shared/extent-tree.c @@ -1898,7 +1898,7 @@ static int pin_down_bytes(struct btrfs_trans_handle *trans, u64 bytenr, if (header_owner != BTRFS_TREE_LOG_OBJECTID && header_transid == trans->transid && !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) { - btrfs_clear_buffer_dirty(buf); + btrfs_clear_buffer_dirty(trans, buf); free_extent_buffer(buf); return 1; } diff --git a/kernel-shared/extent_io.c b/kernel-shared/extent_io.c index c653d7c3..503b63e2 100644 --- a/kernel-shared/extent_io.c +++ b/kernel-shared/extent_io.c @@ -585,7 +585,8 @@ int set_extent_buffer_dirty(struct extent_buffer *eb) return 0; } -int btrfs_clear_buffer_dirty(struct extent_buffer *eb) +int btrfs_clear_buffer_dirty(struct btrfs_trans_handle *trans, + struct extent_buffer *eb) { struct extent_io_tree *tree = &eb->fs_info->dirty_buffers; if (eb->flags & EXTENT_BUFFER_DIRTY) { diff --git a/kernel-shared/extent_io.h b/kernel-shared/extent_io.h index 520ccd78..243ffe74 100644 --- a/kernel-shared/extent_io.h +++ b/kernel-shared/extent_io.h @@ -54,6 +54,7 @@ static inline int le_test_bit(int nr, const u8 *addr) } struct btrfs_fs_info; +struct btrfs_trans_handle; struct extent_buffer { struct cache_extent cache_node; @@ -128,7 +129,8 @@ void memset_extent_buffer(const struct extent_buffer *eb, char c, int extent_buffer_test_bit(const struct extent_buffer *eb, unsigned long start, unsigned long nr); int set_extent_buffer_dirty(struct extent_buffer *eb); -int btrfs_clear_buffer_dirty(struct extent_buffer *eb); +int btrfs_clear_buffer_dirty(struct btrfs_trans_handle *trans, + struct extent_buffer *eb); int read_data_from_disk(struct btrfs_fs_info *info, void *buf, u64 logical, u64 *len, int mirror); int write_data_to_disk(struct btrfs_fs_info *info, const void *buf, u64 offset, diff --git a/kernel-shared/transaction.c b/kernel-shared/transaction.c index 49b435f6..87d86fcd 100644 --- a/kernel-shared/transaction.c +++ b/kernel-shared/transaction.c @@ -163,7 +163,7 @@ again: goto cleanup; } start += eb->len; - btrfs_clear_buffer_dirty(eb); + btrfs_clear_buffer_dirty(trans, eb); free_extent_buffer(eb); } } @@ -186,7 +186,7 @@ cleanup: eb = find_first_extent_buffer(fs_info, start); BUG_ON(!eb || eb->start != start); start += eb->len; - btrfs_clear_buffer_dirty(eb); + btrfs_clear_buffer_dirty(trans, eb); free_extent_buffer(eb); } } From patchwork Wed Aug 23 14:32:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362631 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 5DADDEE49B0 for ; Wed, 23 Aug 2023 14:33:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236475AbjHWOd3 (ORCPT ); Wed, 23 Aug 2023 10:33:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33326 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236454AbjHWOd0 (ORCPT ); Wed, 23 Aug 2023 10:33:26 -0400 Received: from mail-oi1-x234.google.com (mail-oi1-x234.google.com [IPv6:2607:f8b0:4864:20::234]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 962E3E7B for ; Wed, 23 Aug 2023 07:33:16 -0700 (PDT) Received: by mail-oi1-x234.google.com with SMTP id 5614622812f47-3a85b9c6ccdso2310946b6e.0 for ; Wed, 23 Aug 2023 07:33:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801196; x=1693405996; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=tfleQjaFJsXHG17PceH0WHvIOOmL6GRR1AUP0cpo0m0=; b=JcTjc3+f1xCzqZhrK8CpTvc/Z1OcjxeTQ6eSZiJVKPCFV1AFOvNbDn1jLc8X0g5j4U aGtevbIXhkMA+aIRDkBllpxLZ+jlUiXoW8f8H8JTMkl4v+slBsyomXy9timXfohGN81D I721wcqd2i8Ss9mCLt/DkDP7gErRCtV3Drmqf1KbiO8wGlukkg1EFy1FvRVBlVaYIU5l cFmT/rl5XjFbVGyICBw0kmSCh+iJTfnmhl8RXL9l2hp3juiBRjeYfkmpCb4r63i3ylEu A/ZQB7FEwOb4gCDm9ti1HNqitdpjq417PEzxWOWpP7aAUI08GcJjxYc5XvV2IdH2QByy VUJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801196; x=1693405996; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tfleQjaFJsXHG17PceH0WHvIOOmL6GRR1AUP0cpo0m0=; b=HrEymtZJW/1/aBsJIyXVPVfAXx2vOoZkQHYbtZjBLChuQDParyr7+OOE+qlm3wnoXC QTPDBHUA0AMqT8xMZJ5n/dWTJu43gjGas5nAn0WsIK4FeVf9McUPJh6jFqzbIuojTx4a kApG+fpvA412qzSZvxAV0PmVkTGQMSMWA04gQ3XDpRbZ//qj7eButpiCjGKRn5Boo4IW 6qKU+6TevOsl9cRxI5W9v0o4GZyzcYUlrWEP36Jjxy+Qybc2Cfg+w1sccJz74b/NbKrv 2D6+Y5zCY8WG48M5c+ucob9Vz7WSyNHPnDEQbM2gqMGS3gpiYhfJACha5kCQLpUnRdDd ZTQA== X-Gm-Message-State: AOJu0YwoeJYbaPo1xtBQtwllWNKrQsHBFua+MMjXHFsUN5DZdy8oWcz9 QB6/QpFrVckzB7KnhP0zUKdIkozQImX6BCMRCAE= X-Google-Smtp-Source: AGHT+IHt5bZqmMqCIoPRJCMN9eWadwo46kTZxtavcpZbu3DBAczkI7Xti7C7k+M2Jy6yoxFdVkt65A== X-Received: by 2002:a05:6358:60c6:b0:135:acfd:8786 with SMTP id i6-20020a05635860c600b00135acfd8786mr10373035rwi.3.1692801195676; Wed, 23 Aug 2023 07:33:15 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id t10-20020a5b0dca000000b00d7497467d36sm1783368ybr.45.2023.08.23.07.33.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:15 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 06/38] btrfs-progs: update read_node_slot to match the kernel definition Date: Wed, 23 Aug 2023 10:32:32 -0400 Message-ID: <49aa985e67a6ee803cbbfa1992b4ec03e9eb7c6d.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org In the kernel this is called btrfs_read_node_slot, and it doesn't take a btrfs_fs_info. Update the btrfs-progs version to match the kernel and update all of the callers. Signed-off-by: Josef Bacik --- cmds/restore.c | 5 ++--- kernel-shared/ctree.c | 32 +++++++++++++++----------------- kernel-shared/ctree.h | 4 ++-- kernel-shared/print-tree.c | 2 +- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/cmds/restore.c b/cmds/restore.c index 7a360645..ba085f94 100644 --- a/cmds/restore.c +++ b/cmds/restore.c @@ -240,7 +240,6 @@ static int next_leaf(struct btrfs_root *root, struct btrfs_path *path) int offset = 1; struct extent_buffer *c; struct extent_buffer *next = NULL; - struct btrfs_fs_info *fs_info = root->fs_info; again: for (; level < BTRFS_MAX_LEVEL; level++) { @@ -267,7 +266,7 @@ again: continue; } - next = read_node_slot(fs_info, c, slot); + next = btrfs_read_node_slot(c, slot); if (extent_buffer_uptodate(next)) break; offset++; @@ -281,7 +280,7 @@ again: path->slots[level] = 0; if (!level) break; - next = read_node_slot(fs_info, next, 0); + next = btrfs_read_node_slot(next, 0); if (!extent_buffer_uptodate(next)) goto again; } diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index a87a79b2..3b703f7c 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -833,9 +833,10 @@ int btrfs_bin_search(struct extent_buffer *eb, const struct btrfs_key *key, slot); } -struct extent_buffer *read_node_slot(struct btrfs_fs_info *fs_info, - struct extent_buffer *parent, int slot) +struct extent_buffer *btrfs_read_node_slot(struct extent_buffer *parent, + int slot) { + struct btrfs_fs_info *fs_info = parent->fs_info; struct extent_buffer *ret; int level = btrfs_header_level(parent); @@ -909,7 +910,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, return 0; /* promote the child to a root */ - child = read_node_slot(fs_info, mid, 0); + child = btrfs_read_node_slot(mid, 0); BUG_ON(!extent_buffer_uptodate(child)); ret = btrfs_cow_block(trans, root, child, mid, 0, &child); BUG_ON(ret); @@ -933,7 +934,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, BTRFS_NODEPTRS_PER_BLOCK(fs_info) / 4) return 0; - left = read_node_slot(fs_info, parent, pslot - 1); + left = btrfs_read_node_slot(parent, pslot - 1); if (extent_buffer_uptodate(left)) { wret = btrfs_cow_block(trans, root, left, parent, pslot - 1, &left); @@ -942,7 +943,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, goto enospc; } } - right = read_node_slot(fs_info, parent, pslot + 1); + right = btrfs_read_node_slot(parent, pslot + 1); if (extent_buffer_uptodate(right)) { wret = btrfs_cow_block(trans, root, right, parent, pslot + 1, &right); @@ -1097,7 +1098,7 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, if (!parent) return 1; - left = read_node_slot(fs_info, parent, pslot - 1); + left = btrfs_read_node_slot(parent, pslot - 1); /* first, try to make some room in the middle buffer */ if (extent_buffer_uptodate(left)) { @@ -1137,7 +1138,7 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, } free_extent_buffer(left); } - right= read_node_slot(fs_info, parent, pslot + 1); + right= btrfs_read_node_slot(parent, pslot + 1); /* * then try to empty the right most buffer into the middle @@ -1389,7 +1390,7 @@ again: reada_for_search(fs_info, p, level, slot, key->objectid); - b = read_node_slot(fs_info, b, slot); + b = btrfs_read_node_slot(b, slot); if (!extent_buffer_uptodate(b)) return -EIO; } else { @@ -1941,7 +1942,6 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root struct extent_buffer *right; struct extent_buffer *upper; struct btrfs_disk_key disk_key; - struct btrfs_fs_info *fs_info = root->fs_info; int slot; u32 i; int free_space; @@ -1962,7 +1962,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root if (slot >= btrfs_header_nritems(upper) - 1) return 1; - right = read_node_slot(fs_info, upper, slot + 1); + right = btrfs_read_node_slot(upper, slot + 1); if (!extent_buffer_uptodate(right)) { if (IS_ERR(right)) return PTR_ERR(right); @@ -2090,7 +2090,6 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root struct btrfs_disk_key disk_key; struct extent_buffer *right = path->nodes[0]; struct extent_buffer *left; - struct btrfs_fs_info *fs_info = root->fs_info; int slot; int i; int free_space; @@ -2114,7 +2113,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root return 1; } - left = read_node_slot(fs_info, path->nodes[1], slot - 1); + left = btrfs_read_node_slot(path->nodes[1], slot - 1); free_space = btrfs_leaf_free_space(left); if (free_space < data_size) { free_extent_buffer(left); @@ -3046,7 +3045,6 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) int level = 1; struct extent_buffer *c; struct extent_buffer *next = NULL; - struct btrfs_fs_info *fs_info = root->fs_info; while(level < BTRFS_MAX_LEVEL) { if (!path->nodes[level]) @@ -3062,7 +3060,7 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) } slot--; - next = read_node_slot(fs_info, c, slot); + next = btrfs_read_node_slot(c, slot); if (!extent_buffer_uptodate(next)) { if (IS_ERR(next)) return PTR_ERR(next); @@ -3082,7 +3080,7 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) path->slots[level] = slot; if (!level) break; - next = read_node_slot(fs_info, next, slot); + next = btrfs_read_node_slot(next, slot); if (!extent_buffer_uptodate(next)) { if (IS_ERR(next)) return PTR_ERR(next); @@ -3125,7 +3123,7 @@ int btrfs_next_sibling_tree_block(struct btrfs_fs_info *fs_info, if (path->reada) reada_for_search(fs_info, path, level, slot, 0); - next = read_node_slot(fs_info, c, slot); + next = btrfs_read_node_slot(c, slot); if (!extent_buffer_uptodate(next)) return -EIO; break; @@ -3148,7 +3146,7 @@ int btrfs_next_sibling_tree_block(struct btrfs_fs_info *fs_info, break; if (path->reada) reada_for_search(fs_info, path, level, 0, 0); - next = read_node_slot(fs_info, next, 0); + next = btrfs_read_node_slot(next, 0); if (!extent_buffer_uptodate(next)) return -EIO; } diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 15ac310e..dc11b246 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -949,8 +949,8 @@ int btrfs_convert_one_bg(struct btrfs_trans_handle *trans, u64 bytenr); int btrfs_comp_cpu_keys(const struct btrfs_key *k1, const struct btrfs_key *k2); int btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level, int slot); -struct extent_buffer *read_node_slot(struct btrfs_fs_info *fs_info, - struct extent_buffer *parent, int slot); +struct extent_buffer *btrfs_read_node_slot(struct extent_buffer *parent, + int slot); int btrfs_previous_item(struct btrfs_root *root, struct btrfs_path *path, u64 min_objectid, int type); diff --git a/kernel-shared/print-tree.c b/kernel-shared/print-tree.c index d7ffeccd..38524971 100644 --- a/kernel-shared/print-tree.c +++ b/kernel-shared/print-tree.c @@ -1494,7 +1494,7 @@ static int search_leftmost_tree_block(struct btrfs_fs_info *fs_info, struct extent_buffer *eb; path->slots[i] = 0; - eb = read_node_slot(fs_info, path->nodes[i], 0); + eb = btrfs_read_node_slot(path->nodes[i], 0); if (!extent_buffer_uptodate(eb)) { ret = -EIO; goto out; From patchwork Wed Aug 23 14:32:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362629 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 4312EEE49B7 for ; Wed, 23 Aug 2023 14:33:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236476AbjHWOd2 (ORCPT ); Wed, 23 Aug 2023 10:33:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33298 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236466AbjHWOd0 (ORCPT ); Wed, 23 Aug 2023 10:33:26 -0400 Received: from mail-yw1-x1132.google.com (mail-yw1-x1132.google.com [IPv6:2607:f8b0:4864:20::1132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C5940E6E for ; Wed, 23 Aug 2023 07:33:17 -0700 (PDT) Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-59254e181a2so14303577b3.1 for ; Wed, 23 Aug 2023 07:33:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801197; x=1693405997; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=1H2Zlv1o3VIX483lfJm/ywo5TfIg7XeI5NRHVO7sb9I=; b=PSLntg7rHqGsCpZaqg7VVUX2lMVBoomel0a12L3x1EToo310tBaYa6Afe532BXdcL9 i99lpqD+D0qwk/hYr2n051+OosQXANjoDEA6XVd06U9lKlbJmyjNhXenAxc8vPsyVGFI OxSHJWKQexurWoOGfh3dIbYQ3T6dHS9GuIH3mt4sBgZJT3Xwv+/AkAOEhf1Z/MB6d10T N+tuATX+4wwzj1PQW9CVEyCeK/wd5WVdKf9m3pzib0A61TPe6ygs65AxaLBUC/CBDaqS 7CQQGmc23Sm/PFCMrNT3l2sZLv7yP3I7QCJzsrAGy7r04oMqXLaLNKDvAHyjYHbi/Q9p quVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801197; x=1693405997; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1H2Zlv1o3VIX483lfJm/ywo5TfIg7XeI5NRHVO7sb9I=; b=Ez7TyzPWOSVeHk4U87dfFh/PWDs7jBkdZaIJgVqwg3bhhbHQkbDLnx7aAQfvmBeW3u M57aj9UnvvPh9SlPCtHj6ROLRHSclJYgS6kN4mtnNIau9GcdeFiCSNDmDx7ZYx9J8cIz FlXEvusBQX/NDORf22fuYwsSETFEVzQ7nvCuYZJBFtcvAWyvg4zU3Gp/rogsBvqoW8Lv dje/5h+jJh3W0xRoCNdlNLQsCHOedVxy6GH/igOm/KD8ZIY/9uJCn7scISUU7kB/h0qA UJPoGbV74xfUrG8XgdXvxqukrgvPVYleZCOEtlumeW/tclDUI6eEemGJL1iSbZKkcgTV tGjw== X-Gm-Message-State: AOJu0YxKVxVKGBgiUyTUxJIlqYZswhB0DM6AlssSsgJ9mBDcRjLrQq3m TYzfo7dTID8Tjt6sdxaXnuo3GwTNcrTC+VpYnjQ= X-Google-Smtp-Source: AGHT+IEWoSb+aNjZMdqP+gHzhIAzKxqdoF1utlj1uBiPTVUOB10woLhpSB1o1YMUMu1Myz19rAJBJQ== X-Received: by 2002:a0d:ca8e:0:b0:576:8d7f:d163 with SMTP id m136-20020a0dca8e000000b005768d7fd163mr12566264ywd.8.1692801196892; Wed, 23 Aug 2023 07:33:16 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id i126-20020a0df884000000b0057085b18cddsm3364247ywf.54.2023.08.23.07.33.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:16 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 07/38] btrfs-progs: update btrfs_bin_search to match the kernel definition Date: Wed, 23 Aug 2023 10:32:33 -0400 Message-ID: <035b46cd8be1339b6576f08f0dd685423f37da9b.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This was updated to include a first_slot argument, update it to match the kernel definition to make it easier to sync ctree.c. Signed-off-by: Josef Bacik --- check/main.c | 2 +- kernel-shared/ctree.c | 6 +++--- kernel-shared/ctree.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/check/main.c b/check/main.c index d992b9f8..481fe11e 100644 --- a/check/main.c +++ b/check/main.c @@ -6524,7 +6524,7 @@ static int run_next_block(struct btrfs_root *root, * technically unreferenced and don't need to be worried about. */ if (ri != NULL && ri->drop_level && level > ri->drop_level) { - ret = btrfs_bin_search(buf, &ri->drop_key, &i); + ret = btrfs_bin_search(buf, 0, &ri->drop_key, &i); if (ret && i > 0) i--; } diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 3b703f7c..4d269e45 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -816,8 +816,8 @@ static int generic_bin_search(struct extent_buffer *eb, unsigned long p, * simple bin_search frontend that does the right thing for * leaves vs nodes */ -int btrfs_bin_search(struct extent_buffer *eb, const struct btrfs_key *key, - int *slot) +int btrfs_bin_search(struct extent_buffer *eb, int first_slot, + const struct btrfs_key *key, int *slot) { if (btrfs_header_level(eb) == 0) return generic_bin_search(eb, @@ -1355,7 +1355,7 @@ again: ret = check_block(fs_info, p, level); if (ret) return -1; - ret = btrfs_bin_search(b, key, &slot); + ret = btrfs_bin_search(b, 0, key, &slot); if (level != 0) { if (ret && slot > 0) slot -= 1; diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index dc11b246..66c05a69 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -983,8 +983,8 @@ int btrfs_search_slot_for_read(struct btrfs_root *root, const struct btrfs_key *key, struct btrfs_path *p, int find_higher, int return_any); -int btrfs_bin_search(struct extent_buffer *eb, const struct btrfs_key *key, - int *slot); +int btrfs_bin_search(struct extent_buffer *eb, int first_slot, + const struct btrfs_key *key, int *slot); int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path, u64 iobjectid, u64 ioff, u8 key_type, struct btrfs_key *found_key); From patchwork Wed Aug 23 14:32:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362632 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 056BAEE49B8 for ; Wed, 23 Aug 2023 14:33:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236483AbjHWOda (ORCPT ); Wed, 23 Aug 2023 10:33:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33338 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236470AbjHWOd0 (ORCPT ); Wed, 23 Aug 2023 10:33:26 -0400 Received: from mail-oi1-x231.google.com (mail-oi1-x231.google.com [IPv6:2607:f8b0:4864:20::231]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1B11EE5F for ; Wed, 23 Aug 2023 07:33:19 -0700 (PDT) Received: by mail-oi1-x231.google.com with SMTP id 5614622812f47-3a85cc7304fso2130210b6e.1 for ; Wed, 23 Aug 2023 07:33:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801198; x=1693405998; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=P9x70RyqRpYDJDVmuZlQA7eX1lKYX5heI8LbHX9VPsM=; b=yqwb2kQcXNpx4Tj5mbbdkbrjZqKnH7U1MKHJzveQf9MaoRDyV4Rf0Q1wP3qjE2HoAd +vlznQtxrD7HkCNqDwFbsPRZo7ZRpYDiPfDP/bHO1gT8wM8VNgMSJJiCg4d8+8LQpUHF C2jM82FGdMaVyBEc6Q1A8rZE448tnoEllFGQeUzyQRupSC506LfeH2QIZkOxgfDHuf9N JZE5iREK5/iyDfmxVGVKTYHWP0YmtTWB+cmzt3aN0mRLXOu6h0q2pfue84oCeUnW2Jhq puzhVY9pioTWmNchYhQWg6kSKeXc+1LYJ7YrSChyA1lgjxNpw6z6V7Liigc22fXHctaT MDgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801198; x=1693405998; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=P9x70RyqRpYDJDVmuZlQA7eX1lKYX5heI8LbHX9VPsM=; b=Y7Mhx/GgrLk3sOtmdcsrrW3E1PLF2nUiv2osNQ0hoZ5MT8CKfL4QGs1pNUb5Tr3ID3 aX4xhYxgaLXy7tyxfte8RHcah5TG9uWZAsRSoFHfYOKlz7UclyzXipSq8KqjH8vK3j1+ /k8livfzw69Pl4V7hBOE5kjZwt2wJyDooxuyDPpl0X88Q/qufz7Lb2EZGxE8AlpWSPX3 x47jWUoxXjQROx49I0RZzYOzhjL1PcFI4V7bLHesIqY5KgFkqHgSZXKV4Mniq+RNUcZD HrhXKnObgPeKf0L5eUnYghl//HDPPwXLlF5UBgS0Hf94wI7laHNBBkbHNZQTnE892pis vwyw== X-Gm-Message-State: AOJu0Yw5s2cl5mDdMSjOGMlpZTn6dN2KqgkGDzXGYdhtYA77lp3RzXfu YtfCfm4UIJTdZxyyjsUYAqM2HF8yY5BrHf+BNdg= X-Google-Smtp-Source: AGHT+IH2YQAsZPQ0x6MyrPYeyvego6akXjwYWLnJFIfqpcYiD57NZzXZrK8XMRfgZDCvVqoWS87w6Q== X-Received: by 2002:a05:6358:71b:b0:13a:3062:8d72 with SMTP id e27-20020a056358071b00b0013a30628d72mr13669698rwj.9.1692801198209; Wed, 23 Aug 2023 07:33:18 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id v17-20020a814811000000b00583b40d907esm3377420ywa.16.2023.08.23.07.33.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:17 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 08/38] btrfs-progs: update btrfs_set_item_key_safe to match kernel definition Date: Wed, 23 Aug 2023 10:32:34 -0400 Message-ID: <53ff718ecdf1f3d743ad2334f9321439f3ad432c.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org In the kernel we just pass the btrfs_fs_info, and we const'ify the new_key. Update the btrfs-progs definition to make syncing ctree.c easier. Signed-off-by: Josef Bacik --- kernel-shared/ctree.c | 12 +++++------- kernel-shared/ctree.h | 5 +++-- kernel-shared/file-item.c | 3 +-- tune/change-csum.c | 8 +------- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 4d269e45..f94d3ef1 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -1514,8 +1514,9 @@ void btrfs_fixup_low_keys( struct btrfs_path *path, struct btrfs_disk_key *key, * This function isn't completely safe. It's the caller's responsibility * that the new key won't break the order */ -int btrfs_set_item_key_safe(struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_key *new_key) +void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info, + struct btrfs_path *path, + const struct btrfs_key *new_key) { struct btrfs_disk_key disk_key; struct extent_buffer *eb; @@ -1525,13 +1526,11 @@ int btrfs_set_item_key_safe(struct btrfs_root *root, struct btrfs_path *path, slot = path->slots[0]; if (slot > 0) { btrfs_item_key(eb, &disk_key, slot - 1); - if (btrfs_comp_keys(&disk_key, new_key) >= 0) - return -1; + BUG_ON(btrfs_comp_keys(&disk_key, new_key) >= 0); } if (slot < btrfs_header_nritems(eb) - 1) { btrfs_item_key(eb, &disk_key, slot + 1); - if (btrfs_comp_keys(&disk_key, new_key) <= 0) - return -1; + BUG_ON(btrfs_comp_keys(&disk_key, new_key) <= 0); } btrfs_cpu_key_to_disk(&disk_key, new_key); @@ -1539,7 +1538,6 @@ int btrfs_set_item_key_safe(struct btrfs_root *root, struct btrfs_path *path, btrfs_mark_buffer_dirty(eb); if (slot == 0) btrfs_fixup_low_keys(path, &disk_key, 1); - return 0; } /* diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 66c05a69..bf5dde14 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -1056,8 +1056,9 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_leaf_free_space(struct extent_buffer *leaf); void btrfs_fixup_low_keys(struct btrfs_path *path, struct btrfs_disk_key *key, int level); -int btrfs_set_item_key_safe(struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_key *new_key); +void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info, + struct btrfs_path *path, + const struct btrfs_key *new_key); void btrfs_set_item_key_unsafe(struct btrfs_root *root, struct btrfs_path *path, struct btrfs_key *new_key); diff --git a/kernel-shared/file-item.c b/kernel-shared/file-item.c index 1a2f5f14..30a89094 100644 --- a/kernel-shared/file-item.c +++ b/kernel-shared/file-item.c @@ -379,8 +379,7 @@ static noinline int truncate_one_csum(struct btrfs_root *root, BUG_ON(ret); key->offset = end_byte; - ret = btrfs_set_item_key_safe(root, path, key); - BUG_ON(ret); + btrfs_set_item_key_safe(root->fs_info, path, key); } else { BUG(); } diff --git a/tune/change-csum.c b/tune/change-csum.c index 17372890..9edddb05 100644 --- a/tune/change-csum.c +++ b/tune/change-csum.c @@ -459,13 +459,7 @@ static int change_csum_objectids(struct btrfs_fs_info *fs_info) btrfs_item_key_to_cpu(path.nodes[0], &found_key, i); found_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; path.slots[0] = i; - ret = btrfs_set_item_key_safe(csum_root, &path, &found_key); - if (ret < 0) { - errno = -ret; - error("failed to set item key for data csum at logical %llu: %m", - found_key.offset); - goto out; - } + btrfs_set_item_key_safe(fs_info, &path, &found_key); } btrfs_release_path(&path); } From patchwork Wed Aug 23 14:32:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362633 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 BB521EE49A3 for ; Wed, 23 Aug 2023 14:33:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236485AbjHWOda (ORCPT ); Wed, 23 Aug 2023 10:33:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33364 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236471AbjHWOd1 (ORCPT ); Wed, 23 Aug 2023 10:33:27 -0400 Received: from mail-yw1-x112f.google.com (mail-yw1-x112f.google.com [IPv6:2607:f8b0:4864:20::112f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B68210C6 for ; Wed, 23 Aug 2023 07:33:20 -0700 (PDT) Received: by mail-yw1-x112f.google.com with SMTP id 00721157ae682-58419517920so60579157b3.0 for ; Wed, 23 Aug 2023 07:33:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801199; x=1693405999; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Lm1RrsRXMw9AwyqJMVi67ASxVO/3qsz3sTdIMV/NCwI=; b=FZKWmSoG53VO7+VhcEcfSG5hV9YAP/kf289XlHTe0zG82IJX7UYA0HaHcX8FnYqFeq PI8uWmyYYC3MWL/CzvbIINqazOUSXnvcxEwHWBWiJEcjMPayosufPWDlPqPn539beK9E s8aieAq1v/CkOgLfISD+WPj1rLwEQNHQQ3OBRgsEARUBV2pyRrIpHquHFr3t1tiN2sWG vp2gnQcvIWZQ7M1l4xiMWS1UQE53dN/jw/NRAO6SLoPXM8sI6br0cEQ84LfYLyJqw5Uh /DYwP14yZLm4AzbrornBWGj0RsZX9Y2f1wl3By5zts0bx3udMO4wjklTFXYTNStA5NDZ dOGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801199; x=1693405999; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Lm1RrsRXMw9AwyqJMVi67ASxVO/3qsz3sTdIMV/NCwI=; b=D2djC8wu60RmsFqcc0DXDdZLLuNnQDTFghnBPYgTB2Mcgn9RI2mVeL34IL/JRlQNtt la2bz0QMHTeprhhfgLldAGymNjvuWTp+u5i7oYW7Ei4ZtBc3rpGipgISZshTUF2QPkzH xCdhUUMP3JMde/4bKgp9evYbN4t6N0Qgixl5+nYQPbvI/NkqHqayhB5w/7HxN71LjnW3 mAtg+JmtkN7xAY5YrrfmKC8+6/H6bgE1pzXdIqRAnNRDMRPG2GFmNc4kwtTFtOlelyqc qeOUX/Z5d1HTRXkazzrpUK2Sjc7GoQSVpVaBLm0orwKJE57rWsJge0pZbyWl2U9eYzKe JMSA== X-Gm-Message-State: AOJu0YwiLxvigMI9yt1RveTZMZKRvhfN7+2pKURreF08W2UQIlnKgAh8 gYlnKB6JeXBjS2eaBu+jXvsWGE2ZBGAqRXOQ1RM= X-Google-Smtp-Source: AGHT+IGu16VdpScP9/pGU/Ebx783SRuZY3feMoTLh5V4eh7JJbWHLllWa+qyIsAucPJOBsvUubjU5A== X-Received: by 2002:a0d:dd52:0:b0:589:a9fd:a with SMTP id g79-20020a0ddd52000000b00589a9fd000amr12975548ywe.10.1692801199387; Wed, 23 Aug 2023 07:33:19 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id x186-20020a0deec3000000b00586108dd8f5sm3355120ywe.18.2023.08.23.07.33.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:19 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 09/38] btrfs-progs: update btrfs_print_leaf to match the kernel definition Date: Wed, 23 Aug 2023 10:32:35 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org In the kernel we have btrfs_print_leaf(eb) instead of btrfs_print_leaf(eb, mode). In fact in all of the kernel-shared sources we're just using the default mode. Fix this to have a __btrfs_print_leaf() which handles the mode for the user space utilities that want the different behavior, and then change btrfs_print_leaf() to just be the normal default style. Signed-off-by: Josef Bacik --- cmds/inspect-dump-tree.c | 2 +- kernel-shared/ctree.c | 16 ++++++++-------- kernel-shared/extent-tree.c | 8 ++++---- kernel-shared/print-tree.c | 4 ++-- kernel-shared/print-tree.h | 7 ++++++- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/cmds/inspect-dump-tree.c b/cmds/inspect-dump-tree.c index 501b90a1..9726bef5 100644 --- a/cmds/inspect-dump-tree.c +++ b/cmds/inspect-dump-tree.c @@ -52,7 +52,7 @@ static void print_extents(struct extent_buffer *eb) return; if (btrfs_is_leaf(eb)) { - btrfs_print_leaf(eb, BTRFS_PRINT_TREE_DEFAULT); + btrfs_print_leaf(eb); return; } diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index f94d3ef1..2f96d701 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -2566,7 +2566,7 @@ split: ret = 0; if (btrfs_leaf_free_space(leaf) < 0) { - btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT); + btrfs_print_leaf(leaf); BUG(); } kfree(buf); @@ -2658,7 +2658,7 @@ int btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) ret = 0; if (btrfs_leaf_free_space(leaf) < 0) { - btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT); + btrfs_print_leaf(leaf); BUG(); } return ret; @@ -2682,7 +2682,7 @@ int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, data_end = leaf_data_end(leaf); if (btrfs_leaf_free_space(leaf) < data_size) { - btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT); + btrfs_print_leaf(leaf); BUG(); } slot = path->slots[0]; @@ -2690,7 +2690,7 @@ int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, BUG_ON(slot < 0); if (slot >= nritems) { - btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT); + btrfs_print_leaf(leaf); printk("slot %d too large, nritems %u\n", slot, nritems); BUG_ON(1); } @@ -2717,7 +2717,7 @@ int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, ret = 0; if (btrfs_leaf_free_space(leaf) < 0) { - btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT); + btrfs_print_leaf(leaf); BUG(); } return ret; @@ -2765,7 +2765,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, data_end = leaf_data_end(leaf); if (btrfs_leaf_free_space(leaf) < total_size) { - btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT); + btrfs_print_leaf(leaf); printk("not enough freespace need %u have %d\n", total_size, btrfs_leaf_free_space(leaf)); BUG(); @@ -2778,7 +2778,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, unsigned int old_data = btrfs_item_data_end(leaf, slot); if (old_data < data_end) { - btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT); + btrfs_print_leaf(leaf); printk("slot %d old_data %u data_end %u\n", slot, old_data, data_end); BUG_ON(1); @@ -2824,7 +2824,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, } if (btrfs_leaf_free_space(leaf) < 0) { - btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT); + btrfs_print_leaf(leaf); BUG(); } diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c index 8c7dab3f..f23c28af 100644 --- a/kernel-shared/extent-tree.c +++ b/kernel-shared/extent-tree.c @@ -936,7 +936,7 @@ again: printf("Size is %u, needs to be %u, slot %d\n", (unsigned)item_size, (unsigned)sizeof(*ei), path->slots[0]); - btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT); + btrfs_print_leaf(leaf); return -EINVAL; } @@ -1427,7 +1427,7 @@ again: } if (ret != 0) { - btrfs_print_leaf(path->nodes[0], BTRFS_PRINT_TREE_DEFAULT); + btrfs_print_leaf(path->nodes[0]); printk("failed to find block number %llu\n", (unsigned long long)bytenr); BUG(); @@ -2033,7 +2033,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, printk(KERN_ERR "umm, got %d back from search" ", was looking for %llu\n", ret, (unsigned long long)bytenr); - btrfs_print_leaf(path->nodes[0], BTRFS_PRINT_TREE_DEFAULT); + btrfs_print_leaf(path->nodes[0]); } BUG_ON(ret); extent_slot = path->slots[0]; @@ -2047,7 +2047,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, (unsigned long long)owner_objectid, (unsigned long long)owner_offset); printf("path->slots[0]: %d path->nodes[0]:\n", path->slots[0]); - btrfs_print_leaf(path->nodes[0], BTRFS_PRINT_TREE_DEFAULT); + btrfs_print_leaf(path->nodes[0]); ret = -EIO; goto fail; } diff --git a/kernel-shared/print-tree.c b/kernel-shared/print-tree.c index 38524971..b7ca8b7e 100644 --- a/kernel-shared/print-tree.c +++ b/kernel-shared/print-tree.c @@ -1301,7 +1301,7 @@ static void print_header_info(struct extent_buffer *eb, unsigned int mode) fflush(stdout); } -void btrfs_print_leaf(struct extent_buffer *eb, unsigned int mode) +void __btrfs_print_leaf(struct extent_buffer *eb, unsigned int mode) { struct btrfs_disk_key disk_key; u32 leaf_data_size = BTRFS_LEAF_DATA_SIZE(eb->fs_info); @@ -1614,7 +1614,7 @@ void btrfs_print_tree(struct extent_buffer *eb, unsigned int mode) nr = btrfs_header_nritems(eb); if (btrfs_is_leaf(eb)) { - btrfs_print_leaf(eb, mode); + __btrfs_print_leaf(eb, mode); return; } /* We are crossing eb boundary, this node must be corrupted */ diff --git a/kernel-shared/print-tree.h b/kernel-shared/print-tree.h index 80fb6ef7..c1e75d1e 100644 --- a/kernel-shared/print-tree.h +++ b/kernel-shared/print-tree.h @@ -34,7 +34,12 @@ enum { }; void btrfs_print_tree(struct extent_buffer *eb, unsigned int mode); -void btrfs_print_leaf(struct extent_buffer *eb, unsigned int mode); +void __btrfs_print_leaf(struct extent_buffer *eb, unsigned int mode); + +static inline void btrfs_print_leaf(struct extent_buffer *eb) +{ + __btrfs_print_leaf(eb, BTRFS_PRINT_TREE_DEFAULT); +} void btrfs_print_key(struct btrfs_disk_key *disk_key); void print_chunk_item(struct extent_buffer *eb, struct btrfs_chunk *chunk); From patchwork Wed Aug 23 14:32:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362635 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 54E5EEE49B5 for ; Wed, 23 Aug 2023 14:33:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236482AbjHWOdb (ORCPT ); Wed, 23 Aug 2023 10:33:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33376 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236474AbjHWOd2 (ORCPT ); Wed, 23 Aug 2023 10:33:28 -0400 Received: from mail-yw1-x112a.google.com (mail-yw1-x112a.google.com [IPv6:2607:f8b0:4864:20::112a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8069110C8 for ; Wed, 23 Aug 2023 07:33:21 -0700 (PDT) Received: by mail-yw1-x112a.google.com with SMTP id 00721157ae682-591ba8bd094so40602087b3.3 for ; Wed, 23 Aug 2023 07:33:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801200; x=1693406000; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Ibct8f7AJuY8Z6fao388LFVCMbEZ3mOrYQLAIVnkyFY=; b=o7zpwxQdnPDcpXyJbsDeyqPca4j1AASQILSi/Wbfkrfh/vVF2xtw/XS9K/m3WoHHvy CdltY+d/FTjYVntDRle3dLwQd0xZ676zEgprkdLIZNBmgXUCpx086SYKTR00Zarcez3x eA0usQFvyNQ24BToZaA279nKEGDvsk7c4BQj5YQnwf+73dYMtVb5IToTYZCTcHQt8mzB 6kxbw5vFDugPB+K6+BbURTewb7j+h+YaOVJn9evjsVsXjkVjo4cOOCfEYV5GcVtQGRqv xqYNOsUOy+agA2SAeEfZNxI8ZheMwZBpyijroNeSHS5g0fyhBRb6DLyeg364x80g7FXv a2Sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801200; x=1693406000; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ibct8f7AJuY8Z6fao388LFVCMbEZ3mOrYQLAIVnkyFY=; b=hzYRTXg7zdi3gU3EfFoEPtoE8AQhqCxTmDHKG58iGH2sBEVT37PwCrVanUBUr6kbFM 7DffdKNBvPRE8n29BV/rvIXsj6KF/No2/0uMONqQ1+nEHBn9Fd9NW/uFzKN0UoQu3Qjp 3O4ICcHxX14mLSUnNZFzmCM68t72g5hoZWQ0mVELZNoW6funXWEGmlYm+GmCKDEx46jf ekKS+Eew7WsQUign7PVlHXp32hmzmClFMW0NW3hxwXs4G3un7UvBup1e8fD+FYhjLQv6 rXtIu+73UVFYLkrieqhgDCf77ZLVG3dVhZ73AVN3YBEAPYkp1BN3jg2PBN8w0A8CYBDZ 81oA== X-Gm-Message-State: AOJu0YyB9XG1MpOkqXPWFwZW5Qel37oar7XVuI9qqS6mRDRiIWSxulsu 2txLoQ26dNPlmMx4zAwqaQLAAxIqJxD/YZbw/Kw= X-Google-Smtp-Source: AGHT+IE5atLrZAAaTal2hV9U2ghLgggPGftRxk4oc4/Q0Fan0KjEazOA1cS39xz6nmjxCYcL1QzXCg== X-Received: by 2002:a81:6cd5:0:b0:54f:ba89:225d with SMTP id h204-20020a816cd5000000b0054fba89225dmr11909804ywc.19.1692801200592; Wed, 23 Aug 2023 07:33:20 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id a124-20020a818a82000000b005869ca8da8esm3325366ywg.146.2023.08.23.07.33.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:20 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 10/38] btrfs-progs: update btrfs_truncate_item to match the kernel definition Date: Wed, 23 Aug 2023 10:32:36 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This is void in the kernel, and this makes sense in btrfs-progs as it stands currently as it doesn't actually return an error if there's a problem, it simply BUG()'s. Update this to be a void and update the callers to make it easier to sync ctree.c. Signed-off-by: Josef Bacik --- kernel-shared/ctree.c | 7 ++----- kernel-shared/ctree.h | 2 +- kernel-shared/extent-tree.c | 4 +--- kernel-shared/file-item.c | 7 ++----- 4 files changed, 6 insertions(+), 14 deletions(-) diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 2f96d701..b5d3d12e 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -2573,9 +2573,8 @@ split: return ret; } -int btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) +void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) { - int ret = 0; int slot; struct extent_buffer *leaf; u32 nritems; @@ -2590,7 +2589,7 @@ int btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) old_size = btrfs_item_size(leaf, slot); if (old_size == new_size) - return 0; + return; nritems = btrfs_header_nritems(leaf); data_end = leaf_data_end(leaf); @@ -2656,12 +2655,10 @@ int btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) btrfs_set_item_size(leaf, slot, new_size); btrfs_mark_buffer_dirty(leaf); - ret = 0; if (btrfs_leaf_free_space(leaf) < 0) { btrfs_print_leaf(leaf); BUG(); } - return ret; } int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index bf5dde14..81d71d36 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -970,7 +970,7 @@ int btrfs_create_root(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 objectid); int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, u32 data_size); -int btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end); +void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end); int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c index f23c28af..001cffd1 100644 --- a/kernel-shared/extent-tree.c +++ b/kernel-shared/extent-tree.c @@ -1128,7 +1128,6 @@ static int update_inline_extent_backref(struct btrfs_trans_handle *trans, u32 item_size; int size; int type; - int ret; u64 refs; leaf = path->nodes[0]; @@ -1168,8 +1167,7 @@ static int update_inline_extent_backref(struct btrfs_trans_handle *trans, memmove_extent_buffer(leaf, ptr, ptr + size, end - ptr - size); item_size -= size; - ret = btrfs_truncate_item(path, item_size, 1); - BUG_ON(ret); + btrfs_truncate_item(path, item_size, 1); } btrfs_mark_buffer_dirty(leaf); return 0; diff --git a/kernel-shared/file-item.c b/kernel-shared/file-item.c index 30a89094..e23e679e 100644 --- a/kernel-shared/file-item.c +++ b/kernel-shared/file-item.c @@ -346,7 +346,6 @@ static noinline int truncate_one_csum(struct btrfs_root *root, u64 csum_end; u64 end_byte = bytenr + len; u32 blocksize = root->fs_info->sectorsize; - int ret; leaf = path->nodes[0]; csum_end = btrfs_item_size(leaf, path->slots[0]) / csum_size; @@ -362,8 +361,7 @@ static noinline int truncate_one_csum(struct btrfs_root *root, */ u32 new_size = (bytenr - key->offset) / blocksize; new_size *= csum_size; - ret = btrfs_truncate_item(path, new_size, 1); - BUG_ON(ret); + btrfs_truncate_item(path, new_size, 1); } else if (key->offset >= bytenr && csum_end > end_byte && end_byte > key->offset) { /* @@ -375,8 +373,7 @@ static noinline int truncate_one_csum(struct btrfs_root *root, u32 new_size = (csum_end - end_byte) / blocksize; new_size *= csum_size; - ret = btrfs_truncate_item(path, new_size, 0); - BUG_ON(ret); + btrfs_truncate_item(path, new_size, 0); key->offset = end_byte; btrfs_set_item_key_safe(root->fs_info, path, key); From patchwork Wed Aug 23 14:32:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362636 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 5F308EE49A0 for ; Wed, 23 Aug 2023 14:33:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236491AbjHWOdc (ORCPT ); Wed, 23 Aug 2023 10:33:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33506 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236484AbjHWOda (ORCPT ); Wed, 23 Aug 2023 10:33:30 -0400 Received: from mail-yw1-x112a.google.com (mail-yw1-x112a.google.com [IPv6:2607:f8b0:4864:20::112a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 87781E57 for ; Wed, 23 Aug 2023 07:33:23 -0700 (PDT) Received: by mail-yw1-x112a.google.com with SMTP id 00721157ae682-5924093a9b2so23677667b3.2 for ; Wed, 23 Aug 2023 07:33:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801202; x=1693406002; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=T0ZQF567ER/Ck2OhzmAVs5dslXtY3Ed+YTVW2Y/9WFY=; b=Dzj9a09CHJAmdBIjo8sF2NoO1frqEMzSEzMnOaz3NCH/P7IpJxVD6uF9+l4Q9YxhiO 9PISsrXv2txQZAD33mNNih6jbVKVbKW1AarDz/hHhXSHUOMYWUxX/F16iZvAm3hjZDmD nwi6Ho0NSRfkgz3vggi5mF333NVsOKutE/IxuGTvLWVCDeZJywbR2O3CR2vsgaSAz8Ze zTqR+CJrrvz+Ot9E1upVCZGZTvdCyBPEqQ6KRYMQgBLeeIjJyoy0uCnqFU6kGjLtRT5c c6ol+WPdisFmLIzOASyLNbHsrLHBPYiCWSEk7pEnq5pbU7/7Zfm7/d03OgYWuU6w6Mn4 jT4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801202; x=1693406002; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=T0ZQF567ER/Ck2OhzmAVs5dslXtY3Ed+YTVW2Y/9WFY=; b=h95pR7fW6WR3wjhWMIW+DzjlE2/g70JLssGs86KgCkoonG+IdweE09Lu0ZtMF0ilqe +ETNutAfp6a5r8KxLY6nw80Ke9ycaUhxsPAB8l5Y3oYIuxIJoLyhzpJ8TCnCyDBZEt+E FaB9ReYOaC4Izz7fHZE8on+KQQwUS8L0GvdK3YkOy8BBeTqhA8I/gqq6eiz3Phsd3C7T 1MeUfPo9X/+LYPR5b510AWkJIyxVCX/HNkGJRanRnC37/UKT8+X+d9T2PDxet9PniXI9 BoUcTp2VXuHseGv5xqas2nMOCa9LAlrN30XT4RBuIIouOMCkmWjyonCglKt2qhtguxYV uViA== X-Gm-Message-State: AOJu0YyzF2ooS4+2q38nBWpYF4M5xckpbgmRjpJ+LuSZNMEw2iamNvks oKEF4JcWcJoaOeUnFiG/0StMBfPXjs8ahlCcdvY= X-Google-Smtp-Source: AGHT+IG/zs5DjWa9BGMAWs9Qp+dCrvawDSGl0I612pXWxv96HThEcPyzlcH3ub8jPW+ZcuFDJUYQcg== X-Received: by 2002:a81:920a:0:b0:58c:a87b:6e65 with SMTP id j10-20020a81920a000000b0058ca87b6e65mr15220207ywg.26.1692801201795; Wed, 23 Aug 2023 07:33:21 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id m124-20020a0dca82000000b005897fd75c80sm3361612ywd.78.2023.08.23.07.33.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:21 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 11/38] btrfs-progs: update btrfs_extend_item to match the kernel definition Date: Wed, 23 Aug 2023 10:32:37 -0400 Message-ID: <0d67f505513af33ba9d49bb3242cc0884b89a370.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Similar to btrfs_truncate_item(), this is void in the kernel as the failure case is simply BUG_ON(). Additionally there is no root parameter as it's not used in the function at all. Make these changes and update the callers. Signed-off-by: Josef Bacik --- kernel-shared/ctree.c | 8 ++------ kernel-shared/ctree.h | 3 +-- kernel-shared/dir-item.c | 4 ++-- kernel-shared/extent-tree.c | 4 +--- kernel-shared/file-item.c | 3 +-- kernel-shared/inode-item.c | 5 ++--- 6 files changed, 9 insertions(+), 18 deletions(-) diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index b5d3d12e..ed8a7002 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -2661,10 +2661,8 @@ void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) } } -int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, - u32 data_size) +void btrfs_extend_item(struct btrfs_path *path, u32 data_size) { - int ret = 0; int slot; struct extent_buffer *leaf; u32 nritems; @@ -2712,12 +2710,10 @@ int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, btrfs_set_item_size(leaf, slot, old_size + data_size); btrfs_mark_buffer_dirty(leaf); - ret = 0; if (btrfs_leaf_free_space(leaf) < 0) { btrfs_print_leaf(leaf); BUG(); } - return ret; } /* @@ -3366,7 +3362,7 @@ int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type, * ret == -EEXIST case, An item with that type already exists. * Extend the item and store the new subvol_id at the end. */ - btrfs_extend_item(uuid_root, path, sizeof(subvol_id_le)); + btrfs_extend_item(path, sizeof(subvol_id_le)); eb = path->nodes[0]; slot = path->slots[0]; offset = btrfs_item_ptr_offset(eb, slot); diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 81d71d36..c7321a40 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -968,8 +968,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, struct extent_buffer **cow_ret, u64 new_root_objectid); int btrfs_create_root(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 objectid); -int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, - u32 data_size); +void btrfs_extend_item(struct btrfs_path *path, u32 data_size); void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end); int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, diff --git a/kernel-shared/dir-item.c b/kernel-shared/dir-item.c index abf7d047..cb70d7c8 100644 --- a/kernel-shared/dir-item.c +++ b/kernel-shared/dir-item.c @@ -48,8 +48,8 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle di = btrfs_match_dir_item_name(root, path, name, name_len); if (di) return ERR_PTR(-EEXIST); - ret = btrfs_extend_item(root, path, data_size); - WARN_ON(ret > 0); + btrfs_extend_item(path, data_size); + ret = 0; } if (ret < 0) return ERR_PTR(ret); diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c index 001cffd1..543a9952 100644 --- a/kernel-shared/extent-tree.c +++ b/kernel-shared/extent-tree.c @@ -1039,7 +1039,6 @@ static int setup_inline_extent_backref(struct btrfs_root *root, u64 refs; int size; int type; - int ret; leaf = path->nodes[0]; ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); @@ -1048,8 +1047,7 @@ static int setup_inline_extent_backref(struct btrfs_root *root, type = extent_ref_type(parent, owner); size = btrfs_extent_inline_ref_size(type); - ret = btrfs_extend_item(root, path, size); - BUG_ON(ret); + btrfs_extend_item(path, size); ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); refs = btrfs_extent_refs(leaf, ei); diff --git a/kernel-shared/file-item.c b/kernel-shared/file-item.c index e23e679e..7baa5614 100644 --- a/kernel-shared/file-item.c +++ b/kernel-shared/file-item.c @@ -282,8 +282,7 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans, u64 logical, diff = diff - btrfs_item_size(leaf, path->slots[0]); if (diff != csum_size) goto insert; - ret = btrfs_extend_item(root, path, diff); - BUG_ON(ret); + btrfs_extend_item(path, diff); goto csum; } diff --git a/kernel-shared/inode-item.c b/kernel-shared/inode-item.c index 891ae40a..d0705267 100644 --- a/kernel-shared/inode-item.c +++ b/kernel-shared/inode-item.c @@ -78,8 +78,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, goto out; old_size = btrfs_item_size(path->nodes[0], path->slots[0]); - ret = btrfs_extend_item(root, path, ins_len); - BUG_ON(ret); + btrfs_extend_item(path, ins_len); ref = btrfs_item_ptr(path->nodes[0], path->slots[0], struct btrfs_inode_ref); ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size); @@ -352,7 +351,7 @@ int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans, name, name_len, NULL)) goto out; - btrfs_extend_item(root, path, ins_len); + btrfs_extend_item(path, ins_len); ret = 0; } From patchwork Wed Aug 23 14:32:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362634 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 00E9AEE49B6 for ; Wed, 23 Aug 2023 14:33:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236487AbjHWOdc (ORCPT ); Wed, 23 Aug 2023 10:33:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33502 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236479AbjHWOda (ORCPT ); Wed, 23 Aug 2023 10:33:30 -0400 Received: from mail-yw1-x112b.google.com (mail-yw1-x112b.google.com [IPv6:2607:f8b0:4864:20::112b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B865410CB for ; Wed, 23 Aug 2023 07:33:23 -0700 (PDT) Received: by mail-yw1-x112b.google.com with SMTP id 00721157ae682-58d31f142eeso60772747b3.0 for ; Wed, 23 Aug 2023 07:33:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801203; x=1693406003; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=EJeLDb7XgjYYur0llXGicwfcaQ7es0DBAvgnquGsW18=; b=HPvJOzW3NBbcK1xphO9jcM5CXs3/Rd7AipUDepHNbwG1o7UCGyIQesm2cC+hop/5dN 7kLK6XDEMQ6z+4gr4lJDsava2RSg16MwN/4zWq8k6X3u+P8QuhKqB7XpoMeEQQwdSJHB BmHHpPtYv5Ha8Sd1wOk88DdDrAUXun3C9Fg6ig6CuObJtiGa8b74ezSdEHNx/9AYB2+H MPyA0zJd5E+RyzNbMLwm1E+lHmH+H8PV4y3B9NjU3qku1CIKsKuJ3vdn3tms2kwPaz+0 roO3TWQXe2KFq/2Nnf3H98tQ05wPEGXsQ6cfQmGU21gd7NeEbmfAr+X4wjgg3Y9inXGU Hyig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801203; x=1693406003; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EJeLDb7XgjYYur0llXGicwfcaQ7es0DBAvgnquGsW18=; b=UknlIKUesg2Cq9gJ55a0t6umt/gn8kjJnOha9E7a2DMnaNjjaXS0qkkwhWLL9wX/J0 UpbXO6tCkmAb6E+6KF83vBQv4iQb15ppY1098ZuBaoVPSNN/cLfV90NWG0j+ZicH941g MPD7DcpUmtM/cpRpVmh4Js34KaxVhyQTYG6sZ6ZtKCeywG69GCQ9xK4gg9Qn+/cXRUHu AzErYUOZSctokb8xl9t6sBLLTPyFFCxQzy438FYTpnneTOlUxnvfGfCXNu1cFHmWIZHM LPdmC103oZ7tZpf2O73hVIa4+ru9gyla348srg1N7c2uksCk0G5xVGJzODiG9FY6p6m7 1qMA== X-Gm-Message-State: AOJu0YzqZoIA0i2LDCJvPP5JvT3I1JWvu5rROxMs/71ccJq4D+BYdjzH 8+EqpH2LBM8DYwXu7lc7Z6uUgYY3ay0FpBYj0i0= X-Google-Smtp-Source: AGHT+IENL1ZoKWrMFCz+rR+xm1a9slzI2Zqy0iNWJmOmEJ+nVcsaWZJIzor3GIomyCEjf8qDtgAC8Q== X-Received: by 2002:a0d:c781:0:b0:58a:d281:a275 with SMTP id j123-20020a0dc781000000b0058ad281a275mr14306094ywd.21.1692801202910; Wed, 23 Aug 2023 07:33:22 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id a13-20020a81bb4d000000b005732b228a83sm3293501ywl.140.2023.08.23.07.33.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:22 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 12/38] btrfs-progs: sync memcpy_extent_buffer from the kernel Date: Wed, 23 Aug 2023 10:32:38 -0400 Message-ID: <8e6df00ffbccac1dd1b23162acbaa9ed9e91e165.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org We use this in ctree.c in the kernel, so sync this helper into btrfs-progs to make sync'ing ctree.c easier. Signed-off-by: Josef Bacik --- kernel-shared/extent_io.c | 6 ++++++ kernel-shared/extent_io.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/kernel-shared/extent_io.c b/kernel-shared/extent_io.c index 503b63e2..a085c2e6 100644 --- a/kernel-shared/extent_io.c +++ b/kernel-shared/extent_io.c @@ -641,6 +641,12 @@ void copy_extent_buffer(const struct extent_buffer *dst, memcpy((void *)dst->data + dst_offset, src->data + src_offset, len); } +void memcpy_extent_buffer(const struct extent_buffer *dst, unsigned long dst_offset, + unsigned long src_offset, unsigned long len) +{ + memcpy((void *)dst->data + dst_offset, dst->data + src_offset, len); +} + void memmove_extent_buffer(const struct extent_buffer *dst, unsigned long dst_offset, unsigned long src_offset, unsigned long len) { diff --git a/kernel-shared/extent_io.h b/kernel-shared/extent_io.h index 243ffe74..59be49ae 100644 --- a/kernel-shared/extent_io.h +++ b/kernel-shared/extent_io.h @@ -121,6 +121,9 @@ void copy_extent_buffer(const struct extent_buffer *dst, const struct extent_buffer *src, unsigned long dst_offset, unsigned long src_offset, unsigned long len); +void memcpy_extent_buffer(const struct extent_buffer *dst, + unsigned long dst_offset, unsigned long src_offset, + unsigned long len); void memmove_extent_buffer(const struct extent_buffer *dst, const unsigned long dst_offset, unsigned long src_offset, unsigned long len); From patchwork Wed Aug 23 14:32:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362648 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 29985EE49B6 for ; Wed, 23 Aug 2023 14:33:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236507AbjHWOdh (ORCPT ); Wed, 23 Aug 2023 10:33:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236488AbjHWOde (ORCPT ); Wed, 23 Aug 2023 10:33:34 -0400 Received: from mail-yb1-xb32.google.com (mail-yb1-xb32.google.com [IPv6:2607:f8b0:4864:20::b32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC45EE6C for ; Wed, 23 Aug 2023 07:33:25 -0700 (PDT) Received: by mail-yb1-xb32.google.com with SMTP id 3f1490d57ef6-d7481bc4d6fso3859076276.2 for ; Wed, 23 Aug 2023 07:33:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801205; x=1693406005; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=oyYBFkPVVl9PWjQ/B45EklVX4zrE0ph5wI3MWOufMwE=; b=OW1lTw+uUA5noiNhB58N7mIvWRPRcA+ChHhx07HqL1clNG7MZEvJpHKz0kEinTcO0K 0vZiLsP+4qeMvH6ZU8eeFjX3QhGO3gb4g7/4w0+WiuC7SVRjZR8uh02v5DwBjakyXYEm marBHhjyQOI1AI+jXkeGgRE1Jdhpn1SEfhXrMm15fWkbPA7TbMC5NW8Exu7UkNWxhy2T H1qVZ0oet5Bbpa4GeC8LAlDnLOtNwcjJcXYXQf0jMjDPkAhas+uJshio3a0FGBLrKza9 Ed2y5PiMOLzonm7FGlx2RVkRAzzpVWMtNJ51Wxh3a1Sk9l9+i9tJ8eo3Mom+6aYwovHZ A/mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801205; x=1693406005; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oyYBFkPVVl9PWjQ/B45EklVX4zrE0ph5wI3MWOufMwE=; b=QTY6RxuPbtwDDh3/Gc2ds6rMml4/PM/i8lsUYI2N6LjJ+hGXpDkewbTcwwHDOsx/A/ mI5J4QJI6wgX4bQTjQtBTTHBFmNVABxwTP1XdsHGz3SKhcTVE/l54Zp3vOmpXqOy7h0E sMVk0dn7P3ZDW2eGFWgItwaYysyHC7283a3acuhL0uIb13RV2LSvJhvZVaeRmVWi9rX4 6/PSmhW7Xuo57zMYkwz7qw8h19+/bS9KQZtiRNgJAd8EoNPFdEUOemyt9UX1QanqAHMF HZqXsDZANV+eZokfCGLfyIMW9kpqW8luhILUs8p75eQ3Hc4YK6bFaX0fydGE1nZSUQcJ Pdrw== X-Gm-Message-State: AOJu0Yx18DVqdxyzjWfszpXXqOO5xopouvGKgaZE8es1qwEouS7GKgex VO/Upt53VQymY9nO6IoLouQG9y3hh04kloeDb7U= X-Google-Smtp-Source: AGHT+IHEfVnjZ0MYU9cJuTuyi6R8mjk+fYS4mBNKWm6xqJECgpPqn6K3hZGdaPZbAvIpxX8MEcCc6g== X-Received: by 2002:a25:d2c1:0:b0:d74:6681:5c26 with SMTP id j184-20020a25d2c1000000b00d7466815c26mr12741442ybg.16.1692801204112; Wed, 23 Aug 2023 07:33:24 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id f7-20020a5b0d47000000b00d0bad22d652sm2722739ybr.36.2023.08.23.07.33.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:23 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 13/38] btrfs-progs: drop btrfs_init_path Date: Wed, 23 Aug 2023 10:32:39 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This simply zero's out the path, and this is used everywhere we use a stack path. Drop this usage and simply init the path's to empty instead of using a function to do the memset. Signed-off-by: Josef Bacik --- check/clear-cache.c | 12 ++-- check/main.c | 94 ++++++++++---------------------- check/mode-common.c | 35 ++++-------- check/mode-lowmem.c | 84 +++++++++------------------- check/qgroup-verify.c | 14 ++--- check/repair.c | 3 +- cmds/inspect-dump-tree.c | 3 +- cmds/inspect-tree-stats.c | 3 +- cmds/rescue-chunk-recover.c | 13 ++--- cmds/restore.c | 21 +++---- convert/main.c | 9 +-- convert/source-fs.c | 4 +- image/common.c | 3 +- image/image-create.c | 4 +- image/image-restore.c | 6 +- kernel-shared/ctree.c | 5 -- kernel-shared/ctree.h | 1 - kernel-shared/extent-tree.c | 3 +- kernel-shared/file.c | 3 +- kernel-shared/free-space-cache.c | 4 +- kernel-shared/inode.c | 5 +- kernel-shared/print-tree.c | 3 +- kernel-shared/volumes.c | 6 +- mkfs/main.c | 15 ++--- mkfs/rootdir.c | 10 +--- quick-test.c | 6 +- tune/change-uuid.c | 6 +- 27 files changed, 114 insertions(+), 261 deletions(-) diff --git a/check/clear-cache.c b/check/clear-cache.c index 9f8819f0..7a6b6002 100644 --- a/check/clear-cache.c +++ b/check/clear-cache.c @@ -130,11 +130,9 @@ static int check_free_space_tree(struct btrfs_root *root) { struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_key key = { 0 }; - struct btrfs_path path; + struct btrfs_path path = {}; int ret = 0; - btrfs_init_path(&path); - while (1) { struct btrfs_block_group *bg; u64 cur_start = key.objectid; @@ -450,7 +448,6 @@ out: int truncate_free_ino_items(struct btrfs_root *root) { - struct btrfs_path path; struct btrfs_key key = { .objectid = BTRFS_FREE_INO_OBJECTID, .type = (u8)-1, .offset = (u64)-1 }; @@ -468,9 +465,9 @@ int truncate_free_ino_items(struct btrfs_root *root) struct btrfs_file_extent_item *fi; struct btrfs_root *csum_root; struct btrfs_key found_key; + struct btrfs_path path = {}; u8 found_type; - btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, &key, &path, -1, 1); if (ret < 0) { btrfs_abort_transaction(trans, ret); @@ -551,15 +548,14 @@ out: int clear_ino_cache_items(struct btrfs_fs_info *fs_info) { int ret; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; key.objectid = BTRFS_FS_TREE_OBJECTID; key.type = BTRFS_ROOT_ITEM_KEY; key.offset = 0; - btrfs_init_path(&path); - ret = btrfs_search_slot(NULL, fs_info->tree_root, &key, &path, 0, 0); + ret = btrfs_search_slot(NULL, fs_info->tree_root, &key, &path, 0, 0); if (ret < 0) return ret; diff --git a/check/main.c b/check/main.c index 481fe11e..b8bcf5c3 100644 --- a/check/main.c +++ b/check/main.c @@ -889,7 +889,7 @@ static void maybe_free_inode_rec(struct cache_tree *inode_cache, static int check_orphan_item(struct btrfs_root *root, u64 ino) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; int ret; @@ -897,7 +897,6 @@ static int check_orphan_item(struct btrfs_root *root, u64 ino) key.type = BTRFS_ORPHAN_ITEM_KEY; key.offset = ino; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); btrfs_release_path(&path); if (ret > 0) @@ -1325,14 +1324,12 @@ static int leave_shared_node(struct btrfs_root *root, static int is_child_root(struct btrfs_root *root, u64 parent_root_id, u64 child_root_id) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct extent_buffer *leaf; int has_parent = 0; int ret; - btrfs_init_path(&path); - key.objectid = parent_root_id; key.type = BTRFS_ROOT_REF_KEY; key.offset = child_root_id; @@ -2107,7 +2104,7 @@ static int add_missing_dir_index(struct btrfs_root *root, struct inode_record *rec, struct inode_backref *backref) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_trans_handle *trans; struct btrfs_dir_item *dir_item; struct extent_buffer *leaf; @@ -2125,7 +2122,6 @@ static int add_missing_dir_index(struct btrfs_root *root, fprintf(stderr, "repairing missing dir index item for inode %llu\n", (unsigned long long)rec->ino); - btrfs_init_path(&path); key.objectid = backref->dir; key.type = BTRFS_DIR_INDEX_KEY; key.offset = backref->index; @@ -2169,7 +2165,7 @@ static int delete_dir_index(struct btrfs_root *root, { struct btrfs_trans_handle *trans; struct btrfs_dir_item *di; - struct btrfs_path path; + struct btrfs_path path = {}; int ret = 0; trans = btrfs_start_transaction(root, 1); @@ -2181,7 +2177,6 @@ static int delete_dir_index(struct btrfs_root *root, BTRFS_DIR_INDEX_KEY, (unsigned long long)backref->index, (unsigned long long)root->objectid); - btrfs_init_path(&path); di = btrfs_lookup_dir_index_item(trans, root, &path, backref->dir, backref->index, backref->name, backref->namelen, -1); @@ -2535,14 +2530,13 @@ out: */ static int find_normal_file_extent(struct btrfs_root *root, u64 ino) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_key found_key; struct btrfs_file_extent_item *fi; u8 type; int ret = 0; - btrfs_init_path(&path); key.objectid = ino; key.type = BTRFS_EXTENT_DATA_KEY; key.offset = 0; @@ -2755,11 +2749,9 @@ static int repair_mismatch_dir_hash(struct btrfs_trans_handle *trans, static int btrfs_delete_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key) { - struct btrfs_path path; + struct btrfs_path path = {}; int ret = 0; - btrfs_init_path(&path); - ret = btrfs_search_slot(trans, root, key, &path, -1, 1); if (ret) { if (ret > 0) @@ -2779,7 +2771,7 @@ static int find_file_extent_offset_by_bytenr(struct btrfs_root *root, u64 owner, u64 bytenr, u64 *offset_ret) { int ret = 0; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_key found_key; struct btrfs_file_extent_item *fi; @@ -2787,8 +2779,6 @@ static int find_file_extent_offset_by_bytenr(struct btrfs_root *root, u64 disk_bytenr; int slot; - btrfs_init_path(&path); - key.objectid = owner; key.type = BTRFS_INODE_ITEM_KEY; key.offset = 0; @@ -2960,7 +2950,7 @@ static int repair_inode_gen_original(struct btrfs_trans_handle *trans, static int try_repair_inode(struct btrfs_root *root, struct inode_record *rec) { struct btrfs_trans_handle *trans; - struct btrfs_path path; + struct btrfs_path path = {}; int ret = 0; /* unaligned extent recs always lead to csum missing error, clean it */ @@ -2993,7 +2983,6 @@ static int try_repair_inode(struct btrfs_root *root, struct inode_record *rec) if (IS_ERR(trans)) return PTR_ERR(trans); - btrfs_init_path(&path); if (!ret && rec->errors & I_ERR_MISMATCH_DIR_HASH) ret = repair_mismatch_dir_hash(trans, root, rec); if (!ret && rec->errors & I_ERR_INVALID_IMODE) @@ -3539,7 +3528,7 @@ static int repair_btree(struct btrfs_root *root, struct cache_tree *corrupt_blocks) { struct btrfs_trans_handle *trans; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_corrupt_block *corrupt; struct cache_extent *cache; struct btrfs_key key; @@ -3557,7 +3546,6 @@ static int repair_btree(struct btrfs_root *root, fprintf(stderr, "Error starting transaction: %m\n"); return ret; } - btrfs_init_path(&path); cache = first_cache_extent(corrupt_blocks); while (cache) { corrupt = container_of(cache, struct btrfs_corrupt_block, @@ -3625,7 +3613,7 @@ static int check_fs_root(struct btrfs_root *root, int wret; int level; u64 super_generation; - struct btrfs_path path; + struct btrfs_path path = {}; struct shared_node root_node; struct root_record *rec; struct btrfs_root_item *root_item = &root->root_item; @@ -3668,7 +3656,6 @@ static int check_fs_root(struct btrfs_root *root, rec->found_root_item = 1; } - btrfs_init_path(&path); memset(&root_node, 0, sizeof(root_node)); cache_tree_init(&root_node.root_cache); cache_tree_init(&root_node.inode_cache); @@ -3804,7 +3791,7 @@ skip_walking: static int check_fs_roots(struct cache_tree *root_cache) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct walk_control wc; struct extent_buffer *leaf, *tree_node; @@ -3822,7 +3809,6 @@ static int check_fs_roots(struct cache_tree *root_cache) reset_cached_block_groups(); memset(&wc, 0, sizeof(wc)); cache_tree_init(&wc.shared); - btrfs_init_path(&path); again: key.offset = 0; @@ -4212,7 +4198,7 @@ static bool check_owner_ref(struct btrfs_root *root, struct tree_backref *back; struct btrfs_root *ref_root; struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *parent; int level; bool found = false; @@ -4252,7 +4238,6 @@ static bool check_owner_ref(struct btrfs_root *root, else btrfs_node_key_to_cpu(buf, &key, 0); - btrfs_init_path(&path); path.lowest_level = level + 1; ret = btrfs_search_slot(NULL, ref_root, &key, &path, 0, 0); if (ret < 0) @@ -4510,7 +4495,7 @@ static int try_to_fix_bad_block(struct btrfs_root *root, struct ulist *roots; struct ulist_node *node; struct btrfs_root *search_root; - struct btrfs_path path; + struct btrfs_path path = {}; struct ulist_iterator iter; struct btrfs_key root_key, key; int ret; @@ -4523,7 +4508,6 @@ static int try_to_fix_bad_block(struct btrfs_root *root, if (ret) return -EIO; - btrfs_init_path(&path); ULIST_ITER_INIT(&iter); /* * If we found no roots referencing to this tree block, there is no @@ -5768,12 +5752,11 @@ static int check_extent_exists(struct btrfs_root *root, u64 bytenr, u64 num_bytes) { struct btrfs_root *extent_root; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; struct btrfs_key key; int ret; - btrfs_init_path(&path); key.objectid = bytenr; key.type = BTRFS_EXTENT_ITEM_KEY; key.offset = (u64)-1; @@ -5909,7 +5892,7 @@ out: static int check_csum_root(struct btrfs_root *root) { - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; struct btrfs_key key; u64 last_data_end = 0; @@ -5930,7 +5913,6 @@ static int check_csum_root(struct btrfs_root *root) return -ENOENT; } - btrfs_init_path(&path); key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; key.type = BTRFS_EXTENT_CSUM_KEY; key.offset = 0; @@ -7376,14 +7358,12 @@ static int delete_duplicate_records(struct btrfs_root *root, { struct btrfs_trans_handle *trans; LIST_HEAD(delete_list); - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_record *tmp, *good, *n; int nr_del = 0; int ret = 0, err; struct btrfs_key key; - btrfs_init_path(&path); - good = rec; /* Find the record that covers all of the duplicates. */ list_for_each_entry(tmp, &rec->dups, list) { @@ -7479,7 +7459,7 @@ static int __find_possible_backrefs(struct btrfs_root *root, u64 *bytes_ret) { int ret = 0; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_key found_key; struct btrfs_file_extent_item *fi; @@ -7487,8 +7467,6 @@ static int __find_possible_backrefs(struct btrfs_root *root, u64 backref_offset, disk_bytenr; int slot; - btrfs_init_path(&path); - key.objectid = owner; key.type = BTRFS_INODE_ITEM_KEY; key.offset = 0; @@ -7642,7 +7620,7 @@ static int fixup_extent_refs(struct cache_tree *extent_cache, { struct btrfs_trans_handle *trans = NULL; int ret; - struct btrfs_path path; + struct btrfs_path path = {}; struct cache_extent *cache; struct extent_backref *back, *tmp; int allocated = 0; @@ -7651,7 +7629,6 @@ static int fixup_extent_refs(struct cache_tree *extent_cache, if (rec->flag_block_full_backref) flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; - btrfs_init_path(&path); if (rec->refs != rec->extent_item_refs && !rec->metadata) { /* * Sometimes the backrefs themselves are so broken they don't @@ -7727,7 +7704,7 @@ static int fixup_extent_flags(struct extent_record *rec) { struct btrfs_trans_handle *trans; struct btrfs_root *root = btrfs_extent_root(gfs_info, rec->start); - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_extent_item *ei; struct btrfs_key key; u64 flags; @@ -7750,7 +7727,6 @@ retry: if (IS_ERR(trans)) return PTR_ERR(trans); - btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, &key, &path, 0, 1); if (ret < 0) { btrfs_release_path(&path); @@ -7797,14 +7773,13 @@ static int prune_one_block(struct btrfs_trans_handle *trans, { struct btrfs_root *extent_root; int ret; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *eb; u64 found; int slot; int nritems; int level = corrupt->level + 1; - btrfs_init_path(&path); again: extent_root = btrfs_extent_root(gfs_info, corrupt->key.objectid); /* we want to stop at the parent to our busted block */ @@ -7983,7 +7958,7 @@ static int record_unaligned_extent_rec(struct extent_record *rec) static int repair_extent_item_generation(struct extent_record *rec) { struct btrfs_trans_handle *trans; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_extent_item *ei; struct btrfs_root *extent_root = btrfs_extent_root(gfs_info, @@ -8003,7 +7978,6 @@ static int repair_extent_item_generation(struct extent_record *rec) error_msg(ERROR_MSG_START_TRANS, "%m"); return ret; } - btrfs_init_path(&path); ret = btrfs_search_slot(trans, extent_root, &key, &path, 0, 1); /* Not possible */ if (ret == 0) @@ -8728,7 +8702,7 @@ static int check_block_groups(struct block_group_tree *bg_cache) static int parse_tree_roots(struct list_head *normal_trees, struct list_head *dropping_trees) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_key found_key; struct btrfs_root_item ri; @@ -8736,7 +8710,6 @@ static int parse_tree_roots(struct list_head *normal_trees, int slot; int ret = 0; - btrfs_init_path(&path); key.offset = 0; key.objectid = 0; key.type = BTRFS_ROOT_ITEM_KEY; @@ -8801,15 +8774,13 @@ out: */ static int check_dev_extents(void) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_root *dev_root = gfs_info->dev_root; int ret; u64 prev_devid = 0; u64 prev_dev_ext_end = 0; - btrfs_init_path(&path); - key.objectid = 1; key.type = BTRFS_DEV_EXTENT_KEY; key.offset = 0; @@ -9174,14 +9145,13 @@ static int btrfs_fsck_reinit_root(struct btrfs_trans_handle *trans, static int reset_block_groups(void) { struct btrfs_block_group *cache; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; struct btrfs_chunk *chunk; struct btrfs_key key; int ret; u64 start; - btrfs_init_path(&path); key.objectid = 0; key.type = BTRFS_CHUNK_ITEM_KEY; key.offset = 0; @@ -9245,14 +9215,13 @@ static int reset_block_groups(void) static int reset_balance(struct btrfs_trans_handle *trans) { struct btrfs_root *root = gfs_info->tree_root; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; struct btrfs_key key; int del_slot, del_nr = 0; int ret; int found = 0; - btrfs_init_path(&path); key.objectid = BTRFS_BALANCE_OBJECTID; key.type = BTRFS_BALANCE_ITEM_KEY; key.offset = 0; @@ -9351,12 +9320,11 @@ static int reinit_global_roots(struct btrfs_trans_handle *trans, u64 objectid) .type = BTRFS_ROOT_ITEM_KEY, .offset = 0, }; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_root *tree_root = gfs_info->tree_root; struct btrfs_root *root; int ret; - btrfs_init_path(&path); while (1) { ret = btrfs_search_slot(NULL, tree_root, &key, &path, 0, 0); if (ret) { @@ -9509,7 +9477,7 @@ again: static int delete_bad_item(struct btrfs_root *root, struct bad_item *bad) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_trans_handle *trans; struct btrfs_key key; int ret; @@ -9531,7 +9499,6 @@ static int delete_bad_item(struct btrfs_root *root, struct bad_item *bad) if (IS_ERR(trans)) return PTR_ERR(trans); - btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, &bad->key, &path, -1, 1); if (ret) { if (ret > 0) @@ -9583,7 +9550,7 @@ static int build_roots_info_cache(void) int ret = 0; struct btrfs_key key; struct extent_buffer *leaf; - struct btrfs_path path; + struct btrfs_path path = {}; if (!roots_info_cache) { roots_info_cache = malloc(sizeof(*roots_info_cache)); @@ -9592,7 +9559,6 @@ static int build_roots_info_cache(void) cache_tree_init(roots_info_cache); } - btrfs_init_path(&path); key.objectid = 0; key.type = BTRFS_EXTENT_ITEM_KEY; key.offset = 0; @@ -9799,7 +9765,7 @@ static int maybe_repair_root_item(struct btrfs_path *path, */ static int repair_root_items(void) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct extent_buffer *leaf; struct btrfs_trans_handle *trans = NULL; @@ -9810,8 +9776,6 @@ static int repair_root_items(void) if (btrfs_fs_incompat(gfs_info, EXTENT_TREE_V2)) return 0; - btrfs_init_path(&path); - ret = build_roots_info_cache(); if (ret) goto out; diff --git a/check/mode-common.c b/check/mode-common.c index 175e90f7..71e735c4 100644 --- a/check/mode-common.c +++ b/check/mode-common.c @@ -52,10 +52,9 @@ static int check_prealloc_data_ref(u64 disk_bytenr, u64 offset = btrfs_extent_data_ref_offset(eb, dref); struct btrfs_root *root; struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; int ret; - btrfs_init_path(&path); key.objectid = rootid; key.type = BTRFS_ROOT_ITEM_KEY; key.offset = (u64)-1; @@ -190,7 +189,7 @@ int check_prealloc_extent_written(u64 disk_bytenr, u64 num_bytes) { struct btrfs_root *extent_root = btrfs_extent_root(gfs_info, disk_bytenr); - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; int ret; struct btrfs_extent_item *ei; @@ -202,7 +201,6 @@ int check_prealloc_extent_written(u64 disk_bytenr, u64 num_bytes) key.type = BTRFS_EXTENT_ITEM_KEY; key.offset = num_bytes; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, extent_root, &key, &path, 0, 0); if (ret > 0) { fprintf(stderr, @@ -303,7 +301,7 @@ int count_csum_range(u64 start, u64 len, u64 *found) { struct btrfs_root *csum_root = btrfs_csum_root(gfs_info, start); struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; int ret; size_t size; @@ -311,8 +309,6 @@ int count_csum_range(u64 start, u64 len, u64 *found) u64 csum_end; u16 csum_size = gfs_info->csum_size; - btrfs_init_path(&path); - key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; key.offset = start; key.type = BTRFS_EXTENT_CSUM_KEY; @@ -416,7 +412,6 @@ static int get_highest_inode(struct btrfs_trans_handle *trans, struct btrfs_key key, found_key; int ret; - btrfs_init_path(path); key.objectid = BTRFS_LAST_FREE_OBJECTID; key.offset = -1; key.type = BTRFS_INODE_ITEM_KEY; @@ -654,10 +649,9 @@ int delete_corrupted_dir_item(struct btrfs_trans_handle *trans, u32 namelen) { struct btrfs_dir_item *di_item; - struct btrfs_path path; + struct btrfs_path path = {}; int ret; - btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, di_key, &path, 0, 1); if (ret > 0) { error("key (%llu %u %llu) doesn't exist in root %llu", @@ -736,7 +730,7 @@ static int find_file_type_dir_index(struct btrfs_root *root, u64 ino, u64 dirid, u64 index, const char *name, u32 name_len, u32 *imode_ret) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_key location; struct btrfs_dir_item *di; @@ -746,7 +740,6 @@ static int find_file_type_dir_index(struct btrfs_root *root, u64 ino, u64 dirid, u32 len; int ret; - btrfs_init_path(&path); key.objectid = dirid; key.offset = index; key.type = BTRFS_DIR_INDEX_KEY; @@ -788,7 +781,7 @@ static int find_file_type_dir_item(struct btrfs_root *root, u64 ino, u64 dirid, const char *name, u32 name_len, u32 *imode_ret) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_key location; struct btrfs_dir_item *di; @@ -800,7 +793,6 @@ static int find_file_type_dir_item(struct btrfs_root *root, u64 ino, u64 dirid, u32 len; int ret; - btrfs_init_path(&path); key.objectid = dirid; key.offset = btrfs_name_hash(name, name_len); key.type = BTRFS_DIR_INDEX_KEY; @@ -1056,7 +1048,7 @@ int check_repair_free_space_inode(struct btrfs_path *path) int recow_extent_buffer(struct btrfs_root *root, struct extent_buffer *eb) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_trans_handle *trans; struct btrfs_key key; int ret; @@ -1077,7 +1069,6 @@ int recow_extent_buffer(struct btrfs_root *root, struct extent_buffer *eb) if (IS_ERR(trans)) return PTR_ERR(trans); - btrfs_init_path(&path); path.lowest_level = btrfs_header_level(eb); if (path.lowest_level) btrfs_node_key_to_cpu(eb, &key, 0); @@ -1100,7 +1091,7 @@ int get_extent_item_generation(u64 bytenr, u64 *gen_ret) { struct btrfs_root *root = btrfs_extent_root(gfs_info, bytenr); struct btrfs_extent_item *ei; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; int ret; @@ -1108,7 +1099,6 @@ int get_extent_item_generation(u64 bytenr, u64 *gen_ret) key.type = BTRFS_METADATA_ITEM_KEY; key.offset = (u64)-1; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); /* Not possible */ if (ret == 0) @@ -1233,7 +1223,7 @@ static int fill_csum_tree_from_one_fs_root(struct btrfs_trans_handle *trans, struct btrfs_root *cur_root) { struct btrfs_root *csum_root; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct extent_buffer *node; struct btrfs_file_extent_item *fi; @@ -1248,7 +1238,6 @@ static int fill_csum_tree_from_one_fs_root(struct btrfs_trans_handle *trans, if (!buf) return -ENOMEM; - btrfs_init_path(&path); key.objectid = 0; key.offset = 0; key.type = 0; @@ -1340,7 +1329,7 @@ out: static int fill_csum_tree_from_fs(struct btrfs_trans_handle *trans) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_root *tree_root = gfs_info->tree_root; struct btrfs_root *cur_root; struct extent_buffer *node; @@ -1348,7 +1337,6 @@ static int fill_csum_tree_from_fs(struct btrfs_trans_handle *trans) int slot = 0; int ret = 0; - btrfs_init_path(&path); key.objectid = BTRFS_FS_TREE_OBJECTID; key.offset = 0; key.type = BTRFS_ROOT_ITEM_KEY; @@ -1487,14 +1475,13 @@ static int fill_csum_tree_from_extent(struct btrfs_trans_handle *trans, struct btrfs_root *extent_root) { struct btrfs_root *csum_root; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_extent_item *ei; struct extent_buffer *leaf; char *buf; struct btrfs_key key; int ret; - btrfs_init_path(&path); key.objectid = 0; key.type = BTRFS_EXTENT_ITEM_KEY; key.offset = 0; diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c index d4d6125c..35bca857 100644 --- a/check/mode-lowmem.c +++ b/check/mode-lowmem.c @@ -281,7 +281,7 @@ static int modify_block_groups_cache(u64 flags, int cache) { struct btrfs_root *root = btrfs_block_group_root(gfs_info); struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_block_group *bg_cache; struct btrfs_block_group_item *bi; struct btrfs_block_group_item bg_item; @@ -293,7 +293,6 @@ static int modify_block_groups_cache(u64 flags, int cache) key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; key.offset = 0; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); if (ret < 0) { errno = -ret; @@ -430,7 +429,7 @@ err: */ static int is_chunk_almost_full(u64 start) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_root *root = btrfs_block_group_root(gfs_info); struct btrfs_block_group_item *bi; @@ -446,7 +445,6 @@ static int is_chunk_almost_full(u64 start) key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; key.offset = (u64)-1; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); if (!ret) ret = -EIO; @@ -637,7 +635,7 @@ static int repair_tree_block_ref(struct btrfs_root *root, { struct btrfs_trans_handle *trans = NULL; struct btrfs_root *extent_root; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_extent_item *ei; struct btrfs_tree_block_info *bi; struct btrfs_key key; @@ -660,7 +658,6 @@ static int repair_tree_block_ref(struct btrfs_root *root, WARN_ON(level > BTRFS_MAX_LEVEL); WARN_ON(level < 0); - btrfs_init_path(&path); bytenr = btrfs_header_bytenr(node); owner = btrfs_header_owner(node); generation = btrfs_header_generation(node); @@ -820,7 +817,7 @@ static int find_dir_index(struct btrfs_root *root, u64 dirid, u64 location_id, u64 *index_ret, char *namebuf, u32 name_len, u8 file_type) { - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *node; struct btrfs_dir_item *di; struct btrfs_key key; @@ -842,7 +839,6 @@ static int find_dir_index(struct btrfs_root *root, u64 dirid, u64 location_id, key.offset = (u64)-1; key.type = BTRFS_DIR_INDEX_KEY; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); if (ret < 0) return ret; @@ -919,7 +915,7 @@ static int find_dir_item(struct btrfs_root *root, struct btrfs_key *key, struct btrfs_key *location_key, char *name, u32 namelen, u8 file_type) { - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *node; struct btrfs_dir_item *di; struct btrfs_key location; @@ -942,7 +938,6 @@ static int find_dir_item(struct btrfs_root *root, struct btrfs_key *key, return ret; } - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, key, &path, 0, 0); if (ret) { ret = key->type == BTRFS_DIR_ITEM_KEY ? DIR_ITEM_MISSING : @@ -1338,7 +1333,7 @@ static int find_inode_ref(struct btrfs_root *root, struct btrfs_key *key, char *name, int namelen, u64 *index_ret) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_inode_ref *ref; struct btrfs_inode_extref *extref; struct extent_buffer *node; @@ -1355,7 +1350,6 @@ static int find_inode_ref(struct btrfs_root *root, struct btrfs_key *key, UASSERT(index_ret); - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, key, &path, 0, 0); if (ret) { ret = INODE_REF_MISSING; @@ -1415,7 +1409,6 @@ extref: goto out; btrfs_release_path(&path); - btrfs_init_path(&path); dir_id = key->offset; key->type = BTRFS_INODE_EXTREF_KEY; @@ -1498,14 +1491,13 @@ static int repair_inode_item_missing(struct btrfs_root *root, u64 ino, { struct btrfs_key key; struct btrfs_trans_handle *trans; - struct btrfs_path path; + struct btrfs_path path = {}; int ret; key.objectid = ino; key.type = BTRFS_INODE_ITEM_KEY; key.offset = 0; - btrfs_init_path(&path); trans = btrfs_start_transaction(root, 1); if (IS_ERR(trans)) { ret = -EIO; @@ -1564,14 +1556,13 @@ static int lowmem_delete_corrupted_dir_item(struct btrfs_root *root, static int try_repair_imode(struct btrfs_root *root, u64 ino) { struct btrfs_inode_item *iitem; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; int ret; key.objectid = ino; key.type = BTRFS_INODE_ITEM_KEY; key.offset = 0; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); if (ret > 0) @@ -2188,7 +2179,7 @@ static int __count_dir_isize(struct btrfs_root *root, u64 ino, int type, u64 *size_ret) { struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; u32 len; struct btrfs_dir_item *di; int ret; @@ -2202,7 +2193,6 @@ static int __count_dir_isize(struct btrfs_root *root, u64 ino, int type, key.type = type; key.offset = (u64)-1; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); if (ret < 0) { ret = -EIO; @@ -2518,11 +2508,10 @@ out: static bool has_orphan_item(struct btrfs_root *root, u64 ino) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; int ret; - btrfs_init_path(&path); key.objectid = BTRFS_ORPHAN_OBJECTID; key.type = BTRFS_ORPHAN_ITEM_KEY; key.offset = ino; @@ -3019,7 +3008,7 @@ static int check_tree_block_ref(struct btrfs_root *root, { struct btrfs_key key; struct btrfs_root *extent_root; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_extent_item *ei; struct btrfs_extent_inline_ref *iref; struct extent_buffer *leaf; @@ -3038,7 +3027,6 @@ static int check_tree_block_ref(struct btrfs_root *root, int strict = 1; int parent = 0; - btrfs_init_path(&path); key.objectid = bytenr; if (btrfs_fs_incompat(gfs_info, SKINNY_METADATA)) key.type = BTRFS_METADATA_ITEM_KEY; @@ -3239,7 +3227,7 @@ static int repair_extent_data_item(struct btrfs_root *root, struct btrfs_key fi_key; struct btrfs_key key; struct btrfs_extent_item *ei; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_root *extent_root; struct extent_buffer *eb; u64 size; @@ -3291,7 +3279,6 @@ static int repair_extent_data_item(struct btrfs_root *root, key.type = BTRFS_EXTENT_ITEM_KEY; key.offset = num_bytes; - btrfs_init_path(&path); extent_root = btrfs_extent_root(gfs_info, key.objectid); ret = btrfs_search_slot(NULL, extent_root, &key, &path, 0, 0); if (ret < 0) { @@ -3374,7 +3361,7 @@ static int check_extent_data_item(struct btrfs_root *root, { struct btrfs_file_extent_item *fi; struct extent_buffer *eb = pathp->nodes[0]; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_root *extent_root; struct btrfs_key fi_key; struct btrfs_key dbref_key; @@ -3440,7 +3427,6 @@ static int check_extent_data_item(struct btrfs_root *root, owner = btrfs_header_owner(eb); /* Check the extent item of the file extent in extent tree */ - btrfs_init_path(&path); dbref_key.objectid = btrfs_file_extent_disk_bytenr(eb, fi); dbref_key.type = BTRFS_EXTENT_ITEM_KEY; dbref_key.offset = btrfs_file_extent_disk_num_bytes(eb, fi); @@ -3567,7 +3553,7 @@ static int check_block_group_item(struct extent_buffer *eb, int slot) struct btrfs_root *chunk_root = gfs_info->chunk_root; struct btrfs_block_group_item *bi; struct btrfs_block_group_item bg_item; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key bg_key; struct btrfs_key chunk_key; struct btrfs_key extent_key; @@ -3592,7 +3578,6 @@ static int check_block_group_item(struct extent_buffer *eb, int slot) chunk_key.type = BTRFS_CHUNK_ITEM_KEY; chunk_key.offset = bg_key.objectid; - btrfs_init_path(&path); /* Search for the referencer chunk */ ret = btrfs_search_slot(NULL, chunk_root, &chunk_key, &path, 0, 0); if (ret) { @@ -3618,7 +3603,6 @@ static int check_block_group_item(struct extent_buffer *eb, int slot) extent_key.type = 0; extent_key.offset = 0; - btrfs_init_path(&path); extent_root = btrfs_extent_root(gfs_info, extent_key.objectid); ret = btrfs_search_slot(NULL, extent_root, &extent_key, &path, 0, 0); if (ret < 0) @@ -3697,7 +3681,7 @@ static int query_tree_block_level(u64 bytenr) { struct btrfs_root *extent_root; struct extent_buffer *eb; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_extent_item *ei; u64 flags; @@ -3711,8 +3695,6 @@ static int query_tree_block_level(u64 bytenr) key.type = BTRFS_METADATA_ITEM_KEY; key.offset = (u64)-1; - btrfs_init_path(&path); - extent_root = btrfs_extent_root(gfs_info, bytenr); ret = btrfs_search_slot(NULL, extent_root, &key, &path, 0, 0); if (ret < 0) @@ -3775,7 +3757,7 @@ static int check_tree_block_backref(u64 root_id, u64 bytenr, int level) { struct btrfs_root *root; struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *eb; struct extent_buffer *node; u32 nodesize = btrfs_super_nodesize(gfs_info->super_copy); @@ -3821,7 +3803,6 @@ static int check_tree_block_backref(u64 root_id, u64 bytenr, int level) free_extent_buffer(eb); - btrfs_init_path(&path); path.lowest_level = level; /* Search with the first key, to ensure we can reach it */ ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); @@ -3947,7 +3928,7 @@ static int check_extent_data_backref(u64 root_id, u64 objectid, u64 offset, struct btrfs_root *root; struct btrfs_root *extent_root; struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; struct btrfs_file_extent_item *fi; u32 found_count = 0; @@ -3959,7 +3940,6 @@ static int check_extent_data_backref(u64 root_id, u64 objectid, u64 offset, key.type = BTRFS_EXTENT_ITEM_KEY; key.offset = (u64)-1; - btrfs_init_path(&path); extent_root = btrfs_extent_root(gfs_info, bytenr); ret = btrfs_search_slot(NULL, extent_root, &key, &path, 0, 0); if (ret < 0) @@ -3977,7 +3957,6 @@ static int check_extent_data_backref(u64 root_id, u64 objectid, u64 offset, key.objectid = root_id; key.type = BTRFS_ROOT_ITEM_KEY; key.offset = (u64)-1; - btrfs_init_path(&path); root = btrfs_read_fs_root(gfs_info, &key); if (IS_ERR(root)) @@ -4445,7 +4424,7 @@ static int check_dev_extent_item(struct extent_buffer *eb, int slot) { struct btrfs_root *chunk_root = gfs_info->chunk_root; struct btrfs_dev_extent *ptr; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key chunk_key; struct btrfs_key devext_key; struct btrfs_chunk *chunk; @@ -4464,7 +4443,6 @@ static int check_dev_extent_item(struct extent_buffer *eb, int slot) chunk_key.type = BTRFS_CHUNK_ITEM_KEY; chunk_key.offset = btrfs_dev_extent_chunk_offset(eb, ptr); - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, chunk_root, &chunk_key, &path, 0, 0); if (ret) goto out; @@ -4508,7 +4486,7 @@ static int check_dev_item(struct extent_buffer *eb, int slot, { struct btrfs_root *dev_root = gfs_info->dev_root; struct btrfs_dev_item *dev_item; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_dev_extent *ptr; struct btrfs_device *dev; @@ -4537,7 +4515,6 @@ static int check_dev_item(struct extent_buffer *eb, int slot, key.type = BTRFS_DEV_EXTENT_KEY; key.offset = 0; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, dev_root, &key, &path, 0, 0); if (ret < 0) { btrfs_item_key_to_cpu(eb, &key, slot); @@ -4681,7 +4658,7 @@ out: static int check_chunk_item(struct extent_buffer *eb, int slot) { struct btrfs_root *dev_root = gfs_info->dev_root; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key chunk_key; struct btrfs_key devext_key; struct btrfs_chunk *chunk; @@ -4711,7 +4688,6 @@ static int check_chunk_item(struct extent_buffer *eb, int slot) } type = btrfs_chunk_type(eb, chunk); - btrfs_init_path(&path); ret = find_block_group_item(&path, chunk_key.offset, length, type); if (ret < 0) err |= REFERENCER_MISSING; @@ -4720,7 +4696,6 @@ static int check_chunk_item(struct extent_buffer *eb, int slot) stripe_len = btrfs_stripe_length(gfs_info, eb, chunk); for (i = 0; i < num_stripes; i++) { btrfs_release_path(&path); - btrfs_init_path(&path); devext_key.objectid = btrfs_stripe_devid_nr(eb, chunk, i); devext_key.type = BTRFS_DEV_EXTENT_KEY; devext_key.offset = btrfs_stripe_offset_nr(eb, chunk, i); @@ -5117,12 +5092,10 @@ static int repair_fs_first_inode(struct btrfs_root *root, int err) { struct btrfs_trans_handle *trans; struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; int filetype = BTRFS_FT_DIR; int ret = 0; - btrfs_init_path(&path); - if (err & INODE_REF_MISSING) { key.objectid = BTRFS_FIRST_FREE_OBJECTID; key.type = BTRFS_INODE_REF_KEY; @@ -5178,7 +5151,7 @@ out: */ static int check_fs_first_inode(struct btrfs_root *root) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_inode_item *ii; u64 index; @@ -5196,7 +5169,6 @@ static int check_fs_first_inode(struct btrfs_root *root) BTRFS_FIRST_FREE_OBJECTID) return 0; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); if (ret < 0) goto out; @@ -5250,7 +5222,7 @@ out: */ static int check_btrfs_root(struct btrfs_root *root, int check_all) { - struct btrfs_path path; + struct btrfs_path path = {}; struct node_refs nrefs; struct btrfs_root_item *root_item = &root->root_item; u64 super_generation = btrfs_super_generation(gfs_info->super_copy); @@ -5273,7 +5245,6 @@ static int check_btrfs_root(struct btrfs_root *root, int check_all) level = btrfs_header_level(root->node); - btrfs_init_path(&path); if (btrfs_root_generation(root_item) > super_generation + 1) { error( @@ -5358,7 +5329,7 @@ static int check_fs_root(struct btrfs_root *root) static int check_root_ref(struct btrfs_root *root, struct btrfs_key *ref_key, struct extent_buffer *node, int slot) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_root_ref *ref; struct btrfs_root_ref *backref; @@ -5395,7 +5366,6 @@ static int check_root_ref(struct btrfs_root *root, struct btrfs_key *ref_key, key.type = BTRFS_ROOT_BACKREF_KEY + BTRFS_ROOT_REF_KEY - ref_key->type; key.offset = ref_key->objectid; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); if (ret) { err |= ROOT_REF_MISSING; @@ -5450,14 +5420,13 @@ int check_fs_roots_lowmem(void) { struct btrfs_root *tree_root = gfs_info->tree_root; struct btrfs_root *cur_root = NULL; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct extent_buffer *node; int slot; int ret; int err = 0; - btrfs_init_path(&path); key.objectid = BTRFS_FS_TREE_OBJECTID; key.offset = 0; key.type = BTRFS_ROOT_ITEM_KEY; @@ -5556,7 +5525,7 @@ out: */ int check_chunks_and_extents_lowmem(void) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key old_key; struct btrfs_key key; struct btrfs_root *root; @@ -5572,7 +5541,6 @@ int check_chunks_and_extents_lowmem(void) ret = check_btrfs_root(root, 1); err |= ret; - btrfs_init_path(&path); key.objectid = BTRFS_EXTENT_TREE_OBJECTID; key.offset = 0; key.type = BTRFS_ROOT_ITEM_KEY; diff --git a/check/qgroup-verify.c b/check/qgroup-verify.c index 1a62009b..0c08eae8 100644 --- a/check/qgroup-verify.c +++ b/check/qgroup-verify.c @@ -938,7 +938,7 @@ static int load_quota_info(struct btrfs_fs_info *info) int ret; struct btrfs_root *root = info->quota_root; struct btrfs_root *tmproot; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_key root_key; struct btrfs_disk_key disk_key; @@ -954,8 +954,6 @@ loop: * items. The 2nd pass picks up relation items and glues them to their * respective count structures. */ - btrfs_init_path(&path); - key.offset = 0; key.objectid = search_relations ? 0 : BTRFS_QGROUP_RELATION_KEY; key.type = 0; @@ -1164,13 +1162,11 @@ static int scan_extents(struct btrfs_fs_info *info, int ret, i, nr, level; struct btrfs_root *root = btrfs_extent_root(info, start); struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_disk_key disk_key; struct extent_buffer *leaf; u64 bytenr = 0, num_bytes = 0; - btrfs_init_path(&path); - key.objectid = start; key.type = 0; key.offset = 0; @@ -1562,7 +1558,7 @@ static int repair_qgroup_info(struct btrfs_fs_info *info, int ret; struct btrfs_root *root = info->quota_root; struct btrfs_trans_handle *trans; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_qgroup_info_item *info_item; struct btrfs_key key; @@ -1575,7 +1571,6 @@ static int repair_qgroup_info(struct btrfs_fs_info *info, if (IS_ERR(trans)) return PTR_ERR(trans); - btrfs_init_path(&path); key.objectid = 0; key.type = BTRFS_QGROUP_INFO_KEY; key.offset = count->qgroupid; @@ -1619,7 +1614,7 @@ static int repair_qgroup_status(struct btrfs_fs_info *info, bool silent) int ret; struct btrfs_root *root = info->quota_root; struct btrfs_trans_handle *trans; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_qgroup_status_item *status_item; @@ -1630,7 +1625,6 @@ static int repair_qgroup_status(struct btrfs_fs_info *info, bool silent) if (IS_ERR(trans)) return PTR_ERR(trans); - btrfs_init_path(&path); key.objectid = 0; key.type = BTRFS_QGROUP_STATUS_KEY; key.offset = 0; diff --git a/check/repair.c b/check/repair.c index 44fefe3a..eacf4506 100644 --- a/check/repair.c +++ b/check/repair.c @@ -172,12 +172,11 @@ static int populate_used_from_extent_root(struct btrfs_root *root, { struct btrfs_fs_info *fs_info = root->fs_info; struct extent_buffer *leaf; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; int slot; int ret; - btrfs_init_path(&path); key.offset = 0; key.objectid = 0; key.type = BTRFS_EXTENT_ITEM_KEY; diff --git a/cmds/inspect-dump-tree.c b/cmds/inspect-dump-tree.c index 9726bef5..9c3de7aa 100644 --- a/cmds/inspect-dump-tree.c +++ b/cmds/inspect-dump-tree.c @@ -310,7 +310,7 @@ static int cmd_inspect_dump_tree(const struct cmd_struct *cmd, { struct btrfs_root *root; struct btrfs_fs_info *info; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_root_item ri; struct extent_buffer *leaf; @@ -516,7 +516,6 @@ static int cmd_inspect_dump_tree(const struct cmd_struct *cmd, } tree_root_scan = info->tree_root; - btrfs_init_path(&path); again: if (!extent_buffer_uptodate(tree_root_scan->node)) goto no_node; diff --git a/cmds/inspect-tree-stats.c b/cmds/inspect-tree-stats.c index d720d64a..e1808ec5 100644 --- a/cmds/inspect-tree-stats.c +++ b/cmds/inspect-tree-stats.c @@ -314,7 +314,7 @@ static int calc_root_size(struct btrfs_root *tree_root, struct btrfs_key *key, int find_inline) { struct btrfs_root *root; - struct btrfs_path path; + struct btrfs_path path = {}; struct rb_node *n; struct timeval start, end, diff = {0}; struct root_stats stat; @@ -329,7 +329,6 @@ static int calc_root_size(struct btrfs_root *tree_root, struct btrfs_key *key, return 1; } - btrfs_init_path(&path); memset(&stat, 0, sizeof(stat)); level = btrfs_header_level(root->node); stat.lowest_bytenr = btrfs_header_bytenr(root->node); diff --git a/cmds/rescue-chunk-recover.c b/cmds/rescue-chunk-recover.c index bf67fadc..e12dc61c 100644 --- a/cmds/rescue-chunk-recover.c +++ b/cmds/rescue-chunk-recover.c @@ -556,7 +556,7 @@ static int check_chunk_by_metadata(struct recover_control *rc, int ret; int i; int slot; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_root *dev_root; struct stripe *stripe; @@ -564,8 +564,6 @@ static int check_chunk_by_metadata(struct recover_control *rc, struct btrfs_block_group_item *bg_ptr; struct extent_buffer *l; - btrfs_init_path(&path); - if (bg_only) goto bg_check; @@ -985,7 +983,7 @@ static int block_group_remove_all_extent_items(struct btrfs_trans_handle *trans, { struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; u64 start = bg->objectid; u64 end = bg->objectid + bg->offset; @@ -995,7 +993,6 @@ static int block_group_remove_all_extent_items(struct btrfs_trans_handle *trans, int i; int del_s, del_nr; - btrfs_init_path(&path); root = btrfs_extent_root(fs_info, start); key.objectid = start; @@ -1384,14 +1381,13 @@ static int rebuild_block_group(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info = root->fs_info; struct chunk_record *chunk_rec; struct btrfs_key search_key; - struct btrfs_path path; + struct btrfs_path path = {}; u64 used = 0; int ret = 0; if (list_empty(&rc->rebuild_chunks)) return 0; - btrfs_init_path(&path); list_for_each_entry(chunk_rec, &rc->rebuild_chunks, list) { search_key.objectid = chunk_rec->offset; search_key.type = BTRFS_EXTENT_ITEM_KEY; @@ -1968,7 +1964,7 @@ static int rebuild_raid_data_chunk_stripes(struct recover_control *rc, int i; int ret = 0; int slot; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key prev_key; struct btrfs_key key; struct btrfs_root *csum_root; @@ -1988,7 +1984,6 @@ static int rebuild_raid_data_chunk_stripes(struct recover_control *rc, LIST_HEAD(unordered); LIST_HEAD(candidates); - btrfs_init_path(&path); list_splice_init(&chunk->dextents, &candidates); again: if (list_is_last(candidates.next, &candidates)) diff --git a/cmds/restore.c b/cmds/restore.c index ba085f94..b0e04a7e 100644 --- a/cmds/restore.c +++ b/cmds/restore.c @@ -474,7 +474,7 @@ static int set_file_xattrs(struct btrfs_root *root, u64 inode, int fd, const char *file_name) { struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; struct btrfs_dir_item *di; u32 name_len = 0; @@ -485,7 +485,6 @@ static int set_file_xattrs(struct btrfs_root *root, u64 inode, char *data = NULL; int ret = 0; - btrfs_init_path(&path); key.objectid = inode; key.type = BTRFS_XATTR_ITEM_KEY; key.offset = 0; @@ -571,11 +570,10 @@ out: static int copy_metadata(struct btrfs_root *root, int fd, struct btrfs_key *key) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_inode_item *inode_item; int ret; - btrfs_init_path(&path); ret = btrfs_lookup_inode(NULL, root, &path, key, 0); if (ret == 0) { struct btrfs_timespec *bts; @@ -620,7 +618,7 @@ static int copy_file(struct btrfs_root *root, int fd, struct btrfs_key *key, const char *file) { struct extent_buffer *leaf; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_file_extent_item *fi; struct btrfs_inode_item *inode_item; struct btrfs_timespec *bts; @@ -632,7 +630,6 @@ static int copy_file(struct btrfs_root *root, int fd, struct btrfs_key *key, struct timespec times[2]; bool times_ok = false; - btrfs_init_path(&path); ret = btrfs_lookup_inode(NULL, root, &path, key, 0); if (ret == 0) { inode_item = btrfs_item_ptr(path.nodes[0], path.slots[0], @@ -798,7 +795,7 @@ static int overwrite_ok(const char * path) static int copy_symlink(struct btrfs_root *root, struct btrfs_key *key, const char *file) { - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; struct btrfs_file_extent_item *extent_item; struct btrfs_inode_item *inode_item; @@ -821,7 +818,6 @@ static int copy_symlink(struct btrfs_root *root, struct btrfs_key *key, } } - btrfs_init_path(&path); key->type = BTRFS_EXTENT_DATA_KEY; key->offset = 0; ret = btrfs_search_slot(NULL, root, key, &path, 0, 0); @@ -913,7 +909,7 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key, const char *output_rootdir, const char *in_dir, const regex_t *mreg) { - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; struct btrfs_dir_item *dir_item; struct btrfs_key found_key, location; @@ -924,7 +920,6 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key, int fd; u8 type; - btrfs_init_path(&path); key->offset = 0; key->type = BTRFS_DIR_INDEX_KEY; ret = btrfs_search_slot(NULL, root, key, &path, 0, 0); @@ -1159,7 +1154,7 @@ static int do_list_roots(struct btrfs_root *root) struct btrfs_key key; struct btrfs_key found_key; struct btrfs_disk_key disk_key; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; struct btrfs_root_item ri; unsigned long offset; @@ -1168,7 +1163,6 @@ static int do_list_roots(struct btrfs_root *root) root = root->fs_info->tree_root; - btrfs_init_path(&path); key.offset = 0; key.objectid = 0; key.type = BTRFS_ROOT_ITEM_KEY; @@ -1287,13 +1281,12 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location, static int find_first_dir(struct btrfs_root *root, u64 *objectid) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key found_key; struct btrfs_key key; int ret = -1; int i; - btrfs_init_path(&path); key.objectid = 0; key.type = BTRFS_DIR_INDEX_KEY; key.offset = 0; diff --git a/convert/main.c b/convert/main.c index da6d6cf4..a9a1e1d9 100644 --- a/convert/main.c +++ b/convert/main.c @@ -796,7 +796,7 @@ static int create_image(struct btrfs_root *root, { struct btrfs_inode_item buf; struct btrfs_trans_handle *trans; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct cache_extent *cache; struct cache_tree used_tmp; @@ -813,7 +813,6 @@ static int create_image(struct btrfs_root *root, return PTR_ERR(trans); cache_tree_init(&used_tmp); - btrfs_init_path(&path); ret = btrfs_find_free_objectid(trans, root, BTRFS_FIRST_FREE_OBJECTID, &ino); @@ -1475,7 +1474,7 @@ static int check_convert_image(struct btrfs_root *image_root, u64 ino, u64 total_size, char *reserved_ranges[]) { struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_fs_info *fs_info = image_root->fs_info; u64 checked_bytes = 0; int ret; @@ -1484,7 +1483,6 @@ static int check_convert_image(struct btrfs_root *image_root, u64 ino, key.offset = 0; key.type = BTRFS_EXTENT_DATA_KEY; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, image_root, &key, &path, 0, 0); /* * It's possible that some fs doesn't store any (including sb) @@ -1640,7 +1638,7 @@ static int do_rollback(const char *devname) struct btrfs_root *image_root; struct btrfs_fs_info *fs_info; struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_dir_item *dir; struct btrfs_inode_item *inode_item; struct btrfs_root_ref *root_ref_item; @@ -1700,7 +1698,6 @@ static int do_rollback(const char *devname) key.objectid = CONV_IMAGE_SUBVOL_OBJECTID; key.type = BTRFS_ROOT_BACKREF_KEY; key.offset = BTRFS_FS_TREE_OBJECTID; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, fs_info->tree_root, &key, &path, 0, 0); if (ret > 0) { error("unable to find source fs image subvolume, is it deleted?"); diff --git a/convert/source-fs.c b/convert/source-fs.c index f600b2c3..d206fab6 100644 --- a/convert/source-fs.c +++ b/convert/source-fs.c @@ -228,7 +228,7 @@ int record_file_blocks(struct blk_iterate_data *data, int ret = 0; struct btrfs_root *root = data->root; struct btrfs_root *convert_root = data->convert_root; - struct btrfs_path path; + struct btrfs_path path = {}; u32 sectorsize = root->fs_info->sectorsize; u64 file_pos = file_block * sectorsize; u64 old_disk_bytenr = disk_block * sectorsize; @@ -241,8 +241,6 @@ int record_file_blocks(struct blk_iterate_data *data, data->objectid, data->inode, file_pos, 0, num_bytes); - btrfs_init_path(&path); - /* * Search real disk bytenr from convert root */ diff --git a/image/common.c b/image/common.c index 36e90fd2..3aa298d5 100644 --- a/image/common.c +++ b/image/common.c @@ -120,7 +120,7 @@ int update_disk_super_on_device(struct btrfs_fs_info *info, { struct btrfs_key key; struct extent_buffer *leaf; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_dev_item *dev_item; struct btrfs_super_block disk_super; char dev_uuid[BTRFS_UUID_SIZE]; @@ -134,7 +134,6 @@ int update_disk_super_on_device(struct btrfs_fs_info *info, key.type = BTRFS_DEV_ITEM_KEY; key.offset = cur_devid; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, info->chunk_root, &key, &path, 0, 0); if (ret) { error("search key failed: %d", ret); diff --git a/image/image-create.c b/image/image-create.c index baaeba4e..894969ed 100644 --- a/image/image-create.c +++ b/image/image-create.c @@ -753,7 +753,7 @@ int create_metadump(const char *input, FILE *out, int num_threads, int walk_trees, bool dump_data) { struct btrfs_root *root; - struct btrfs_path path; + struct btrfs_path path = {}; struct metadump_struct metadump; int ret; int err = 0; @@ -781,8 +781,6 @@ int create_metadump(const char *input, FILE *out, int num_threads, goto out; } - btrfs_init_path(&path); - if (walk_trees) { ret = copy_tree_blocks(root, root->fs_info->chunk_root->node, &metadump, 1); diff --git a/image/image-restore.c b/image/image-restore.c index 771e169b..36cdc554 100644 --- a/image/image-restore.c +++ b/image/image-restore.c @@ -1426,7 +1426,7 @@ static int remove_all_dev_extents(struct btrfs_trans_handle *trans) { struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_root *root = fs_info->dev_root; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct extent_buffer *leaf; int slot; @@ -1435,7 +1435,6 @@ static int remove_all_dev_extents(struct btrfs_trans_handle *trans) key.objectid = 1; key.type = BTRFS_DEV_EXTENT_KEY; key.offset = 0; - btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, &key, &path, -1, 1); if (ret < 0) { @@ -1574,7 +1573,7 @@ static int fixup_device_size(struct btrfs_trans_handle *trans, struct btrfs_dev_item *dev_item; struct btrfs_dev_extent *dev_ext; struct btrfs_device *dev; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; struct btrfs_root *root = fs_info->chunk_root; struct btrfs_key key; @@ -1585,7 +1584,6 @@ static int fixup_device_size(struct btrfs_trans_handle *trans, dev_item = &fs_info->super_copy->dev_item; - btrfs_init_path(&path); devid = btrfs_stack_device_id(dev_item); key.objectid = devid; diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index ed8a7002..bbbb2cc3 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -201,11 +201,6 @@ u64 btrfs_extref_hash(u64 parent_objectid, const char *name, int len) return (u64)crc32c(parent_objectid, name, len); } -inline void btrfs_init_path(struct btrfs_path *p) -{ - memset(p, 0, sizeof(*p)); -} - struct btrfs_path *btrfs_alloc_path(void) { might_sleep(); diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index c7321a40..0d9b75bf 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -990,7 +990,6 @@ int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path, void btrfs_release_path(struct btrfs_path *p); struct btrfs_path *btrfs_alloc_path(void); void btrfs_free_path(struct btrfs_path *p); -void btrfs_init_path(struct btrfs_path *p); int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int slot, int nr); diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c index 543a9952..55fdf881 100644 --- a/kernel-shared/extent-tree.c +++ b/kernel-shared/extent-tree.c @@ -3462,7 +3462,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, { struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_block_group *block_group; - struct btrfs_path path; + struct btrfs_path path = {}; int ret = 0; block_group = btrfs_lookup_block_group(fs_info, bytenr); @@ -3484,7 +3484,6 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, */ btrfs_pin_extent(fs_info, bytenr, len); - btrfs_init_path(&path); /* delete block group item and chunk item */ ret = remove_block_group_item(trans, &path, block_group); btrfs_release_path(&path); diff --git a/kernel-shared/file.c b/kernel-shared/file.c index 100ea31c..de5ecfea 100644 --- a/kernel-shared/file.c +++ b/kernel-shared/file.c @@ -187,7 +187,7 @@ int btrfs_read_file(struct btrfs_root *root, u64 ino, u64 start, int len, { struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; struct btrfs_inode_item *ii; u64 isize; @@ -203,7 +203,6 @@ int btrfs_read_file(struct btrfs_root *root, u64 ino, u64 start, int len, return -EINVAL; } - btrfs_init_path(&path); key.objectid = ino; key.offset = start; key.type = BTRFS_EXTENT_DATA_KEY; diff --git a/kernel-shared/free-space-cache.c b/kernel-shared/free-space-cache.c index 7bd76e39..e27c1b62 100644 --- a/kernel-shared/free-space-cache.c +++ b/kernel-shared/free-space-cache.c @@ -910,7 +910,7 @@ int btrfs_clear_free_space_cache(struct btrfs_trans_handle *trans, { struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_root *tree_root = fs_info->tree_root; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_disk_key location; struct btrfs_free_space_header *sc_header; @@ -919,8 +919,6 @@ int btrfs_clear_free_space_cache(struct btrfs_trans_handle *trans, int slot; int ret; - btrfs_init_path(&path); - key.objectid = BTRFS_FREE_SPACE_OBJECTID; key.type = 0; key.offset = bg->start; diff --git a/kernel-shared/inode.c b/kernel-shared/inode.c index 1430cf33..d4018406 100644 --- a/kernel-shared/inode.c +++ b/kernel-shared/inode.c @@ -585,7 +585,7 @@ struct btrfs_root *btrfs_mksubvol(struct btrfs_root *root, struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_root *tree_root = fs_info->tree_root; struct btrfs_root *new_root = NULL; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_inode_item *inode_item; struct extent_buffer *leaf; struct btrfs_key key; @@ -600,7 +600,6 @@ struct btrfs_root *btrfs_mksubvol(struct btrfs_root *root, if (len == 0 || len > BTRFS_NAME_LEN) return NULL; - btrfs_init_path(&path); key.objectid = dirid; key.type = BTRFS_DIR_INDEX_KEY; key.offset = (u64)-1; @@ -705,7 +704,6 @@ struct btrfs_root *btrfs_mksubvol(struct btrfs_root *root, new_root = NULL; } fail: - btrfs_init_path(&path); return new_root; } @@ -737,7 +735,6 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, search_key.offset = 0; search_key.type = 0; - btrfs_init_path(path); start_found = 0; ret = btrfs_search_slot(trans, root, &search_key, path, 0, 0); if (ret < 0) diff --git a/kernel-shared/print-tree.c b/kernel-shared/print-tree.c index b7ca8b7e..a32c9a2a 100644 --- a/kernel-shared/print-tree.c +++ b/kernel-shared/print-tree.c @@ -1508,7 +1508,7 @@ out: static void bfs_print_children(struct extent_buffer *root_eb, unsigned int mode) { struct btrfs_fs_info *fs_info = root_eb->fs_info; - struct btrfs_path path; + struct btrfs_path path = {}; int root_level = btrfs_header_level(root_eb); int cur_level; int ret; @@ -1520,7 +1520,6 @@ static void bfs_print_children(struct extent_buffer *root_eb, unsigned int mode) mode |= BTRFS_PRINT_TREE_BFS; mode &= ~(BTRFS_PRINT_TREE_DFS); - btrfs_init_path(&path); /* For path */ extent_buffer_get(root_eb); path.nodes[root_level] = root_eb; diff --git a/kernel-shared/volumes.c b/kernel-shared/volumes.c index 946c2e7a..831359be 100644 --- a/kernel-shared/volumes.c +++ b/kernel-shared/volumes.c @@ -2680,7 +2680,7 @@ static int check_dev_extent_beyond_bytenr(struct btrfs_fs_info *fs_info, u64 physical) { struct btrfs_root *root = fs_info->dev_root; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_dev_extent *dext; struct btrfs_key key; u64 dext_len; @@ -2691,7 +2691,6 @@ static int check_dev_extent_beyond_bytenr(struct btrfs_fs_info *fs_info, key.type = BTRFS_DEV_EXTENT_KEY; key.offset = (u64)-1; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); if (ret < 0) return ret; @@ -2730,7 +2729,7 @@ static int reset_device_item_total_bytes(struct btrfs_fs_info *fs_info, { struct btrfs_trans_handle *trans; struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_root *chunk_root = fs_info->chunk_root; struct btrfs_dev_item *di; u64 old_bytes = device->total_bytes; @@ -2753,7 +2752,6 @@ static int reset_device_item_total_bytes(struct btrfs_fs_info *fs_info, return ret; } - btrfs_init_path(&path); ret = btrfs_search_slot(trans, chunk_root, &key, &path, 0, 1); if (ret > 0) { error("failed to find DEV_ITEM for devid %llu", device->devid); diff --git a/mkfs/main.c b/mkfs/main.c index 1b917f55..4de57c8a 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -235,11 +235,10 @@ err: static int __recow_root(struct btrfs_trans_handle *trans, struct btrfs_root *root) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; int ret; - btrfs_init_path(&path); key.objectid = 0; key.type = 0; key.offset = 0; @@ -590,10 +589,9 @@ static int cleanup_temp_chunks(struct btrfs_fs_info *fs_info, struct btrfs_root *root = btrfs_block_group_root(fs_info); struct btrfs_key key; struct btrfs_key found_key; - struct btrfs_path path; + struct btrfs_path path = {}; int ret = 0; - btrfs_init_path(&path); trans = btrfs_start_transaction(root, 1); if (IS_ERR(trans)) { ret = PTR_ERR(trans); @@ -707,7 +705,7 @@ static int create_data_reloc_tree(struct btrfs_trans_handle *trans) struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_inode_item *inode; struct btrfs_root *root; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key = { .objectid = BTRFS_DATA_RELOC_TREE_OBJECTID, .type = BTRFS_ROOT_ITEM_KEY, @@ -749,7 +747,6 @@ static int create_data_reloc_tree(struct btrfs_trans_handle *trans) key.objectid = ino; key.type = BTRFS_INODE_ITEM_KEY; key.offset = 0; - btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, &key, &path, 0, 1); if (ret > 0) { @@ -851,7 +848,7 @@ static int insert_qgroup_items(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 qgroupid) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_root *quota_root = fs_info->quota_root; struct btrfs_key key; int ret; @@ -865,7 +862,6 @@ static int insert_qgroup_items(struct btrfs_trans_handle *trans, key.type = BTRFS_QGROUP_INFO_KEY; key.offset = qgroupid; - btrfs_init_path(&path); ret = btrfs_insert_empty_item(trans, quota_root, &path, &key, sizeof(struct btrfs_qgroup_info_item)); btrfs_release_path(&path); @@ -886,7 +882,7 @@ static int setup_quota_root(struct btrfs_fs_info *fs_info) struct btrfs_trans_handle *trans; struct btrfs_qgroup_status_item *qsi; struct btrfs_root *quota_root; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; int qgroup_repaired = 0; int ret; @@ -910,7 +906,6 @@ static int setup_quota_root(struct btrfs_fs_info *fs_info) key.type = BTRFS_QGROUP_STATUS_KEY; key.offset = 0; - btrfs_init_path(&path); ret = btrfs_insert_empty_item(trans, quota_root, &path, &key, sizeof(*qsi)); if (ret < 0) { diff --git a/mkfs/rootdir.c b/mkfs/rootdir.c index a04d27af..bb2666ee 100644 --- a/mkfs/rootdir.c +++ b/mkfs/rootdir.c @@ -444,7 +444,7 @@ static int traverse_directory(struct btrfs_trans_handle *trans, ino_t parent_inum, cur_inum; ino_t highest_inum = 0; const char *parent_dir_name; - struct btrfs_path path; + struct btrfs_path path = {}; struct extent_buffer *leaf; struct btrfs_key root_dir_key; u64 root_dir_inode_size = 0; @@ -465,8 +465,6 @@ static int traverse_directory(struct btrfs_trans_handle *trans, dir_entry->inum = parent_inum; list_add_tail(&dir_entry->list, &dir_head->list); - btrfs_init_path(&path); - root_dir_key.objectid = btrfs_root_dirid(&root->root_item); root_dir_key.offset = 0; root_dir_key.type = BTRFS_INODE_ITEM_KEY; @@ -800,7 +798,7 @@ static int get_device_extent_end(struct btrfs_fs_info *fs_info, { struct btrfs_root *dev_root = fs_info->dev_root; struct btrfs_key key; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_dev_extent *de; int ret; @@ -808,7 +806,6 @@ static int get_device_extent_end(struct btrfs_fs_info *fs_info, key.type = BTRFS_DEV_EXTENT_KEY; key.offset = (u64)-1; - btrfs_init_path(&path); ret = btrfs_search_slot(NULL, dev_root, &key, &path, 0, 0); if (ret == 0) { error("DEV_EXTENT for devid %llu not found", devid); @@ -852,7 +849,7 @@ static int set_device_size(struct btrfs_fs_info *fs_info, struct btrfs_root *chunk_root = fs_info->chunk_root; struct btrfs_trans_handle *trans; struct btrfs_dev_item *di; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key; int ret; @@ -861,7 +858,6 @@ static int set_device_size(struct btrfs_fs_info *fs_info, * super->dev_item will also get updated */ device->total_bytes = new_size; - btrfs_init_path(&path); /* Update device item in chunk tree */ trans = btrfs_start_transaction(chunk_root, 1); diff --git a/quick-test.c b/quick-test.c index 480e78bb..3f3c1cb3 100644 --- a/quick-test.c +++ b/quick-test.c @@ -41,7 +41,7 @@ int main(int ac, char **av) { int run_size = 300000; int max_key = 100000000; int tree_size = 2; - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_root *root; struct btrfs_trans_handle *trans; @@ -86,7 +86,6 @@ int main(int ac, char **av) { for (i = 0; i < run_size; i++) { num = next_key(i, max_key); ins.objectid = num; - btrfs_init_path(&path); if (i % 10000 == 0) fprintf(stderr, "search %d:%d\n", num, i); ret = btrfs_search_slot(NULL, root, &ins, &path, 0, 0); @@ -117,7 +116,6 @@ int main(int ac, char **av) { for (i = 0 ; i < run_size/4; i++) { num = next_key(i, max_key); ins.objectid = num; - btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, &ins, &path, -1, 1); if (!ret) { if (i % 10000 == 0) @@ -163,7 +161,6 @@ int main(int ac, char **av) { for (i = 0; i < run_size; i++) { num = next_key(i, max_key); ins.objectid = num; - btrfs_init_path(&path); if (i % 10000 == 0) fprintf(stderr, "search %d:%d\n", num, i); ret = btrfs_search_slot(NULL, root, &ins, &path, 0, 0); @@ -181,7 +178,6 @@ int main(int ac, char **av) { struct extent_buffer *leaf; int slot; ins.objectid = (u64)-1; - btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, &ins, &path, -1, 1); if (ret == 0) BUG(); diff --git a/tune/change-uuid.c b/tune/change-uuid.c index 30cfb145..54184811 100644 --- a/tune/change-uuid.c +++ b/tune/change-uuid.c @@ -82,11 +82,10 @@ static int change_buffer_header_uuid(struct extent_buffer *eb, uuid_t new_fsid) static int change_extent_tree_uuid(struct btrfs_fs_info *fs_info, uuid_t new_fsid) { struct btrfs_root *root = btrfs_extent_root(fs_info, 0); - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key = {0, 0, 0}; int ret = 0; - btrfs_init_path(&path); /* * Here we don't use transaction as it will takes a lot of reserve * space, and that will make a near-full btrfs unable to change uuid @@ -162,11 +161,10 @@ static int change_device_uuid(struct extent_buffer *eb, int slot, static int change_chunk_tree_uuid(struct btrfs_root *root, uuid_t new_fsid) { - struct btrfs_path path; + struct btrfs_path path = {}; struct btrfs_key key = {0, 0, 0}; int ret = 0; - btrfs_init_path(&path); /* No transaction again */ ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); if (ret < 0) From patchwork Wed Aug 23 14:32:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362639 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 42A16EE49B9 for ; Wed, 23 Aug 2023 14:33:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236486AbjHWOdd (ORCPT ); Wed, 23 Aug 2023 10:33:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236471AbjHWOdb (ORCPT ); Wed, 23 Aug 2023 10:33:31 -0400 Received: from mail-yw1-x1131.google.com (mail-yw1-x1131.google.com [IPv6:2607:f8b0:4864:20::1131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 509AEE5F for ; Wed, 23 Aug 2023 07:33:26 -0700 (PDT) Received: by mail-yw1-x1131.google.com with SMTP id 00721157ae682-5925e580e87so8150247b3.1 for ; Wed, 23 Aug 2023 07:33:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801205; x=1693406005; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=pdjZjPhS25CFNhSP07KJQZLiGxYjA/BPasxjgyWmPcQ=; b=mddn1k8uEMnJfTTJ8N9gAaBKur8qIf9OjtwK5T9ie5OJFZIcI3N+Otq36vtbkql1T1 4Q28/EjK4F0O++6G4eZPqmEVOFRM4LFfYm9dbh+UYujtXgmzY0xdBpZaMWXI22bHAcvp 9gKbeDhpNCyzSYRuNZSy5wpj43zcAm+Z+w62YwgeCv0pPISkIvLKOCOL5Ao4uSVlbN6G wXJw8giha0AHfe8Vz3cRVrh66cp5YuMYirsbJaqx4Gz/ZVrPwND2p6PVVLAAyCAInX69 wlaCFo8mYY/lIwjq3cWXIX+qBbFva2ifUFaujWqI+kujpe8szNgwSuQTcL8zytSSy9h6 vVpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801205; x=1693406005; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pdjZjPhS25CFNhSP07KJQZLiGxYjA/BPasxjgyWmPcQ=; b=FBmpczv27P3dNeYcR4gBY2uxNjgmoKpXKvQTCOCQpdMm1qHlukUTFsXAiNsb2WvNn7 WVTJoful7tq7djUPTPKp3tCPEKryNaW3EMVlfOBySDCXtq8AmlwROAuGf8ztU0b9TI54 lZutjmBJg514bZ7Hper0MdI3kcRhYi3DUcnfCib0I3uuGSrmj8ZZULq9szsIvOmEOSzF MSqc8GVdCsTZY5AIXYndOWSBlo4H3XWGBTjsBLrPRPUYhOnXNNRcrM3sYbnMHpRooJ6t ilbDlWI3gihrt6eU3TzzudSNuzzzE16LCUxrYDI6tlsSEpkxabl/hzPepaDuLL1+Mt0c a5Hw== X-Gm-Message-State: AOJu0YyQW9WdJ6WGwauXIeCq1EqMQe7QHm5by2EhwL1KQr1MsCuYoi2E RaDft4Q+mAaxMWkVb46n4+xEr2VmSUxIUMWRmNU= X-Google-Smtp-Source: AGHT+IHHwJAFNYW2KwG584vhMcg1dlXoEJPd5nWHQK0bT2oVo3krwNNsNOhgX8kVnygxrIXjNALswA== X-Received: by 2002:a0d:cc4f:0:b0:589:9717:22c7 with SMTP id o76-20020a0dcc4f000000b00589971722c7mr13637616ywd.22.1692801205372; Wed, 23 Aug 2023 07:33:25 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id r67-20020a0de846000000b00589e84acafasm3379307ywe.48.2023.08.23.07.33.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:25 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 14/38] btrfs-progs: move btrfs_set_item_key_unsafe to check/ Date: Wed, 23 Aug 2023 10:32:40 -0400 Message-ID: <3c55d9a5d40e799d82bea269de589a41e44a6b56.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This helper exists for check and for btrfs-corrupt-block. Move the helper and the btrfs_fixup_low_keys helper into check/repair.[ch] so we can keep the kernel-shared sources close to the upstream kernel. Signed-off-by: Josef Bacik --- btrfs-corrupt-block.c | 1 + check/repair.c | 47 +++++++++++++++++++++++++++++++++++++++++++ check/repair.h | 5 +++++ kernel-shared/ctree.c | 40 +++++++++--------------------------- kernel-shared/ctree.h | 5 ----- 5 files changed, 62 insertions(+), 36 deletions(-) diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c index 3c742cc8..3e741c08 100644 --- a/btrfs-corrupt-block.c +++ b/btrfs-corrupt-block.c @@ -35,6 +35,7 @@ #include "common/messages.h" #include "common/string-utils.h" #include "cmds/commands.h" +#include "check/repair.h" #define FIELD_BUF_LEN 80 diff --git a/check/repair.c b/check/repair.c index eacf4506..d8900c41 100644 --- a/check/repair.c +++ b/check/repair.c @@ -33,6 +33,53 @@ int opt_check_repair = 0; +/* + * adjust the pointers going up the tree, starting at level + * making sure the right key of each node is points to 'key'. + * This is used after shifting pointers to the left, so it stops + * fixing up pointers when a given leaf/node is not in slot 0 of the + * higher levels + */ +void btrfs_fixup_low_keys(struct btrfs_path *path, struct btrfs_disk_key *key, + int level) +{ + int i; + struct extent_buffer *t; + + for (i = level; i < BTRFS_MAX_LEVEL; i++) { + int tslot = path->slots[i]; + if (!path->nodes[i]) + break; + t = path->nodes[i]; + btrfs_set_node_key(t, key, tslot); + btrfs_mark_buffer_dirty(path->nodes[i]); + if (tslot != 0) + break; + } +} + +/* + * update an item key without the safety checks. This is meant to be called by + * fsck only. + */ +void btrfs_set_item_key_unsafe(struct btrfs_root *root, + struct btrfs_path *path, + struct btrfs_key *new_key) +{ + struct btrfs_disk_key disk_key; + struct extent_buffer *eb; + int slot; + + eb = path->nodes[0]; + slot = path->slots[0]; + + btrfs_cpu_key_to_disk(&disk_key, new_key); + btrfs_set_item_key(eb, &disk_key, slot); + btrfs_mark_buffer_dirty(eb); + if (slot == 0) + btrfs_fixup_low_keys(path, &disk_key, 1); +} + int btrfs_add_corrupt_extent_record(struct btrfs_fs_info *info, struct btrfs_key *first_key, u64 start, u64 len, int level) diff --git a/check/repair.h b/check/repair.h index 3c44a498..81440a87 100644 --- a/check/repair.h +++ b/check/repair.h @@ -45,5 +45,10 @@ int btrfs_mark_used_blocks(struct btrfs_fs_info *fs_info, struct extent_io_tree *tree); enum btrfs_tree_block_status btrfs_check_block_for_repair(struct extent_buffer *eb, struct btrfs_key *first_key); +void btrfs_set_item_key_unsafe(struct btrfs_root *root, + struct btrfs_path *path, + struct btrfs_key *new_key); +void btrfs_fixup_low_keys(struct btrfs_path *path, struct btrfs_disk_key *key, + int level); #endif diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index bbbb2cc3..8eba7812 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -1485,8 +1485,8 @@ again: * fixing up pointers when a given leaf/node is not in slot 0 of the * higher levels */ -void btrfs_fixup_low_keys( struct btrfs_path *path, struct btrfs_disk_key *key, - int level) +static void fixup_low_keys(struct btrfs_path *path, struct btrfs_disk_key *key, + int level) { int i; struct extent_buffer *t; @@ -1532,29 +1532,7 @@ void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info, btrfs_set_item_key(eb, &disk_key, slot); btrfs_mark_buffer_dirty(eb); if (slot == 0) - btrfs_fixup_low_keys(path, &disk_key, 1); -} - -/* - * update an item key without the safety checks. This is meant to be called by - * fsck only. - */ -void btrfs_set_item_key_unsafe(struct btrfs_root *root, - struct btrfs_path *path, - struct btrfs_key *new_key) -{ - struct btrfs_disk_key disk_key; - struct extent_buffer *eb; - int slot; - - eb = path->nodes[0]; - slot = path->slots[0]; - - btrfs_cpu_key_to_disk(&disk_key, new_key); - btrfs_set_item_key(eb, &disk_key, slot); - btrfs_mark_buffer_dirty(eb); - if (slot == 0) - btrfs_fixup_low_keys(path, &disk_key, 1); + fixup_low_keys(path, &disk_key, 1); } /* @@ -2213,7 +2191,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root btrfs_mark_buffer_dirty(right); btrfs_item_key(right, &disk_key, 0); - btrfs_fixup_low_keys(path, &disk_key, 1); + fixup_low_keys(path, &disk_key, 1); /* then fixup the leaf pointer in the path */ if (path->slots[0] < push_items) { @@ -2439,7 +2417,7 @@ again: path->nodes[0] = right; path->slots[0] = 0; if (path->slots[1] == 0) - btrfs_fixup_low_keys(path, &disk_key, 1); + fixup_low_keys(path, &disk_key, 1); } btrfs_mark_buffer_dirty(right); return ret; @@ -2644,7 +2622,7 @@ void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) btrfs_set_disk_key_offset(&disk_key, offset + size_diff); btrfs_set_item_key(leaf, &disk_key, slot); if (slot == 0) - btrfs_fixup_low_keys(path, &disk_key, 1); + fixup_low_keys(path, &disk_key, 1); } btrfs_set_item_size(leaf, slot, new_size); @@ -2808,7 +2786,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, ret = 0; if (slot == 0) { btrfs_cpu_key_to_disk(&disk_key, cpu_key); - btrfs_fixup_low_keys(path, &disk_key, 1); + fixup_low_keys(path, &disk_key, 1); } if (btrfs_leaf_free_space(leaf) < 0) { @@ -2881,7 +2859,7 @@ int btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, struct btrfs_disk_key disk_key; btrfs_node_key(parent, &disk_key, 0); - btrfs_fixup_low_keys(path, &disk_key, level + 1); + fixup_low_keys(path, &disk_key, level + 1); } btrfs_mark_buffer_dirty(parent); return ret; @@ -2979,7 +2957,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_disk_key disk_key; btrfs_item_key(leaf, &disk_key, 0); - btrfs_fixup_low_keys(path, &disk_key, 1); + fixup_low_keys(path, &disk_key, 1); } /* delete the leaf if it is mostly empty */ diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 0d9b75bf..3e00d69b 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -1052,14 +1052,9 @@ static inline int btrfs_next_item(struct btrfs_root *root, int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_leaf_free_space(struct extent_buffer *leaf); -void btrfs_fixup_low_keys(struct btrfs_path *path, struct btrfs_disk_key *key, - int level); void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info, struct btrfs_path *path, const struct btrfs_key *new_key); -void btrfs_set_item_key_unsafe(struct btrfs_root *root, - struct btrfs_path *path, - struct btrfs_key *new_key); int btrfs_super_csum_size(const struct btrfs_super_block *sb); const char *btrfs_super_csum_name(u16 csum_type); From patchwork Wed Aug 23 14:32:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362640 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 679D6EE49B2 for ; Wed, 23 Aug 2023 14:33:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236503AbjHWOde (ORCPT ); Wed, 23 Aug 2023 10:33:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236488AbjHWOdd (ORCPT ); Wed, 23 Aug 2023 10:33:33 -0400 Received: from mail-yw1-x112f.google.com (mail-yw1-x112f.google.com [IPv6:2607:f8b0:4864:20::112f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D8FABE6E for ; Wed, 23 Aug 2023 07:33:27 -0700 (PDT) Received: by mail-yw1-x112f.google.com with SMTP id 00721157ae682-59209b12c50so38712847b3.0 for ; Wed, 23 Aug 2023 07:33:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801207; x=1693406007; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=dv1BvEESgxKBQKD54WPSl6r52AXPLtcc11Ed5oi2gg4=; b=AdSG4PuJKe5r1L40MIBYX3FqKM51A9hwyYihI46ZykZ/fWPuovV7BRcqn+7L9qBFCE UyI68mwFLiFsF/3cmF9I+MhAkIoUZP14vbJUYlfn2Kx9GwBmmLZPtupt1vQ9YZGVcRXo ggDIzWu5XJ0/MS+2Dplv8hVkGMdb8kMYj8QjkLixEUHrpblsg3UgBcb+0xUhXXBOv8ip azwNbob2QSzXOqSgXSzXHaUGWlkUCKnsPAopSiuTUA5wZrDWxkvKp1NUHnNDRG0oCDy4 t/2fu33tXVAUtfyiVyZgp4PrAjodAB7wewx50vAxTdNAOmNALtGaGecIGPCVkRKc5m4j mhEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801207; x=1693406007; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dv1BvEESgxKBQKD54WPSl6r52AXPLtcc11Ed5oi2gg4=; b=SekqzEZgCwByYbYHzKZfhg5MblIrQrLJrGFMGeMnU+mGa24ooqZ4wcRqGVBEuHkR09 akINlzMRrjEod7frOxa4lf1Ch2XY3j01HLNdHQYFPK/53QniwNbdiQn1RoIhjtTWayIz /Ygx2avtvc9rGjKLa/eKjb4WBRso81hY0d7ovbJ2hnqgXV72nx04AP5AYfznU73c7uNR LpgxPuirxUTvuFtanNVGzBhbeyJYPl4H3EED6E5sD3WM1kjFp5KhUqT9LsL36WaE/RFy f/ETq5h/rWsXYh2rp+kYG/OKCoLVLDIGx4tlMYhpncS09AZDO7d4x9rHJRTrBkiq+qX1 80Zw== X-Gm-Message-State: AOJu0Yz19z4xgG/O5zf8/IOSufBiemwssHYvSZ7pr4WuoIlxa34n/l5i 9QI3Z0qqsMf8XyBkBx1e3Y7xwWZPHhg8lNxmisE= X-Google-Smtp-Source: AGHT+IHpRcrTF/yHzZ0S/SdeI72zwm8Z4O0V6ju/BVyHq92ouNsgGAioo0ECqPb8oW489gFYz6G+gA== X-Received: by 2002:a81:6d53:0:b0:583:9018:6fbb with SMTP id i80-20020a816d53000000b0058390186fbbmr14838957ywc.37.1692801206600; Wed, 23 Aug 2023 07:33:26 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id q3-20020a0dce03000000b005844ae2bfa3sm3370033ywd.95.2023.08.23.07.33.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:26 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 15/38] btrfs-progs: move btrfs_record_file_extent and code into a new file Date: Wed, 23 Aug 2023 10:32:41 -0400 Message-ID: <16bbeb0b919f4e39100b54f43d4f712041fde32f.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This function and it's related functions only exist for the utilities that populate existing file systems, and do not exist in the upstream kernel. Move this function and the related function into it's own common source file and out of the kernel-shared sources, and then update all of the users to include the new location of this code. Signed-off-by: Josef Bacik --- Makefile | 1 + btrfs-map-logical.c | 1 + common/extent-tree-utils.c | 282 ++++++++++++++++++++++++++++++++++++ common/extent-tree-utils.h | 28 ++++ convert/main.c | 1 + convert/source-fs.c | 1 + convert/source-reiserfs.c | 1 + kernel-shared/ctree.c | 24 --- kernel-shared/ctree.h | 7 - kernel-shared/extent-tree.c | 234 ------------------------------ mkfs/rootdir.c | 1 + tune/change-csum.c | 1 + 12 files changed, 317 insertions(+), 265 deletions(-) create mode 100644 common/extent-tree-utils.c create mode 100644 common/extent-tree-utils.h diff --git a/Makefile b/Makefile index e6afe272..8c0f78f9 100644 --- a/Makefile +++ b/Makefile @@ -201,6 +201,7 @@ objects = \ common/device-scan.o \ common/device-utils.o \ common/extent-cache.o \ + common/extent-tree-utils.o \ common/filesystem-utils.o \ common/format-output.o \ common/fsfeatures.o \ diff --git a/btrfs-map-logical.c b/btrfs-map-logical.c index d85b4be4..2a6c6785 100644 --- a/btrfs-map-logical.c +++ b/btrfs-map-logical.c @@ -33,6 +33,7 @@ #include "common/utils.h" #include "common/help.h" #include "common/extent-cache.h" +#include "common/extent-tree-utils.h" #include "common/string-utils.h" #include "cmds/commands.h" diff --git a/common/extent-tree-utils.c b/common/extent-tree-utils.c new file mode 100644 index 00000000..06d5436f --- /dev/null +++ b/common/extent-tree-utils.c @@ -0,0 +1,282 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#include "kerncompat.h" +#include "kernel-shared/ctree.h" +#include "kernel-shared/disk-io.h" +#include "kernel-shared/file-item.h" +#include "kernel-shared/transaction.h" +#include "kernel-shared/free-space-tree.h" +#include "common/internal.h" +#include "common/extent-tree-utils.h" +#include "common/messages.h" + +/* + * Search in extent tree to found next meta/data extent + * Caller needs to check for no-hole or skinny metadata features. + */ +int btrfs_next_extent_item(struct btrfs_root *root, struct btrfs_path *path, + u64 max_objectid) +{ + struct btrfs_key found_key; + int ret; + + while (1) { + ret = btrfs_next_item(root, path); + if (ret) + return ret; + btrfs_item_key_to_cpu(path->nodes[0], &found_key, + path->slots[0]); + if (found_key.objectid > max_objectid) + return 1; + if (found_key.type == BTRFS_EXTENT_ITEM_KEY || + found_key.type == BTRFS_METADATA_ITEM_KEY) + return 0; + } +} + +static void __get_extent_size(struct btrfs_root *root, struct btrfs_path *path, + u64 *start, u64 *len) +{ + struct btrfs_key key; + + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); + BUG_ON(!(key.type == BTRFS_EXTENT_ITEM_KEY || + key.type == BTRFS_METADATA_ITEM_KEY)); + *start = key.objectid; + if (key.type == BTRFS_EXTENT_ITEM_KEY) + *len = key.offset; + else + *len = root->fs_info->nodesize; +} + +/* + * Find first overlap extent for range [bytenr, bytenr + len) + * Return 0 for found and point path to it. + * Return >0 for not found. + * Return <0 for err + */ +static int btrfs_search_overlap_extent(struct btrfs_root *root, + struct btrfs_path *path, u64 bytenr, u64 len) +{ + struct btrfs_key key; + u64 cur_start; + u64 cur_len; + int ret; + + key.objectid = bytenr; + key.type = BTRFS_EXTENT_DATA_KEY; + key.offset = (u64)-1; + + ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); + if (ret < 0) + return ret; + BUG_ON(ret == 0); + + ret = btrfs_previous_extent_item(root, path, 0); + if (ret < 0) + return ret; + /* no previous, check next extent */ + if (ret > 0) + goto next; + __get_extent_size(root, path, &cur_start, &cur_len); + /* Tail overlap */ + if (cur_start + cur_len > bytenr) + return 1; + +next: + ret = btrfs_next_extent_item(root, path, bytenr + len); + if (ret < 0) + return ret; + /* No next, prev already checked, no overlap */ + if (ret > 0) + return 0; + __get_extent_size(root, path, &cur_start, &cur_len); + /* head overlap*/ + if (cur_start < bytenr + len) + return 1; + return 0; +} + +static int __btrfs_record_file_extent(struct btrfs_trans_handle *trans, + struct btrfs_root *root, u64 objectid, + struct btrfs_inode_item *inode, + u64 file_pos, u64 disk_bytenr, + u64 *ret_num_bytes) +{ + int ret; + struct btrfs_fs_info *info = root->fs_info; + struct btrfs_root *extent_root = btrfs_extent_root(info, disk_bytenr); + struct extent_buffer *leaf; + struct btrfs_file_extent_item *fi; + struct btrfs_key ins_key; + struct btrfs_path *path; + struct btrfs_extent_item *ei; + u64 nbytes; + u64 extent_num_bytes; + u64 extent_bytenr; + u64 extent_offset; + u64 num_bytes = *ret_num_bytes; + + /* + * @objectid should be an inode number, thus it must not be smaller + * than BTRFS_FIRST_FREE_OBJECTID. + */ + UASSERT(objectid >= BTRFS_FIRST_FREE_OBJECTID); + + /* + * All supported file system should not use its 0 extent. + * As it's for hole + * + * And hole extent has no size limit, no need to loop. + */ + if (disk_bytenr == 0) { + ret = btrfs_insert_file_extent(trans, root, objectid, + file_pos, disk_bytenr, + num_bytes, num_bytes); + return ret; + } + num_bytes = min_t(u64, num_bytes, BTRFS_MAX_EXTENT_SIZE); + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + /* First to check extent overlap */ + ret = btrfs_search_overlap_extent(extent_root, path, disk_bytenr, + num_bytes); + if (ret < 0) + goto fail; + if (ret > 0) { + /* Found overlap */ + u64 cur_start; + u64 cur_len; + + __get_extent_size(extent_root, path, &cur_start, &cur_len); + /* + * For convert case, this extent should be a subset of + * existing one. + */ + BUG_ON(disk_bytenr < cur_start); + + extent_bytenr = cur_start; + extent_num_bytes = cur_len; + extent_offset = disk_bytenr - extent_bytenr; + } else { + /* No overlap, create new extent */ + btrfs_release_path(path); + ins_key.objectid = disk_bytenr; + ins_key.offset = num_bytes; + ins_key.type = BTRFS_EXTENT_ITEM_KEY; + + ret = btrfs_insert_empty_item(trans, extent_root, path, + &ins_key, sizeof(*ei)); + if (ret == 0) { + leaf = path->nodes[0]; + ei = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_extent_item); + + btrfs_set_extent_refs(leaf, ei, 0); + btrfs_set_extent_generation(leaf, ei, trans->transid); + btrfs_set_extent_flags(leaf, ei, + BTRFS_EXTENT_FLAG_DATA); + btrfs_mark_buffer_dirty(leaf); + + ret = btrfs_update_block_group(trans, disk_bytenr, + num_bytes, 1, 0); + if (ret) + goto fail; + } else if (ret != -EEXIST) { + goto fail; + } + + ret = remove_from_free_space_tree(trans, disk_bytenr, num_bytes); + if (ret) + goto fail; + + btrfs_run_delayed_refs(trans, -1); + extent_bytenr = disk_bytenr; + extent_num_bytes = num_bytes; + extent_offset = 0; + } + btrfs_release_path(path); + ins_key.objectid = objectid; + ins_key.offset = file_pos; + ins_key.type = BTRFS_EXTENT_DATA_KEY; + ret = btrfs_insert_empty_item(trans, root, path, &ins_key, + sizeof(*fi)); + if (ret) + goto fail; + leaf = path->nodes[0]; + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + btrfs_set_file_extent_generation(leaf, fi, trans->transid); + btrfs_set_file_extent_type(leaf, fi, BTRFS_FILE_EXTENT_REG); + btrfs_set_file_extent_disk_bytenr(leaf, fi, extent_bytenr); + btrfs_set_file_extent_disk_num_bytes(leaf, fi, extent_num_bytes); + btrfs_set_file_extent_offset(leaf, fi, extent_offset); + btrfs_set_file_extent_num_bytes(leaf, fi, num_bytes); + btrfs_set_file_extent_ram_bytes(leaf, fi, extent_num_bytes); + btrfs_set_file_extent_compression(leaf, fi, 0); + btrfs_set_file_extent_encryption(leaf, fi, 0); + btrfs_set_file_extent_other_encoding(leaf, fi, 0); + btrfs_mark_buffer_dirty(leaf); + + nbytes = btrfs_stack_inode_nbytes(inode) + num_bytes; + btrfs_set_stack_inode_nbytes(inode, nbytes); + btrfs_release_path(path); + + ret = btrfs_inc_extent_ref(trans, extent_bytenr, extent_num_bytes, + 0, root->root_key.objectid, objectid, + file_pos - extent_offset); + if (ret) + goto fail; + ret = 0; + *ret_num_bytes = min(extent_num_bytes - extent_offset, num_bytes); +fail: + btrfs_free_path(path); + return ret; +} + +/* + * Record a file extent. Do all the required works, such as inserting + * file extent item, inserting extent item and backref item into extent + * tree and updating block accounting. + */ +int btrfs_record_file_extent(struct btrfs_trans_handle *trans, + struct btrfs_root *root, u64 objectid, + struct btrfs_inode_item *inode, + u64 file_pos, u64 disk_bytenr, + u64 num_bytes) +{ + u64 cur_disk_bytenr = disk_bytenr; + u64 cur_file_pos = file_pos; + u64 cur_num_bytes = num_bytes; + int ret = 0; + + while (num_bytes > 0) { + ret = __btrfs_record_file_extent(trans, root, objectid, + inode, cur_file_pos, + cur_disk_bytenr, + &cur_num_bytes); + if (ret < 0) + break; + cur_disk_bytenr += cur_num_bytes; + cur_file_pos += cur_num_bytes; + num_bytes -= cur_num_bytes; + } + return ret; +} diff --git a/common/extent-tree-utils.h b/common/extent-tree-utils.h new file mode 100644 index 00000000..4a774dc2 --- /dev/null +++ b/common/extent-tree-utils.h @@ -0,0 +1,28 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#ifndef _EXTENT_TREE_UTILS_H_ +#define _EXTENT_TREE_UTILS_H_ + +int btrfs_next_extent_item(struct btrfs_root *root, struct btrfs_path *path, + u64 max_objectid); +int btrfs_record_file_extent(struct btrfs_trans_handle *trans, + struct btrfs_root *root, u64 objectid, + struct btrfs_inode_item *inode, + u64 file_pos, u64 disk_bytenr, + u64 num_bytes); + +#endif /* _EXTENT_TREE_UTILS_H_ */ diff --git a/convert/main.c b/convert/main.c index a9a1e1d9..84d5913f 100644 --- a/convert/main.c +++ b/convert/main.c @@ -115,6 +115,7 @@ #include "common/device-scan.h" #include "common/box.h" #include "common/open-utils.h" +#include "common/extent-tree-utils.h" #include "cmds/commands.h" #include "check/repair.h" #include "check/clear-cache.h" diff --git a/convert/source-fs.c b/convert/source-fs.c index d206fab6..cc82fdb6 100644 --- a/convert/source-fs.c +++ b/convert/source-fs.c @@ -24,6 +24,7 @@ #include "common/internal.h" #include "common/messages.h" #include "common/extent-cache.h" +#include "common/extent-tree-utils.h" #include "convert/common.h" #include "convert/source-fs.h" diff --git a/convert/source-reiserfs.c b/convert/source-reiserfs.c index 35fd0105..3edc72ed 100644 --- a/convert/source-reiserfs.c +++ b/convert/source-reiserfs.c @@ -35,6 +35,7 @@ #include "common/extent-cache.h" #include "common/internal.h" #include "common/messages.h" +#include "common/extent-tree-utils.h" #include "convert/common.h" #include "convert/source-reiserfs.h" diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 8eba7812..eae233b9 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -3195,30 +3195,6 @@ int btrfs_previous_extent_item(struct btrfs_root *root, return 1; } -/* - * Search in extent tree to found next meta/data extent - * Caller needs to check for no-hole or skinny metadata features. - */ -int btrfs_next_extent_item(struct btrfs_root *root, - struct btrfs_path *path, u64 max_objectid) -{ - struct btrfs_key found_key; - int ret; - - while (1) { - ret = btrfs_next_item(root, path); - if (ret) - return ret; - btrfs_item_key_to_cpu(path->nodes[0], &found_key, - path->slots[0]); - if (found_key.objectid > max_objectid) - return 1; - if (found_key.type == BTRFS_EXTENT_ITEM_KEY || - found_key.type == BTRFS_METADATA_ITEM_KEY) - return 0; - } -} - /* * Search uuid tree - unmounted * diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 3e00d69b..c7d5167d 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -929,11 +929,6 @@ int btrfs_make_block_groups(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); int btrfs_update_block_group(struct btrfs_trans_handle *trans, u64 bytenr, u64 num, int alloc, int mark_free); -int btrfs_record_file_extent(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 objectid, - struct btrfs_inode_item *inode, - u64 file_pos, u64 disk_bytenr, - u64 num_bytes); int btrfs_remove_block_group(struct btrfs_trans_handle *trans, u64 bytenr, u64 len); void free_excluded_extents(struct btrfs_fs_info *fs_info, @@ -956,8 +951,6 @@ int btrfs_previous_item(struct btrfs_root *root, int type); int btrfs_previous_extent_item(struct btrfs_root *root, struct btrfs_path *path, u64 min_objectid); -int btrfs_next_extent_item(struct btrfs_root *root, - struct btrfs_path *path, u64 max_objectid); int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, struct extent_buffer *parent, int parent_slot, diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c index 55fdf881..433cf4fc 100644 --- a/kernel-shared/extent-tree.c +++ b/kernel-shared/extent-tree.c @@ -3519,240 +3519,6 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, return ret; } -static void __get_extent_size(struct btrfs_root *root, struct btrfs_path *path, - u64 *start, u64 *len) -{ - struct btrfs_key key; - - btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); - BUG_ON(!(key.type == BTRFS_EXTENT_ITEM_KEY || - key.type == BTRFS_METADATA_ITEM_KEY)); - *start = key.objectid; - if (key.type == BTRFS_EXTENT_ITEM_KEY) - *len = key.offset; - else - *len = root->fs_info->nodesize; -} - -/* - * Find first overlap extent for range [bytenr, bytenr + len) - * Return 0 for found and point path to it. - * Return >0 for not found. - * Return <0 for err - */ -static int btrfs_search_overlap_extent(struct btrfs_root *root, - struct btrfs_path *path, u64 bytenr, u64 len) -{ - struct btrfs_key key; - u64 cur_start; - u64 cur_len; - int ret; - - key.objectid = bytenr; - key.type = BTRFS_EXTENT_DATA_KEY; - key.offset = (u64)-1; - - ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); - if (ret < 0) - return ret; - BUG_ON(ret == 0); - - ret = btrfs_previous_extent_item(root, path, 0); - if (ret < 0) - return ret; - /* no previous, check next extent */ - if (ret > 0) - goto next; - __get_extent_size(root, path, &cur_start, &cur_len); - /* Tail overlap */ - if (cur_start + cur_len > bytenr) - return 1; - -next: - ret = btrfs_next_extent_item(root, path, bytenr + len); - if (ret < 0) - return ret; - /* No next, prev already checked, no overlap */ - if (ret > 0) - return 0; - __get_extent_size(root, path, &cur_start, &cur_len); - /* head overlap*/ - if (cur_start < bytenr + len) - return 1; - return 0; -} - -static int __btrfs_record_file_extent(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 objectid, - struct btrfs_inode_item *inode, - u64 file_pos, u64 disk_bytenr, - u64 *ret_num_bytes) -{ - int ret; - struct btrfs_fs_info *info = root->fs_info; - struct btrfs_root *extent_root = btrfs_extent_root(info, disk_bytenr); - struct extent_buffer *leaf; - struct btrfs_file_extent_item *fi; - struct btrfs_key ins_key; - struct btrfs_path *path; - struct btrfs_extent_item *ei; - u64 nbytes; - u64 extent_num_bytes; - u64 extent_bytenr; - u64 extent_offset; - u64 num_bytes = *ret_num_bytes; - - /* - * @objectid should be an inode number, thus it must not be smaller - * than BTRFS_FIRST_FREE_OBJECTID. - */ - ASSERT(objectid >= BTRFS_FIRST_FREE_OBJECTID); - - /* - * All supported file system should not use its 0 extent. - * As it's for hole - * - * And hole extent has no size limit, no need to loop. - */ - if (disk_bytenr == 0) { - ret = btrfs_insert_file_extent(trans, root, objectid, - file_pos, disk_bytenr, - num_bytes, num_bytes); - return ret; - } - num_bytes = min_t(u64, num_bytes, BTRFS_MAX_EXTENT_SIZE); - - path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; - - /* First to check extent overlap */ - ret = btrfs_search_overlap_extent(extent_root, path, disk_bytenr, - num_bytes); - if (ret < 0) - goto fail; - if (ret > 0) { - /* Found overlap */ - u64 cur_start; - u64 cur_len; - - __get_extent_size(extent_root, path, &cur_start, &cur_len); - /* - * For convert case, this extent should be a subset of - * existing one. - */ - BUG_ON(disk_bytenr < cur_start); - - extent_bytenr = cur_start; - extent_num_bytes = cur_len; - extent_offset = disk_bytenr - extent_bytenr; - } else { - /* No overlap, create new extent */ - btrfs_release_path(path); - ins_key.objectid = disk_bytenr; - ins_key.offset = num_bytes; - ins_key.type = BTRFS_EXTENT_ITEM_KEY; - - ret = btrfs_insert_empty_item(trans, extent_root, path, - &ins_key, sizeof(*ei)); - if (ret == 0) { - leaf = path->nodes[0]; - ei = btrfs_item_ptr(leaf, path->slots[0], - struct btrfs_extent_item); - - btrfs_set_extent_refs(leaf, ei, 0); - btrfs_set_extent_generation(leaf, ei, trans->transid); - btrfs_set_extent_flags(leaf, ei, - BTRFS_EXTENT_FLAG_DATA); - btrfs_mark_buffer_dirty(leaf); - - ret = btrfs_update_block_group(trans, disk_bytenr, - num_bytes, 1, 0); - if (ret) - goto fail; - } else if (ret != -EEXIST) { - goto fail; - } - - ret = remove_from_free_space_tree(trans, disk_bytenr, num_bytes); - if (ret) - goto fail; - - btrfs_run_delayed_refs(trans, -1); - extent_bytenr = disk_bytenr; - extent_num_bytes = num_bytes; - extent_offset = 0; - } - btrfs_release_path(path); - ins_key.objectid = objectid; - ins_key.offset = file_pos; - ins_key.type = BTRFS_EXTENT_DATA_KEY; - ret = btrfs_insert_empty_item(trans, root, path, &ins_key, - sizeof(*fi)); - if (ret) - goto fail; - leaf = path->nodes[0]; - fi = btrfs_item_ptr(leaf, path->slots[0], - struct btrfs_file_extent_item); - btrfs_set_file_extent_generation(leaf, fi, trans->transid); - btrfs_set_file_extent_type(leaf, fi, BTRFS_FILE_EXTENT_REG); - btrfs_set_file_extent_disk_bytenr(leaf, fi, extent_bytenr); - btrfs_set_file_extent_disk_num_bytes(leaf, fi, extent_num_bytes); - btrfs_set_file_extent_offset(leaf, fi, extent_offset); - btrfs_set_file_extent_num_bytes(leaf, fi, num_bytes); - btrfs_set_file_extent_ram_bytes(leaf, fi, extent_num_bytes); - btrfs_set_file_extent_compression(leaf, fi, 0); - btrfs_set_file_extent_encryption(leaf, fi, 0); - btrfs_set_file_extent_other_encoding(leaf, fi, 0); - btrfs_mark_buffer_dirty(leaf); - - nbytes = btrfs_stack_inode_nbytes(inode) + num_bytes; - btrfs_set_stack_inode_nbytes(inode, nbytes); - btrfs_release_path(path); - - ret = btrfs_inc_extent_ref(trans, extent_bytenr, extent_num_bytes, - 0, root->root_key.objectid, objectid, - file_pos - extent_offset); - if (ret) - goto fail; - ret = 0; - *ret_num_bytes = min(extent_num_bytes - extent_offset, num_bytes); -fail: - btrfs_free_path(path); - return ret; -} - -/* - * Record a file extent. Do all the required works, such as inserting - * file extent item, inserting extent item and backref item into extent - * tree and updating block accounting. - */ -int btrfs_record_file_extent(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 objectid, - struct btrfs_inode_item *inode, - u64 file_pos, u64 disk_bytenr, - u64 num_bytes) -{ - u64 cur_disk_bytenr = disk_bytenr; - u64 cur_file_pos = file_pos; - u64 cur_num_bytes = num_bytes; - int ret = 0; - - while (num_bytes > 0) { - ret = __btrfs_record_file_extent(trans, root, objectid, - inode, cur_file_pos, - cur_disk_bytenr, - &cur_num_bytes); - if (ret < 0) - break; - cur_disk_bytenr += cur_num_bytes; - cur_file_pos += cur_num_bytes; - num_bytes -= cur_num_bytes; - } - return ret; -} - - static int add_excluded_extent(struct btrfs_fs_info *fs_info, u64 start, u64 num_bytes) { diff --git a/mkfs/rootdir.c b/mkfs/rootdir.c index bb2666ee..c42c7a20 100644 --- a/mkfs/rootdir.c +++ b/mkfs/rootdir.c @@ -40,6 +40,7 @@ #include "common/messages.h" #include "common/path-utils.h" #include "common/utils.h" +#include "common/extent-tree-utils.h" #include "mkfs/rootdir.h" static u32 fs_block_size; diff --git a/tune/change-csum.c b/tune/change-csum.c index 9edddb05..cf895df7 100644 --- a/tune/change-csum.c +++ b/tune/change-csum.c @@ -28,6 +28,7 @@ #include "common/internal.h" #include "common/utils.h" #include "common/inject-error.h" +#include "common/extent-tree-utils.h" #include "tune/tune.h" static int check_csum_change_requreiment(struct btrfs_fs_info *fs_info, u16 new_csum_type) From patchwork Wed Aug 23 14:32:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362637 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 152CBEE49B7 for ; Wed, 23 Aug 2023 14:33:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236490AbjHWOdd (ORCPT ); Wed, 23 Aug 2023 10:33:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34280 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236486AbjHWOdb (ORCPT ); Wed, 23 Aug 2023 10:33:31 -0400 Received: from mail-yw1-x1135.google.com (mail-yw1-x1135.google.com [IPv6:2607:f8b0:4864:20::1135]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B1A6CE71 for ; Wed, 23 Aug 2023 07:33:28 -0700 (PDT) Received: by mail-yw1-x1135.google.com with SMTP id 00721157ae682-5925e580e87so8150717b3.1 for ; Wed, 23 Aug 2023 07:33:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801208; x=1693406008; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=haLw09pFHAY4XRAffxLzVGIkco3b9tDOk8bK//gatW0=; b=D/qLY+lH9hDFLZAIu/2K8MOpb9moerZiQQbC/VRg8UWXMXX2GHqRYnX4ODVQx/QCZ6 1V+uhNtqr6vgdIUhThHJCLr13FisRxD1IJP01Hcpi1WAVQcSuG899Ndt8SD9orkccSed +PubCZXXN8FN8XcuOhQ3XRGvSlmgQ5QEGdqAiUZC+1YORCdaN352b6aHwZyYplLgI741 3YajgV4B6iX4z5UvQ17NFK6tqm1QjEuKaxZJs0PozAZ1q0xp3TqudWuKOA0dPcQUClTe HzUs08rhy0s0fLPS39KUgriexpdQzVqahj4Mdh5ycCFltPEqIH+Y+u5ro+YrtkdTf5SH l5uw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801208; x=1693406008; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=haLw09pFHAY4XRAffxLzVGIkco3b9tDOk8bK//gatW0=; b=QB6Th1W3UbDJVV9/0yZUxu9+XSSVGLwnQFKgYZ9Gxw3tyzwZkvglEP/92PCLPdFkDG OWLYwvGprom8nOrHy55C0U4/mjOQLwnMT1z0cegGqfWXSkZmDvX260bzEJS196uy6PLO Ef7E3jvcp1kiBnj/gcf4mqKL6ASMI4Q2lVddOPS6yoWwpuirq62KgbjikFfvKo/SxJfP Bz+w7QkQBBAGCZWeVfBUwhT6dPQ7T/yJOm2c0smfdY8i2BrjyASQ3n6JuroXb60vOx7x 3xMbkVb5fhRTMnQoFgah6C+v6nyYEr9zQXEBoCnpgjRC9ffByDqxsHQLwp330kp/i8oV fjCA== X-Gm-Message-State: AOJu0YxOM7a1AuymkdFhtunQg57x4Tv8sQ0sE319kR5L1HE378H6EGij xETzBa9QSBN0VRCADeLe8URRmQZZrAfZlKLc0Tk= X-Google-Smtp-Source: AGHT+IFhaRbcWXMWKeOHlEIpQaZEwzorZ8NEuehYLRKiXZdc7FaL5CPviohvosxyE4khv715mA3GKg== X-Received: by 2002:a81:5388:0:b0:577:1560:9e17 with SMTP id h130-20020a815388000000b0057715609e17mr11444370ywb.35.1692801207809; Wed, 23 Aug 2023 07:33:27 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id m185-20020a0dfcc2000000b00589b653b7adsm3379463ywf.136.2023.08.23.07.33.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:27 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 16/38] btrfs-progs: make a local copy of btrfs_next_sibling_block in print-tree.c Date: Wed, 23 Aug 2023 10:32:42 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org We use this in print-tree to do BFS tree printing, but there are no other users and it doesn't exist upstream. Copy the current code and clean it up so it can exist in print-tree.c and use the local copy there. This will allow us to remove the function call when ctree.c is synced. Signed-off-by: Josef Bacik --- kernel-shared/print-tree.c | 53 +++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/kernel-shared/print-tree.c b/kernel-shared/print-tree.c index a32c9a2a..9796085d 100644 --- a/kernel-shared/print-tree.c +++ b/kernel-shared/print-tree.c @@ -1505,6 +1505,57 @@ out: return ret; } +/* + * Walk up the tree as far as necessary to find the next sibling tree block. + * More generic version of btrfs_next_leaf(), as it could find sibling nodes + * if @path->lowest_level is not 0. + * + * returns 0 if it found something or 1 if there are no greater leaves. + * returns < 0 on io errors. + */ +static int next_sibling_tree_block(struct btrfs_fs_info *fs_info, + struct btrfs_path *path) +{ + int slot; + int level = path->lowest_level + 1; + struct extent_buffer *c; + struct extent_buffer *next = NULL; + + BUG_ON(path->lowest_level + 1 >= BTRFS_MAX_LEVEL); + do { + if (!path->nodes[level]) + return 1; + + slot = path->slots[level] + 1; + c = path->nodes[level]; + if (slot >= btrfs_header_nritems(c)) { + level++; + if (level == BTRFS_MAX_LEVEL) + return 1; + continue; + } + + next = btrfs_read_node_slot(c, slot); + if (!extent_buffer_uptodate(next)) + return -EIO; + break; + } while (level < BTRFS_MAX_LEVEL); + path->slots[level] = slot; + while(1) { + level--; + c = path->nodes[level]; + free_extent_buffer(c); + path->nodes[level] = next; + path->slots[level] = 0; + if (level == path->lowest_level) + break; + next = btrfs_read_node_slot(next, 0); + if (!extent_buffer_uptodate(next)) + return -EIO; + } + return 0; +} + static void bfs_print_children(struct extent_buffer *root_eb, unsigned int mode) { struct btrfs_fs_info *fs_info = root_eb->fs_info; @@ -1535,7 +1586,7 @@ static void bfs_print_children(struct extent_buffer *root_eb, unsigned int mode) /* Print all sibling tree blocks */ while (1) { btrfs_print_tree(path.nodes[cur_level], mode); - ret = btrfs_next_sibling_tree_block(fs_info, &path); + ret = next_sibling_tree_block(fs_info, &path); if (ret < 0) goto out; if (ret > 0) { From patchwork Wed Aug 23 14:32:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362638 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 BAE22EE49BA for ; Wed, 23 Aug 2023 14:33:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236497AbjHWOde (ORCPT ); Wed, 23 Aug 2023 10:33:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236470AbjHWOdc (ORCPT ); Wed, 23 Aug 2023 10:33:32 -0400 Received: from mail-yw1-x1132.google.com (mail-yw1-x1132.google.com [IPv6:2607:f8b0:4864:20::1132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0BCB7E68 for ; Wed, 23 Aug 2023 07:33:30 -0700 (PDT) Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-58cf42a32b9so63487817b3.2 for ; Wed, 23 Aug 2023 07:33:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801209; x=1693406009; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=LWYVPdrAqaymGLj3vcZR+O2TJhyfMPKOtfcj/j8VF8Y=; b=kwjJ8FOfrG+qoYtTk9GQxzJpfUEa5CN7suIJhbeHlvQTQxuJW6Uk2T4bszTxRaPHn3 njWvStD36+0bkn2bMmv+iHqddemgwGUyzTwXYAaupxshnHInZw6tL+b8g2cOPeFIs1wD uxbVUaSe+qz1gB3YV+CB+MVY6OO0CcLuIRdJNUseFHL0n2BcytDRfw5hvSPRC/H6bdUJ ztsAESviLYQAxWVT0iXWPZF8jpL7lZw7YqUKM3g0ln5BvBb1h0lSSieAzOtD+uoTFssg h7nVbG3y+NtUjOxm3akyVxYlA+2zGERzDpQOm+FrnCQNvP3CRuUY+ZNGjWu1b3IZi+mT OyVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801209; x=1693406009; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LWYVPdrAqaymGLj3vcZR+O2TJhyfMPKOtfcj/j8VF8Y=; b=gt2pmP0LtpIFw3r58AqXnxP8TADsZCJQq4xiZxY0ZHlw53CkFPf3qNOs0iQziZdmnk 1UdKRrqIeg6zLuRLrLWvmsd4reQ04lLQdmNnOHbzQgynvxFqkUsztweTuRFzVnHUc0pU Eh6qXMg27THANN5cvW+owt8FmF+srNxN+Jy7X+gS44H75XrrNTSHislykhDC0w+mAieN apH9ZhmpO8ICkj2PAUlJwq8oNrSOSY63lEP+qMwBdYcSi469252AEZ6Q26sKxdN116A3 NSwKmmP4SKvmskx7EasiU1xC4Gy2M0K12MXXWiLyHpRCHko1O1tM+oVgOc2wUoqUdCF8 Fzkw== X-Gm-Message-State: AOJu0Yy0qw1Nr4VVNqVF4oRxxzBCl8t8DODnfvs2nKOBtRxN6BnkbI+C GRBxn3Hvy6nO/sdach8asjE+ZqaZwwS6KBpWt0c= X-Google-Smtp-Source: AGHT+IHSZ7yKLNX420/FyKi3C7j0voijBP7xl05u3o+KYch4j3PqEYFQR0+1JMW81tZHf21+0cbcjg== X-Received: by 2002:a05:690c:e0d:b0:586:a249:d396 with SMTP id cp13-20020a05690c0e0d00b00586a249d396mr14119160ywb.12.1692801209137; Wed, 23 Aug 2023 07:33:29 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id p188-20020a815bc5000000b0057a6e41aad1sm3332907ywb.67.2023.08.23.07.33.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:28 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 17/38] btrfs-progs: don't set the ->commit_root in btrfs_create_tree Date: Wed, 23 Aug 2023 10:32:43 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org In btrfs_create_tree we set ->commit_root to the current node, however we don't add the root to the dirty list, so this is never cleaned up. This is a problem in btrfs-progs because the transaction commit stuff clears the commit_root when we write the dirty root out, so if we try to re-modify this root later we'll fail to start the transaction. Fix this by noting that we do this differently in the kernel, and drop the assignment as we're inserting the root into the tree_root in this function and thus don't need to update it again at transaction commit time. Signed-off-by: Josef Bacik --- kernel-shared/disk-io.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c index 35b6cde9..c98addd2 100644 --- a/kernel-shared/disk-io.c +++ b/kernel-shared/disk-io.c @@ -2340,7 +2340,14 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(leaf); extent_buffer_get(root->node); - root->commit_root = root->node; + + /* + * MODIFIED: + * - In the kernel we set ->commit_root here, however in btrfs-progs + * confuses the transaction code. For now don't set the commit_root + * here, if we update transaction.c to match the kernel version we + * need to revisit this. + */ set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state); root->root_item.flags = 0; From patchwork Wed Aug 23 14:32:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362641 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 26E03EE49A0 for ; Wed, 23 Aug 2023 14:33:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236504AbjHWOdf (ORCPT ); Wed, 23 Aug 2023 10:33:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34344 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236489AbjHWOdd (ORCPT ); Wed, 23 Aug 2023 10:33:33 -0400 Received: from mail-yb1-xb2b.google.com (mail-yb1-xb2b.google.com [IPv6:2607:f8b0:4864:20::b2b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3042DE67 for ; Wed, 23 Aug 2023 07:33:31 -0700 (PDT) Received: by mail-yb1-xb2b.google.com with SMTP id 3f1490d57ef6-d743a5fe05aso5049606276.2 for ; Wed, 23 Aug 2023 07:33:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801210; x=1693406010; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ofgEyvBe3ui82lRdlcvI6rHrBc3Ju6bigS+xexWEBGk=; b=BzXzsHM0l1Mf01mtOeJk4Vgdl4N/oWI0lYcfO0n0VB363NtduL64w2wqf27nmY2QST PX6KLFQwqVATneU5tWZ07ASqUNjAm43kaOsNLymp1FbnpIDzK5iDgYtC6qYNjIhfk/Y9 2axzDzRn03vZ3FYFl8l9B/PyfgRU6g5H5Cmr/DJxdHTtCSOeF4L0o1D/OePgEJED+rEW 8qaIb/ze/Cr4siaRn8bVshInpYcisBOISsWusq7d6Uz3xG3VMSyhoqxsua8MCh6v3j5I +k7V3x+iPcJtsNwyFTHVr28aAe/irdi21yTPHBODZA+xsTQ14zQkqRwPWnmuJ9N5eYK6 yPyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801210; x=1693406010; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ofgEyvBe3ui82lRdlcvI6rHrBc3Ju6bigS+xexWEBGk=; b=A+LnVSJBOftrl6VwVtWtNB5mBB9X0V5/m9aNr4N0j90nQjWsJPmcczaGnjJLzizGrh lCnV10SFwrPnFcC2MCAh79OPDUpVXhwDT7AlADn6jSemZDgRJ/cQI/JNn7z8CkqTRkSM l0m5wPnH2oN9BB4SvjPtx+O1gz/FxQxl+HLw+pRlDi/Mx91Mj3iz7QFUnBWH8AwiQfzm x97r/LwxQS66xg9rBj5ApaEFxewDbJmtRS5QjBK/e0z8MipgtOqQqKCMKE4F2WYeIDRA eCc7Ai8XLEQKmiWMZm8UPAODe8lGfFF/B/K6X8e9b2nUnsLapl0BwN+dfkdBSkLc25Lf hcKQ== X-Gm-Message-State: AOJu0YzNvorND7tAXDxnCNERXehFJil5ff0+U5Yui3Wq/o+vRFkq/BWg pzV7WrbSYjINBkZvnMtqubYpHCECVve3XnDo9M0= X-Google-Smtp-Source: AGHT+IFn7RqHWk4fR2enYicb3DeaBAZb5j8Nac8s4m9ycwlRdvworOLUt6JfOptkz+H8U+p57uzdIA== X-Received: by 2002:a25:ac19:0:b0:d6b:7df8:a9ec with SMTP id w25-20020a25ac19000000b00d6b7df8a9ecmr11479608ybi.50.1692801210241; Wed, 23 Aug 2023 07:33:30 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id m6-20020a056902004600b00c62e0df7ca8sm2734899ybh.24.2023.08.23.07.33.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:29 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 18/38] btrfs-progs: remove btrfs_create_root Date: Wed, 23 Aug 2023 10:32:44 -0400 Message-ID: <4dfa8b042cca9eb749050df7638e20891c2afe36.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org We have btrfs_create_root and btrfs_create_tree that do essentially the same thing. However btrfs_create_root isn't in the kernel, and btrfs_create_tree is. Update all of the callers of btrfs_create_root to use btrfs_create_tree instead and then remove btrfs_create_root. Signed-off-by: Josef Bacik --- kernel-shared/ctree.c | 117 ------------------------------------------ kernel-shared/ctree.h | 2 - mkfs/main.c | 14 +++-- tune/convert-bgt.c | 13 +++-- 4 files changed, 20 insertions(+), 126 deletions(-) diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index eae233b9..1e45f756 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -341,123 +341,6 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, return 0; } -/* - * Create a new tree root, with root objectid set to @objectid. - * - * NOTE: Doesn't support tree with non-zero offset, like data reloc tree. - */ -int btrfs_create_root(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info, u64 objectid) -{ - struct extent_buffer *node; - struct btrfs_root *new_root; - struct btrfs_disk_key disk_key; - struct btrfs_key location; - struct btrfs_root_item root_item = { 0 }; - int ret; - - new_root = malloc(sizeof(*new_root)); - if (!new_root) - return -ENOMEM; - - btrfs_setup_root(new_root, fs_info, objectid); - if (!is_fstree(objectid)) - set_bit(BTRFS_ROOT_TRACK_DIRTY, &new_root->state); - add_root_to_dirty_list(new_root); - - new_root->objectid = objectid; - new_root->root_key.objectid = objectid; - new_root->root_key.type = BTRFS_ROOT_ITEM_KEY; - new_root->root_key.offset = 0; - - node = btrfs_alloc_tree_block(trans, new_root, fs_info->nodesize, - objectid, &disk_key, 0, 0, 0, - BTRFS_NESTING_NORMAL); - if (IS_ERR(node)) { - ret = PTR_ERR(node); - error("failed to create root node for tree %llu: %d (%m)", - objectid, ret); - return ret; - } - new_root->node = node; - - memset_extent_buffer(node, 0, 0, sizeof(struct btrfs_header)); - btrfs_set_header_bytenr(node, node->start); - btrfs_set_header_generation(node, trans->transid); - btrfs_set_header_backref_rev(node, BTRFS_MIXED_BACKREF_REV); - btrfs_set_header_owner(node, objectid); - write_extent_buffer_fsid(node, fs_info->fs_devices->metadata_uuid); - write_extent_buffer_chunk_tree_uuid(node, fs_info->chunk_tree_uuid); - btrfs_set_header_nritems(node, 0); - btrfs_set_header_level(node, 0); - ret = btrfs_inc_ref(trans, new_root, node, 0); - if (ret < 0) - goto free; - - /* - * Special tree roots may need to modify pointers in @fs_info - * Only quota is supported yet. - */ - switch (objectid) { - case BTRFS_QUOTA_TREE_OBJECTID: - if (fs_info->quota_root) { - error("quota root already exists"); - ret = -EEXIST; - goto free; - } - fs_info->quota_root = new_root; - fs_info->quota_enabled = 1; - break; - case BTRFS_BLOCK_GROUP_TREE_OBJECTID: - if (fs_info->block_group_root) { - error("bg root already exists"); - ret = -EEXIST; - goto free; - } - fs_info->block_group_root = new_root; - break; - - /* - * Essential trees can't be created by this function, yet. - * As we expect such skeleton exists, or a lot of functions like - * btrfs_alloc_tree_block() doesn't work at all - */ - case BTRFS_ROOT_TREE_OBJECTID: - case BTRFS_EXTENT_TREE_OBJECTID: - case BTRFS_CHUNK_TREE_OBJECTID: - case BTRFS_FS_TREE_OBJECTID: - ret = -EEXIST; - goto free; - default: - /* Subvolume trees don't need special handling */ - if (is_fstree(objectid)) - break; - /* Other special trees are not supported yet */ - ret = -ENOTTY; - goto free; - } - btrfs_mark_buffer_dirty(node); - btrfs_set_root_bytenr(&root_item, btrfs_header_bytenr(node)); - btrfs_set_root_level(&root_item, 0); - btrfs_set_root_generation(&root_item, trans->transid); - btrfs_set_root_dirid(&root_item, 0); - btrfs_set_root_refs(&root_item, 1); - btrfs_set_root_used(&root_item, fs_info->nodesize); - location.objectid = objectid; - location.type = BTRFS_ROOT_ITEM_KEY; - location.offset = 0; - - ret = btrfs_insert_root(trans, fs_info->tree_root, &location, &root_item); - if (ret < 0) - goto free; - return ret; - -free: - free_extent_buffer(node); - free(new_root); - return ret; -} - /* * check if the tree block can be shared by multiple trees */ diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index c7d5167d..26cdae92 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -959,8 +959,6 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, struct extent_buffer **cow_ret, u64 new_root_objectid); -int btrfs_create_root(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info, u64 objectid); void btrfs_extend_item(struct btrfs_path *path, u32 data_size); void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end); int btrfs_split_item(struct btrfs_trans_handle *trans, diff --git a/mkfs/main.c b/mkfs/main.c index 4de57c8a..5d98ab69 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -883,7 +883,10 @@ static int setup_quota_root(struct btrfs_fs_info *fs_info) struct btrfs_qgroup_status_item *qsi; struct btrfs_root *quota_root; struct btrfs_path path = {}; - struct btrfs_key key; + struct btrfs_key key = { + .objectid = BTRFS_QUOTA_TREE_OBJECTID, + .type = BTRFS_ROOT_ITEM_KEY, + }; int qgroup_repaired = 0; int ret; @@ -895,12 +898,15 @@ static int setup_quota_root(struct btrfs_fs_info *fs_info) error_msg(ERROR_MSG_START_TRANS, "%m"); return ret; } - ret = btrfs_create_root(trans, fs_info, BTRFS_QUOTA_TREE_OBJECTID); - if (ret < 0) { + + quota_root = btrfs_create_tree(trans, fs_info, &key); + if (IS_ERR(quota_root)) { + ret = PTR_ERR(quota_root); error("failed to create quota root: %d (%m)", ret); goto fail; } - quota_root = fs_info->quota_root; + fs_info->quota_root = quota_root; + fs_info->quota_enabled = 1; key.objectid = 0; key.type = BTRFS_QGROUP_STATUS_KEY; diff --git a/tune/convert-bgt.c b/tune/convert-bgt.c index a2915376..15ec1042 100644 --- a/tune/convert-bgt.c +++ b/tune/convert-bgt.c @@ -31,7 +31,12 @@ int convert_to_bg_tree(struct btrfs_fs_info *fs_info) { struct btrfs_super_block *sb = fs_info->super_copy; struct btrfs_trans_handle *trans; + struct btrfs_root *root; struct cache_extent *ce; + struct btrfs_key key = { + .objectid = BTRFS_BLOCK_GROUP_TREE_OBJECTID, + .type = BTRFS_ROOT_ITEM_KEY, + }; int converted_bgs = 0; int ret; @@ -51,12 +56,14 @@ int convert_to_bg_tree(struct btrfs_fs_info *fs_info) if (btrfs_super_flags(sb) & BTRFS_SUPER_FLAG_CHANGING_BG_TREE) goto iterate_bgs; - ret = btrfs_create_root(trans, fs_info, - BTRFS_BLOCK_GROUP_TREE_OBJECTID); - if (ret < 0) { + root = btrfs_create_tree(trans, fs_info, &key); + if (IS_ERR(root)) { + ret = PTR_ERR(root); error("failed to create block group root: %d", ret); goto error; } + fs_info->block_group_root = root; + btrfs_set_super_flags(sb, btrfs_super_flags(sb) | BTRFS_SUPER_FLAG_CHANGING_BG_TREE); From patchwork Wed Aug 23 14:32:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362642 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 453D2EE49B5 for ; Wed, 23 Aug 2023 14:33:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229748AbjHWOdf (ORCPT ); Wed, 23 Aug 2023 10:33:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34348 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236501AbjHWOde (ORCPT ); Wed, 23 Aug 2023 10:33:34 -0400 Received: from mail-yb1-xb32.google.com (mail-yb1-xb32.google.com [IPv6:2607:f8b0:4864:20::b32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 98161E54 for ; Wed, 23 Aug 2023 07:33:32 -0700 (PDT) Received: by mail-yb1-xb32.google.com with SMTP id 3f1490d57ef6-d748d8cf074so5219880276.0 for ; Wed, 23 Aug 2023 07:33:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801211; x=1693406011; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=T9Pfbvfgkav1oa6o5OV8ZVbBs6vOfj2IAo+JgEBWrYo=; b=WVFLFVJUphehpv+QoMp8DC6d/nbmosYoDnkPXd9+DGsy6IU64qZZdmxYWxUGGYN9g7 D0eyFhVJqCvVhTLuR+kitnOQdndbnDsMn3o/bifG4qDVGwA2rBlq2+FJXN7GPadfK80F VMa2CYKWAAALl6a3ThmrXnwRL3Sonce8Gap8EF8p20Pl3vg1GkgG5obPiImPQoVXHjqu +PZ5ADZRn0oi8OXn/ATwwyxGo7dWjaECmk1pck3okCDIq/mKM0Xb7hFjBABWblAHhwmk JIcejWpnp6JL01pCTa0zxzBO7FS76ZJ70xmPiVfFnZDyfwWy1fgBDOSxueRy38EXrpWF BfSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801211; x=1693406011; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=T9Pfbvfgkav1oa6o5OV8ZVbBs6vOfj2IAo+JgEBWrYo=; b=GCZO+9qVz66nKxcB+8b/48hwAbigZqmqn8DV8raytZ1wNuHoDobBHkiJjcGcOmPtGd TOLjtvOt5F8U//anhuIisUgW+fho0GviZVz8J53wtopLGPY2isZPfTHizJLsgxWfLLGB d09xzDJkk+AlPLurKk841ej1csdchTu1h5Bk20n/XbiRQGfr9sgu0MxE4xny+O+Ts8D1 w0hW1ak/cjDU0W0spBSFtn5+Jv0qsY7oWOf/s0+RtLPwJF+C7xUcTpyhUZQl944JcA+G rCAZylGKmJWT1QTvmCoOmOBHinY1ONqFjeG1ZezcAG3LGsETRk5YMmmPnd4ykX343/fr Lw2g== X-Gm-Message-State: AOJu0Yy9ouTIFoOyOSf3Hyx95CtJka5IGsYb1c4EVhbx1Zay4X699rbV b7OH7wx04jRz3FXj7w7jBkGKJ94bIR/iEfXVAH0= X-Google-Smtp-Source: AGHT+IGgyhSlprP72Cvi3D9IcNW3Ty0gnYeZSQ2YEmL3oY1+G81HJrnh7nIUtILzq/ZH5K33Hn3m9g== X-Received: by 2002:a25:d4c5:0:b0:d62:b8f4:a03f with SMTP id m188-20020a25d4c5000000b00d62b8f4a03fmr13563521ybf.24.1692801211467; Wed, 23 Aug 2023 07:33:31 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id v71-20020a252f4a000000b00d1732567560sm2845437ybv.5.2023.08.23.07.33.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:31 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 19/38] btrfs-progs: move btrfs_uuid_tree_add into mkfs/main.c Date: Wed, 23 Aug 2023 10:32:45 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This function is only used in mkfs, and doesn't exist in the kernel in ctree.c. Additionally we have a uuid lookup function to see if the uuid exists in the tree, which for mkfs it won't because we just created the tree. Move btrfs_uuid_tree_add into mkfs, and remove the lookup function as it's not needed. Signed-off-by: Josef Bacik --- kernel-shared/ctree.c | 133 ------------------------------------------ kernel-shared/ctree.h | 2 - mkfs/main.c | 59 +++++++++++++++++++ 3 files changed, 59 insertions(+), 135 deletions(-) diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 1e45f756..ae6c03f9 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -3077,136 +3077,3 @@ int btrfs_previous_extent_item(struct btrfs_root *root, } return 1; } - -/* - * Search uuid tree - unmounted - * - * return -ENOENT for !found, < 0 for errors, or 0 if an item was found - */ -static int btrfs_uuid_tree_lookup(struct btrfs_root *uuid_root, u8 *uuid, - u8 type, u64 subid) -{ - int ret; - struct btrfs_path *path = NULL; - struct extent_buffer *eb; - int slot; - u32 item_size; - unsigned long offset; - struct btrfs_key key; - - if (!uuid_root) { - ret = -ENOENT; - goto out; - } - - path = btrfs_alloc_path(); - if (!path) { - ret = -ENOMEM; - goto out; - } - - btrfs_uuid_to_key(uuid, &key); - key.type = type; - ret = btrfs_search_slot(NULL, uuid_root, &key, path, 0, 0); - if (ret < 0) { - goto out; - } else if (ret > 0) { - ret = -ENOENT; - goto out; - } - - eb = path->nodes[0]; - slot = path->slots[0]; - item_size = btrfs_item_size(eb, slot); - offset = btrfs_item_ptr_offset(eb, slot); - ret = -ENOENT; - - if (!IS_ALIGNED(item_size, sizeof(u64))) { - warning("uuid item with invalid size %lu!", - (unsigned long)item_size); - goto out; - } - while (item_size) { - __le64 data; - - read_extent_buffer(eb, &data, offset, sizeof(data)); - if (le64_to_cpu(data) == subid) { - ret = 0; - break; - } - offset += sizeof(data); - item_size -= sizeof(data); - } - -out: - btrfs_free_path(path); - return ret; -} - -int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type, - u64 subvol_id_cpu) -{ - struct btrfs_fs_info *fs_info = trans->fs_info; - struct btrfs_root *uuid_root = fs_info->uuid_root; - int ret; - struct btrfs_path *path = NULL; - struct btrfs_key key; - struct extent_buffer *eb; - int slot; - unsigned long offset; - __le64 subvol_id_le; - - if (!uuid_root) { - warning("%s: uuid root is not initialized", __func__); - return -EINVAL; - } - - ret = btrfs_uuid_tree_lookup(uuid_root, uuid, type, subvol_id_cpu); - if (ret != -ENOENT) - return ret; - - key.type = type; - btrfs_uuid_to_key(uuid, &key); - - path = btrfs_alloc_path(); - if (!path) { - ret = -ENOMEM; - goto out; - } - - ret = btrfs_insert_empty_item(trans, uuid_root, path, &key, - sizeof(subvol_id_le)); - if (ret < 0 && ret != -EEXIST) { - warning( - "inserting uuid item failed (0x%016llx, 0x%016llx) type %u: %d", - (unsigned long long)key.objectid, - (unsigned long long)key.offset, type, ret); - goto out; - } - - if (ret >= 0) { - /* Add an item for the type for the first time */ - eb = path->nodes[0]; - slot = path->slots[0]; - offset = btrfs_item_ptr_offset(eb, slot); - } else { - /* - * ret == -EEXIST case, An item with that type already exists. - * Extend the item and store the new subvol_id at the end. - */ - btrfs_extend_item(path, sizeof(subvol_id_le)); - eb = path->nodes[0]; - slot = path->slots[0]; - offset = btrfs_item_ptr_offset(eb, slot); - offset += btrfs_item_size(eb, slot) - sizeof(subvol_id_le); - } - - ret = 0; - subvol_id_le = cpu_to_le64(subvol_id_cpu); - write_extent_buffer(eb, &subvol_id_le, offset, sizeof(subvol_id_le)); - btrfs_mark_buffer_dirty(eb); - -out: - btrfs_free_path(path); - return ret; -} diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 26cdae92..ec81a46c 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -1133,8 +1133,6 @@ int btrfs_lookup_uuid_received_subvol_item(int fd, const u8 *uuid, u64 *subvol_id); /* uuid-tree.c, interface for unmounte filesystem */ -int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type, - u64 subvol_id_cpu); int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, u8 *uuid, u8 type, u64 subid); diff --git a/mkfs/main.c b/mkfs/main.c index 5d98ab69..9f824727 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -769,6 +769,65 @@ out: return ret; } +static int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, + u8 type, u64 subvol_id_cpu) +{ + struct btrfs_fs_info *fs_info = trans->fs_info; + struct btrfs_root *uuid_root = fs_info->uuid_root; + int ret; + struct btrfs_path *path = NULL; + struct btrfs_key key; + struct extent_buffer *eb; + int slot; + unsigned long offset; + __le64 subvol_id_le; + + key.type = type; + btrfs_uuid_to_key(uuid, &key); + + path = btrfs_alloc_path(); + if (!path) { + ret = -ENOMEM; + goto out; + } + + ret = btrfs_insert_empty_item(trans, uuid_root, path, &key, + sizeof(subvol_id_le)); + if (ret < 0 && ret != -EEXIST) { + warning( + "inserting uuid item failed (0x%016llx, 0x%016llx) type %u: %d", + (unsigned long long)key.objectid, + (unsigned long long)key.offset, type, ret); + goto out; + } + + if (ret >= 0) { + /* Add an item for the type for the first time */ + eb = path->nodes[0]; + slot = path->slots[0]; + offset = btrfs_item_ptr_offset(eb, slot); + } else { + /* + * ret == -EEXIST case, An item with that type already exists. + * Extend the item and store the new subvol_id at the end. + */ + btrfs_extend_item(path, sizeof(subvol_id_le)); + eb = path->nodes[0]; + slot = path->slots[0]; + offset = btrfs_item_ptr_offset(eb, slot); + offset += btrfs_item_size(eb, slot) - sizeof(subvol_id_le); + } + + ret = 0; + subvol_id_le = cpu_to_le64(subvol_id_cpu); + write_extent_buffer(eb, &subvol_id_le, offset, sizeof(subvol_id_le)); + btrfs_mark_buffer_dirty(eb); + +out: + btrfs_free_path(path); + return ret; +} + static int create_uuid_tree(struct btrfs_trans_handle *trans) { struct btrfs_fs_info *fs_info = trans->fs_info; From patchwork Wed Aug 23 14:32:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362643 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 B391CEE49A3 for ; Wed, 23 Aug 2023 14:33:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236509AbjHWOdh (ORCPT ); Wed, 23 Aug 2023 10:33:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236505AbjHWOdf (ORCPT ); Wed, 23 Aug 2023 10:33:35 -0400 Received: from mail-yw1-x1134.google.com (mail-yw1-x1134.google.com [IPv6:2607:f8b0:4864:20::1134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7C62FE57 for ; Wed, 23 Aug 2023 07:33:33 -0700 (PDT) Received: by mail-yw1-x1134.google.com with SMTP id 00721157ae682-5925e580f12so8400687b3.3 for ; Wed, 23 Aug 2023 07:33:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801212; x=1693406012; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=JMur5JvaWbgPaGGZaTOFjR8ufthd4YpaCdeoWzxIOU4=; b=iWTxDE5+phpXnNDLitPLRv/UbLHlVLEEzm0mNOim+5IgSH2zBYpTtBV9uSgDgRZhOO nTBCGk96IrwZjhYkEDmjPJYBoBvB6k7gaJBrDlxXeml2SXZmdpWFHBBRDurrH5t/jAMl VSlYqGreJj4CaFdM1wbOVigDnaDubLTj03sWDHx111rjJz7SEMKa4j3/qTL7kXO7fGJt x2500WYBvaM2E+F7DUpoixZcVA0AvxbjDm33xGLaZJKFqFQju0CBczWnp2o79jzozSOP ML6wQwwlJA4yVvO+z/U4XW6/ZeIaeWD9bEXrFOPuJGnRLj3k6EgQNzh7uFhUcome929I 7fUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801212; x=1693406012; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JMur5JvaWbgPaGGZaTOFjR8ufthd4YpaCdeoWzxIOU4=; b=Ba4eNfiZipdqYaFYtPkTabChk359eE//GfyL6DQ+x8rTbqbChy2VIO9a70Zs4cKY09 vl+SCLarvGZhzBuitovIji2Er9ZCM+soL162k6Gud2P5JQ1R3elR3h66Z+ayJtUYb21r qo4I2QwQrxXpwuWTML+8htpvSOxhZF6B20qeoiOvKd3J6WiME2/+5g34cbRZD685sEcO YvzrecXMuwtgrY61LbrnXjiKSCeEV1ltET/lSoHg42mUHZOwS6nfws/nONqeYCXSegpV Ta6GWPNzilp8oCU3OxDnKCsUPItEKOCZt+es4pPTWkYGpXGaXgWz39mPCvyLLQJLV1Rx RcPA== X-Gm-Message-State: AOJu0YzBP90LBNnkYjT1aAcCwEc00jeo0kfZDwY4hkzMTg6XAf31q1Et M6+biVGy8iQm/xdNyH8v42zMS/wMspISwwkz3is= X-Google-Smtp-Source: AGHT+IFUATgpmvG0J8B1TMIuKnMdbu477qMCom6wDbRRIyB5jywAWPBtntkYtzNpKAwdDlTkB2XtIQ== X-Received: by 2002:a0d:cf44:0:b0:56f:ff55:2b7d with SMTP id r65-20020a0dcf44000000b0056fff552b7dmr12531177ywd.17.1692801212611; Wed, 23 Aug 2023 07:33:32 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id w67-20020a818646000000b0054f50f71834sm3367990ywf.124.2023.08.23.07.33.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:32 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 20/38] btrfs-progs: make btrfs_del_ptr a void Date: Wed, 23 Aug 2023 10:32:46 -0400 Message-ID: <3d784e00931075ead1acad5165be616c8f3bd898.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This always returns 0, and in the kernel is a void. Update the definition to match the kernel and then update all of the callers. Signed-off-by: Josef Bacik --- check/main.c | 7 +++---- kernel-shared/ctree.c | 16 ++++------------ kernel-shared/ctree.h | 2 +- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/check/main.c b/check/main.c index b8bcf5c3..a33a300a 100644 --- a/check/main.c +++ b/check/main.c @@ -3569,9 +3569,8 @@ static int repair_btree(struct btrfs_root *root, path.slots[level]); /* Remove the ptr */ - ret = btrfs_del_ptr(root, &path, level, path.slots[level]); - if (ret < 0) - goto out; + btrfs_del_ptr(root, &path, level, path.slots[level]); + /* * Remove the corresponding extent * return value is not concerned. @@ -7829,7 +7828,7 @@ again: del_ptr: printk("deleting pointer to block %llu\n", corrupt->cache.start); - ret = btrfs_del_ptr(extent_root, &path, level, slot); + btrfs_del_ptr(extent_root, &path, level, slot); out: btrfs_release_path(&path); diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index ae6c03f9..91127933 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -853,9 +853,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, btrfs_clear_buffer_dirty(trans, right); free_extent_buffer(right); right = NULL; - wret = btrfs_del_ptr(root, path, level + 1, pslot + 1); - if (wret) - ret = wret; + btrfs_del_ptr(root, path, level + 1, pslot + 1); root_sub_used(root, blocksize); wret = btrfs_free_extent(trans, bytenr, blocksize, 0, @@ -900,9 +898,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, btrfs_clear_buffer_dirty(trans, mid); free_extent_buffer(mid); mid = NULL; - wret = btrfs_del_ptr(root, path, level + 1, pslot); - if (wret) - ret = wret; + btrfs_del_ptr(root, path, level + 1, pslot); root_sub_used(root, blocksize); wret = btrfs_free_extent(trans, bytenr, blocksize, 0, @@ -2716,12 +2712,11 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root * continuing all the way the root if required. The root is converted into * a leaf if all the nodes are emptied. */ -int btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, +void btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level, int slot) { struct extent_buffer *parent = path->nodes[level]; u32 nritems; - int ret = 0; nritems = btrfs_header_nritems(parent); if (slot < nritems - 1) { @@ -2745,7 +2740,6 @@ int btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, fixup_low_keys(path, &disk_key, level + 1); } btrfs_mark_buffer_dirty(parent); - return ret; } /* @@ -2766,9 +2760,7 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, int ret; WARN_ON(btrfs_header_generation(leaf) != trans->transid); - ret = btrfs_del_ptr(root, path, 1, path->slots[1]); - if (ret) - return ret; + btrfs_del_ptr(root, path, 1, path->slots[1]); root_sub_used(root, leaf->len); diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index ec81a46c..a1c09d97 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -942,7 +942,7 @@ int btrfs_convert_one_bg(struct btrfs_trans_handle *trans, u64 bytenr); /* ctree.c */ int btrfs_comp_cpu_keys(const struct btrfs_key *k1, const struct btrfs_key *k2); -int btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, +void btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level, int slot); struct extent_buffer *btrfs_read_node_slot(struct extent_buffer *parent, int slot); From patchwork Wed Aug 23 14:32:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362644 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 46F97EE49B7 for ; Wed, 23 Aug 2023 14:33:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232887AbjHWOdi (ORCPT ); Wed, 23 Aug 2023 10:33:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34376 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236506AbjHWOdg (ORCPT ); Wed, 23 Aug 2023 10:33:36 -0400 Received: from mail-yw1-x112b.google.com (mail-yw1-x112b.google.com [IPv6:2607:f8b0:4864:20::112b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AEA63E54 for ; Wed, 23 Aug 2023 07:33:34 -0700 (PDT) Received: by mail-yw1-x112b.google.com with SMTP id 00721157ae682-58d40c2debeso62279687b3.2 for ; Wed, 23 Aug 2023 07:33:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801214; x=1693406014; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Y9LNgjQ9gxDam5zBCWotVFHgLh6mbx0viiWOaWN1WYE=; b=EGzJEO3ibxXt+OFP9ZtF6BaD0WMVl7sBQIiAVElF3oSmLPE24cr6CQq5oUYAmVImme cXH0f4UM3hiVKm9IYnszFe7hhO7tkRhEinXR9EL0J0yWFUq/9u2frcAqnR13CpWvY4Ut Dgr0VQtpG5NkqF0edrUiF7/j5T1uD4ZOHMiwqIAvoysI87L0hVGnyFxLUGGkcsmfwPMb 7A4vaa6W/lS/njffBx6Bq65hFhMoK+aoXJgbNXNy51pyEVaYedZi4zUr214bbiojTOP7 prVTgaQg9W9hMLtHG5oBXHdjb4iZrQnNYCY0j4ChM451fIJKid3tLDdcKtSUISKr7P0C N07g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801214; x=1693406014; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Y9LNgjQ9gxDam5zBCWotVFHgLh6mbx0viiWOaWN1WYE=; b=XwxzBo08RCPQE26WfbI2hTnjz9KmylBkE2G+1U4kvWam1IfpV4rHNVkR5f5PHPe9te K7pUKyzuhQhRp8Ptj+ytDsMA9RSzswMkBuQ4S3e8puJHxtpJBWAiaAHlCfKMGPzY/Al4 lZP/pyPPOSTn9RBKWU46/rI/5qVFYgRpKLlTmIgPqCOcgTcSFFEQR8cKJ7b8bdfv/HJd AlbbqQLZora4jyJ211k/jeoeZ0+9GCCQUwn9PKYQvZ2ssLkN58RiG1E4N94d+yzleENI YXcVg3rsO92hPScw3oBwYE6X15UIrj1zd4YfE1Xe9/CZQB3X8hnjL5zu53Eo7fTgqztM uVZQ== X-Gm-Message-State: AOJu0YwIm0Spg7Lt1LBwOLALLu52onHaqHTIJYS/lDRkaQEARNJPYu8D peN0qWuy4QBumrqxF1hHOAPMGZh29v15bMO+qus= X-Google-Smtp-Source: AGHT+IEHDDLyJCUkOQ+XB6DM43f5zL6CdbqN9+ySL/9HdUcrF+U69QpSU0toZ5p2Nlj46qPzEm6T+w== X-Received: by 2002:a0d:d80f:0:b0:589:e7ab:d4e5 with SMTP id a15-20020a0dd80f000000b00589e7abd4e5mr12758714ywe.0.1692801213763; Wed, 23 Aug 2023 07:33:33 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id i194-20020a816dcb000000b0057042405e2csm3368883ywc.71.2023.08.23.07.33.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:33 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 21/38] btrfs-progs: replace blocksize with parent argument for btrfs_alloc_tree_block Date: Wed, 23 Aug 2023 10:32:47 -0400 Message-ID: <621e47bfa5cbdd21ee2c6639602c028585aacc79.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org In the kernel we pass in the parent to btrfs_alloc_tree_block instead of the blocksize and simply derive the blocksize from the fs_info. Update the function to match the kernel's convention and update all of the callers so we can sync ctree.c easily. Signed-off-by: Josef Bacik --- check/main.c | 3 +-- cmds/rescue-chunk-recover.c | 3 +-- kernel-shared/ctree.c | 29 ++++++++++++----------------- kernel-shared/ctree.h | 2 +- kernel-shared/disk-io.c | 5 ++--- kernel-shared/extent-tree.c | 9 +++++---- 6 files changed, 22 insertions(+), 29 deletions(-) diff --git a/check/main.c b/check/main.c index a33a300a..08c49f7a 100644 --- a/check/main.c +++ b/check/main.c @@ -9067,8 +9067,7 @@ static struct extent_buffer *btrfs_fsck_clear_root( if (!path) return ERR_PTR(-ENOMEM); - c = btrfs_alloc_tree_block(trans, gfs_info->tree_root, - gfs_info->nodesize, key->objectid, + c = btrfs_alloc_tree_block(trans, gfs_info->tree_root, 0, key->objectid, &disk_key, 0, 0, 0, BTRFS_NESTING_NORMAL); if (IS_ERR(c)) { btrfs_free_path(path); diff --git a/cmds/rescue-chunk-recover.c b/cmds/rescue-chunk-recover.c index e12dc61c..89b778d5 100644 --- a/cmds/rescue-chunk-recover.c +++ b/cmds/rescue-chunk-recover.c @@ -1143,8 +1143,7 @@ static int __rebuild_chunk_root(struct btrfs_trans_handle *trans, btrfs_set_disk_key_type(&disk_key, BTRFS_DEV_ITEM_KEY); btrfs_set_disk_key_offset(&disk_key, min_devid); - cow = btrfs_alloc_tree_block(trans, root, root->fs_info->nodesize, - BTRFS_CHUNK_TREE_OBJECTID, + cow = btrfs_alloc_tree_block(trans, root, 0, BTRFS_CHUNK_TREE_OBJECTID, &disk_key, 0, 0, 0, BTRFS_NESTING_NORMAL); btrfs_set_header_bytenr(cow, cow->start); btrfs_set_header_generation(cow, trans->transid); diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 91127933..e3b29a3a 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -307,9 +307,8 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, else btrfs_node_key(buf, &disk_key, 0); - cow = btrfs_alloc_tree_block(trans, new_root, buf->len, - new_root_objectid, &disk_key, - level, buf->start, 0, + cow = btrfs_alloc_tree_block(trans, new_root, 0, new_root_objectid, + &disk_key, level, buf->start, 0, BTRFS_NESTING_NORMAL); if (IS_ERR(cow)) { kfree(new_root); @@ -489,9 +488,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, else btrfs_node_key(buf, &disk_key, 0); - cow = btrfs_alloc_tree_block(trans, root, buf->len, - root->root_key.objectid, &disk_key, - level, search_start, empty_size, + cow = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid, + &disk_key, level, search_start, empty_size, BTRFS_NESTING_NORMAL); if (IS_ERR(cow)) return PTR_ERR(cow); @@ -1566,9 +1564,8 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans, else btrfs_node_key(lower, &lower_key, 0); - c = btrfs_alloc_tree_block(trans, root, root->fs_info->nodesize, - root->root_key.objectid, &lower_key, - level, root->node->start, 0, + c = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid, + &lower_key, level, root->node->start, 0, BTRFS_NESTING_NORMAL); if (IS_ERR(c)) @@ -1688,10 +1685,9 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root mid = (c_nritems + 1) / 2; btrfs_node_key(c, &disk_key, mid); - split = btrfs_alloc_tree_block(trans, root, root->fs_info->nodesize, - root->root_key.objectid, - &disk_key, level, c->start, 0, - BTRFS_NESTING_NORMAL); + split = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid, + &disk_key, level, c->start, 0, + BTRFS_NESTING_NORMAL); if (IS_ERR(split)) return PTR_ERR(split); @@ -2251,10 +2247,9 @@ again: else btrfs_item_key(l, &disk_key, mid); - right = btrfs_alloc_tree_block(trans, root, root->fs_info->nodesize, - root->root_key.objectid, - &disk_key, 0, l->start, 0, - BTRFS_NESTING_NORMAL); + right = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid, + &disk_key, 0, l->start, 0, + BTRFS_NESTING_NORMAL); if (IS_ERR(right)) { BUG_ON(1); return PTR_ERR(right); diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index a1c09d97..0b440b1a 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -886,7 +886,7 @@ struct btrfs_block_group *btrfs_lookup_first_block_group(struct u64 bytenr); struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, - u32 blocksize, u64 root_objectid, + u64 parent, u64 root_objectid, struct btrfs_disk_key *key, int level, u64 hint, u64 empty_size, enum btrfs_lock_nesting nest); diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c index c98addd2..286eb9cb 100644 --- a/kernel-shared/disk-io.c +++ b/kernel-shared/disk-io.c @@ -2319,9 +2319,8 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans, btrfs_setup_root(root, fs_info, key->objectid); memcpy(&root->root_key, key, sizeof(struct btrfs_key)); - leaf = btrfs_alloc_tree_block(trans, root, fs_info->nodesize, - root->root_key.objectid, NULL, 0, 0, 0, - BTRFS_NESTING_NORMAL); + leaf = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid, + NULL, 0, 0, 0, BTRFS_NESTING_NORMAL); if (IS_ERR(leaf)) { ret = PTR_ERR(leaf); leaf = NULL; diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c index 433cf4fc..439ac530 100644 --- a/kernel-shared/extent-tree.c +++ b/kernel-shared/extent-tree.c @@ -2479,7 +2479,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, } static int alloc_tree_block(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 num_bytes, + struct btrfs_root *root, u64 parent, u64 root_objectid, u64 generation, u64 flags, struct btrfs_disk_key *key, int level, u64 empty_size, u64 hint_byte, @@ -2490,6 +2490,7 @@ static int alloc_tree_block(struct btrfs_trans_handle *trans, struct btrfs_delayed_extent_op *extent_op; struct btrfs_space_info *sinfo; struct btrfs_fs_info *fs_info = root->fs_info; + u64 num_bytes = fs_info->nodesize; bool skinny_metadata = btrfs_fs_incompat(root->fs_info, SKINNY_METADATA); @@ -2536,7 +2537,7 @@ static int alloc_tree_block(struct btrfs_trans_handle *trans, sinfo->bytes_reserved += extent_size; ret = btrfs_add_delayed_tree_ref(root->fs_info, trans, ins->objectid, - extent_size, 0, root_objectid, + extent_size, parent, root_objectid, level, BTRFS_ADD_DELAYED_EXTENT, extent_op, NULL, NULL); return ret; @@ -2548,7 +2549,7 @@ static int alloc_tree_block(struct btrfs_trans_handle *trans, */ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, - u32 blocksize, u64 root_objectid, + u64 parent, u64 root_objectid, struct btrfs_disk_key *key, int level, u64 hint, u64 empty_size, enum btrfs_lock_nesting nest) @@ -2557,7 +2558,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, int ret; struct extent_buffer *buf; - ret = alloc_tree_block(trans, root, blocksize, root_objectid, + ret = alloc_tree_block(trans, root, parent, root_objectid, trans->transid, 0, key, level, empty_size, hint, (u64)-1, &ins); if (ret) { From patchwork Wed Aug 23 14:32:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362645 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 D851DEE49B0 for ; Wed, 23 Aug 2023 14:33:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236511AbjHWOdi (ORCPT ); Wed, 23 Aug 2023 10:33:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236488AbjHWOdh (ORCPT ); Wed, 23 Aug 2023 10:33:37 -0400 Received: from mail-oo1-xc2d.google.com (mail-oo1-xc2d.google.com [IPv6:2607:f8b0:4864:20::c2d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BDA06E57 for ; Wed, 23 Aug 2023 07:33:35 -0700 (PDT) Received: by mail-oo1-xc2d.google.com with SMTP id 006d021491bc7-5710b054710so595920eaf.1 for ; Wed, 23 Aug 2023 07:33:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801215; x=1693406015; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=By9Q/LMA6FtAhPIM1j6On7nXfUxFdhlB7musiSsZK40=; b=mEPu+5JuDvAV6bvveJPae6O3RH8l6Z+24fbMg9kxxt0C1jRImYhrwTJZusUC5tXF4J hDLHq3J4wdtO7YPWL+Hi5+jjVAbjLHMBZsYmhVzYN05EUfFiZ7i9ALVkoR1TgViLPpT0 04Z7Y/MrH2m35G0VEqUzuqAPEvEe0K+LdaSq/Ot65EVRVn8EVPmQAJgciMMyeXWbKtsT xHDmGY/xWhRNGEG4n4GzfRwTQcd1pCPq642Gk3YJ2dyBn3DVq80omefDHwaCm5Yh8UGs rpUN/W2YalhAtD84KpDJIeZP0tw+G4mcBzmG+NJBj4n3cU67VswWauGJey4Iplyjce6A mH0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801215; x=1693406015; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=By9Q/LMA6FtAhPIM1j6On7nXfUxFdhlB7musiSsZK40=; b=M3wr39bdo5cBCR1bWayWLgKWCnhBATKSE6TTg5KUlBQMR2nd7V/oDC022kBo2KPSso aNdR2UPzm6PxytyA7wpmrrMrpxPXsiPU3/11xz9mp/YQsz34n9fBaHdVlzWab36fDdYL N9A6i56RGBHKBINRnSMlCyGEXWqbnS9yglWogS+plnBBq4wZcpoxo9dd1fxFi5xbSUlB QosR0sUhF/7ej8RBhOcmyNx/8AjRTvnfz98u3kL4Ea14Rlh6dVSlRB00SqBxFJPn0SLN COYizzh9IjMkTkURGoKfRLy/tRCGjmAiDJCGLYhu/ez5Hsg7JR3/8oHX9CWNsT+e7FU+ bbrA== X-Gm-Message-State: AOJu0Yzb4jpdb0B9925FgxAhX6NJD3/kMaXVj+iK5oTebJWwU/3F/BCt R/c2GR7i7NeqPNdtx7VB5tbFS7g5tQi+OkNYHRU= X-Google-Smtp-Source: AGHT+IHTFwRDvrCMAMMwivqyq6x9cVG/RI+9SdRQ40pa5UAVPKnXBMRPJPneQJN7qKLyZm9PtMAcQA== X-Received: by 2002:a05:6358:6f16:b0:133:428:35dc with SMTP id r22-20020a0563586f1600b00133042835dcmr11309633rwn.11.1692801214854; Wed, 23 Aug 2023 07:33:34 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id x123-20020a818781000000b0057a918d6644sm3355408ywf.128.2023.08.23.07.33.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:34 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 22/38] btrfs-progs: use path->search_for_extension Date: Wed, 23 Aug 2023 10:32:48 -0400 Message-ID: <0c55a506da48747708c4ec759712c25d5a7b2e1d.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This flag is used by the kernel btrfs_search_slot to make sure that leaf splitting decision doesn't subtract the size of an item. This is for inline extent items and csum items where we know we're going to find the item we want, and we're only going to want to extend it. Currently this flag doesn't do anything, but when we sync ctree.c we'll stop making the right decision WRT the leaf space, so add the flag usage in the places we need it so we can sync ctree.c easily. Signed-off-by: Josef Bacik --- kernel-shared/extent-tree.c | 8 ++++++-- kernel-shared/file-item.c | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c index 439ac530..10482652 100644 --- a/kernel-shared/extent-tree.c +++ b/kernel-shared/extent-tree.c @@ -881,10 +881,12 @@ static int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, key.offset = num_bytes; want = extent_ref_type(parent, owner); - if (insert) + if (insert) { extra_size = btrfs_extent_inline_ref_size(want); - else + path->search_for_extension = 1; + } else { extra_size = -1; + } if (owner < BTRFS_FIRST_FREE_OBJECTID && skinny_metadata) { key.type = BTRFS_METADATA_ITEM_KEY; @@ -1022,6 +1024,8 @@ again: } *ref_ret = (struct btrfs_extent_inline_ref *)ptr; out: + if (insert) + path->search_for_extension = 0; return err; } diff --git a/kernel-shared/file-item.c b/kernel-shared/file-item.c index 7baa5614..54d7c094 100644 --- a/kernel-shared/file-item.c +++ b/kernel-shared/file-item.c @@ -257,8 +257,10 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans, u64 logical, * enough yet to put our csum in. Grow it */ btrfs_release_path(path); + path->search_for_extension = 1; ret = btrfs_search_slot(trans, root, &file_key, path, csum_size, 1); + path->search_for_extension = 0; if (ret < 0) goto fail; if (ret == 0) { From patchwork Wed Aug 23 14:32:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362646 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 6D6A1EE49B2 for ; Wed, 23 Aug 2023 14:33:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236512AbjHWOdj (ORCPT ); Wed, 23 Aug 2023 10:33:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236510AbjHWOdi (ORCPT ); Wed, 23 Aug 2023 10:33:38 -0400 Received: from mail-yb1-xb36.google.com (mail-yb1-xb36.google.com [IPv6:2607:f8b0:4864:20::b36]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D85CFE54 for ; Wed, 23 Aug 2023 07:33:36 -0700 (PDT) Received: by mail-yb1-xb36.google.com with SMTP id 3f1490d57ef6-d7225259f52so5632780276.0 for ; Wed, 23 Aug 2023 07:33:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801216; x=1693406016; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=BNGWm6NdL1drTn/oo0Y/OvcWe2LvUaNmbQUrs43rWaM=; b=mWYJo2ovvPTbNIETS99PBpSJRzYnw1cZ0ceVzhKHLjGkOi1F65TeEZftBzOQj5yBJL Vb40S9ikfgjxV/1zYgqYYkcb8n1c+F9GQB7/PKqf/Kd8YguqG10w5l5tScuLWyaiM+Ty 3vKGMguskPZqHo2UNKVfpUKV7EC58/1i/R+auhgxub+dKigB7QOaC/zGROT118O6T1do vg2Tnev7bbZkWr47tXNwB7ZjFALZivvSTP5nfIsgnr824KNV9BU0Vopw6lku4NZTp8qt suNMfWB3VfvNfMuu3Rr/eV+r2a8CXKfGZVjUG/pKw/LpNi75Ua5GMMFF+0TxZEzp0f5b TsiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801216; x=1693406016; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BNGWm6NdL1drTn/oo0Y/OvcWe2LvUaNmbQUrs43rWaM=; b=Npf5HeoouaQsxKKhOrYzasErU+aZZ7BYSHLOiwXqb+ZVp7qUndp4q126E2cDu5y7A8 LddgyWgqdUvV6cHB3m2Sf0P51R0cpHayn51HYoTbCe5L/F2Z7IAwvvthzPJ3Ahwja+0C AKV1fQRn7WpuQHg92eXrvBGfXopELAfpT/P/jHt1v6oVI5F7P/EB2uzsufLr1P/5auSl gHeGfK76X5qBkSqwMAQzMNEi8Y20yHX/ZAAgE1hIyJNT+6BUS/6FsjoicfSVdii+sfUw FzZlfz91FoohUqyxM34ouRxA0JEZHXOCUGndHEz6re5WYuwr2PYIUVHV84KZM+GE4XT7 n5jg== X-Gm-Message-State: AOJu0YwOorWfkGA0kZpwQ+ShY3mlcwbEVad3wLeFG7/f/fd02U8WRhze VTjo3eFl8l0LfwT7FXvJ8uhaXAmt/vFZGGTsVFI= X-Google-Smtp-Source: AGHT+IFHrUhABIjTWGW43a6tRWnX7J2PtzXcKPvFK0dGL4VrluUysISn/3aEaBFOayNUPo6Y4WIYsg== X-Received: by 2002:a25:504:0:b0:d0b:bbc7:56bc with SMTP id 4-20020a250504000000b00d0bbbc756bcmr11402053ybf.45.1692801215917; Wed, 23 Aug 2023 07:33:35 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id 10-20020a25030a000000b00c5ec980da48sm2860977ybd.9.2023.08.23.07.33.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:35 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 23/38] btrfs-progs: init new tree blocks in btrfs_alloc_tree_block Date: Wed, 23 Aug 2023 10:32:49 -0400 Message-ID: <01c064dd2704444211d0a4ee6cd13f89d4d3a55c.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This is how the kernel initializes blocks, so anybody who uses btrfs_alloc_tree_block in the kernel expects the blocks to be already initialized. Put this init code into btrfs-progs so as we sync code from the kernel we get the correct behavior. Signed-off-by: Josef Bacik --- kernel-shared/extent-tree.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c index 10482652..4ddf5222 100644 --- a/kernel-shared/extent-tree.c +++ b/kernel-shared/extent-tree.c @@ -2558,6 +2558,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, u64 hint, u64 empty_size, enum btrfs_lock_nesting nest) { + struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_key ins; int ret; struct extent_buffer *buf; @@ -2578,6 +2579,14 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, return ERR_PTR(-ENOMEM); } btrfs_set_buffer_uptodate(buf); + memset_extent_buffer(buf, 0, 0, sizeof(struct btrfs_header)); + btrfs_set_header_level(buf, level); + btrfs_set_header_bytenr(buf, buf->start); + btrfs_set_header_generation(buf, trans->transid); + btrfs_set_header_backref_rev(buf, BTRFS_MIXED_BACKREF_REV); + btrfs_set_header_owner(buf, root_objectid); + write_extent_buffer_fsid(buf, fs_info->fs_devices->metadata_uuid); + write_extent_buffer_chunk_tree_uuid(buf, fs_info->chunk_tree_uuid); trans->blocks_used++; return buf; From patchwork Wed Aug 23 14:32:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362647 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 40C64EE49B5 for ; Wed, 23 Aug 2023 14:33:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236514AbjHWOdk (ORCPT ); Wed, 23 Aug 2023 10:33:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34394 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236510AbjHWOdj (ORCPT ); Wed, 23 Aug 2023 10:33:39 -0400 Received: from mail-oi1-x230.google.com (mail-oi1-x230.google.com [IPv6:2607:f8b0:4864:20::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1C278E54 for ; Wed, 23 Aug 2023 07:33:38 -0700 (PDT) Received: by mail-oi1-x230.google.com with SMTP id 5614622812f47-3a7d4030621so3456777b6e.3 for ; Wed, 23 Aug 2023 07:33:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801217; x=1693406017; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ja42/0krc0tgrw7J9d9Ut4P0FrbTNsvhFKDo0vim6Ls=; b=1uBJ4cbc6y5hi+Uvbz8kx6wQzkPyZ39p7wlUgxvEIFhn+fjUQq4bLDzUam3fnRYbvw MP9mC4hyA2WhWNIhSIFWxZf7kglxk552cVeb3qC/VHAIYHrENIlCWTu8r+zKP0dEMR2z /vJrYhox3dsOaTkDlhLG1InQ6XGn2MdG4Eby4Lzq644SMG/jPRoJApKKC6/mMh8X+TYs Jsygf03N1nGw447w+JVRA2PzB3PydAVWBi7cxsBlHzm02DSPZri7oaNoUvE/a2qe1qtO PH6yNa5E3aL+yhAueRV14zdEoPqsEX++kevyhll7YNtsCNpMAgubIUfDHJ6P/zjyy3s2 QyBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801217; x=1693406017; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ja42/0krc0tgrw7J9d9Ut4P0FrbTNsvhFKDo0vim6Ls=; b=ldyNiaCq4qyV+o7ziSpLybo+R2N/KLd9ZORH8GpaTVWmcYCWV3YNfuW0y9I0CsODDC ynrXIbcLYojnDgfaz9A8sq9xDCinFf0qXlAkvjJcbOxVN3KPU/geF502ra716m/5BqsA YioIX5/9kvHd/AEvHMUumQrUtz/mzfGyDSx0MEwt9go2epQpb2ozmoAFdG3vkLMzJMWd hOQ6sQUvvicEi8WqyCvzM0QF2aFvA/4rBJ9qrxP3MBXbhNjgcbJ0WrDIO2OtcqSy+WQB E/Ej+hlZ4EqGcDCdTu7XxatRYJy0/WphFnokn2ve7SpWrYhiU7/e4LsrbcrvEObpdzFs SOpA== X-Gm-Message-State: AOJu0YwOG93PdsfqIRusc9fmH/JyQ4hZvqCwIb+ef9mMY2zoiMIULXc6 HB6LRh/XDEp+WhZZrFWIN6xwL1qAcYq+68ixw2o= X-Google-Smtp-Source: AGHT+IE1H8jmOGQ4aumUSfiBCmStqSMyWW9ckUB6hZdJpjyAjkXKEkMsue8pQWOG0JIXK9rctVXM3Q== X-Received: by 2002:a05:6358:998b:b0:134:c279:c81d with SMTP id j11-20020a056358998b00b00134c279c81dmr7597719rwb.20.1692801217153; Wed, 23 Aug 2023 07:33:37 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id q83-20020a815c56000000b005869d49212fsm3414927ywb.32.2023.08.23.07.33.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:36 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 24/38] btrfs-progs: add dwarves to the package list for ci Date: Wed, 23 Aug 2023 10:32:50 -0400 Message-ID: <87d564c27e921f0e4e11e8cbf5018473998de3ef.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org We run pahole for the ioctl-test, which requires the dwarves package. Add that to the docker images. Signed-off-by: Josef Bacik --- ci/images/ci-centos-7-x86_64/Dockerfile | 2 +- ci/images/ci-centos-8-x86_64/Dockerfile | 2 +- ci/images/ci-musl-x86_64/Dockerfile | 2 +- ci/images/ci-openSUSE-Leap-15.3-x86_64/Dockerfile | 2 +- ci/images/ci-openSUSE-Leap-15.4-x86_64/Dockerfile | 2 +- ci/images/ci-openSUSE-tumbleweed-x86_64/Dockerfile | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ci/images/ci-centos-7-x86_64/Dockerfile b/ci/images/ci-centos-7-x86_64/Dockerfile index ccf0bc2d..89beef70 100644 --- a/ci/images/ci-centos-7-x86_64/Dockerfile +++ b/ci/images/ci-centos-7-x86_64/Dockerfile @@ -10,7 +10,7 @@ RUN yum -y install autoconf automake pkg-config RUN yum -y install libattr-devel libblkid-devel libuuid-devel RUN yum -y install e2fsprogs-libs e2fsprogs-devel reiserfs-utils RUN yum -y install zlib-devel lzo-devel libzstd-devel zstd-devel zstd -RUN yum -y install make gcc tar gzip clang +RUN yum -y install make gcc tar gzip clang dwarves RUN yum -y install python3 python3-devel python3-setuptools # For downloading fresh sources diff --git a/ci/images/ci-centos-8-x86_64/Dockerfile b/ci/images/ci-centos-8-x86_64/Dockerfile index edc9ed90..e8ef1c8b 100644 --- a/ci/images/ci-centos-8-x86_64/Dockerfile +++ b/ci/images/ci-centos-8-x86_64/Dockerfile @@ -13,7 +13,7 @@ RUN yum -y install autoconf automake pkg-config RUN yum -y install libattr-devel libblkid-devel libuuid-devel RUN yum -y install e2fsprogs-libs e2fsprogs-devel RUN yum -y install zlib-devel lzo-devel libzstd-devel zstd -RUN yum -y install make gcc tar gzip clang +RUN yum -y install make gcc tar gzip clang dwarves RUN yum -y install python3 python3-devel python3-setuptools # For downloading fresh sources diff --git a/ci/images/ci-musl-x86_64/Dockerfile b/ci/images/ci-musl-x86_64/Dockerfile index 16c1a123..43455365 100644 --- a/ci/images/ci-musl-x86_64/Dockerfile +++ b/ci/images/ci-musl-x86_64/Dockerfile @@ -7,7 +7,7 @@ RUN apk add linux-headers musl-dev util-linux-dev bash RUN apk add attr-dev acl-dev e2fsprogs-dev zlib-dev lzo-dev zstd-dev RUN apk add autoconf automake make gcc tar gzip clang RUN apk add python3 py3-setuptools python3-dev -RUN apk add libgcrypt-dev libsodium-dev libkcapi-dev +RUN apk add libgcrypt-dev libsodium-dev libkcapi-dev dwarves # For downloading fresh sources RUN apk add wget diff --git a/ci/images/ci-openSUSE-Leap-15.3-x86_64/Dockerfile b/ci/images/ci-openSUSE-Leap-15.3-x86_64/Dockerfile index 11cf0dde..aafd210a 100644 --- a/ci/images/ci-openSUSE-Leap-15.3-x86_64/Dockerfile +++ b/ci/images/ci-openSUSE-Leap-15.3-x86_64/Dockerfile @@ -8,7 +8,7 @@ RUN zypper install -y --no-recommends libext2fs-devel libreiserfscore-devel RUN zypper install -y --no-recommends zlib-devel lzo-devel libzstd-devel RUN zypper install -y --no-recommends make gcc tar gzip clang RUN zypper install -y --no-recommends python3 python3-devel python3-setuptools -RUN zypper install -y --no-recommends libudev-devel +RUN zypper install -y --no-recommends libudev-devel dwarves # For downloading fresh sources RUN zypper install -y --no-recommends wget diff --git a/ci/images/ci-openSUSE-Leap-15.4-x86_64/Dockerfile b/ci/images/ci-openSUSE-Leap-15.4-x86_64/Dockerfile index 0b0f584a..7d3c7a6d 100644 --- a/ci/images/ci-openSUSE-Leap-15.4-x86_64/Dockerfile +++ b/ci/images/ci-openSUSE-Leap-15.4-x86_64/Dockerfile @@ -8,7 +8,7 @@ RUN zypper install -y --no-recommends libext2fs-devel libreiserfscore-devel RUN zypper install -y --no-recommends zlib-devel lzo-devel libzstd-devel RUN zypper install -y --no-recommends make gcc tar gzip clang RUN zypper install -y --no-recommends python3 python3-devel python3-setuptools -RUN zypper install -y --no-recommends libudev-devel +RUN zypper install -y --no-recommends libudev-devel dwarves # For downloading fresh sources RUN zypper install -y --no-recommends wget diff --git a/ci/images/ci-openSUSE-tumbleweed-x86_64/Dockerfile b/ci/images/ci-openSUSE-tumbleweed-x86_64/Dockerfile index 6487957e..fe543314 100644 --- a/ci/images/ci-openSUSE-tumbleweed-x86_64/Dockerfile +++ b/ci/images/ci-openSUSE-tumbleweed-x86_64/Dockerfile @@ -9,7 +9,7 @@ RUN zypper install -y --no-recommends libext2fs-devel RUN zypper install -y --no-recommends zlib-devel lzo-devel libzstd-devel RUN zypper install -y --no-recommends autoconf automake pkg-config RUN zypper install -y --no-recommends python3 python3-devel python3-setuptools -RUN zypper install -y --no-recommends libudev-devel +RUN zypper install -y --no-recommends libudev-devel dwarves # For downloading fresh sources RUN zypper install -y --no-recommends wget From patchwork Wed Aug 23 14:32:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362649 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 B84F5EE49A3 for ; Wed, 23 Aug 2023 14:33:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236517AbjHWOdl (ORCPT ); Wed, 23 Aug 2023 10:33:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236510AbjHWOdl (ORCPT ); Wed, 23 Aug 2023 10:33:41 -0400 Received: from mail-yw1-x1130.google.com (mail-yw1-x1130.google.com [IPv6:2607:f8b0:4864:20::1130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F4EBE54 for ; Wed, 23 Aug 2023 07:33:39 -0700 (PDT) Received: by mail-yw1-x1130.google.com with SMTP id 00721157ae682-59209b12c50so38715437b3.0 for ; Wed, 23 Aug 2023 07:33:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801218; x=1693406018; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=3CVxHJH64G9pSVCR0UXaeIK4fHbECJBYN6AQ3B0iLlE=; b=gZ7Aknv0dnHYKRn1Ob1bdcF3glxXvn+K/P6yH/pWYDPQL2wGX3gw7PtH3C5S87x7da gWu/FhbWyvQ/S1AqJBlSEvbCSfvFacKPxVkBGWW57eDOytNjA3nBF7UTI6x3pCMu8VFj Gt3ix4oMvmd7IT3xu2UBtww/iFhrJEtZUHdL0s72DvT/1Ioy8TjB1LLjk7iqfvoLOwyF +pDXrrRQyJvfcTFi0dMZa1X9qRk9cyXqtCgksvna/N10aksXDGeu54K67u3uvqvh5yjU NV3xh3YBmlEArdDgC7Ln7F6mzsdhTG7frrxjXXTynN/YA5g8wPQzVNPeZSM/IQjb3fSt Bj+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801218; x=1693406018; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3CVxHJH64G9pSVCR0UXaeIK4fHbECJBYN6AQ3B0iLlE=; b=PkuEfBWb/PaAn1fhSgzXPKF59LuMn5SqSQltjXENmgE/+0XKG2nV/sI0X8ug7I8vet DHDuLLwBVEasX/0BAZOMlvaiYPCsdjdYw+oiYnB4uDHrDkQcuS2hHoztKgnS7gnBzk5m KwLsA4EsYHlI90nHxkY2C+b0rDI9LKfrwq/sPUdUOWH3s7Y/vraCLzKOU7f0RixVH9bp 7MNj1g43Eoog3D0o5RO5G7nUttzDr0Hc6sybHdt9akR56ptbpGD809itEQSaMtfIkGmh +r9jFxKsirlMBGM2Js5Z2S9KSgZbVFhUjr6ktuUwS0N4uQMf6TwL6j+/tcPJHjfE64ye n8rA== X-Gm-Message-State: AOJu0Yw3D1zv2UMYoe802dAN+voGgazo+pqskbk23ZKrjUdPjBLCyu8O L52SML7Z1jYx/g+gVPl3TKtd1xjjZZwytCnoiro= X-Google-Smtp-Source: AGHT+IERhZ55LDndzsXxNQeJTJXzoqjhnScpXwRbc7RB6QoF9sPVVvdlYquiPaX55QQFrKwJrl5IJA== X-Received: by 2002:a81:4783:0:b0:56d:2d82:63dc with SMTP id u125-20020a814783000000b0056d2d8263dcmr12203330ywa.10.1692801218436; Wed, 23 Aug 2023 07:33:38 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id t12-20020a81c24c000000b005925d7b62e0sm475532ywg.24.2023.08.23.07.33.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:38 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 25/38] btrfs-progs: add kerncompat helpers for ctree.c sync Date: Wed, 23 Aug 2023 10:32:51 -0400 Message-ID: <3de4bf57a30d11793cfd46f59d27f03233ff2451.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Here are the helpers and stubbed out functions to be able to sync in ctree.c into btrfs-progs. These are various utilities the kernel provides, 1 relocation and qgroup related function, and a trace point we have in ctree.c. Signed-off-by: Josef Bacik --- include/kerncompat.h | 76 ++++++++++++++++++++++++++++++++++++++++++++ kernel-lib/trace.h | 6 ++++ 2 files changed, 82 insertions(+) diff --git a/include/kerncompat.h b/include/kerncompat.h index 0f73efcd..4ba6b3dc 100644 --- a/include/kerncompat.h +++ b/include/kerncompat.h @@ -201,6 +201,10 @@ typedef struct spinlock_struct { unsigned long lock; } spinlock_t; +struct rw_semaphore { + long lock; +}; + #define mutex_init(m) \ do { \ (m)->lock = 1; \ @@ -243,6 +247,27 @@ static inline void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) spin_unlock(lock); } +static inline void init_rwsem(struct rw_semaphore *sem) +{ + sem->lock = 0; +} + +static inline bool down_read_trylock(struct rw_semaphore *sem) +{ + sem->lock++; + return true; +} + +static inline void down_read(struct rw_semaphore *sem) +{ + sem->lock++; +} + +static inline void up_read(struct rw_semaphore *sem) +{ + sem->lock--; +} + #define cond_resched() do { } while (0) #define preempt_enable() do { } while (0) #define preempt_disable() do { } while (0) @@ -400,6 +425,11 @@ static inline void *kmem_cache_alloc(struct kmem_cache *cache, gfp_t mask) return malloc(cache->size); } +static inline void *kmem_cache_zalloc(struct kmem_cache *cache, gfp_t mask) +{ + return calloc(1, cache->size); +} + static inline void kmem_cache_free(struct kmem_cache *cache, void *ptr) { free(ptr); @@ -704,6 +734,10 @@ static inline bool sb_rdonly(struct super_block *sb) #define unlikely(cond) (cond) +#define rcu_dereference(c) (c) + +#define rcu_assign_pointer(p, v) do { (p) = (v); } while (0) + static inline void atomic_set(atomic_t *a, int val) { *a = val; @@ -724,6 +758,15 @@ static inline void atomic_dec(atomic_t *a) (*a)--; } +static inline bool atomic_inc_not_zero(atomic_t *a) +{ + if (*a) { + atomic_inc(a); + return true; + } + return false; +} + static inline struct workqueue_struct *alloc_workqueue(const char *name, unsigned long flags, int max_active, ...) @@ -766,6 +809,10 @@ static inline void lockdep_set_class(spinlock_t *lock, struct lock_class_key *lc { } +static inline void lockdep_assert_held_read(struct rw_semaphore *sem) +{ +} + static inline bool cond_resched_lock(spinlock_t *lock) { return false; @@ -800,11 +847,26 @@ static inline void schedule(void) { } +static inline void rcu_read_lock(void) +{ +} + +static inline void rcu_read_unlock(void) +{ +} + +static inline void synchronize_rcu(void) +{ +} + /* * Temporary definitions while syncing. */ struct btrfs_inode; struct extent_state; +struct extent_buffer; +struct btrfs_root; +struct btrfs_trans_handle; static inline void btrfs_merge_delalloc_extent(struct btrfs_inode *inode, struct extent_state *state, @@ -830,4 +892,18 @@ static inline void btrfs_clear_delalloc_extent(struct btrfs_inode *inode, { } +static inline int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct extent_buffer *buf, + struct extent_buffer *cow) +{ + return 0; +} + +static inline void btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct extent_buffer *buf) +{ +} + #endif diff --git a/kernel-lib/trace.h b/kernel-lib/trace.h index 588429e0..2542f9ea 100644 --- a/kernel-lib/trace.h +++ b/kernel-lib/trace.h @@ -57,4 +57,10 @@ static inline void trace_btrfs_convert_extent_bit(struct extent_io_tree *tree, { } +static inline void trace_btrfs_cow_block(struct btrfs_root *root, + struct extent_buffer *buf, + struct extent_buffer *cow) +{ +} + #endif /* __PROGS_TRACE_H__ */ From patchwork Wed Aug 23 14:32:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362650 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 6F381EE49B0 for ; Wed, 23 Aug 2023 14:33:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236519AbjHWOdm (ORCPT ); Wed, 23 Aug 2023 10:33:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42294 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236516AbjHWOdl (ORCPT ); Wed, 23 Aug 2023 10:33:41 -0400 Received: from mail-yw1-x1134.google.com (mail-yw1-x1134.google.com [IPv6:2607:f8b0:4864:20::1134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61779E5F for ; Wed, 23 Aug 2023 07:33:40 -0700 (PDT) Received: by mail-yw1-x1134.google.com with SMTP id 00721157ae682-58ca499456dso61952717b3.1 for ; Wed, 23 Aug 2023 07:33:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801219; x=1693406019; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=qasZHistys+4vnRfwE5lfGydn7AMo6TWpiHN1XgEjVA=; b=oRJ1CjiPaViQdJ/1DIk3BZwylF5VPR37PeE9UTfWJiq3cprBbBeb9CsshmFUq4zLmy o4MU9BB0Mmh6tc0pb+JQ3pmXsEntiJwpySNDTGNiJFvhXtiQHiG/rN7frDrUkV4V4tjc 3dQixy1EvC/2SfemFwsgwq5CHlNPns17VmGdqf4Fcnz5Hh+xODAMZGY1wDv84gKmpJgX Sp8W6yDpjMDXtjr8EpBDfSHYZMPQL8KjmJL5DgojMlyl2G41Zf4SNhm2d1G3ZE586Erk Dze1BkaivcEc7PG0R71QGRWuoSFaLEB9NMPzJClicWqHVKwg8rWNfdJ8D09/+mYR1+vO zxSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801219; x=1693406019; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qasZHistys+4vnRfwE5lfGydn7AMo6TWpiHN1XgEjVA=; b=UnSAXHkLu+Kyr5EuBL2e9rL/2XtKcHAxpDfaO5jAvra8XbgyGq6qgmgduABzID4N6b SWy/Zh+Uly4Zvfps4JcPz69AD4tfHt3eugfOaqlMtaFCpwOK1naPlNI3iwa26or59KCU 2TWgoRwKH1r239gmSqW41G9IV9uxICJar0LO7QNYNKvbYVvn4tzdnJQ9T+6kX8WWwF+P UZC1tqnVQE8cFsbAgT147G3um58wq9Go8FuQYBxTPyT48rGDCdkCJow+IMLwPqNDo+lF XirUgDvatadkwuBETR/A8R3Vyzx+1zOwanCX8aqF1tb7t23s+OlGOd2yI9wX+F87CfJf st7w== X-Gm-Message-State: AOJu0YzqoH34DloOWHpOZPG1UZ9mEdnkyzRIFzYtwFobSxHu31P8+9Cq dc2TWx5sqUo9rqKiobZkIncYojvrtvUcAwoz4jU= X-Google-Smtp-Source: AGHT+IELKhJyWWD7d/dRx3xrrQo1rd6FhxfFagKNQMRtGLRglOxD80ju/ysfNN42yA9UFxQTGBewdQ== X-Received: by 2002:a81:6055:0:b0:57a:5099:2217 with SMTP id u82-20020a816055000000b0057a50992217mr13156814ywb.18.1692801219528; Wed, 23 Aug 2023 07:33:39 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id w6-20020a814906000000b005773afca47bsm3374475ywa.27.2023.08.23.07.33.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:39 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 26/38] btrfs-progs: add trans_lock to fs_info Date: Wed, 23 Aug 2023 10:32:52 -0400 Message-ID: <99c37d184d3095659df91da2df5ef7ebdae70080.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This exists in the kernel, and is touched by ctree.c, add it to the btrfs_fs_info to make sync'ing ctree.c more straightforward. Signed-off-by: Josef Bacik --- kernel-shared/ctree.h | 2 ++ kernel-shared/disk-io.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 0b440b1a..6ceae3e9 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -324,6 +324,8 @@ struct btrfs_fs_info { struct extent_io_tree extent_ins; struct extent_io_tree *excluded_extents; + spinlock_t trans_lock; + struct rb_root block_group_cache_tree; /* logical->physical extent mapping */ struct btrfs_mapping_tree mapping_tree; diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c index 286eb9cb..4f87b6fb 100644 --- a/kernel-shared/disk-io.c +++ b/kernel-shared/disk-io.c @@ -870,6 +870,8 @@ struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr) INIT_LIST_HEAD(&fs_info->space_info); INIT_LIST_HEAD(&fs_info->recow_ebs); + spin_lock_init(&fs_info->trans_lock); + if (!writable) fs_info->readonly = 1; From patchwork Wed Aug 23 14:32:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362651 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 8A98EEE49A0 for ; Wed, 23 Aug 2023 14:33:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236520AbjHWOdn (ORCPT ); Wed, 23 Aug 2023 10:33:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42322 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236516AbjHWOdn (ORCPT ); Wed, 23 Aug 2023 10:33:43 -0400 Received: from mail-yb1-xb2c.google.com (mail-yb1-xb2c.google.com [IPv6:2607:f8b0:4864:20::b2c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 71ED5E5F for ; Wed, 23 Aug 2023 07:33:41 -0700 (PDT) Received: by mail-yb1-xb2c.google.com with SMTP id 3f1490d57ef6-d7225259f52so5632873276.0 for ; Wed, 23 Aug 2023 07:33:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801220; x=1693406020; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=KBf1nGxn9VxkTM3VNbcdt8zSGbcHJ2jgNvEYTlFSjtM=; b=wa7Fw8aSzrgGQOXy1gQVcpbZtnr3VP3x5aHkJ61cIBOwUJhUTLWmtos/JvsXnpmQqr EvyTuza8MU2YZqPv2r0qGyFPpFlQeUlFTXwkUZtVe+OAotbnzPaK/DQLZEtf9GJybqk8 8ju38DCDrwSIY7pWkVXI2rxYX0vR/EMfExiZ9SNt9MS+Xvj9aGzziHK13XPjDwqZ9cvN pmB2l78CzjJQ0XJF433UDRG/rfCRmAqW/W3Or1bs4PjNnM8K3mKHbwPI6UfQjfnkTzTJ daIABTZET8jMmKkv/jq9JB5JEK8b4mk0ooaF8QgPFuGoM7DHoG8Ws/Z18dsX4iqI8Vep 9drA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801220; x=1693406020; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KBf1nGxn9VxkTM3VNbcdt8zSGbcHJ2jgNvEYTlFSjtM=; b=B+Erkw/p/BaAIv70eJY1Vv4T1SEGdBvF2wongGYz5N74WInyYcohdFcoIx9hWRo1el DwV9BWy6R+2hR56QymY0dQ3qBW4SedhsOvQluHSq0D51bE4xKZoAg2NFZkZ9vFAhKBZR X9l6VACJ7VZ/G5UNeuMXju4cF/cjd2Y78TNtW7tRCqBCSYegsTBM75gRtVh8g/YAZICJ PEg/5nj/UnubC97dddrydfqN7HNV00g6L1/aQli+eq3bZyQ5Zje2NM//hr0pWkTZwgD4 mulXHwrx+GXyXBgVttwxkigRKUYuis9WLDwczdE1K53uRbeC3JbCAqytZgne8twRqjXC waRg== X-Gm-Message-State: AOJu0Yxer82i2dD0wFa7yP679KHwBMy8WuhNusdCdWfa8S1UhkrE6zRN CW5z2jgzgDj1RrTxFVaph9UHizJBbSvJPQUSWGs= X-Google-Smtp-Source: AGHT+IHjUcs4ooo10HL86bg7P2LytYH40a6oXD2Vbxb3JVAsSOhAlaL81vp6VZOcJF5N8UIP30cGNA== X-Received: by 2002:a25:b208:0:b0:d49:4869:1bd1 with SMTP id i8-20020a25b208000000b00d4948691bd1mr11276442ybj.6.1692801220616; Wed, 23 Aug 2023 07:33:40 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id 203-20020a2501d4000000b00d4fc4132653sm2852195ybb.11.2023.08.23.07.33.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:40 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 27/38] btrfs-progs: add commit_root_sem to btrfs_fs_info Date: Wed, 23 Aug 2023 10:32:53 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This is used in ctree.c around getting the old root, add this to our btrfs_fs_info to make it more straightforward to sync ctree.c into btrfs-progs. Signed-off-by: Josef Bacik --- kernel-shared/ctree.h | 1 + kernel-shared/disk-io.c | 1 + 2 files changed, 2 insertions(+) diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 6ceae3e9..2f6a0cab 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -325,6 +325,7 @@ struct btrfs_fs_info { struct extent_io_tree *excluded_extents; spinlock_t trans_lock; + struct rw_semaphore commit_root_sem; struct rb_root block_group_cache_tree; /* logical->physical extent mapping */ diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c index 4f87b6fb..092b54af 100644 --- a/kernel-shared/disk-io.c +++ b/kernel-shared/disk-io.c @@ -871,6 +871,7 @@ struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr) INIT_LIST_HEAD(&fs_info->recow_ebs); spin_lock_init(&fs_info->trans_lock); + init_rwsem(&fs_info->commit_root_sem); if (!writable) fs_info->readonly = 1; From patchwork Wed Aug 23 14:32:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362652 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 A0463EE49A3 for ; Wed, 23 Aug 2023 14:33:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236523AbjHWOdo (ORCPT ); Wed, 23 Aug 2023 10:33:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42346 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236516AbjHWOdo (ORCPT ); Wed, 23 Aug 2023 10:33:44 -0400 Received: from mail-yw1-x1133.google.com (mail-yw1-x1133.google.com [IPv6:2607:f8b0:4864:20::1133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A8CEDE54 for ; Wed, 23 Aug 2023 07:33:42 -0700 (PDT) Received: by mail-yw1-x1133.google.com with SMTP id 00721157ae682-59209b12c50so38716057b3.0 for ; Wed, 23 Aug 2023 07:33:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801221; x=1693406021; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=1VZ0u/h3MaEVNSrqFw3lZ2LvelYuaUdBTBHZTg32hUU=; b=HVjJGI0eXjzE1qY74e8PM7ecoQjlmJytpyG5iAwB4F0/HcarvZBMmkWZ8ch+cihT/u 1J9wcwSFW27Z1u7+fWEDbjLU3enQ6y9qsokDgYdZK5nOvsl0Kiz5ZBCeAzOWKJIv84B3 eQl2SpPcjWAFy7UQQTDUT9Zmd0akb2sBHxzS/PYGhptRS7ZkyGAPEn6TqhQAFby7gwBh iBA+kO5Lq+TYsfHIcioWHGEH8lMEzLullRSI6e2n+/2FJnLxMpv/LVPOMay/RS75e+gd GHxvrSu8xNWgtZ1lMpbgLaVKnUp6z51RSuwe14SlRIOiAD+BwuIv/mi//YONrfAkFcru Axtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801222; x=1693406022; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1VZ0u/h3MaEVNSrqFw3lZ2LvelYuaUdBTBHZTg32hUU=; b=Q4/JtXOIDwHoh7WyFIk/A3LeMoAPad3D3NUF1OxC+IR2Et7QRNoKHuV2QaXjxRFVXC 3sTtR6gQ3eG4UNHcz6EHJ2uOmfls08srABb+5hRRh6loYDk6pNJHA1+78TICr++Xxd/7 wUYsVlyrMGWyyLg40SivihTyXsF6jTkos8cc62iWc+wE6B2X7UPdXZSJ/0E5IkXPIv8x TPWe2fLIUyUtG7hgD8B2CSWWnl9ApcBohZ7llGdPVjnDFtj1+s9lLKiDtXipgYj2vvQh en8vLlIXSk8QPO3faae18xh8KTs5qHYU9lqw2sKQAgSeI3Vgf8XMOzfwFa6PZfJFJlIV i1Eg== X-Gm-Message-State: AOJu0YwEm0FPbDHRa0W90mfned+LQInTSSV/sHujSJLFATMgO8uQv7Uj +bXM0MM9CoABWQXut4ymA9xA3XUYMrQ5O2HUoZM= X-Google-Smtp-Source: AGHT+IF4NDC1TbLkP7BoRWuOJCKyE6+OEiIO6bhCVy55ughlGZKsPkTWL5ueZIjaP4mdsfs4WYlJKg== X-Received: by 2002:a81:4e11:0:b0:561:429e:acd2 with SMTP id c17-20020a814e11000000b00561429eacd2mr12446383ywb.35.1692801221730; Wed, 23 Aug 2023 07:33:41 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id j80-20020a819253000000b005845e6f9b50sm3370069ywg.113.2023.08.23.07.33.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:41 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 28/38] btrfs-progs: update btrfs_cow_block to match the in-kernel definition Date: Wed, 23 Aug 2023 10:32:54 -0400 Message-ID: <282e8789254caaed291d825616d0c1d3fe203e3e.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org btrfs_cow_block takes the lockdep nesting enum in the kernel. Update the definition to match the kernel version to make sync'ing ctree.c into btrfs-progs more straightforward. Signed-off-by: Josef Bacik --- kernel-shared/ctree.c | 24 +++++++++++++++--------- kernel-shared/ctree.h | 3 ++- kernel-shared/transaction.c | 3 ++- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index e3b29a3a..13f8a437 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -557,7 +557,8 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans, int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, struct extent_buffer *parent, int parent_slot, - struct extent_buffer **cow_ret) + struct extent_buffer **cow_ret, + enum btrfs_lock_nesting nest) { u64 search_start; int ret; @@ -788,7 +789,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, /* promote the child to a root */ child = btrfs_read_node_slot(mid, 0); BUG_ON(!extent_buffer_uptodate(child)); - ret = btrfs_cow_block(trans, root, child, mid, 0, &child); + ret = btrfs_cow_block(trans, root, child, mid, 0, &child, + BTRFS_NESTING_NORMAL); BUG_ON(ret); root->node = child; @@ -813,7 +815,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, left = btrfs_read_node_slot(parent, pslot - 1); if (extent_buffer_uptodate(left)) { wret = btrfs_cow_block(trans, root, left, - parent, pslot - 1, &left); + parent, pslot - 1, &left, + BTRFS_NESTING_NORMAL); if (wret) { ret = wret; goto enospc; @@ -822,7 +825,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, right = btrfs_read_node_slot(parent, pslot + 1); if (extent_buffer_uptodate(right)) { wret = btrfs_cow_block(trans, root, right, - parent, pslot + 1, &right); + parent, pslot + 1, &right, + BTRFS_NESTING_NORMAL); if (wret) { ret = wret; goto enospc; @@ -980,7 +984,8 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, wret = 1; } else { ret = btrfs_cow_block(trans, root, left, parent, - pslot - 1, &left); + pslot - 1, &left, + BTRFS_NESTING_NORMAL); if (ret) wret = 1; else { @@ -1023,7 +1028,7 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, } else { ret = btrfs_cow_block(trans, root, right, parent, pslot + 1, - &right); + &right, BTRFS_NESTING_NORMAL); if (ret) wret = 1; else { @@ -1213,7 +1218,7 @@ again: wret = btrfs_cow_block(trans, root, b, p->nodes[level + 1], p->slots[level + 1], - &b); + &b, BTRFS_NESTING_NORMAL); if (wret) { free_extent_buffer(b); return wret; @@ -1822,7 +1827,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root /* cow and double check */ ret = btrfs_cow_block(trans, root, right, upper, - slot + 1, &right); + slot + 1, &right, BTRFS_NESTING_NORMAL); if (ret) { free_extent_buffer(right); return 1; @@ -1968,7 +1973,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root /* cow and double check */ ret = btrfs_cow_block(trans, root, left, - path->nodes[1], slot - 1, &left); + path->nodes[1], slot - 1, &left, + BTRFS_NESTING_NORMAL); if (ret) { /* we hit -ENOSPC, but it isn't fatal here */ free_extent_buffer(left); diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 2f6a0cab..07a5992c 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -957,7 +957,8 @@ int btrfs_previous_extent_item(struct btrfs_root *root, int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, struct extent_buffer *parent, int parent_slot, - struct extent_buffer **cow_ret); + struct extent_buffer **cow_ret, + enum btrfs_lock_nesting nest); int btrfs_copy_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, diff --git a/kernel-shared/transaction.c b/kernel-shared/transaction.c index 87d86fcd..48947d10 100644 --- a/kernel-shared/transaction.c +++ b/kernel-shared/transaction.c @@ -100,7 +100,8 @@ int commit_tree_roots(struct btrfs_trans_handle *trans, eb = fs_info->tree_root->node; extent_buffer_get(eb); - ret = btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, 0, &eb); + ret = btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, 0, &eb, + BTRFS_NESTING_NORMAL); free_extent_buffer(eb); if (ret) return ret; From patchwork Wed Aug 23 14:32:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362653 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 34F8FEE49A0 for ; Wed, 23 Aug 2023 14:33:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236526AbjHWOdq (ORCPT ); Wed, 23 Aug 2023 10:33:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42360 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236516AbjHWOdp (ORCPT ); Wed, 23 Aug 2023 10:33:45 -0400 Received: from mail-yw1-x112d.google.com (mail-yw1-x112d.google.com [IPv6:2607:f8b0:4864:20::112d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B604EE54 for ; Wed, 23 Aug 2023 07:33:43 -0700 (PDT) Received: by mail-yw1-x112d.google.com with SMTP id 00721157ae682-58d31f142eeso60776487b3.0 for ; Wed, 23 Aug 2023 07:33:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801223; x=1693406023; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=CiUcmOreLVu8AWBRtee+YCkD4MmXgQZd0jqvEJH/atM=; b=1J04DnguzKXcJsQZtHQZIpxRodPzoZxAW+FNDREmsnO4mAyak63nKfgMxAKYaLSusT EmJyKUibn9AFFA7VkusvgZ3hRoJfio/qt7e1xn2hkPfMGZgoR9Gxi7T16wbNaokanBgF Tn4bYkWbQkJLqT/fG04JnfX+HFOmvCxBKuOzrsm8NYL74TWfeX1ElmumV5ocYoMaogTM cSKKcX3Ib2FKbc7EBaozwcz9P9RASCkRCuHYtJLknQn4GOVDUYh/yvb55C/6AKetT1tJ jl5oPI1OuGifSosNI2JvCNzUgZPJiD841oHNOz2FEZNeYZH5jgLy+GsVpqvZxViJebQk EFcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801223; x=1693406023; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CiUcmOreLVu8AWBRtee+YCkD4MmXgQZd0jqvEJH/atM=; b=d+ou/Pc3zIlU2H53tb+K3DT6yfuJowmxpW81ZqlOMlZ1JfVz2Jh26MOPEpzxhueTPF Gxw3KpHoxX/J5JOCVxqtC5vqC4R1Gc60Lh3M9SGWGd10AsHPEJQcIiRMrxTE7z394IUP lo02WdV5h9XaRAMh9ieRCSrROu1PQpvnRn+SkPUQpn+ccIZqn/CeAlzwBaK186CPcFQ2 dHSDRfVG14FQDXAaEoR49SAjWiNXJCMBYO4QZ4FqLsNsZ+ZFPE5m80iazTth9XAe90xq u3gCWLEohMp5BvTh+MEwAwC6soKLoncSYe/V8vEznxX1nhLhB1nDt9a6agYsbduWv4SV dSPA== X-Gm-Message-State: AOJu0YwCMjL+bwkXm7VRe680x3Gt2YebaQG/DL1nI1Z4YDuzK0i77UlG iSlWPNBbS2iTPia6nzYoUG8c3i6V6Os3KlbvFnI= X-Google-Smtp-Source: AGHT+IEbdcY+cgk4AG5iYDc0EwUjXBCq7fcYfyR/hMrrQ+cZf/EFQTzTwEY7NRheE9PwMcfJ28+s3A== X-Received: by 2002:a0d:d68c:0:b0:565:cf47:7331 with SMTP id y134-20020a0dd68c000000b00565cf477331mr14976393ywd.2.1692801222818; Wed, 23 Aug 2023 07:33:42 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id p5-20020a0dcd05000000b00589a1dc0809sm3370006ywd.120.2023.08.23.07.33.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:42 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 29/38] btrfs-progs: update btrfs_insert_empty_items to match the kernel Date: Wed, 23 Aug 2023 10:32:55 -0400 Message-ID: <2181de3ff24d50339f61f74bf57798147b2893c4.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org In the kernel we have a control struct called btrfs_item_batch that encodes all of the information for bulk inserting a bunch of items. Update btrfs_insert_empty_times to match the in-kernel implementation to make sync'ing ctree.c more straightforward. Signed-off-by: Josef Bacik --- kernel-shared/ctree.c | 36 +++++++++++++++++------------------- kernel-shared/ctree.h | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 21 deletions(-) diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 13f8a437..c3b86e2e 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -2576,8 +2576,7 @@ void btrfs_extend_item(struct btrfs_path *path, u32 data_size) int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_key *cpu_key, u32 *data_size, - int nr) + const struct btrfs_item_batch *batch) { struct extent_buffer *leaf; int ret = 0; @@ -2585,20 +2584,16 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, int i; u32 nritems; u32 total_size = 0; - u32 total_data = 0; unsigned int data_end; struct btrfs_disk_key disk_key; - for (i = 0; i < nr; i++) { - total_data += data_size[i]; - } - /* create a root if there isn't one */ if (!root->node) BUG(); - total_size = total_data + nr * sizeof(struct btrfs_item); - ret = btrfs_search_slot(trans, root, cpu_key, path, total_size, 1); + total_size = batch->total_data_size + + (batch->nr * sizeof(struct btrfs_item)); + ret = btrfs_search_slot(trans, root, &batch->keys[0], path, total_size, 1); if (ret == 0) { return -EEXIST; } @@ -2637,35 +2632,38 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, u32 ioff; ioff = btrfs_item_offset(leaf, i); - btrfs_set_item_offset(leaf, i, ioff - total_data); + btrfs_set_item_offset(leaf, i, + ioff - batch->total_data_size); } /* shift the items */ - memmove_extent_buffer(leaf, btrfs_item_nr_offset(leaf, slot + nr), + memmove_extent_buffer(leaf, + btrfs_item_nr_offset(leaf, slot + batch->nr), btrfs_item_nr_offset(leaf, slot), (nritems - slot) * sizeof(struct btrfs_item)); /* shift the data */ memmove_extent_buffer(leaf, btrfs_item_nr_offset(leaf, 0) + - data_end - total_data, btrfs_item_nr_offset(leaf, 0) + + data_end - batch->total_data_size, + btrfs_item_nr_offset(leaf, 0) + data_end, old_data - data_end); data_end = old_data; } /* setup the item for the new data */ - for (i = 0; i < nr; i++) { - btrfs_cpu_key_to_disk(&disk_key, cpu_key + i); + for (i = 0; i < batch->nr; i++) { + btrfs_cpu_key_to_disk(&disk_key, &batch->keys[i]); btrfs_set_item_key(leaf, &disk_key, slot + i); - btrfs_set_item_offset(leaf, slot + i, data_end - data_size[i]); - data_end -= data_size[i]; - btrfs_set_item_size(leaf, slot + i, data_size[i]); + data_end -= batch->data_sizes[i]; + btrfs_set_item_offset(leaf, slot + i, data_end); + btrfs_set_item_size(leaf, slot + i, batch->data_sizes[i]); } - btrfs_set_header_nritems(leaf, nritems + nr); + btrfs_set_header_nritems(leaf, nritems + batch->nr); btrfs_mark_buffer_dirty(leaf); ret = 0; if (slot == 0) { - btrfs_cpu_key_to_disk(&disk_key, cpu_key); + btrfs_cpu_key_to_disk(&disk_key, &batch->keys[0]); fixup_low_keys(path, &disk_key, 1); } diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 07a5992c..d2b1b421 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -995,12 +995,38 @@ static inline int btrfs_del_item(struct btrfs_trans_handle *trans, return btrfs_del_items(trans, root, path, path->slots[0], 1); } +/* + * Describes a batch of items to insert in a btree. This is used by + * btrfs_insert_empty_items(). + */ +struct btrfs_item_batch { + /* + * Pointer to an array containing the keys of the items to insert (in + * sorted order). + */ + const struct btrfs_key *keys; + /* Pointer to an array containing the data size for each item to insert. */ + const u32 *data_sizes; + /* + * The sum of data sizes for all items. The caller can compute this while + * setting up the data_sizes array, so it ends up being more efficient + * than having btrfs_insert_empty_items() or setup_item_for_insert() + * doing it, as it would avoid an extra loop over a potentially large + * array, and in the case of setup_item_for_insert(), we would be doing + * it while holding a write lock on a leaf and often on upper level nodes + * too, unnecessarily increasing the size of a critical section. + */ + u32 total_data_size; + /* Size of the keys and data_sizes arrays (number of items in the batch). */ + int nr; +}; + int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key, void *data, u32 data_size); int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_key *cpu_key, u32 *data_size, int nr); + const struct btrfs_item_batch *batch); static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, @@ -1008,7 +1034,14 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_key *key, u32 data_size) { - return btrfs_insert_empty_items(trans, root, path, key, &data_size, 1); + struct btrfs_item_batch batch; + + batch.keys = key; + batch.data_sizes = &data_size; + batch.total_data_size = data_size; + batch.nr = 1; + + return btrfs_insert_empty_items(trans, root, path, &batch); } int btrfs_next_sibling_tree_block(struct btrfs_fs_info *fs_info, From patchwork Wed Aug 23 14:32:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362654 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 96290EE49B0 for ; Wed, 23 Aug 2023 14:33:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236527AbjHWOdr (ORCPT ); Wed, 23 Aug 2023 10:33:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236524AbjHWOdq (ORCPT ); Wed, 23 Aug 2023 10:33:46 -0400 Received: from mail-yb1-xb32.google.com (mail-yb1-xb32.google.com [IPv6:2607:f8b0:4864:20::b32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E36AEE67 for ; Wed, 23 Aug 2023 07:33:44 -0700 (PDT) Received: by mail-yb1-xb32.google.com with SMTP id 3f1490d57ef6-d743f58050bso4963254276.1 for ; Wed, 23 Aug 2023 07:33:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801224; x=1693406024; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Otnudf0yJk+9JqRUuetbj+rdG8mdGfYos/arTvq87o0=; b=02Dr0YiCuLRQpcaAkpT6MKsnulK0IpVlPApE3YjPr850zzMFtPqGYT690xnruxocUF SZCfV+91xNMeGBrXYybWy+Kx623MqTlnwGEPjvMPYTlbxZ/jgwEW/F1kbANTTOmz7JEM EdC5aYUMrcIG/spH6NLhLa+EAip6BMzypvnXJ4TVxIqcwUo8Kfz1hEVCBkXGhS9NS/hv sXtBG6RxVnHGzF9iwA2RdnbbZVURVA/ppSHdjxKYNclC+fCZ8MyttdQH1C92ek2Zxo9v YLsTe7ctWNaTdpaMngfHQA6koPBLpP0Lg/TJ0xaFjsPI0PO7qMFJrgbyBgUVkuFkDoEu +FXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801224; x=1693406024; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Otnudf0yJk+9JqRUuetbj+rdG8mdGfYos/arTvq87o0=; b=D3SDZlfmE0l/ZztLBwRiGsy0skTrBcTL98XS9N4ny7dHEUfHL6bjKcuIBlweJdVVnF +oGI7skWGseWz1oBBHYzXj2hVH5iBpUHvzZmuiCU//NbgxLrIunzhvw4LfYzTw5fwKqL 0HqyP8NZZJAw8MuBeiBh7KZe9n1eenI05DUOh22uZkDX97AWDqm0mRLvWbTPfvsqB6gb KDVrKWznt4JDkSYCSIai2sBu8YjiM7qj0JZiiDvZ6MBIo78+TXiMAj9c4BWPThYsEIvm uiGCW7/kXpUIfx2G2L/DPKqvS8SCsqp9iKeG1XW5mSjjF5z3lOyOsETrUv8N3WbLhhzs WMHw== X-Gm-Message-State: AOJu0YyENFWNX5wNpYGYFycWEo4a6SYQd1qtQK9ceHTcO5ocebzD/wiU NI3IwA/GodcP+ksDSXJvp4Codu83I9+tY1JB54U= X-Google-Smtp-Source: AGHT+IGG17XTvxVDnDNW2RnMu5NiTEVU0iQXzMaktnWndiez69akhpPU2F64vLn8ACSubpjzkoJ2Ww== X-Received: by 2002:a25:cb92:0:b0:d4c:f456:d55b with SMTP id b140-20020a25cb92000000b00d4cf456d55bmr13903369ybg.31.1692801224087; Wed, 23 Aug 2023 07:33:44 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id 64-20020a251443000000b00d74c9618c6fsm1463381ybu.1.2023.08.23.07.33.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:43 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 30/38] btrfs-progs: update btrfs_insert_empty_item to match the kernel Date: Wed, 23 Aug 2023 10:32:56 -0400 Message-ID: <7e405edf2190e6d6cb4af35ca19d734a0fe79123.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org In the kernel the key for btrfs_insert_empty_item is a const, update the helper to match the in-kernel version. Signed-off-by: Josef Bacik --- kernel-shared/ctree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index d2b1b421..ce2122d7 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -1031,7 +1031,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_key *key, + const struct btrfs_key *key, u32 data_size) { struct btrfs_item_batch batch; From patchwork Wed Aug 23 14:32:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362655 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 61F59EE49B2 for ; Wed, 23 Aug 2023 14:33:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236531AbjHWOds (ORCPT ); Wed, 23 Aug 2023 10:33:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42380 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232836AbjHWOds (ORCPT ); Wed, 23 Aug 2023 10:33:48 -0400 Received: from mail-yw1-x1134.google.com (mail-yw1-x1134.google.com [IPv6:2607:f8b0:4864:20::1134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2993CE6C for ; Wed, 23 Aug 2023 07:33:46 -0700 (PDT) Received: by mail-yw1-x1134.google.com with SMTP id 00721157ae682-5922b96c5fcso30193117b3.0 for ; Wed, 23 Aug 2023 07:33:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801225; x=1693406025; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=gj6qbpzq+O76NzAkrP/HnYs6Gn+voslRowEty2olNHY=; b=4XzZDGPO6H7zTlz/lgICmk3k7NHPSSxaNTkLmnleeOz9A2BIUg4Yl5VD6YSMIEO4TQ WI/UHu4nmxmLnAB1BTG3heFZRWIVSaZLbpePOlNcl+S+ZX1ckMbZrEDT8tqGFiPFoKI4 Q4ZhE4Hid6Qg0FiizKx65UKUOFedfFv1/QoRUx0BPf34N0Rr18X0BTqfW3RzFW81dNK6 DVKXrXxizRoAQ20f+nw0PbjGuUkQ1sr/jMF2SvCiVTIime/zxYj2HQMLqZUUfyj2cgoD yptU2qxLjiS10kqvylS/6uzN6N7hHsQ7aI9mJfvFmlQAwTIBsA+Q7hNFWOdZE/5xZ472 82Mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801225; x=1693406025; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gj6qbpzq+O76NzAkrP/HnYs6Gn+voslRowEty2olNHY=; b=D21tnvyqm7PU2vUU5iTc+7LopgHMENW+WEKvVJZtJ9s7JmDsB9TAKaiISzIV561ixt LZsTuBwbwqeXxenUGVoYGFmMZJXX42vHElTk23KQtMAuljo4IbIrIC0z+lTsKMmgwWYv ExfuUgVWWE9rJMKmcr5+T2sa+ykW5BGQmsgZ058tn9gz4np3Cl7ncBC2VhaDSBZzR9GM jFchOgDlXRcXHUHidC+kxewwKMMDPLuadazKowuHL3j5XBktm3M4FFFEPGg3Tk6AjyGw vWAO0JL31FerXPF6UbCB/62Uli5a1ocxd98n3qj4F7Gxpp05rBDIWNh4WfhwC/RH6B1g /Ccg== X-Gm-Message-State: AOJu0YzuLFRsE2xT77DDMiwrWkxb5ND/A4K1dHURjLzKA1Sge+GiSs0D MTXnwIbTb+ugWE5iDBSdxhTNG2b2ifpgZhMI0yQ= X-Google-Smtp-Source: AGHT+IFgK7sRAur8ll6XmKxKaPP19vCGNezhQPjNLwqDyD+tcFZ776eTPl1/xTINsFCVKwU0OUEBwA== X-Received: by 2002:a81:9144:0:b0:584:4b5f:bac3 with SMTP id i65-20020a819144000000b005844b5fbac3mr13163968ywg.15.1692801225276; Wed, 23 Aug 2023 07:33:45 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id c13-20020a814e0d000000b0058c668e46cbsm3299690ywb.46.2023.08.23.07.33.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:45 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 31/38] btrfs-progs: update btrfs_del_ptr to match the kernel Date: Wed, 23 Aug 2023 10:32:57 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org The kernel version of btrfs_del_ptr takes a trans handle as an argument and returns an error in the case of tree-mod-log, update our version to match to make syncing ctree.c more straightforward. Signed-off-by: Josef Bacik --- check/main.c | 4 ++-- kernel-shared/ctree.c | 12 +++++++----- kernel-shared/ctree.h | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/check/main.c b/check/main.c index 08c49f7a..04c965ab 100644 --- a/check/main.c +++ b/check/main.c @@ -3569,7 +3569,7 @@ static int repair_btree(struct btrfs_root *root, path.slots[level]); /* Remove the ptr */ - btrfs_del_ptr(root, &path, level, path.slots[level]); + btrfs_del_ptr(trans, root, &path, level, path.slots[level]); /* * Remove the corresponding extent @@ -7828,7 +7828,7 @@ again: del_ptr: printk("deleting pointer to block %llu\n", corrupt->cache.start); - btrfs_del_ptr(extent_root, &path, level, slot); + btrfs_del_ptr(trans, extent_root, &path, level, slot); out: btrfs_release_path(&path); diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index c3b86e2e..47938f01 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -855,7 +855,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, btrfs_clear_buffer_dirty(trans, right); free_extent_buffer(right); right = NULL; - btrfs_del_ptr(root, path, level + 1, pslot + 1); + btrfs_del_ptr(trans, root, path, level + 1, pslot + 1); root_sub_used(root, blocksize); wret = btrfs_free_extent(trans, bytenr, blocksize, 0, @@ -900,7 +900,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, btrfs_clear_buffer_dirty(trans, mid); free_extent_buffer(mid); mid = NULL; - btrfs_del_ptr(root, path, level + 1, pslot); + btrfs_del_ptr(trans, root, path, level + 1, pslot); root_sub_used(root, blocksize); wret = btrfs_free_extent(trans, bytenr, blocksize, 0, @@ -2711,8 +2711,8 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root * continuing all the way the root if required. The root is converted into * a leaf if all the nodes are emptied. */ -void btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, - int level, int slot) +int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_path *path, int level, int slot) { struct extent_buffer *parent = path->nodes[level]; u32 nritems; @@ -2739,6 +2739,8 @@ void btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, fixup_low_keys(path, &disk_key, level + 1); } btrfs_mark_buffer_dirty(parent); + + return 0; } /* @@ -2759,7 +2761,7 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, int ret; WARN_ON(btrfs_header_generation(leaf) != trans->transid); - btrfs_del_ptr(root, path, 1, path->slots[1]); + btrfs_del_ptr(trans, root, path, 1, path->slots[1]); root_sub_used(root, leaf->len); diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index ce2122d7..d15c16c0 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -945,8 +945,8 @@ int btrfs_convert_one_bg(struct btrfs_trans_handle *trans, u64 bytenr); /* ctree.c */ int btrfs_comp_cpu_keys(const struct btrfs_key *k1, const struct btrfs_key *k2); -void btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, - int level, int slot); +int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_path *path, int level, int slot); struct extent_buffer *btrfs_read_node_slot(struct extent_buffer *parent, int slot); int btrfs_previous_item(struct btrfs_root *root, From patchwork Wed Aug 23 14:32:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362656 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 1F097EE49A0 for ; Wed, 23 Aug 2023 14:33:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236528AbjHWOdt (ORCPT ); Wed, 23 Aug 2023 10:33:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42406 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236524AbjHWOds (ORCPT ); Wed, 23 Aug 2023 10:33:48 -0400 Received: from mail-yw1-x1131.google.com (mail-yw1-x1131.google.com [IPv6:2607:f8b0:4864:20::1131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 51AEDE69 for ; Wed, 23 Aug 2023 07:33:47 -0700 (PDT) Received: by mail-yw1-x1131.google.com with SMTP id 00721157ae682-58d70c441d5so61850977b3.2 for ; Wed, 23 Aug 2023 07:33:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801226; x=1693406026; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=EjQZ/h9RD+k6uqUrhH4ybvt1cO8w26OLPFQJOJw2Ens=; b=U6f98Ce2m8ruHvgNE+dNHfInG8IhvljjS34sPp6b4Cr2XXnNj2VjmtUDipSTzVAIsD 5TuynpOJaSgAWAR0d9V0IToH5oZG54DDicIPhdlaaxcTLbvMt4CXqQ9IaRjfnTL4bzll 1AC5SotC8KQsa0Wt1axNPMSosPFBO7/x2/m0Fv5rduf/RYYaTiqSFGiqJNnELYL5cpxw E2RHneLp/wwT4CIHrO8H3TNv03nGa4LarpiGR3VOVjIPiqOlKucAsQr9MRHFpl46tT4A wVLUsWy3v26f4tKsYcDFTVVzQd/7MO3sdueOlYNSRd/353RKL0QwSTRu7o2e3Ghh0w5a OW7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801226; x=1693406026; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EjQZ/h9RD+k6uqUrhH4ybvt1cO8w26OLPFQJOJw2Ens=; b=BnnCp129ySf/4Zyby6RYqiM03NZD9iCFM6StwWQPSiDQ1PMe/A/IywrTlIlkEdtq8n YweX5vVWZ1TWXWWIo+DZyG5+zDRrglgMY/CYZfycvir8BiObthKzG+Y8DvgSEJvC9GpW AjW7tvMPM7bjgJO3CKujsBC19DT10aMiFdP9VIqmXV1cNN8kgwBac/mrgO3R4vM1Q6LF PMUv1XIbnLzsdF3lvEjkYY0b4dPaN026OwoZXT64Rwra7UE8siPMpg8+g/ujuf/0mNnJ 3yLSBwwsJKLIRN+8VppVaq3fEtME+DnGsPdtyHncgHudPhHKGa1Cz0EC7CPOmJgI6Wvf kGrg== X-Gm-Message-State: AOJu0Yx/+sDh/q3agwqvgeUXGA8yclBJlo6Axulzq80KWz7yZIO3pMTJ IiUP1IQOJrLphZWC1WcTCOsEXO+yAqaEHArFokI= X-Google-Smtp-Source: AGHT+IG6j4s9fqJeOxuydh+4hLfP4HXNma2gHoqMvKWTKnQpVXc8+dgyDWuYlPovvMlzk08ek0K9OA== X-Received: by 2002:a81:4783:0:b0:56d:2d82:63dc with SMTP id u125-20020a814783000000b0056d2d8263dcmr12203640ywa.10.1692801226440; Wed, 23 Aug 2023 07:33:46 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id u80-20020a0deb53000000b00592236855cesm1537362ywe.61.2023.08.23.07.33.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:46 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 32/38] btrfs-progs: update btrfs_insert_item to match the kernel Date: Wed, 23 Aug 2023 10:32:58 -0400 Message-ID: <774735885aa9f77d3bafc3903e3ac364909b96e2.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This has const struct btrfs_key instead of just struct btrfs_key, update this to make it more straightforward to sync ctree.c. Signed-off-by: Josef Bacik --- kernel-shared/ctree.c | 6 +++--- kernel-shared/ctree.h | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 47938f01..5355d385 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -2680,9 +2680,9 @@ out: * Given a key and some data, insert an item into the tree. * This does all the path init required, making room in the tree if needed. */ -int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root - *root, struct btrfs_key *cpu_key, void *data, u32 - data_size) +int btrfs_insert_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, const struct btrfs_key *cpu_key, + void *data, u32 data_size) { int ret = 0; struct btrfs_path *path; diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index d15c16c0..5551d256 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -1021,8 +1021,9 @@ struct btrfs_item_batch { int nr; }; -int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root - *root, struct btrfs_key *key, void *data, u32 data_size); +int btrfs_insert_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, const struct btrfs_key *key, + void *data, u32 data_size); int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, From patchwork Wed Aug 23 14:32:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362657 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 794AEEE49B0 for ; Wed, 23 Aug 2023 14:33:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236536AbjHWOdu (ORCPT ); Wed, 23 Aug 2023 10:33:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42434 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236530AbjHWOdt (ORCPT ); Wed, 23 Aug 2023 10:33:49 -0400 Received: from mail-yb1-xb2c.google.com (mail-yb1-xb2c.google.com [IPv6:2607:f8b0:4864:20::b2c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61C31E5F for ; Wed, 23 Aug 2023 07:33:48 -0700 (PDT) Received: by mail-yb1-xb2c.google.com with SMTP id 3f1490d57ef6-d77c5414433so684835276.0 for ; Wed, 23 Aug 2023 07:33:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801227; x=1693406027; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=iMu2CwI+bLkq149TYP8lMxufPqfWGVbZmFYmRx+T1Z0=; b=ivto+ha3MD1ly59k50mCnhsj1S4SwkXa9vLLAIjc0/S9cx6ifOJPgErNm5DgXx81DU t3W4rcjqSVJzHQuRKPR9a71QNjkwRqKL2WZHgP7bwLf7kEXYZPfCw0SWS9wmJ54eL5tK HGXtYtgnX1NfHGqwZuMhAMFmpFn5v2R9AptNhZpdu93daetgMzInbUxR7KXxYHGfWj/v dqljxqFdFbj7sa3wf7aBrWZgJW9Id41gNA3sN/UTJowkOp/vVGE4/gw+d2+Gmg+kI6PP DybL5m6dOcBWfAXh4NfDuqlSr2Fhjc2EkFJdXNbbeh0wGDtUnboI6pKzj9z0yFtFNYzQ mQCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801227; x=1693406027; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=iMu2CwI+bLkq149TYP8lMxufPqfWGVbZmFYmRx+T1Z0=; b=hZ/KEYFeaPzbijsI9dMy/s8iweCOgq00uiL8IjrBlsZXCLwKOCz2ZidOYG6KZO0maH 4VrFQXCkzjvNJW6adlKAT6gCfoZi3uXV9huGD4BIpWULZePbnRrN1QfbljnZ46oFQnjT yM8OqajnO2zV8uB73hi7Slgrj+eDfECgKD9QAPXFsoCmO8Ito4Qdx233Gug5MGEuR6Cp u/tInE/4pqceLF01jjdYTnqyM2fW/2gByQv+EQSUiM43OzoDHhzPYAcEkFcTUvxbSBvc Eu6tFyugwyV+s7TOhT1LTZ5PTQEMvTkAgQxKaJLIS/GmRMofLkyfNuK9pUs7yc/5uqUy AC0A== X-Gm-Message-State: AOJu0YxMIZUoK+rSRlx1Od6gBa2piZ5fBZ+lOFUW2lSasb2ka64bzyNR WPrtM2d6fQUwmfSSN+KLGDp3EzUVJ/XQ09GjDZE= X-Google-Smtp-Source: AGHT+IE9xjZXNEVTPeHEBOyTMSBFWonRTeGp7CPSgp0OSwjmL71c3BPuDLZX906LBvdA7BjEuqwbLg== X-Received: by 2002:a25:d886:0:b0:d07:f1ed:51f6 with SMTP id p128-20020a25d886000000b00d07f1ed51f6mr13563299ybg.2.1692801227515; Wed, 23 Aug 2023 07:33:47 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id p3-20020a25ea03000000b00d217e46d25csm2875715ybd.4.2023.08.23.07.33.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:47 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 33/38] btrfs-progs: update btrfs_leaf_free_space to match the kernel Date: Wed, 23 Aug 2023 10:32:59 -0400 Message-ID: <83136ab7881aa253f3cb31c022e3b1208ff32818.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org In the kernel we have const struct extent_buffer instead of struct extent_buffer, update this to make it more straightforward to sync ctree.c. Signed-off-by: Josef Bacik --- kernel-shared/ctree.c | 4 ++-- kernel-shared/ctree.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 5355d385..e95839bd 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -1740,7 +1740,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root * and nr indicate which items in the leaf to check. This totals up the * space used both by the item structs and the item data */ -static int leaf_space_used(struct extent_buffer *l, int start, int nr) +static int leaf_space_used(const struct extent_buffer *l, int start, int nr) { int data_len; int nritems = btrfs_header_nritems(l); @@ -1760,7 +1760,7 @@ static int leaf_space_used(struct extent_buffer *l, int start, int nr) * the start of the leaf data. IOW, how much room * the leaf has left for both items and data */ -int btrfs_leaf_free_space(struct extent_buffer *leaf) +int btrfs_leaf_free_space(const struct extent_buffer *leaf) { int nritems = btrfs_header_nritems(leaf); u32 leaf_data_size; diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 5551d256..67c5a6f8 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -1080,7 +1080,7 @@ static inline int btrfs_next_item(struct btrfs_root *root, } int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); -int btrfs_leaf_free_space(struct extent_buffer *leaf); +int btrfs_leaf_free_space(const struct extent_buffer *leaf); void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info, struct btrfs_path *path, const struct btrfs_key *new_key); From patchwork Wed Aug 23 14:33:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362658 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 C2DB9EE49A0 for ; Wed, 23 Aug 2023 14:33:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236534AbjHWOdw (ORCPT ); Wed, 23 Aug 2023 10:33:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53354 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236532AbjHWOdv (ORCPT ); Wed, 23 Aug 2023 10:33:51 -0400 Received: from mail-yw1-x1130.google.com (mail-yw1-x1130.google.com [IPv6:2607:f8b0:4864:20::1130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A1732E71 for ; Wed, 23 Aug 2023 07:33:49 -0700 (PDT) Received: by mail-yw1-x1130.google.com with SMTP id 00721157ae682-58dce1f42d6so91539417b3.0 for ; Wed, 23 Aug 2023 07:33:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801229; x=1693406029; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=fQxLWT7p66JnlNzQqpfpCSZgtBfkKj1AYX1eK/QIzdY=; b=ffAxJzJvCJdyi6gpo+R4mZcyNrIetFTRDG/lX/lJta5vLFL56p3M8l0G6NI5cAtcOQ UAmmiJIzeyhUc6M3cqMC3HKHDhFrMf6+o4Gvb65JI8oucyeyg8lpPob+La5tyxhARu14 o+NsJyM+IZpFKBAEH772kmb5VL5lDaTnWhLcUvk2+WhZAipdCIS3hatNZdX7vUXcLjAC /JJmBpD4ZVUnID5DzhxgtDC4exHe7KhYG6AkpJDItvexPoUpi3O8X8yqNTk4hnxeoVTE OjGUQQ04e+viENnm4jnIH6tuaVv3KQtFrxDQoTptlxeTH9A/Uu8g5RCeAarhxOjBRRYB n5Nw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801229; x=1693406029; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fQxLWT7p66JnlNzQqpfpCSZgtBfkKj1AYX1eK/QIzdY=; b=d7uocJArUkmxy8tiAAwrrHNSYmC+iNm8TE6P1gaRmqtcYMfFGeM2YAmGVcO+9yifUO IVL6gnvtueGLzo9+jHaUsYAT9m1U2FfdP6FD+uH3mX9UQ6f8vH1x+eGCzuNf5hB7iSRn Zv1bU9LQQubIAGeLFqkSBmvKdi9q2HJlrVqFf7ZWw7WwbSYjveCelM+52Yv75UC08LaT 8dBGw5vFCgbyYGhAXIguQyn1LOua3VFBHulLaoDHup349ApEHRSOaRQN5KKuzH5FmTB5 8YVvYhgDSCxxa59dyAGIEYrm4oOgiLf+d/H5ytbC71I0srZYlLTKyyQH6qOtnCeOEU8m TxQg== X-Gm-Message-State: AOJu0Yy1+IzOJ3vJpaZwEybg7vBWjc9qtV+TCFcjEC3MBL35I6cJdury sHrAcZmO2/mPeoWgiRcPAw6d/MgifjNqMhYp2xk= X-Google-Smtp-Source: AGHT+IGzqVA0Zl1yj8cLG+TKLJXl+R5+oIrTSG19YkG4HYvBsDg4+WwmPsSlqZ35+qsWp1G2f++kmg== X-Received: by 2002:a81:8406:0:b0:58c:5598:be97 with SMTP id u6-20020a818406000000b0058c5598be97mr11690145ywf.15.1692801228733; Wed, 23 Aug 2023 07:33:48 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id x123-20020a818781000000b0058d856efb31sm3371445ywf.98.2023.08.23.07.33.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:48 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 34/38] btrfs-progs: use btrfs_tree_parent_check for btrfs_read_extent_buffer Date: Wed, 23 Aug 2023 10:33:00 -0400 Message-ID: <342ae866d3c27b426ca3cfc48efd26992eb089d5.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org In the kernel we have a control structure call btrfs_tree_parent_check to pass around the various sanity checks we have for extent buffers. Add this to btrfs_tree_parent_check and then update the callers. Signed-off-by: Josef Bacik --- kernel-shared/disk-io.c | 18 ++++++++++++++---- kernel-shared/disk-io.h | 6 ++++-- tune/change-csum.c | 4 +++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c index 092b54af..ef5ea391 100644 --- a/kernel-shared/disk-io.c +++ b/kernel-shared/disk-io.c @@ -332,8 +332,8 @@ int read_whole_eb(struct btrfs_fs_info *info, struct extent_buffer *eb, int mirr return 0; } -int btrfs_read_extent_buffer(struct extent_buffer *eb, u64 parent_transid, - int level, struct btrfs_key *first_key) +int btrfs_read_extent_buffer(struct extent_buffer *eb, + struct btrfs_tree_parent_check *check) { struct btrfs_fs_info *fs_info = eb->fs_info; int ret; @@ -349,7 +349,7 @@ int btrfs_read_extent_buffer(struct extent_buffer *eb, u64 parent_transid, ret = read_whole_eb(fs_info, eb, mirror_num); if (ret == 0 && csum_tree_block(fs_info, eb, 1) == 0 && check_tree_block(fs_info, eb) == 0 && - verify_parent_transid(eb, parent_transid, ignore) == 0) { + verify_parent_transid(eb, check->transid, ignore) == 0) { if (eb->flags & EXTENT_BUFFER_BAD_TRANSID && list_empty(&eb->recow)) { list_add_tail(&eb->recow, @@ -420,10 +420,20 @@ struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr, u64 owner_root, u64 parent_transid, int level, struct btrfs_key *first_key) { + struct btrfs_tree_parent_check check = { + .owner_root = owner_root, + .transid = parent_transid, + .level = level, + }; int ret; struct extent_buffer *eb; u32 sectorsize = fs_info->sectorsize; + if (first_key) { + check.has_first_key = true; + memcpy(&check.first_key, first_key, sizeof(*first_key)); + } + /* * Don't even try to create tree block for unaligned tree block * bytenr. @@ -443,7 +453,7 @@ struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr, if (btrfs_buffer_uptodate(eb, parent_transid, 0)) return eb; - ret = btrfs_read_extent_buffer(eb, parent_transid, level, first_key); + ret = btrfs_read_extent_buffer(eb, &check); if (ret) { /* * We failed to read this tree block, it be should deleted right diff --git a/kernel-shared/disk-io.h b/kernel-shared/disk-io.h index 424b953e..78c6e8c7 100644 --- a/kernel-shared/disk-io.h +++ b/kernel-shared/disk-io.h @@ -23,6 +23,8 @@ #include "kernel-shared/ctree.h" #include "kernel-lib/sizes.h" +struct btrfs_tree_parent_check; + #define BTRFS_SUPER_MIRROR_MAX 3 #define BTRFS_SUPER_MIRROR_SHIFT 12 @@ -238,8 +240,8 @@ int btrfs_global_root_insert(struct btrfs_fs_info *fs_info, int btrfs_find_and_setup_root(struct btrfs_root *tree_root, struct btrfs_fs_info *fs_info, u64 objectid, struct btrfs_root *root); -int btrfs_read_extent_buffer(struct extent_buffer *eb, u64 parent_transid, - int level, struct btrfs_key *first_key); +int btrfs_read_extent_buffer(struct extent_buffer *eb, + struct btrfs_tree_parent_check *check); static inline struct btrfs_root *btrfs_block_group_root( struct btrfs_fs_info *fs_info) diff --git a/tune/change-csum.c b/tune/change-csum.c index cf895df7..f12a2832 100644 --- a/tune/change-csum.c +++ b/tune/change-csum.c @@ -24,6 +24,7 @@ #include "kernel-shared/file-item.h" #include "kernel-shared/extent_io.h" #include "kernel-shared/transaction.h" +#include "kernel-shared/tree-checker.h" #include "common/messages.h" #include "common/internal.h" #include "common/utils.h" @@ -494,6 +495,7 @@ static int rewrite_tree_block_csum(struct btrfs_fs_info *fs_info, u64 logical, u16 new_csum_type) { struct extent_buffer *eb; + struct btrfs_tree_parent_check check = { 0 }; u8 result_old[BTRFS_CSUM_SIZE]; u8 result_new[BTRFS_CSUM_SIZE]; int ret; @@ -502,7 +504,7 @@ static int rewrite_tree_block_csum(struct btrfs_fs_info *fs_info, u64 logical, if (!eb) return -ENOMEM; - ret = btrfs_read_extent_buffer(eb, 0, 0, NULL); + ret = btrfs_read_extent_buffer(eb, &check); if (ret < 0) { errno = -ret; error("failed to read tree block at logical %llu: %m", logical); From patchwork Wed Aug 23 14:33:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362661 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 41E46EE49A0 for ; Wed, 23 Aug 2023 14:33:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236533AbjHWOd4 (ORCPT ); Wed, 23 Aug 2023 10:33:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53434 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235007AbjHWOdz (ORCPT ); Wed, 23 Aug 2023 10:33:55 -0400 Received: from mail-yw1-x112b.google.com (mail-yw1-x112b.google.com [IPv6:2607:f8b0:4864:20::112b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A7FEE54 for ; Wed, 23 Aug 2023 07:33:51 -0700 (PDT) Received: by mail-yw1-x112b.google.com with SMTP id 00721157ae682-5922b96c5fcso30193987b3.0 for ; Wed, 23 Aug 2023 07:33:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801230; x=1693406030; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=biDBJWvlDH7z5+kIEbB0Hyvz0Y8yo6n5Hv8DM+HIiHw=; b=RN6FNNjE3bdyE5J0DRPmSuBumI8tdxJmE1qJeGZLzTGa71AWLf84KV2IlZJO+mbB0A Rvhiu8Cc/dsYxoDfrte7l+radzoJurVJ9Fiko4FYdwlNzTWxDap3EmZYcz7DgaIHx1Lg wxOaY0MC9zrDkg1shTWO6hNiZyXnLGQLiUiOlCIEGfDLrUxhl1vNkF10WPabsku2h3t1 4e5P/OiRHCzIkvhxgbmKy5Fjq1qPhtYMf4Zq2dk7x5dFXgDHst638y2rb8wugKV6ag5T q53BRn6lbCsqPUptOtd3mdjymYRAGHIjx7DsejC7O51DlVCiu/eSGLqwxibAksWceNX4 4MpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801230; x=1693406030; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=biDBJWvlDH7z5+kIEbB0Hyvz0Y8yo6n5Hv8DM+HIiHw=; b=P8GmPh3T2JX+vlGNtlvh1bEektGqsK1oHAHETa3q5lGYwK2WqfI3JtB7z11p8e5EAW VwoKviGw25UcV7zgT/pX/9s4ZdZWhI4GJRabVNfnw4WpyufNJZmcvhrByThE/EAOvftx Y6tjTSPIyqkT2VPB8RAMdlXlViwAUErXHdXOQCr5uRPpD8IFVv+NvcCSDvYK/0HgHBtw v9GIvkkMukhrYV8TloJXSnqwsIaqhEjSlVPtl1Mwqi4Al+pL3/7mFVjOQCZRMzUDYKAT B/mneMcAgBVKuOyRI0jlvLlQHEt51vViOLGC+5uzFD2bNFnGbxBfHSHQNWK3lfB1Lcxt CJUA== X-Gm-Message-State: AOJu0Yy962hmNwro+2iN+hmBWCQaaVNZ1oOQbyBV3dQTXe5y2od5ASPv 1ZTlhhGARVNw5+BHVorZrf246lSFlXhgAlAQzs0= X-Google-Smtp-Source: AGHT+IEURou8Lhvkjq+NoLRNbcpStG7eRcP878Xa+rOb+2HWUFrzSr05UvfLoEQC+L/WFcfhZp0Hdg== X-Received: by 2002:a0d:d585:0:b0:577:1be8:c1ae with SMTP id x127-20020a0dd585000000b005771be8c1aemr14646686ywd.24.1692801230190; Wed, 23 Aug 2023 07:33:50 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id a4-20020a0dd804000000b005832fe29034sm3341717ywe.89.2023.08.23.07.33.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:49 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 35/38] btrfs-progs: update read_tree_block to take a btrfs_parent_tree_check Date: Wed, 23 Aug 2023 10:33:01 -0400 Message-ID: <7dd4ba1382211701b1b3658b414cce3693103453.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org In the kernel we've added a control struct to handle the different checks we want to do on extent buffers when we read them. Update our copy of read_tree_block to take this as an argument, then update all of the callers to use the new structure. Signed-off-by: Josef Bacik --- btrfs-corrupt-block.c | 16 +++++++++++----- btrfs-find-root.c | 5 ++++- check/main.c | 21 +++++++++++++++------ check/mode-common.c | 7 +++++-- check/mode-lowmem.c | 25 ++++++++++++++++++------- check/qgroup-verify.c | 7 +++++-- check/repair.c | 16 ++++++++++------ cmds/inspect-dump-tree.c | 20 ++++++++++++++------ cmds/inspect-tree-stats.c | 11 +++++++---- cmds/restore.c | 13 ++++++++----- image/image-create.c | 10 ++++++---- image/image-restore.c | 6 ++++-- image/main.c | 1 + kernel-shared/backref.c | 17 +++++++++++++---- kernel-shared/ctree.c | 9 ++++++--- kernel-shared/disk-io.c | 26 ++++++++++---------------- kernel-shared/disk-io.h | 3 +-- kernel-shared/print-tree.c | 10 +++++++--- tune/change-uuid.c | 4 +++- 19 files changed, 148 insertions(+), 79 deletions(-) diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c index 3e741c08..432dc859 100644 --- a/btrfs-corrupt-block.c +++ b/btrfs-corrupt-block.c @@ -29,6 +29,7 @@ #include "kernel-shared/transaction.h" #include "kernel-shared/extent_io.h" #include "kernel-shared/file-item.h" +#include "kernel-shared/tree-checker.h" #include "common/utils.h" #include "common/help.h" #include "common/extent-cache.h" @@ -172,8 +173,9 @@ static void corrupt_keys(struct btrfs_trans_handle *trans, static int corrupt_keys_in_block(struct btrfs_fs_info *fs_info, u64 bytenr) { struct extent_buffer *eb; + struct btrfs_tree_parent_check check = { 0 }; - eb = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL); + eb = read_tree_block(fs_info, bytenr, &check); if (!extent_buffer_uptodate(eb)) return -EIO;; @@ -301,11 +303,14 @@ static void btrfs_corrupt_extent_tree(struct btrfs_trans_handle *trans, for (i = 0; i < btrfs_header_nritems(eb); i++) { struct extent_buffer *next; + struct btrfs_tree_parent_check check = { + .owner_root = btrfs_header_owner(eb), + .transid = btrfs_node_ptr_generation(eb, i), + .level = btrfs_header_level(eb) - 1, + }; next = read_tree_block(fs_info, btrfs_node_blockptr(eb, i), - btrfs_header_owner(eb), - btrfs_node_ptr_generation(eb, i), - btrfs_header_level(eb) - 1, NULL); + &check); if (!extent_buffer_uptodate(next)) continue; btrfs_corrupt_extent_tree(trans, root, next); @@ -860,6 +865,7 @@ static int corrupt_metadata_block(struct btrfs_fs_info *fs_info, u64 block, char *field) { struct extent_buffer *eb; + struct btrfs_tree_parent_check check = { 0 }; enum btrfs_metadata_block_field corrupt_field; int ret; @@ -869,7 +875,7 @@ static int corrupt_metadata_block(struct btrfs_fs_info *fs_info, u64 block, return -EINVAL; } - eb = read_tree_block(fs_info, block, 0, 0, 0, NULL); + eb = read_tree_block(fs_info, block, &check); if (!extent_buffer_uptodate(eb)) { error("couldn't read in tree block %s", field); return -EINVAL; diff --git a/btrfs-find-root.c b/btrfs-find-root.c index 6e32859f..32d32429 100644 --- a/btrfs-find-root.c +++ b/btrfs-find-root.c @@ -25,6 +25,7 @@ #include "kernel-shared/disk-io.h" #include "kernel-shared/volumes.h" #include "kernel-shared/extent_io.h" +#include "kernel-shared/tree-checker.h" #include "common/box.h" #include "common/utils.h" #include "common/extent-cache.h" @@ -200,7 +201,9 @@ int btrfs_find_root_search(struct btrfs_fs_info *fs_info, for (offset = chunk_offset; offset < chunk_offset + chunk_size; offset += nodesize) { - eb = read_tree_block(fs_info, offset, 0, 0, 0, NULL); + struct btrfs_tree_parent_check check = { 0 }; + + eb = read_tree_block(fs_info, offset, &check); if (!eb || IS_ERR(eb)) continue; ret = add_eb_to_result(eb, result, nodesize, filter, diff --git a/check/main.c b/check/main.c index 04c965ab..08e6a94b 100644 --- a/check/main.c +++ b/check/main.c @@ -1894,11 +1894,15 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path, next = btrfs_find_tree_block(gfs_info, bytenr, gfs_info->nodesize); if (!next || !btrfs_buffer_uptodate(next, ptr_gen, 0)) { + struct btrfs_tree_parent_check check = { + .owner_root = btrfs_header_owner(cur), + .transid = ptr_gen, + .level = *level - 1, + }; + free_extent_buffer(next); reada_walk_down(root, cur, path->slots[*level]); - next = read_tree_block(gfs_info, bytenr, - btrfs_header_owner(cur), ptr_gen, - *level - 1, NULL); + next = read_tree_block(gfs_info, bytenr, &check); if (!extent_buffer_uptodate(next)) { struct btrfs_key node_key; @@ -6196,6 +6200,7 @@ static int run_next_block(struct btrfs_root *root, { struct extent_buffer *buf; struct extent_record *rec = NULL; + struct btrfs_tree_parent_check check = { 0 }; u64 bytenr; u32 size; u64 parent; @@ -6252,7 +6257,8 @@ static int run_next_block(struct btrfs_root *root, } /* fixme, get the real parent transid */ - buf = read_tree_block(gfs_info, bytenr, 0, gen, 0, NULL); + check.transid = gen; + buf = read_tree_block(gfs_info, bytenr, &check); if (!extent_buffer_uptodate(buf)) { record_bad_block_io(extent_cache, bytenr, size); goto out; @@ -8586,12 +8592,15 @@ static int deal_root_from_list(struct list_head *list, while (!list_empty(list)) { struct root_item_record *rec; struct extent_buffer *buf; + struct btrfs_tree_parent_check check = { 0 }; rec = list_entry(list->next, struct root_item_record, list); last = 0; - buf = read_tree_block(gfs_info, rec->bytenr, rec->objectid, 0, - rec->level, NULL); + + check.owner_root = rec->objectid; + check.level = rec->level; + buf = read_tree_block(gfs_info, rec->bytenr, &check); if (!extent_buffer_uptodate(buf)) { free_extent_buffer(buf); ret = -EIO; diff --git a/check/mode-common.c b/check/mode-common.c index 71e735c4..f6cdcee3 100644 --- a/check/mode-common.c +++ b/check/mode-common.c @@ -29,6 +29,7 @@ #include "kernel-shared/backref.h" #include "kernel-shared/compression.h" #include "kernel-shared/file-item.h" +#include "kernel-shared/tree-checker.h" #include "common/internal.h" #include "common/messages.h" #include "common/utils.h" @@ -127,11 +128,12 @@ next: static int check_prealloc_shared_data_ref(u64 parent, u64 disk_bytenr) { struct extent_buffer *eb; + struct btrfs_tree_parent_check check = { 0 }; u32 nr; int i; int ret = 0; - eb = read_tree_block(gfs_info, parent, 0, 0, 0, NULL); + eb = read_tree_block(gfs_info, parent, &check); if (!extent_buffer_uptodate(eb)) { ret = -EIO; goto out; @@ -1116,8 +1118,9 @@ int get_extent_item_generation(u64 bytenr, u64 *gen_ret) if (btrfs_extent_flags(path.nodes[0], ei) & BTRFS_EXTENT_FLAG_TREE_BLOCK) { struct extent_buffer *eb; + struct btrfs_tree_parent_check check = { 0 }; - eb = read_tree_block(gfs_info, bytenr, 0, 0, 0, NULL); + eb = read_tree_block(gfs_info, bytenr, &check); if (extent_buffer_uptodate(eb)) { *gen_ret = btrfs_header_generation(eb); ret = 0; diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c index 35bca857..0189a656 100644 --- a/check/mode-lowmem.c +++ b/check/mode-lowmem.c @@ -3684,6 +3684,7 @@ static int query_tree_block_level(u64 bytenr) struct btrfs_path path = {}; struct btrfs_key key; struct btrfs_extent_item *ei; + struct btrfs_tree_parent_check check = { 0 }; u64 flags; u64 transid; u8 backref_level; @@ -3731,7 +3732,8 @@ static int query_tree_block_level(u64 bytenr) btrfs_release_path(&path); /* Get level from tree block as an alternative source */ - eb = read_tree_block(gfs_info, bytenr, 0, transid, 0, NULL); + check.transid = transid; + eb = read_tree_block(gfs_info, bytenr, &check); if (!extent_buffer_uptodate(eb)) { free_extent_buffer(eb); return -EIO; @@ -3760,6 +3762,9 @@ static int check_tree_block_backref(u64 root_id, u64 bytenr, int level) struct btrfs_path path = {}; struct extent_buffer *eb; struct extent_buffer *node; + struct btrfs_tree_parent_check check = { + .owner_root = root_id, + }; u32 nodesize = btrfs_super_nodesize(gfs_info->super_copy); int err = 0; int ret; @@ -3783,7 +3788,7 @@ static int check_tree_block_backref(u64 root_id, u64 bytenr, int level) } /* Read out the tree block to get item/node key */ - eb = read_tree_block(gfs_info, bytenr, root_id, 0, 0, NULL); + eb = read_tree_block(gfs_info, bytenr, &check); if (!extent_buffer_uptodate(eb)) { err |= REFERENCER_MISSING; free_extent_buffer(eb); @@ -3877,11 +3882,12 @@ static int is_tree_reloc_root(struct extent_buffer *eb) static int check_shared_block_backref(u64 parent, u64 bytenr, int level) { struct extent_buffer *eb; + struct btrfs_tree_parent_check check = { 0 }; u32 nr; int found_parent = 0; int i; - eb = read_tree_block(gfs_info, parent, 0, 0, 0, NULL); + eb = read_tree_block(gfs_info, parent, &check); if (!extent_buffer_uptodate(eb)) goto out; @@ -4048,11 +4054,12 @@ static int check_shared_data_backref(u64 parent, u64 bytenr) struct extent_buffer *eb; struct btrfs_key key; struct btrfs_file_extent_item *fi; + struct btrfs_tree_parent_check check = { 0 }; u32 nr; int found_parent = 0; int i; - eb = read_tree_block(gfs_info, parent, 0, 0, 0, NULL); + eb = read_tree_block(gfs_info, parent, &check); if (!extent_buffer_uptodate(eb)) goto out; @@ -5018,11 +5025,15 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path, next = btrfs_find_tree_block(gfs_info, bytenr, gfs_info->nodesize); if (!next || !btrfs_buffer_uptodate(next, ptr_gen, 0)) { + struct btrfs_tree_parent_check check = { + .owner_root = btrfs_header_owner(cur), + .transid = ptr_gen, + .level = *level - 1, + }; + free_extent_buffer(next); reada_walk_down(root, cur, path->slots[*level]); - next = read_tree_block(gfs_info, bytenr, - btrfs_header_owner(cur), - ptr_gen, *level - 1, NULL); + next = read_tree_block(gfs_info, bytenr, &check); if (!extent_buffer_uptodate(next)) { struct btrfs_key node_key; diff --git a/check/qgroup-verify.c b/check/qgroup-verify.c index 0c08eae8..0491d6a3 100644 --- a/check/qgroup-verify.c +++ b/check/qgroup-verify.c @@ -30,6 +30,7 @@ #include "kernel-shared/ulist.h" #include "kernel-shared/extent_io.h" #include "kernel-shared/transaction.h" +#include "kernel-shared/tree-checker.h" #include "common/messages.h" #include "common/rbtree-utils.h" #include "check/repair.h" @@ -714,14 +715,16 @@ static int travel_tree(struct btrfs_fs_info *info, struct btrfs_root *root, { int ret, nr, i; struct extent_buffer *eb; + struct btrfs_tree_parent_check check = { + .owner_root = btrfs_root_id(root), + }; u64 new_bytenr; u64 new_num_bytes; // printf("travel_tree: bytenr: %llu\tnum_bytes: %llu\tref_parent: %llu\n", // bytenr, num_bytes, ref_parent); - eb = read_tree_block(info, bytenr, btrfs_root_id(root), 0, - 0, NULL); + eb = read_tree_block(info, bytenr, &check); if (!extent_buffer_uptodate(eb)) return -EIO; diff --git a/check/repair.c b/check/repair.c index d8900c41..240ac7fb 100644 --- a/check/repair.c +++ b/check/repair.c @@ -137,6 +137,8 @@ static int traverse_tree_blocks(struct extent_io_tree *tree, nritems = btrfs_header_nritems(eb); for (i = 0; i < nritems; i++) { + struct btrfs_tree_parent_check check = { 0 }; + if (level == 0) { bool is_extent_root; btrfs_item_key_to_cpu(eb, &key, i); @@ -150,15 +152,16 @@ static int traverse_tree_blocks(struct extent_io_tree *tree, ri = btrfs_item_ptr(eb, i, struct btrfs_root_item); bytenr = btrfs_disk_root_bytenr(eb, ri); + check.owner_root = key.objectid; + check.level = btrfs_disk_root_level(eb, ri); + /* * If at any point we start needing the real root we * will have to build a stump root for the root we are * in, but for now this doesn't actually use the root so * just pass in extent_root. */ - tmp = read_tree_block(fs_info, bytenr, key.objectid, 0, - btrfs_disk_root_level(eb, ri), - NULL); + tmp = read_tree_block(fs_info, bytenr, &check); if (!extent_buffer_uptodate(tmp)) { fprintf(stderr, "Error reading root block\n"); return -EIO; @@ -183,9 +186,10 @@ static int traverse_tree_blocks(struct extent_io_tree *tree, continue; } - tmp = read_tree_block(fs_info, bytenr, - btrfs_header_owner(eb), 0, - level - 1, NULL); + check.owner_root = btrfs_header_owner(eb); + check.level = level - 1; + + tmp = read_tree_block(fs_info, bytenr, &check); if (!extent_buffer_uptodate(tmp)) { fprintf(stderr, "Error reading tree block\n"); return -EIO; diff --git a/cmds/inspect-dump-tree.c b/cmds/inspect-dump-tree.c index 9c3de7aa..c16d3aa2 100644 --- a/cmds/inspect-dump-tree.c +++ b/cmds/inspect-dump-tree.c @@ -32,6 +32,7 @@ #include "kernel-shared/print-tree.h" #include "kernel-shared/volumes.h" #include "kernel-shared/extent_io.h" +#include "kernel-shared/tree-checker.h" #include "common/defs.h" #include "common/extent-cache.h" #include "common/messages.h" @@ -58,10 +59,14 @@ static void print_extents(struct extent_buffer *eb) nr = btrfs_header_nritems(eb); for (i = 0; i < nr; i++) { + struct btrfs_tree_parent_check check = { + .owner_root = btrfs_header_owner(eb), + .transid = btrfs_node_ptr_generation(eb, i), + .level = btrfs_header_level(eb) - 1, + }; + next = read_tree_block(fs_info, btrfs_node_blockptr(eb, i), - btrfs_header_owner(eb), - btrfs_node_ptr_generation(eb, i), - btrfs_header_level(eb) - 1, NULL); + &check); if (!extent_buffer_uptodate(next)) continue; if (btrfs_is_leaf(next) && btrfs_header_level(eb) != 1) { @@ -269,6 +274,7 @@ static int dump_print_tree_blocks(struct btrfs_fs_info *fs_info, { struct cache_extent *ce; struct extent_buffer *eb; + struct btrfs_tree_parent_check check = { 0 }; u64 bytenr; int ret = 0; @@ -289,7 +295,7 @@ static int dump_print_tree_blocks(struct btrfs_fs_info *fs_info, goto next; } - eb = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL); + eb = read_tree_block(fs_info, bytenr, &check); if (!extent_buffer_uptodate(eb)) { error("failed to read tree block %llu", bytenr); ret = -EIO; @@ -592,12 +598,14 @@ again: if (found_key.type == BTRFS_ROOT_ITEM_KEY) { unsigned long offset; struct extent_buffer *buf; + struct btrfs_tree_parent_check check = { + .owner_root = key.objectid, + }; bool skip = (extent_only || device_only || uuid_tree_only); offset = btrfs_item_ptr_offset(leaf, slot); read_extent_buffer(leaf, &ri, offset, sizeof(ri)); - buf = read_tree_block(info, btrfs_root_bytenr(&ri), - key.objectid, 0, 0, NULL); + buf = read_tree_block(info, btrfs_root_bytenr(&ri), &check); if (!extent_buffer_uptodate(buf)) goto next; if (tree_id && found_key.objectid != tree_id) { diff --git a/cmds/inspect-tree-stats.c b/cmds/inspect-tree-stats.c index e1808ec5..0d6db150 100644 --- a/cmds/inspect-tree-stats.c +++ b/cmds/inspect-tree-stats.c @@ -29,6 +29,7 @@ #include "kernel-shared/disk-io.h" #include "kernel-shared/extent_io.h" #include "kernel-shared/file-item.h" +#include "kernel-shared/tree-checker.h" #include "common/utils.h" #include "common/help.h" #include "common/messages.h" @@ -152,10 +153,12 @@ static int walk_nodes(struct btrfs_root *root, struct btrfs_path *path, path->slots[level] = i; if ((level - 1) > 0 || find_inline) { - tmp = read_tree_block(root->fs_info, cur_blocknr, - btrfs_header_owner(b), - btrfs_node_ptr_generation(b, i), - level - 1, NULL); + struct btrfs_tree_parent_check check = { + .owner_root = btrfs_header_owner(b), + .transid = btrfs_node_ptr_generation(b, i), + .level = level - 1, + }; + tmp = read_tree_block(root->fs_info, cur_blocknr, &check); if (!extent_buffer_uptodate(tmp)) { error("failed to read blocknr %llu", btrfs_node_blockptr(b, i)); diff --git a/cmds/restore.c b/cmds/restore.c index b0e04a7e..74462bca 100644 --- a/cmds/restore.c +++ b/cmds/restore.c @@ -45,6 +45,7 @@ #include "kernel-shared/extent_io.h" #include "kernel-shared/compression.h" #include "kernel-shared/file-item.h" +#include "kernel-shared/tree-checker.h" #include "common/utils.h" #include "common/help.h" #include "common/open-utils.h" @@ -1241,15 +1242,17 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location, * the fs_root. */ if (!extent_buffer_uptodate(fs_info->tree_root->node)) { + struct btrfs_tree_parent_check check = { 0 }; u64 generation; root = fs_info->tree_root; if (!root_location) root_location = btrfs_super_root(fs_info->super_copy); generation = btrfs_super_generation(fs_info->super_copy); - root->node = read_tree_block(fs_info, root_location, - btrfs_root_id(root), generation, - 0, NULL); + + check.owner_root = btrfs_root_id(root); + check.transid = generation; + root->node = read_tree_block(fs_info, root_location, &check); if (!extent_buffer_uptodate(root->node)) { error("opening tree root failed"); close_ctree(root); @@ -1514,9 +1517,9 @@ static int cmd_restore(const struct cmd_struct *cmd, int argc, char **argv) goto out; if (fs_location != 0) { + struct btrfs_tree_parent_check check = { 0 }; free_extent_buffer(root->node); - root->node = read_tree_block(root->fs_info, fs_location, 0, 0, - 0, NULL); + root->node = read_tree_block(root->fs_info, fs_location, &check); if (!extent_buffer_uptodate(root->node)) { error("failed to read fs location"); ret = 1; diff --git a/image/image-create.c b/image/image-create.c index 894969ed..c802ba14 100644 --- a/image/image-create.c +++ b/image/image-create.c @@ -21,6 +21,7 @@ #include "kernel-shared/file-item.h" #include "kernel-shared/disk-io.h" #include "kernel-shared/volumes.h" +#include "kernel-shared/tree-checker.h" #include "crypto/crc32c.h" #include "common/internal.h" #include "common/messages.h" @@ -437,11 +438,11 @@ static int flush_pending(struct metadump_struct *md, int done) } while (!md->data && size > 0) { + struct btrfs_tree_parent_check check = { 0 }; u64 this_read = min((u64)md->root->fs_info->nodesize, size); - eb = read_tree_block(md->root->fs_info, start, 0, 0, 0, - NULL); + eb = read_tree_block(md->root->fs_info, start, &check); if (!extent_buffer_uptodate(eb)) { free(async->buffer); free(async); @@ -510,6 +511,7 @@ static int copy_tree_blocks(struct btrfs_root *root, struct extent_buffer *eb, struct btrfs_root_item *ri; struct btrfs_key key; struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_tree_parent_check check = { 0 }; u64 bytenr; int level; int nritems = 0; @@ -545,7 +547,7 @@ static int copy_tree_blocks(struct btrfs_root *root, struct extent_buffer *eb, continue; ri = btrfs_item_ptr(eb, i, struct btrfs_root_item); bytenr = btrfs_disk_root_bytenr(eb, ri); - tmp = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL); + tmp = read_tree_block(fs_info, bytenr, &check); if (!extent_buffer_uptodate(tmp)) { error("unable to read log root block"); return -EIO; @@ -556,7 +558,7 @@ static int copy_tree_blocks(struct btrfs_root *root, struct extent_buffer *eb, return ret; } else { bytenr = btrfs_node_blockptr(eb, i); - tmp = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL); + tmp = read_tree_block(fs_info, bytenr, &check); if (!extent_buffer_uptodate(tmp)) { error("unable to read log root block"); return -EIO; diff --git a/image/image-restore.c b/image/image-restore.c index 36cdc554..5ac254cf 100644 --- a/image/image-restore.c +++ b/image/image-restore.c @@ -20,6 +20,7 @@ #include "kernel-shared/disk-io.h" #include "kernel-shared/volumes.h" #include "kernel-shared/transaction.h" +#include "kernel-shared/tree-checker.h" #include "common/internal.h" #include "common/messages.h" #include "common/open-utils.h" @@ -1366,6 +1367,7 @@ static int iter_tree_blocks(struct btrfs_fs_info *fs_info, struct extent_buffer *eb, bool pin) { void (*func)(struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes); + struct btrfs_tree_parent_check check = { 0 }; int nritems; int level; int i; @@ -1396,7 +1398,7 @@ static int iter_tree_blocks(struct btrfs_fs_info *fs_info, continue; ri = btrfs_item_ptr(eb, i, struct btrfs_root_item); bytenr = btrfs_disk_root_bytenr(eb, ri); - tmp = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL); + tmp = read_tree_block(fs_info, bytenr, &check); if (!extent_buffer_uptodate(tmp)) { error("unable to read log root block"); return -EIO; @@ -1407,7 +1409,7 @@ static int iter_tree_blocks(struct btrfs_fs_info *fs_info, return ret; } else { bytenr = btrfs_node_blockptr(eb, i); - tmp = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL); + tmp = read_tree_block(fs_info, bytenr, &check); if (!extent_buffer_uptodate(tmp)) { error("unable to read log root block"); return -EIO; diff --git a/image/main.c b/image/main.c index fcec725d..52b46588 100644 --- a/image/main.c +++ b/image/main.c @@ -41,6 +41,7 @@ #include "kernel-shared/volumes.h" #include "kernel-shared/extent_io.h" #include "kernel-shared/file-item.h" +#include "kernel-shared/tree-checker.h" #include "crypto/crc32c.h" #include "crypto/hash.h" #include "common/internal.h" diff --git a/kernel-shared/backref.c b/kernel-shared/backref.c index c4e76823..14f045d7 100644 --- a/kernel-shared/backref.c +++ b/kernel-shared/backref.c @@ -23,6 +23,7 @@ #include "kernel-shared/ulist.h" #include "kernel-shared/transaction.h" #include "kernel-shared/messages.h" +#include "kernel-shared/tree-checker.h" #include "common/internal.h" #define pr_debug(...) do { } while (0) @@ -454,6 +455,7 @@ static int __add_missing_keys(struct btrfs_fs_info *fs_info, while (!list_empty(&prefstate->pending_missing_keys)) { struct __prelim_ref *ref; + struct btrfs_tree_parent_check check; ref = list_first_pref(&prefstate->pending_missing_keys); @@ -461,8 +463,13 @@ static int __add_missing_keys(struct btrfs_fs_info *fs_info, ASSERT(!ref->parent); ASSERT(!ref->key_for_search.type); BUG_ON(!ref->wanted_disk_byte); - eb = read_tree_block(fs_info, ref->wanted_disk_byte, - ref->root_id, 0, ref->level - 1, NULL); + + check.owner_root = ref->root_id; + check.transid = 0; + check.has_first_key = false; + check.level = ref->level - 1; + + eb = read_tree_block(fs_info, ref->wanted_disk_byte, &check); if (!extent_buffer_uptodate(eb)) { free_extent_buffer(eb); return -EIO; @@ -823,9 +830,11 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, if (extent_item_pos && !ref->inode_list && ref->level == 0) { struct extent_buffer *eb; + struct btrfs_tree_parent_check check = { + .level = ref->level, + }; - eb = read_tree_block(fs_info, ref->parent, 0, - 0, ref->level, NULL); + eb = read_tree_block(fs_info, ref->parent, &check); if (!extent_buffer_uptodate(eb)) { free_extent_buffer(eb); ret = -EIO; diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index e95839bd..fb3b9899 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -715,6 +715,7 @@ struct extent_buffer *btrfs_read_node_slot(struct extent_buffer *parent, { struct btrfs_fs_info *fs_info = parent->fs_info; struct extent_buffer *ret; + struct btrfs_tree_parent_check check = { 0 }; int level = btrfs_header_level(parent); if (slot < 0) @@ -725,10 +726,12 @@ struct extent_buffer *btrfs_read_node_slot(struct extent_buffer *parent, if (level == 0) return NULL; + check.owner_root = btrfs_header_owner(parent); + check.transid = btrfs_node_ptr_generation(parent, slot); + check.level = level - 1; + ret = read_tree_block(fs_info, btrfs_node_blockptr(parent, slot), - btrfs_header_owner(parent), - btrfs_node_ptr_generation(parent, slot), - level - 1, NULL); + &check); if (!extent_buffer_uptodate(ret)) return ERR_PTR(-EIO); diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c index ef5ea391..b2fdc48d 100644 --- a/kernel-shared/disk-io.c +++ b/kernel-shared/disk-io.c @@ -417,23 +417,12 @@ int btrfs_read_extent_buffer(struct extent_buffer *eb, } struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr, - u64 owner_root, u64 parent_transid, - int level, struct btrfs_key *first_key) + struct btrfs_tree_parent_check *check) { - struct btrfs_tree_parent_check check = { - .owner_root = owner_root, - .transid = parent_transid, - .level = level, - }; int ret; struct extent_buffer *eb; u32 sectorsize = fs_info->sectorsize; - if (first_key) { - check.has_first_key = true; - memcpy(&check.first_key, first_key, sizeof(*first_key)); - } - /* * Don't even try to create tree block for unaligned tree block * bytenr. @@ -450,10 +439,10 @@ struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr, if (!eb) return ERR_PTR(-ENOMEM); - if (btrfs_buffer_uptodate(eb, parent_transid, 0)) + if (btrfs_buffer_uptodate(eb, check->transid, 0)) return eb; - ret = btrfs_read_extent_buffer(eb, &check); + ret = btrfs_read_extent_buffer(eb, check); if (ret) { /* * We failed to read this tree block, it be should deleted right @@ -508,8 +497,13 @@ static int read_root_node(struct btrfs_fs_info *fs_info, struct btrfs_root *root, u64 bytenr, u64 gen, int level) { - root->node = read_tree_block(fs_info, bytenr, btrfs_root_id(root), - gen, level, NULL); + struct btrfs_tree_parent_check check = { + .owner_root = btrfs_root_id(root), + .transid = gen, + .level = level, + }; + + root->node = read_tree_block(fs_info, bytenr, &check); if (!extent_buffer_uptodate(root->node)) goto err; if (btrfs_header_level(root->node) != level) { diff --git a/kernel-shared/disk-io.h b/kernel-shared/disk-io.h index 78c6e8c7..20dfb01c 100644 --- a/kernel-shared/disk-io.h +++ b/kernel-shared/disk-io.h @@ -147,8 +147,7 @@ struct btrfs_device; int read_whole_eb(struct btrfs_fs_info *info, struct extent_buffer *eb, int mirror); struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr, - u64 owner_root, u64 parent_transid, - int level, struct btrfs_key *first_key); + struct btrfs_tree_parent_check *check); void readahead_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr, u64 parent_transid); diff --git a/kernel-shared/print-tree.c b/kernel-shared/print-tree.c index 9796085d..a5ca51e3 100644 --- a/kernel-shared/print-tree.c +++ b/kernel-shared/print-tree.c @@ -28,6 +28,7 @@ #include "kernel-shared/compression.h" #include "kernel-shared/accessors.h" #include "kernel-shared/file-item.h" +#include "kernel-shared/tree-checker.h" #include "common/utils.h" static void print_dir_item_type(struct extent_buffer *eb, @@ -1613,10 +1614,13 @@ static void dfs_print_children(struct extent_buffer *root_eb, unsigned int mode) mode &= ~(BTRFS_PRINT_TREE_BFS); for (i = 0; i < nr; i++) { + struct btrfs_tree_parent_check check = { + .owner_root = btrfs_header_owner(root_eb), + .transid = btrfs_node_ptr_generation(root_eb, i), + .level = root_eb_level, + }; next = read_tree_block(fs_info, btrfs_node_blockptr(root_eb, i), - btrfs_header_owner(root_eb), - btrfs_node_ptr_generation(root_eb, i), - root_eb_level, NULL); + &check); if (!extent_buffer_uptodate(next)) { fprintf(stderr, "failed to read %llu in tree %llu\n", btrfs_node_blockptr(root_eb, i), diff --git a/tune/change-uuid.c b/tune/change-uuid.c index 54184811..a9e5385e 100644 --- a/tune/change-uuid.c +++ b/tune/change-uuid.c @@ -24,6 +24,7 @@ #include "kernel-shared/disk-io.h" #include "kernel-shared/extent_io.h" #include "kernel-shared/volumes.h" +#include "kernel-shared/tree-checker.h" #include "common/defs.h" #include "common/messages.h" #include "tune/tune.h" @@ -97,6 +98,7 @@ static int change_extent_tree_uuid(struct btrfs_fs_info *fs_info, uuid_t new_fsi while (1) { struct btrfs_extent_item *ei; struct extent_buffer *eb; + struct btrfs_tree_parent_check check = { 0 }; u64 flags; u64 bytenr; @@ -111,7 +113,7 @@ static int change_extent_tree_uuid(struct btrfs_fs_info *fs_info, uuid_t new_fsi goto next; bytenr = key.objectid; - eb = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL); + eb = read_tree_block(fs_info, bytenr, &check); if (IS_ERR(eb)) { error("failed to read tree block: %llu", bytenr); ret = PTR_ERR(eb); From patchwork Wed Aug 23 14:33:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362659 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 2465DEE49A3 for ; Wed, 23 Aug 2023 14:33:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236537AbjHWOdz (ORCPT ); Wed, 23 Aug 2023 10:33:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53412 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236530AbjHWOdy (ORCPT ); Wed, 23 Aug 2023 10:33:54 -0400 Received: from mail-yw1-x1131.google.com (mail-yw1-x1131.google.com [IPv6:2607:f8b0:4864:20::1131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 643D3E68 for ; Wed, 23 Aug 2023 07:33:52 -0700 (PDT) Received: by mail-yw1-x1131.google.com with SMTP id 00721157ae682-5921a962adfso35230047b3.1 for ; Wed, 23 Aug 2023 07:33:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801231; x=1693406031; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=KsQcvJy6IvGA3FUYeG4qX/Sves1np50ycXSgLGGwSCQ=; b=N4BUWs688l5E8SaScRJ+Hs+cECSKWdNnGHbqlsFao3UffMvq/iGa5+HrGzhNQn5HoD DpsHwOMmArOo5ozNjU8Y75cpWa5p+k/upfQdHChSfcqWF7hTPbT2nhLsmDTpWYcZnO2R PECLrDAyBCjNaxkJlxhmz3a2Z3pSjpxbViDRdj9+rcgeWXDiFpmqEwBvzoX/bHAQEshX RcYhH1uQd0XRe2ZfUKcbomu4eTofGugMOr2yxxW2k+tRNocoK44cnLyWTRQS9Lx7eS55 gDEmpeAcgfI9Dyjx02KK//lULY8n+LCCiSmO0RU2xRc/w6d+pq10N6d5c3SDHgHY12nB IR2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801231; x=1693406031; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KsQcvJy6IvGA3FUYeG4qX/Sves1np50ycXSgLGGwSCQ=; b=ZGWgRKIPcgOlrI3F1x1fF8NQ/pokwIN7xWi6bk5Xqsw53GeWc77qNhb7Mvf00Cfuee qPuH9afoHLPMThniyBmavW4zausTshKUZANvNxmqGBHkcTdqI8b/prnH78Y0Vhi7pIYF Os0fPWBBKn4gT6ykJLEmsXoLGRNsxxKUHJOkbjsnpcEGCPNGJPZDGoUvWD7eawp9oRSX MoVuRYfzRpwcbShFveEPGKgrSUvdMvhlFDjXqo8rBqW7TLCWlOBATde7YfpO+h75HhUN Agwelg9pHsHILac+tRldSlQ0RNk4k13gYH2GPVzD87DdT1KMJwAWA6rbLmiPMgeG2nSV pbtQ== X-Gm-Message-State: AOJu0YyOGfsUeRDL6VlW2w5ofqG6t5lsgHrKo02rDzW5aGSvY8lfkQs3 gOcwOTob2qzgVlGVDe1Xp2WnN/M/iaoroUBR3e0= X-Google-Smtp-Source: AGHT+IHnfEZgmo8Yg0raenuVZ7/EZgrV0w7VioHTe8H8NeCHJUyODwFJ4WcaqpUusrDpRV5c7hR3QQ== X-Received: by 2002:a81:4843:0:b0:561:cb45:d7de with SMTP id v64-20020a814843000000b00561cb45d7demr12938757ywa.31.1692801231362; Wed, 23 Aug 2023 07:33:51 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id q62-20020a815c41000000b0057736c436f1sm3321994ywb.141.2023.08.23.07.33.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:51 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 36/38] btrfs-progs: inline btrfs_name_hash and btrfs_extref_hash Date: Wed, 23 Aug 2023 10:33:02 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This is the opposite of what we do in the kernel, however in the kernel we put the helpers in dir-item.h and inode-item.h respectively. Those do not exist in btrfs-progs right now, so instead of doing all that work right now simply inline them in ctree.h to make it easier to sync ctree.c from the kernel. Signed-off-by: Josef Bacik --- kernel-shared/ctree.c | 14 -------------- kernel-shared/ctree.h | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index fb3b9899..0bfebdc2 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -24,7 +24,6 @@ #include "kernel-shared/print-tree.h" #include "kernel-shared/tree-checker.h" #include "kernel-shared/volumes.h" -#include "crypto/crc32c.h" #include "common/internal.h" #include "common/messages.h" #include "common/utils.h" @@ -188,19 +187,6 @@ u16 btrfs_csum_type_size(u16 csum_type) return btrfs_csums[csum_type].size; } -u64 btrfs_name_hash(const char *name, int len) -{ - return crc32c((u32)~1, name, len); -} - -/* - * Figure the key offset of an extended inode ref - */ -u64 btrfs_extref_hash(u64 parent_objectid, const char *name, int len) -{ - return (u64)crc32c(parent_objectid, name, len); -} - struct btrfs_path *btrfs_alloc_path(void) { might_sleep(); diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 67c5a6f8..7ffef9fa 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -25,6 +25,7 @@ #include "kernel-lib/rbtree.h" #include "kerncompat.h" #include "common/extent-cache.h" +#include "crypto/crc32c.h" #include "kernel-shared/uapi/btrfs.h" #include "kernel-shared/uapi/btrfs_tree.h" #include "kernel-shared/extent_io.h" @@ -869,8 +870,19 @@ static inline int __btrfs_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag) return !!(btrfs_super_compat_ro_flags(disk_super) & flag); } -u64 btrfs_name_hash(const char *name, int len); -u64 btrfs_extref_hash(u64 parent_objectid, const char *name, int len); +static inline u64 btrfs_name_hash(const char *name, int len) +{ + return crc32c((u32)~1, name, len); +} + +/* + * Figure the key offset of an extended inode ref + */ +static inline u64 btrfs_extref_hash(u64 parent_objectid, const char *name, + int len) +{ + return (u64)crc32c(parent_objectid, name, len); +} /* extent-tree.c */ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, From patchwork Wed Aug 23 14:33:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362660 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 B1B12EE49B0 for ; Wed, 23 Aug 2023 14:33:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236540AbjHWOd5 (ORCPT ); Wed, 23 Aug 2023 10:33:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53436 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236530AbjHWOdz (ORCPT ); Wed, 23 Aug 2023 10:33:55 -0400 Received: from mail-yw1-x1135.google.com (mail-yw1-x1135.google.com [IPv6:2607:f8b0:4864:20::1135]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 798F1E69 for ; Wed, 23 Aug 2023 07:33:53 -0700 (PDT) Received: by mail-yw1-x1135.google.com with SMTP id 00721157ae682-58fb8963617so45853407b3.3 for ; Wed, 23 Aug 2023 07:33:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801232; x=1693406032; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=+6V3il9/GDZstvmbz60811i4zmplZ2RotmVA2GKZD/Y=; b=bLaEIVHnL1oiPZA073MeQp8Lk1tTXDfxcN6xWB/mvIPdcPyXAbic/vxNqdeRkEkTQ6 FDdgxKUn2n15Ce6E0fy+V8egeUAiBsqnxRQh+vU0yYU5QmrFUhpXLo1gPmMT0b0lh1uy Q4K0jPNhkZu0MUX7wjC79M0BcIxry23qoADy0juTjR8YsptjNbnY5LxMkdCpmsY2+l5i qWJtNX2n1cer+YSJQKvZWOT9xZvdFg9x+T5FhU6/UWo18DhthIx5OOerBhjsatfSqLPH 5zoUGOYgGvJIQei0QiGJIg10KyqJG/4BlI2YN3fNMDQGrJxkU2d/i9LiKWfkdAc3yYLs 3PDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801232; x=1693406032; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+6V3il9/GDZstvmbz60811i4zmplZ2RotmVA2GKZD/Y=; b=JOnhyD+KnzkN6Y8XRsz+PhhNHHx3r7M1PNOHa/LV3CnFJsHczC9guZviC5M5oVB6SS vpqoJhb7F6GcHgTxWrOnJQ8qglNJS5Chknj+9F/X/3pZTk7rzWRQJQgQuqx8BE/kMHnz /tu1x0+nu+Q2Yr8Rf9JlaVzgXAdrVzl7tJmCBpyQs7rmTcC/YpRC6CqEOjYN7pV2SZUx r+dmJEq38slCvgtniI9I8Askv5kdINYmBvPMHV823fvFl851IutjODR8jfQg0EaVZWR7 CMtzlaPK3Oqc6JXBh/6oGYY3csguEOEr4F/rOjrzoqDBy9Zei44Fdq2lI7lJqwTFCrtN qM/g== X-Gm-Message-State: AOJu0Yw2MwKos0G1vTJd31r1lwh1LfkAqqXAX2b3BimD8qbproJFi3L3 D9wFKoVb2fSr8qr/Zf2MjV/hBXBnU26lyjFfoew= X-Google-Smtp-Source: AGHT+IEhEw0tApMAbRepQ/vm95wuKxvA/9HBjXl/WgqKN0MiwfQjKFMUMVzq1qteMVl/FPyTYwIlmQ== X-Received: by 2002:a0d:f243:0:b0:56d:3b91:7e78 with SMTP id b64-20020a0df243000000b0056d3b917e78mr13757346ywf.20.1692801232634; Wed, 23 Aug 2023 07:33:52 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id z128-20020a818986000000b00583cf4ed41esm3347616ywf.2.2023.08.23.07.33.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:52 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 37/38] btrfs-progs: update btrfs_split_item to match the in-kernel definition Date: Wed, 23 Aug 2023 10:33:03 -0400 Message-ID: <6da1aebd175ed8c37ac9d9f6cff58b37a37b7865.1692800904.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org In the kernel new_key is const, update the definition in btrfs-progs to match the in-kernel definition. Signed-off-by: Josef Bacik --- kernel-shared/ctree.c | 2 +- kernel-shared/ctree.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 0bfebdc2..866a748f 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -2322,7 +2322,7 @@ again: int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_key *new_key, + const struct btrfs_key *new_key, unsigned long split_offset) { u32 item_size; diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index 7ffef9fa..fbdf3aef 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -980,7 +980,7 @@ void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end); int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_key *new_key, + const struct btrfs_key *new_key, unsigned long split_offset); int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root, const struct btrfs_key *key, From patchwork Wed Aug 23 14:33:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13362662 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 2CCA3EE49A0 for ; Wed, 23 Aug 2023 14:34:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235270AbjHWOeF (ORCPT ); Wed, 23 Aug 2023 10:34:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235007AbjHWOeC (ORCPT ); Wed, 23 Aug 2023 10:34:02 -0400 Received: from mail-yw1-x112d.google.com (mail-yw1-x112d.google.com [IPv6:2607:f8b0:4864:20::112d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B0CEBE6A for ; Wed, 23 Aug 2023 07:33:56 -0700 (PDT) Received: by mail-yw1-x112d.google.com with SMTP id 00721157ae682-59209b12c50so38718617b3.0 for ; Wed, 23 Aug 2023 07:33:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20221208.gappssmtp.com; s=20221208; t=1692801236; x=1693406036; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=5WdiKFb+xyitKxkEcE4CLZu/FEeC1TYOTHzS6mub1Vw=; b=IUfHaCreAl6Vv4pzoZlN5l1T/nFZLE3EYwmSh1cuqNuXmXlGfq0RbK+XEPlAcizxrN PUA78awhMoBs4tYASAm6khw0hKCkHGjwmt74i1F51qNM7TGVI5OwiDbNgp1dlQ5mbyfC 0NUUsEXutfYYVR9yQKdaCik2RpfXkK7KE6JOs33qAHHI9WNntxIeXTEsK/nbv7hdXG67 sWCgyFhJFq+ghqQ+fZFVCgCUKj50vNgvV0OYC27bni5XmcbP0X2eFvclEqRyjcFM5ixj 4uovw7Hq/+/W4O8G/8McCyZa0proeuLxVH+bwSJp2UbFd2jmgssPOuomoNMuy/mcn2tR XSrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692801236; x=1693406036; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5WdiKFb+xyitKxkEcE4CLZu/FEeC1TYOTHzS6mub1Vw=; b=XOUh7mM3+aWOIdUMenPgpEKRF75Dmea5rNFzeEkl4W1AV8Gd+ZAQ59bWh6jO3eVmnn v2LLIvGIZCcciV7fbOrD9r5ykyRTs/iaZ82n3sD2e13GG7AtIHkU7QygDiuWNHHE1BvY 7OQoL6ZMxy2JLESLtzXcUv9I9NrlQYJMCanBRhQ7IH4bcnVf8xGywfeti03XPDsmTDMT ILcdXBE6t5ulvRoqwIjEAs0TbxqrcmHGZYjv4wMT12HaC6QTVVmDfS/HBEH7A/1EGTEY iPhJFkf27lO9pGhjTcmbRcMICjg2jHZJQiJwEU+pHo5PamQ+xvZFyWoPXUF0qGkGv4EN upDQ== X-Gm-Message-State: AOJu0YyC97EJiH3HOdPOGDFs1FVtPG6PiUk59sV2fQkm29gIELw77vOd u2/++qTdn+4ZCbxVqPJ6zh+CbhNRbwOlWbd5uF8= X-Google-Smtp-Source: AGHT+IG+a0I3t0zX9j/a4h5qVKDj/A/acUpjafHNaHqCgUEa8948t9fusYyC1AewTsCFKpx33u3dBg== X-Received: by 2002:a81:bf48:0:b0:58d:65d4:72cf with SMTP id s8-20020a81bf48000000b0058d65d472cfmr13463728ywk.24.1692801234114; Wed, 23 Aug 2023 07:33:54 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id z3-20020a81c203000000b005899c8e8242sm3338930ywc.138.2023.08.23.07.33.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 07:33:53 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 38/38] btrfs-progs: sync ctree.c from kernel Date: Wed, 23 Aug 2023 10:33:04 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This copies the current copy of ctree.c into btrfs-progs. There are a few modifications, they are all hi-lighted by a "MODIFIED" tag in the code. - The btrfs_path_cachep is a static struct to avoid needing to call btrfs_ctree_init to be able to use stuff. - There is a single page optimization in the search that is not relevant in btrfs-progs. - We have a few warnings around trans->transaction, but we don't have this distinction in btrfs-progs yet. - Obvious include cleanups The rest is a straight copy, the only "modifications" that I didn't note were in ctree.h to clean up some of the inline helpers that use different functions. Signed-off-by: Josef Bacik --- kernel-shared/ctree.c | 4258 ++++++++++++++++++++++++++++++----------- kernel-shared/ctree.h | 50 +- 2 files changed, 3219 insertions(+), 1089 deletions(-) diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c index 866a748f..5333c071 100644 --- a/kernel-shared/ctree.c +++ b/kernel-shared/ctree.c @@ -1,33 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) 2007 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License v2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. + * Copyright (C) 2007,2008 Oracle. All rights reserved. */ #include "kernel-lib/bitops.h" -#include "kernel-lib/sizes.h" -#include "kernel-shared/ctree.h" -#include "kernel-shared/disk-io.h" -#include "kernel-shared/transaction.h" -#include "kernel-shared/print-tree.h" -#include "kernel-shared/tree-checker.h" -#include "kernel-shared/volumes.h" -#include "common/internal.h" -#include "common/messages.h" -#include "common/utils.h" -#include "check/repair.h" +#include "kernel-lib/trace.h" +#include "messages.h" +#include "ctree.h" +#include "disk-io.h" +#include "transaction.h" +#include "print-tree.h" +#include "locking.h" +#include "volumes.h" +#include "tree-mod-log.h" +#include "tree-checker.h" +#include "accessors.h" +#include "file-item.h" + +/* MODIFIED: use this instead of calling btrfs_ctree_init. */ +static struct kmem_cache btrfs_path_cache_struct = { + .size = sizeof(struct btrfs_path), +}; + +static struct kmem_cache *btrfs_path_cachep = &btrfs_path_cache_struct; static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int level); @@ -151,12 +146,19 @@ static inline void copy_leaf_items(const struct extent_buffer *dst, nr_items * sizeof(struct btrfs_item)); } -int btrfs_super_csum_size(const struct btrfs_super_block *sb) +/* This exists for btrfs-progs usages. */ +u16 btrfs_csum_type_size(u16 type) { - const u16 csum_type = btrfs_super_csum_type(sb); + return btrfs_csums[type].size; +} - /* csum type is validated at mount time */ - return btrfs_csums[csum_type].size; +int btrfs_super_csum_size(const struct btrfs_super_block *s) +{ + u16 t = btrfs_super_csum_type(s); + /* + * csum type is validated at mount time + */ + return btrfs_csum_type_size(t); } const char *btrfs_super_csum_name(u16 csum_type) @@ -182,16 +184,11 @@ size_t __attribute_const__ btrfs_get_num_csums(void) return ARRAY_SIZE(btrfs_csums); } -u16 btrfs_csum_type_size(u16 csum_type) -{ - return btrfs_csums[csum_type].size; -} - struct btrfs_path *btrfs_alloc_path(void) { might_sleep(); - return kzalloc(sizeof(struct btrfs_path), GFP_NOFS); + return kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS); } /* this also releases the path */ @@ -200,7 +197,7 @@ void btrfs_free_path(struct btrfs_path *p) if (!p) return; btrfs_release_path(p); - kfree(p); + kmem_cache_free(btrfs_path_cachep, p); } /* @@ -224,7 +221,6 @@ noinline void btrfs_release_path(struct btrfs_path *p) free_extent_buffer(p->nodes[i]); p->nodes[i] = NULL; } - memset(p, 0, sizeof(*p)); } /* @@ -243,47 +239,84 @@ bool __cold abort_should_print_stack(int errno) return true; } +/* + * safely gets a reference on the root node of a tree. A lock + * is not taken, so a concurrent writer may put a different node + * at the root of the tree. See btrfs_lock_root_node for the + * looping required. + * + * The extent buffer returned by this has a reference taken, so + * it won't disappear. It may stop being the root of the tree + * at any time because there are no locks held. + */ +struct extent_buffer *btrfs_root_node(struct btrfs_root *root) +{ + struct extent_buffer *eb; + + while (1) { + rcu_read_lock(); + eb = rcu_dereference(root->node); + + /* + * RCU really hurts here, we could free up the root node because + * it was COWed but we may not get the new root node yet so do + * the inc_not_zero dance and if it doesn't work then + * synchronize_rcu and try again. + */ + if (atomic_inc_not_zero(&eb->refs)) { + rcu_read_unlock(); + break; + } + rcu_read_unlock(); + synchronize_rcu(); + } + return eb; +} + +/* + * Cowonly root (not-shareable trees, everything not subvolume or reloc roots), + * just get put onto a simple dirty list. Transaction walks this list to make + * sure they get properly updated on disk. + */ static void add_root_to_dirty_list(struct btrfs_root *root) { - if (test_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state) && - list_empty(&root->dirty_list)) { - list_add(&root->dirty_list, - &root->fs_info->dirty_cowonly_roots); + struct btrfs_fs_info *fs_info = root->fs_info; + + if (test_bit(BTRFS_ROOT_DIRTY, &root->state) || + !test_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state)) + return; + + spin_lock(&fs_info->trans_lock); + if (!test_and_set_bit(BTRFS_ROOT_DIRTY, &root->state)) { + /* Want the extent tree to be the last on the list */ + if (root->root_key.objectid == BTRFS_EXTENT_TREE_OBJECTID) + list_move_tail(&root->dirty_list, + &fs_info->dirty_cowonly_roots); + else + list_move(&root->dirty_list, + &fs_info->dirty_cowonly_roots); } + spin_unlock(&fs_info->trans_lock); } -static void root_add_used(struct btrfs_root *root, u32 size) -{ - btrfs_set_root_used(&root->root_item, - btrfs_root_used(&root->root_item) + size); -} - -static void root_sub_used(struct btrfs_root *root, u32 size) -{ - btrfs_set_root_used(&root->root_item, - btrfs_root_used(&root->root_item) - size); -} - +/* + * used by snapshot creation to make a copy of a root for a tree with + * a given objectid. The buffer with the new root node is returned in + * cow_ret, and this func returns zero on success or a negative error code. + */ int btrfs_copy_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, struct extent_buffer **cow_ret, u64 new_root_objectid) { + struct btrfs_fs_info *fs_info = root->fs_info; struct extent_buffer *cow; int ret = 0; int level; - struct btrfs_root *new_root; struct btrfs_disk_key disk_key; - new_root = kmalloc(sizeof(*new_root), GFP_NOFS); - if (!new_root) - return -ENOMEM; - - memcpy(new_root, root, sizeof(*new_root)); - new_root->root_key.objectid = new_root_objectid; - WARN_ON(test_bit(BTRFS_ROOT_SHAREABLE, &root->state) && - trans->transid != root->fs_info->running_transaction->transid); + trans->transid != fs_info->running_transaction->transid); WARN_ON(test_bit(BTRFS_ROOT_SHAREABLE, &root->state) && trans->transid != root->last_trans); @@ -293,13 +326,11 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, else btrfs_node_key(buf, &disk_key, 0); - cow = btrfs_alloc_tree_block(trans, new_root, 0, new_root_objectid, + cow = btrfs_alloc_tree_block(trans, root, 0, new_root_objectid, &disk_key, level, buf->start, 0, - BTRFS_NESTING_NORMAL); - if (IS_ERR(cow)) { - kfree(new_root); + BTRFS_NESTING_NEW_ROOT); + if (IS_ERR(cow)) return PTR_ERR(cow); - } copy_extent_buffer_full(cow, buf); btrfs_set_header_bytenr(cow, cow->start); @@ -312,14 +343,19 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, else btrfs_set_header_owner(cow, new_root_objectid); - write_extent_buffer_fsid(cow, root->fs_info->fs_devices->metadata_uuid); + write_extent_buffer_fsid(cow, fs_info->fs_devices->metadata_uuid); WARN_ON(btrfs_header_generation(buf) > trans->transid); - ret = btrfs_inc_ref(trans, new_root, cow, 0); - kfree(new_root); - - if (ret) + if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID) + ret = btrfs_inc_ref(trans, root, cow, 1); + else + ret = btrfs_inc_ref(trans, root, cow, 0); + if (ret) { + btrfs_tree_unlock(cow); + free_extent_buffer(cow); + btrfs_abort_transaction(trans, ret); return ret; + } btrfs_mark_buffer_dirty(cow); *cow_ret = cow; @@ -329,8 +365,8 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, /* * check if the tree block can be shared by multiple trees */ -static int btrfs_block_can_be_shared(struct btrfs_root *root, - struct extent_buffer *buf) +int btrfs_block_can_be_shared(struct btrfs_root *root, + struct extent_buffer *buf) { /* * Tree blocks not in shareable trees and tree roots are never shared. @@ -350,8 +386,10 @@ static int btrfs_block_can_be_shared(struct btrfs_root *root, static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, - struct extent_buffer *cow) + struct extent_buffer *cow, + int *last_ref) { + struct btrfs_fs_info *fs_info = root->fs_info; u64 refs; u64 owner; u64 flags; @@ -376,12 +414,20 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, */ if (btrfs_block_can_be_shared(root, buf)) { - ret = btrfs_lookup_extent_info(trans, trans->fs_info, - buf->start, + ret = btrfs_lookup_extent_info(trans, fs_info, buf->start, btrfs_header_level(buf), 1, &refs, &flags); - BUG_ON(ret); - BUG_ON(refs == 0); + if (ret) + return ret; + if (unlikely(refs == 0)) { + btrfs_crit(fs_info, + "found 0 references for tree block at bytenr %llu level %d root %llu", + buf->start, btrfs_header_level(buf), + btrfs_root_id(root)); + ret = -EUCLEAN; + btrfs_abort_transaction(trans, ret); + return ret; + } } else { refs = 1; if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID || @@ -392,22 +438,25 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, } owner = btrfs_header_owner(buf); - BUG_ON(!(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) && - owner == BTRFS_TREE_RELOC_OBJECTID); + BUG_ON(owner == BTRFS_TREE_RELOC_OBJECTID && + !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)); if (refs > 1) { if ((owner == root->root_key.objectid || root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) { ret = btrfs_inc_ref(trans, root, buf, 1); - BUG_ON(ret); + if (ret) + return ret; if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) { ret = btrfs_dec_ref(trans, root, buf, 0); - BUG_ON(ret); + if (ret) + return ret; ret = btrfs_inc_ref(trans, root, cow, 1); - BUG_ON(ret); + if (ret) + return ret; } new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; } else { @@ -417,11 +466,13 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ret = btrfs_inc_ref(trans, root, cow, 1); else ret = btrfs_inc_ref(trans, root, cow, 0); - BUG_ON(ret); + if (ret) + return ret; } if (new_flags != 0) { ret = btrfs_set_disk_extent_flags(trans, buf, new_flags); - BUG_ON(ret); + if (ret) + return ret; } } else { if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) { @@ -430,11 +481,14 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ret = btrfs_inc_ref(trans, root, cow, 1); else ret = btrfs_inc_ref(trans, root, cow, 0); - BUG_ON(ret); + if (ret) + return ret; ret = btrfs_dec_ref(trans, root, buf, 1); - BUG_ON(ret); + if (ret) + return ret; } btrfs_clear_buffer_dirty(trans, buf); + *last_ref = 1; } return 0; } @@ -456,14 +510,24 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, struct extent_buffer *buf, struct extent_buffer *parent, int parent_slot, struct extent_buffer **cow_ret, - u64 search_start, u64 empty_size) + u64 search_start, u64 empty_size, + enum btrfs_lock_nesting nest) { - struct extent_buffer *cow; + struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_disk_key disk_key; - int level; + struct extent_buffer *cow; + int level, ret; + int last_ref = 0; + int unlock_orig = 0; + u64 parent_start = 0; + + if (*cow_ret == buf) + unlock_orig = 1; + + btrfs_assert_tree_write_locked(buf); WARN_ON(test_bit(BTRFS_ROOT_SHAREABLE, &root->state) && - trans->transid != root->fs_info->running_transaction->transid); + trans->transid != fs_info->running_transaction->transid); WARN_ON(test_bit(BTRFS_ROOT_SHAREABLE, &root->state) && trans->transid != root->last_trans); @@ -474,12 +538,17 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, else btrfs_node_key(buf, &disk_key, 0); - cow = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid, - &disk_key, level, search_start, empty_size, - BTRFS_NESTING_NORMAL); + if ((root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && parent) + parent_start = parent->start; + + cow = btrfs_alloc_tree_block(trans, root, parent_start, + root->root_key.objectid, &disk_key, level, + search_start, empty_size, nest); if (IS_ERR(cow)) return PTR_ERR(cow); + /* cow is set to blocking by btrfs_init_new_buffer */ + copy_extent_buffer_full(cow, buf); btrfs_set_header_bytenr(cow, cow->start); btrfs_set_header_generation(cow, trans->transid); @@ -491,38 +560,76 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, else btrfs_set_header_owner(cow, root->root_key.objectid); - write_extent_buffer_fsid(cow, root->fs_info->fs_devices->metadata_uuid); + write_extent_buffer_fsid(cow, fs_info->fs_devices->metadata_uuid); - WARN_ON(!(buf->flags & EXTENT_BUFFER_BAD_TRANSID) && - btrfs_header_generation(buf) > trans->transid); + ret = update_ref_for_cow(trans, root, buf, cow, &last_ref); + if (ret) { + btrfs_tree_unlock(cow); + free_extent_buffer(cow); + btrfs_abort_transaction(trans, ret); + return ret; + } - update_ref_for_cow(trans, root, buf, cow); + if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state)) { + ret = btrfs_reloc_cow_block(trans, root, buf, cow); + if (ret) { + btrfs_tree_unlock(cow); + free_extent_buffer(cow); + btrfs_abort_transaction(trans, ret); + return ret; + } + } if (buf == root->node) { - root->node = cow; - extent_buffer_get(cow); + WARN_ON(parent && parent != buf); + if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID || + btrfs_header_backref_rev(buf) < BTRFS_MIXED_BACKREF_REV) + parent_start = buf->start; - btrfs_free_extent(trans, buf->start, buf->len, 0, - root->root_key.objectid, level, 0); + ret = btrfs_tree_mod_log_insert_root(root->node, cow, true); + if (ret < 0) { + btrfs_tree_unlock(cow); + free_extent_buffer(cow); + btrfs_abort_transaction(trans, ret); + return ret; + } + atomic_inc(&cow->refs); + rcu_assign_pointer(root->node, cow); + + btrfs_free_tree_block(trans, btrfs_root_id(root), buf, + parent_start, last_ref); free_extent_buffer(buf); add_root_to_dirty_list(root); } else { + WARN_ON(trans->transid != btrfs_header_generation(parent)); + ret = btrfs_tree_mod_log_insert_key(parent, parent_slot, + BTRFS_MOD_LOG_KEY_REPLACE); + if (ret) { + btrfs_tree_unlock(cow); + free_extent_buffer(cow); + btrfs_abort_transaction(trans, ret); + return ret; + } btrfs_set_node_blockptr(parent, parent_slot, cow->start); - WARN_ON(trans->transid == 0); btrfs_set_node_ptr_generation(parent, parent_slot, trans->transid); btrfs_mark_buffer_dirty(parent); - WARN_ON(btrfs_header_generation(parent) != trans->transid); - - btrfs_free_extent(trans, buf->start, buf->len, 0, - root->root_key.objectid, level, 0); + if (last_ref) { + ret = btrfs_tree_mod_log_free_eb(buf); + if (ret) { + btrfs_tree_unlock(cow); + free_extent_buffer(cow); + btrfs_abort_transaction(trans, ret); + return ret; + } + } + btrfs_free_tree_block(trans, btrfs_root_id(root), buf, + parent_start, last_ref); } - if (!list_empty(&buf->recow)) { - list_del_init(&buf->recow); - free_extent_buffer(buf); - } - free_extent_buffer(buf); + if (unlock_orig) + btrfs_tree_unlock(buf); + free_extent_buffer_stale(buf); btrfs_mark_buffer_dirty(cow); *cow_ret = cow; return 0; @@ -532,51 +639,91 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf) { + if (btrfs_is_testing(root->fs_info)) + return 0; + + /* Ensure we can see the FORCE_COW bit */ + smp_mb__before_atomic(); + + /* + * We do not need to cow a block if + * 1) this block is not created or changed in this transaction; + * 2) this block does not belong to TREE_RELOC tree; + * 3) the root is not forced COW. + * + * What is forced COW: + * when we create snapshot during committing the transaction, + * after we've finished copying src root, we must COW the shared + * block to ensure the metadata consistency. + */ if (btrfs_header_generation(buf) == trans->transid && !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN) && !(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID && - btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC))) + btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)) && + !test_bit(BTRFS_ROOT_FORCE_COW, &root->state)) return 0; return 1; } -int btrfs_cow_block(struct btrfs_trans_handle *trans, +/* + * cows a single block, see __btrfs_cow_block for the real work. + * This version of it has extra checks so that a block isn't COWed more than + * once per transaction, as long as it hasn't been written yet + */ +noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, struct extent_buffer *parent, int parent_slot, struct extent_buffer **cow_ret, enum btrfs_lock_nesting nest) { + struct btrfs_fs_info *fs_info = root->fs_info; u64 search_start; int ret; - /* - if (trans->transaction != root->fs_info->running_transaction) { - printk(KERN_CRIT "trans %llu running %llu\n", trans->transid, - root->fs_info->running_transaction->transid); - WARN_ON(1); - } - */ - if (trans->transid != root->fs_info->generation) { - printk(KERN_CRIT "trans %llu running %llu\n", - (unsigned long long)trans->transid, - (unsigned long long)root->fs_info->generation); - WARN_ON(1); - } + + if (test_bit(BTRFS_ROOT_DELETING, &root->state)) + btrfs_err(fs_info, + "COW'ing blocks on a fs root that's being dropped"); + + /* MODIFIED: We don't have trans->transaction. */ +#if 0 + if (trans->transaction != fs_info->running_transaction) + WARN(1, KERN_CRIT "trans %llu running %llu\n", + trans->transid, + fs_info->running_transaction->transid); +#endif + + if (trans->transid != fs_info->generation) + WARN(1, KERN_CRIT "trans %llu running %llu\n", + trans->transid, fs_info->generation); + if (!should_cow_block(trans, root, buf)) { *cow_ret = buf; return 0; } search_start = buf->start & ~((u64)SZ_1G - 1); + + /* + * Before CoWing this block for later modification, check if it's + * the subtree root and do the delayed subtree trace if needed. + * + * Also We don't care about the error, as it's handled internally. + */ + btrfs_qgroup_trace_subtree_after_cow(trans, root, buf); ret = __btrfs_cow_block(trans, root, buf, parent, - parent_slot, cow_ret, search_start, 0); + parent_slot, cow_ret, search_start, 0, nest); + + trace_btrfs_cow_block(root, buf, *cow_ret); + return ret; } +ALLOW_ERROR_INJECTION(btrfs_cow_block, ERRNO); /* * helper function for defrag to decide if two blocks pointed to by a * node are actually close by */ -static __attribute__((unused)) int close_blocks(u64 blocknr, u64 other, u32 blocksize) +static int close_blocks(u64 blocknr, u64 other, u32 blocksize) { if (blocknr < other && other - (blocknr + blocksize) < 32768) return 1; @@ -585,6 +732,35 @@ static __attribute__((unused)) int close_blocks(u64 blocknr, u64 other, u32 bloc return 0; } +#ifdef __LITTLE_ENDIAN + +/* + * Compare two keys, on little-endian the disk order is same as CPU order and + * we can avoid the conversion. + */ +static int comp_keys(const struct btrfs_disk_key *disk_key, + const struct btrfs_key *k2) +{ + const struct btrfs_key *k1 = (const struct btrfs_key *)disk_key; + + return btrfs_comp_cpu_keys(k1, k2); +} + +#else + +/* + * compare two keys in a memcmp fashion + */ +static int comp_keys(const struct btrfs_disk_key *disk, + const struct btrfs_key *k2) +{ + struct btrfs_key k1; + + btrfs_disk_key_to_cpu(&k1, disk); + + return btrfs_comp_cpu_keys(&k1, k2); +} +#endif /* * same as comp_keys only with two btrfs_key's @@ -607,60 +783,151 @@ int __pure btrfs_comp_cpu_keys(const struct btrfs_key *k1, const struct btrfs_ke } /* - * compare two keys in a memcmp fashion + * this is used by the defrag code to go through all the + * leaves pointed to by a node and reallocate them so that + * disk order is close to key order */ -static int btrfs_comp_keys(struct btrfs_disk_key *disk, - const struct btrfs_key *k2) +int btrfs_realloc_node(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct extent_buffer *parent, + int start_slot, u64 *last_ret, + struct btrfs_key *progress) { - struct btrfs_key k1; + struct btrfs_fs_info *fs_info = root->fs_info; + struct extent_buffer *cur; + u64 blocknr; + u64 search_start = *last_ret; + u64 last_block = 0; + u64 other; + u32 parent_nritems; + int end_slot; + int i; + int err = 0; + u32 blocksize; + int progress_passed = 0; + struct btrfs_disk_key disk_key; - btrfs_disk_key_to_cpu(&k1, disk); - return btrfs_comp_cpu_keys(&k1, k2); -} + /* MODIFIED: We don't have trans->transaction. + WARN_ON(trans->transaction != fs_info->running_transaction); + */ + WARN_ON(trans->transid != fs_info->generation); -static int noinline check_block(struct btrfs_fs_info *fs_info, - struct btrfs_path *path, int level) -{ - enum btrfs_tree_block_status ret; + parent_nritems = btrfs_header_nritems(parent); + blocksize = fs_info->nodesize; + end_slot = parent_nritems - 1; - if (path->skip_check_block) + if (parent_nritems <= 1) return 0; - if (level == 0) - ret = __btrfs_check_leaf(path->nodes[0]); - else - ret = __btrfs_check_node(path->nodes[level]); - if (ret == BTRFS_TREE_BLOCK_CLEAN) - return 0; - return -EIO; + + for (i = start_slot; i <= end_slot; i++) { + int close = 1; + + btrfs_node_key(parent, &disk_key, i); + if (!progress_passed && comp_keys(&disk_key, progress) < 0) + continue; + + progress_passed = 1; + blocknr = btrfs_node_blockptr(parent, i); + if (last_block == 0) + last_block = blocknr; + + if (i > 0) { + other = btrfs_node_blockptr(parent, i - 1); + close = close_blocks(blocknr, other, blocksize); + } + if (!close && i < end_slot) { + other = btrfs_node_blockptr(parent, i + 1); + close = close_blocks(blocknr, other, blocksize); + } + if (close) { + last_block = blocknr; + continue; + } + + cur = btrfs_read_node_slot(parent, i); + if (IS_ERR(cur)) + return PTR_ERR(cur); + if (search_start == 0) + search_start = last_block; + + btrfs_tree_lock(cur); + err = __btrfs_cow_block(trans, root, cur, parent, i, + &cur, search_start, + min(16 * blocksize, + (end_slot - i) * blocksize), + BTRFS_NESTING_COW); + if (err) { + btrfs_tree_unlock(cur); + free_extent_buffer(cur); + break; + } + search_start = cur->start; + last_block = cur->start; + *last_ret = search_start; + btrfs_tree_unlock(cur); + free_extent_buffer(cur); + } + return err; } /* - * search for key in the extent_buffer. The items start at offset p, - * and they are item_size apart. There are 'max' items in p. + * Search for a key in the given extent_buffer. * - * the slot in the array is returned via slot, and it points to - * the place where you would insert key if it is not found in - * the array. + * The lower boundary for the search is specified by the slot number @first_slot. + * Use a value of 0 to search over the whole extent buffer. Works for both + * leaves and nodes. * - * slot may point to max if the key is bigger than all of the keys + * The slot in the extent buffer is returned via @slot. If the key exists in the + * extent buffer, then @slot will point to the slot where the key is, otherwise + * it points to the slot where you would insert the key. + * + * Slot may point to the total number of items (i.e. one position beyond the last + * key) if the key is bigger than the last key in the extent buffer. + * + * MODIFIED: Removed the in page optimization. */ -static int generic_bin_search(struct extent_buffer *eb, unsigned long p, - int item_size, const struct btrfs_key *key, - int max, int *slot) +int btrfs_bin_search(struct extent_buffer *eb, int first_slot, + const struct btrfs_key *key, int *slot) { - int low = 0; - int high = max; - int mid; + unsigned long p; + int item_size; + /* + * Use unsigned types for the low and high slots, so that we get a more + * efficient division in the search loop below. + */ + u32 low = first_slot; + u32 high = btrfs_header_nritems(eb); int ret; - unsigned long offset; - struct btrfs_disk_key *tmp; + const int key_size = sizeof(struct btrfs_disk_key); + + if (unlikely(low > high)) { + btrfs_err(eb->fs_info, + "%s: low (%u) > high (%u) eb %llu owner %llu level %d", + __func__, low, high, eb->start, + btrfs_header_owner(eb), btrfs_header_level(eb)); + return -EINVAL; + } + + if (btrfs_header_level(eb) == 0) { + p = offsetof(struct btrfs_leaf, items); + item_size = sizeof(struct btrfs_item); + } else { + p = offsetof(struct btrfs_node, ptrs); + item_size = sizeof(struct btrfs_key_ptr); + } + + while (low < high) { + unsigned long offset; + struct btrfs_disk_key *tmp; + struct btrfs_disk_key unaligned; + int mid; - while(low < high) { mid = (low + high) / 2; offset = p + mid * item_size; - tmp = (struct btrfs_disk_key *)(eb->data + offset); - ret = btrfs_comp_keys(tmp, key); + read_extent_buffer(eb, &unaligned, offset, key_size); + tmp = &unaligned; + + ret = comp_keys(tmp, key); if (ret < 0) low = mid + 1; @@ -675,61 +942,53 @@ static int generic_bin_search(struct extent_buffer *eb, unsigned long p, return 1; } -/* - * simple bin_search frontend that does the right thing for - * leaves vs nodes - */ -int btrfs_bin_search(struct extent_buffer *eb, int first_slot, - const struct btrfs_key *key, int *slot) +static void root_add_used(struct btrfs_root *root, u32 size) { - if (btrfs_header_level(eb) == 0) - return generic_bin_search(eb, - offsetof(struct btrfs_leaf, items), - sizeof(struct btrfs_item), - key, btrfs_header_nritems(eb), - slot); - else - return generic_bin_search(eb, - offsetof(struct btrfs_node, ptrs), - sizeof(struct btrfs_key_ptr), - key, btrfs_header_nritems(eb), - slot); + spin_lock(&root->accounting_lock); + btrfs_set_root_used(&root->root_item, + btrfs_root_used(&root->root_item) + size); + spin_unlock(&root->accounting_lock); } +static void root_sub_used(struct btrfs_root *root, u32 size) +{ + spin_lock(&root->accounting_lock); + btrfs_set_root_used(&root->root_item, + btrfs_root_used(&root->root_item) - size); + spin_unlock(&root->accounting_lock); +} + +/* given a node and slot number, this reads the blocks it points to. The + * extent buffer is returned with a reference taken (but unlocked). + */ struct extent_buffer *btrfs_read_node_slot(struct extent_buffer *parent, int slot) { - struct btrfs_fs_info *fs_info = parent->fs_info; - struct extent_buffer *ret; - struct btrfs_tree_parent_check check = { 0 }; int level = btrfs_header_level(parent); + struct btrfs_tree_parent_check check = { 0 }; + struct extent_buffer *eb; - if (slot < 0) - return NULL; - if (slot >= btrfs_header_nritems(parent)) - return NULL; + if (slot < 0 || slot >= btrfs_header_nritems(parent)) + return ERR_PTR(-ENOENT); - if (level == 0) - return NULL; + ASSERT(level); - check.owner_root = btrfs_header_owner(parent); - check.transid = btrfs_node_ptr_generation(parent, slot); check.level = level - 1; + check.transid = btrfs_node_ptr_generation(parent, slot); + check.owner_root = btrfs_header_owner(parent); + check.has_first_key = true; + btrfs_node_key_to_cpu(parent, &check.first_key, slot); - ret = read_tree_block(fs_info, btrfs_node_blockptr(parent, slot), - &check); - if (!extent_buffer_uptodate(ret)) - return ERR_PTR(-EIO); - - if (btrfs_header_level(ret) != level - 1) { - error( -"child eb corrupted: parent bytenr=%llu item=%d parent level=%d child bytenr=%llu child level=%d", - btrfs_header_bytenr(parent), slot, btrfs_header_level(parent), - btrfs_header_bytenr(ret), btrfs_header_level(ret)); - free_extent_buffer(ret); + eb = read_tree_block(parent->fs_info, btrfs_node_blockptr(parent, slot), + &check); + if (IS_ERR(eb)) + return eb; + if (!extent_buffer_uptodate(eb)) { + free_extent_buffer(eb); return ERR_PTR(-EIO); } - return ret; + + return eb; } /* @@ -752,10 +1011,11 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, int orig_slot = path->slots[level]; u64 orig_ptr; - if (level == 0) - return 0; + ASSERT(level > 0); mid = path->nodes[level]; + + WARN_ON(path->locks[level] != BTRFS_WRITE_LOCK); WARN_ON(btrfs_header_generation(mid) != trans->transid); orig_ptr = btrfs_node_blockptr(mid, orig_slot); @@ -777,48 +1037,82 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, /* promote the child to a root */ child = btrfs_read_node_slot(mid, 0); - BUG_ON(!extent_buffer_uptodate(child)); - ret = btrfs_cow_block(trans, root, child, mid, 0, &child, - BTRFS_NESTING_NORMAL); - BUG_ON(ret); + if (IS_ERR(child)) { + ret = PTR_ERR(child); + goto out; + } + + btrfs_tree_lock(child); + ret = btrfs_cow_block(trans, root, child, mid, 0, &child, + BTRFS_NESTING_COW); + if (ret) { + btrfs_tree_unlock(child); + free_extent_buffer(child); + goto out; + } + + ret = btrfs_tree_mod_log_insert_root(root->node, child, true); + if (ret < 0) { + btrfs_tree_unlock(child); + free_extent_buffer(child); + btrfs_abort_transaction(trans, ret); + goto out; + } + rcu_assign_pointer(root->node, child); - root->node = child; add_root_to_dirty_list(root); + btrfs_tree_unlock(child); + + path->locks[level] = 0; path->nodes[level] = NULL; btrfs_clear_buffer_dirty(trans, mid); + btrfs_tree_unlock(mid); /* once for the path */ free_extent_buffer(mid); root_sub_used(root, mid->len); - - ret = btrfs_free_extent(trans, mid->start, mid->len, 0, - root->root_key.objectid, level, 0); + btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1); /* once for the root ptr */ - free_extent_buffer(mid); - return ret; + free_extent_buffer_stale(mid); + return 0; } if (btrfs_header_nritems(mid) > BTRFS_NODEPTRS_PER_BLOCK(fs_info) / 4) return 0; - left = btrfs_read_node_slot(parent, pslot - 1); - if (extent_buffer_uptodate(left)) { + if (pslot) { + left = btrfs_read_node_slot(parent, pslot - 1); + if (IS_ERR(left)) { + ret = PTR_ERR(left); + left = NULL; + goto out; + } + + __btrfs_tree_lock(left, BTRFS_NESTING_LEFT); wret = btrfs_cow_block(trans, root, left, parent, pslot - 1, &left, - BTRFS_NESTING_NORMAL); + BTRFS_NESTING_LEFT_COW); if (wret) { ret = wret; - goto enospc; + goto out; } } - right = btrfs_read_node_slot(parent, pslot + 1); - if (extent_buffer_uptodate(right)) { + + if (pslot + 1 < btrfs_header_nritems(parent)) { + right = btrfs_read_node_slot(parent, pslot + 1); + if (IS_ERR(right)) { + ret = PTR_ERR(right); + right = NULL; + goto out; + } + + __btrfs_tree_lock(right, BTRFS_NESTING_RIGHT); wret = btrfs_cow_block(trans, root, right, parent, pslot + 1, &right, - BTRFS_NESTING_NORMAL); + BTRFS_NESTING_RIGHT_COW); if (wret) { ret = wret; - goto enospc; + goto out; } } @@ -838,23 +1132,28 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, if (wret < 0 && wret != -ENOSPC) ret = wret; if (btrfs_header_nritems(right) == 0) { - u64 bytenr = right->start; - u32 blocksize = right->len; - btrfs_clear_buffer_dirty(trans, right); - free_extent_buffer(right); + btrfs_tree_unlock(right); + ret = btrfs_del_ptr(trans, root, path, level + 1, pslot + 1); + if (ret < 0) { + free_extent_buffer_stale(right); + right = NULL; + goto out; + } + root_sub_used(root, right->len); + btrfs_free_tree_block(trans, btrfs_root_id(root), right, + 0, 1); + free_extent_buffer_stale(right); right = NULL; - btrfs_del_ptr(trans, root, path, level + 1, pslot + 1); - - root_sub_used(root, blocksize); - wret = btrfs_free_extent(trans, bytenr, blocksize, 0, - root->root_key.objectid, level, - 0); - if (wret) - ret = wret; } else { struct btrfs_disk_key right_key; btrfs_node_key(right, &right_key, 0); + ret = btrfs_tree_mod_log_insert_key(parent, pslot + 1, + BTRFS_MOD_LOG_KEY_REPLACE); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + goto out; + } btrfs_set_node_key(parent, &right_key, pslot + 1); btrfs_mark_buffer_dirty(parent); } @@ -869,11 +1168,19 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, * otherwise we would have pulled some pointers from the * right */ - BUG_ON(!left); + if (unlikely(!left)) { + btrfs_crit(fs_info, +"missing left child when middle child only has 1 item, parent bytenr %llu level %d mid bytenr %llu root %llu", + parent->start, btrfs_header_level(parent), + mid->start, btrfs_root_id(root)); + ret = -EUCLEAN; + btrfs_abort_transaction(trans, ret); + goto out; + } wret = balance_node_right(trans, mid, left); if (wret < 0) { ret = wret; - goto enospc; + goto out; } if (wret == 1) { wret = push_node_left(trans, left, mid, 1); @@ -883,23 +1190,28 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, BUG_ON(wret == 1); } if (btrfs_header_nritems(mid) == 0) { - /* we've managed to empty the middle node, drop it */ - u64 bytenr = mid->start; - u32 blocksize = mid->len; btrfs_clear_buffer_dirty(trans, mid); - free_extent_buffer(mid); + btrfs_tree_unlock(mid); + ret = btrfs_del_ptr(trans, root, path, level + 1, pslot); + if (ret < 0) { + free_extent_buffer_stale(mid); + mid = NULL; + goto out; + } + root_sub_used(root, mid->len); + btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1); + free_extent_buffer_stale(mid); mid = NULL; - btrfs_del_ptr(trans, root, path, level + 1, pslot); - - root_sub_used(root, blocksize); - wret = btrfs_free_extent(trans, bytenr, blocksize, 0, - root->root_key.objectid, level, 0); - if (wret) - ret = wret; } else { /* update the parent key to reflect our changes */ struct btrfs_disk_key mid_key; btrfs_node_key(mid, &mid_key, 0); + ret = btrfs_tree_mod_log_insert_key(parent, pslot, + BTRFS_MOD_LOG_KEY_REPLACE); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + goto out; + } btrfs_set_node_key(parent, &mid_key, pslot); btrfs_mark_buffer_dirty(parent); } @@ -907,27 +1219,34 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, /* update the path */ if (left) { if (btrfs_header_nritems(left) > orig_slot) { - extent_buffer_get(left); + atomic_inc(&left->refs); + /* left was locked after cow */ path->nodes[level] = left; path->slots[level + 1] -= 1; path->slots[level] = orig_slot; - if (mid) + if (mid) { + btrfs_tree_unlock(mid); free_extent_buffer(mid); + } } else { orig_slot -= btrfs_header_nritems(left); path->slots[level] = orig_slot; } } /* double check we haven't messed things up */ - check_block(root->fs_info, path, level); if (orig_ptr != btrfs_node_blockptr(path->nodes[level], path->slots[level])) BUG(); -enospc: - if (right) +out: + if (right) { + btrfs_tree_unlock(right); free_extent_buffer(right); - if (left) + } + if (left) { + if (path->nodes[level] != left) + btrfs_tree_unlock(left); free_extent_buffer(left); + } return ret; } @@ -963,18 +1282,23 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, if (!parent) return 1; - left = btrfs_read_node_slot(parent, pslot - 1); - /* first, try to make some room in the middle buffer */ - if (extent_buffer_uptodate(left)) { + if (pslot) { u32 left_nr; + + left = btrfs_read_node_slot(parent, pslot - 1); + if (IS_ERR(left)) + return PTR_ERR(left); + + __btrfs_tree_lock(left, BTRFS_NESTING_LEFT); + left_nr = btrfs_header_nritems(left); if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(fs_info) - 1) { wret = 1; } else { ret = btrfs_cow_block(trans, root, left, parent, pslot - 1, &left, - BTRFS_NESTING_NORMAL); + BTRFS_NESTING_LEFT_COW); if (ret) wret = 1; else { @@ -987,37 +1311,54 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, struct btrfs_disk_key disk_key; orig_slot += left_nr; btrfs_node_key(mid, &disk_key, 0); + ret = btrfs_tree_mod_log_insert_key(parent, pslot, + BTRFS_MOD_LOG_KEY_REPLACE); + if (ret < 0) { + btrfs_tree_unlock(left); + free_extent_buffer(left); + btrfs_abort_transaction(trans, ret); + return ret; + } btrfs_set_node_key(parent, &disk_key, pslot); btrfs_mark_buffer_dirty(parent); if (btrfs_header_nritems(left) > orig_slot) { path->nodes[level] = left; path->slots[level + 1] -= 1; path->slots[level] = orig_slot; + btrfs_tree_unlock(mid); free_extent_buffer(mid); } else { orig_slot -= btrfs_header_nritems(left); path->slots[level] = orig_slot; + btrfs_tree_unlock(left); free_extent_buffer(left); } return 0; } + btrfs_tree_unlock(left); free_extent_buffer(left); } - right= btrfs_read_node_slot(parent, pslot + 1); /* * then try to empty the right most buffer into the middle */ - if (extent_buffer_uptodate(right)) { + if (pslot + 1 < btrfs_header_nritems(parent)) { u32 right_nr; + + right = btrfs_read_node_slot(parent, pslot + 1); + if (IS_ERR(right)) + return PTR_ERR(right); + + __btrfs_tree_lock(right, BTRFS_NESTING_RIGHT); + right_nr = btrfs_header_nritems(right); - if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root->fs_info) - 1) { + if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(fs_info) - 1) { wret = 1; } else { ret = btrfs_cow_block(trans, root, right, parent, pslot + 1, - &right, BTRFS_NESTING_NORMAL); + &right, BTRFS_NESTING_RIGHT_COW); if (ret) wret = 1; else { @@ -1030,6 +1371,14 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, struct btrfs_disk_key disk_key; btrfs_node_key(right, &disk_key, 0); + ret = btrfs_tree_mod_log_insert_key(parent, pslot + 1, + BTRFS_MOD_LOG_KEY_REPLACE); + if (ret < 0) { + btrfs_tree_unlock(right); + free_extent_buffer(right); + btrfs_abort_transaction(trans, ret); + return ret; + } btrfs_set_node_key(parent, &disk_key, pslot + 1); btrfs_mark_buffer_dirty(parent); @@ -1038,12 +1387,15 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, path->slots[level + 1] += 1; path->slots[level] = orig_slot - btrfs_header_nritems(mid); + btrfs_tree_unlock(mid); free_extent_buffer(mid); } else { + btrfs_tree_unlock(right); free_extent_buffer(right); } return 0; } + btrfs_tree_unlock(right); free_extent_buffer(right); } return 1; @@ -1061,222 +1413,1101 @@ static void reada_for_search(struct btrfs_fs_info *fs_info, struct btrfs_disk_key disk_key; u32 nritems; u64 search; - u64 lowest_read; - u64 highest_read; + u64 target; u64 nread = 0; - int direction = path->reada; - struct extent_buffer *eb; + u64 nread_max; u32 nr; + u32 blocksize; u32 nscan = 0; - if (level != 1) + if (level != 1 && path->reada != READA_FORWARD_ALWAYS) return; if (!path->nodes[level]) return; node = path->nodes[level]; - search = btrfs_node_blockptr(node, slot); - eb = btrfs_find_tree_block(fs_info, search, fs_info->nodesize); - if (eb) { - free_extent_buffer(eb); - return; + + /* + * Since the time between visiting leaves is much shorter than the time + * between visiting nodes, limit read ahead of nodes to 1, to avoid too + * much IO at once (possibly random). + */ + if (path->reada == READA_FORWARD_ALWAYS) { + if (level > 1) + nread_max = node->fs_info->nodesize; + else + nread_max = SZ_128K; + } else { + nread_max = SZ_64K; } - highest_read = search; - lowest_read = search; + search = btrfs_node_blockptr(node, slot); + blocksize = fs_info->nodesize; + if (path->reada != READA_FORWARD_ALWAYS) { + struct extent_buffer *eb; + + eb = find_extent_buffer(fs_info, search); + if (eb) { + free_extent_buffer(eb); + return; + } + } + + target = search; nritems = btrfs_header_nritems(node); nr = slot; - while(1) { - if (direction < 0) { + + while (1) { + if (path->reada == READA_BACK) { if (nr == 0) break; nr--; - } else if (direction > 0) { + } else if (path->reada == READA_FORWARD || + path->reada == READA_FORWARD_ALWAYS) { nr++; if (nr >= nritems) break; } - if (path->reada < 0 && objectid) { + if (path->reada == READA_BACK && objectid) { btrfs_node_key(node, &disk_key, nr); if (btrfs_disk_key_objectid(&disk_key) != objectid) break; } search = btrfs_node_blockptr(node, nr); - if ((search >= lowest_read && search <= highest_read) || - (search < lowest_read && lowest_read - search <= 32768) || - (search > highest_read && search - highest_read <= 32768)) { - readahead_tree_block(fs_info, search, - btrfs_node_ptr_generation(node, nr)); - nread += fs_info->nodesize; + if (path->reada == READA_FORWARD_ALWAYS || + (search <= target && target - search <= 65536) || + (search > target && search - target <= 65536)) { + btrfs_readahead_node_child(node, nr); + nread += blocksize; } nscan++; - if (path->reada < 2 && (nread > SZ_256K || nscan > 32)) + if (nread > nread_max || nscan > 32) break; - if(nread > SZ_1M || nscan > 128) - break; - - if (search < lowest_read) - lowest_read = search; - if (search > highest_read) - highest_read = search; } } -int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path, +static noinline void reada_for_balance(struct btrfs_path *path, int level) +{ + struct extent_buffer *parent; + int slot; + int nritems; + + parent = path->nodes[level + 1]; + if (!parent) + return; + + nritems = btrfs_header_nritems(parent); + slot = path->slots[level + 1]; + + if (slot > 0) + btrfs_readahead_node_child(parent, slot - 1); + if (slot + 1 < nritems) + btrfs_readahead_node_child(parent, slot + 1); +} + + +/* + * when we walk down the tree, it is usually safe to unlock the higher layers + * in the tree. The exceptions are when our path goes through slot 0, because + * operations on the tree might require changing key pointers higher up in the + * tree. + * + * callers might also have set path->keep_locks, which tells this code to keep + * the lock if the path points to the last slot in the block. This is part of + * walking through the tree, and selecting the next slot in the higher block. + * + * lowest_unlock sets the lowest level in the tree we're allowed to unlock. so + * if lowest_unlock is 1, level 0 won't be unlocked + */ +static noinline void unlock_up(struct btrfs_path *path, int level, + int lowest_unlock, int min_write_lock_level, + int *write_lock_level) +{ + int i; + int skip_level = level; + bool check_skip = true; + + for (i = level; i < BTRFS_MAX_LEVEL; i++) { + if (!path->nodes[i]) + break; + if (!path->locks[i]) + break; + + if (check_skip) { + if (path->slots[i] == 0) { + skip_level = i + 1; + continue; + } + + if (path->keep_locks) { + u32 nritems; + + nritems = btrfs_header_nritems(path->nodes[i]); + if (nritems < 1 || path->slots[i] >= nritems - 1) { + skip_level = i + 1; + continue; + } + } + } + + if (i >= lowest_unlock && i > skip_level) { + check_skip = false; + btrfs_tree_unlock_rw(path->nodes[i], path->locks[i]); + path->locks[i] = 0; + if (write_lock_level && + i > min_write_lock_level && + i <= *write_lock_level) { + *write_lock_level = i - 1; + } + } + } +} + +/* + * Helper function for btrfs_search_slot() and other functions that do a search + * on a btree. The goal is to find a tree block in the cache (the radix tree at + * fs_info->buffer_radix), but if we can't find it, or it's not up to date, read + * its pages from disk. + * + * Returns -EAGAIN, with the path unlocked, if the caller needs to repeat the + * whole btree search, starting again from the current root node. + */ +static int +read_block_for_search(struct btrfs_root *root, struct btrfs_path *p, + struct extent_buffer **eb_ret, int level, int slot, + const struct btrfs_key *key) +{ + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_tree_parent_check check = { 0 }; + u64 blocknr; + u64 gen; + struct extent_buffer *tmp; + int ret; + int parent_level; + bool unlock_up; + + unlock_up = ((level + 1 < BTRFS_MAX_LEVEL) && p->locks[level + 1]); + blocknr = btrfs_node_blockptr(*eb_ret, slot); + gen = btrfs_node_ptr_generation(*eb_ret, slot); + parent_level = btrfs_header_level(*eb_ret); + btrfs_node_key_to_cpu(*eb_ret, &check.first_key, slot); + check.has_first_key = true; + check.level = parent_level - 1; + check.transid = gen; + check.owner_root = root->root_key.objectid; + + /* + * If we need to read an extent buffer from disk and we are holding locks + * on upper level nodes, we unlock all the upper nodes before reading the + * extent buffer, and then return -EAGAIN to the caller as it needs to + * restart the search. We don't release the lock on the current level + * because we need to walk this node to figure out which blocks to read. + */ + tmp = find_extent_buffer(fs_info, blocknr); + if (tmp) { + if (p->reada == READA_FORWARD_ALWAYS) + reada_for_search(fs_info, p, level, slot, key->objectid); + + /* first we do an atomic uptodate check */ + if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) { + /* + * Do extra check for first_key, eb can be stale due to + * being cached, read from scrub, or have multiple + * parents (shared tree blocks). + */ + if (btrfs_verify_level_key(tmp, + parent_level - 1, &check.first_key, gen)) { + free_extent_buffer(tmp); + return -EUCLEAN; + } + *eb_ret = tmp; + return 0; + } + + if (p->nowait) { + free_extent_buffer(tmp); + return -EAGAIN; + } + + if (unlock_up) + btrfs_unlock_up_safe(p, level + 1); + + /* now we're allowed to do a blocking uptodate check */ + ret = btrfs_read_extent_buffer(tmp, &check); + if (ret) { + free_extent_buffer(tmp); + btrfs_release_path(p); + return -EIO; + } + if (btrfs_check_eb_owner(tmp, root->root_key.objectid)) { + free_extent_buffer(tmp); + btrfs_release_path(p); + return -EUCLEAN; + } + + if (unlock_up) + ret = -EAGAIN; + + goto out; + } else if (p->nowait) { + return -EAGAIN; + } + + if (unlock_up) { + btrfs_unlock_up_safe(p, level + 1); + ret = -EAGAIN; + } else { + ret = 0; + } + + if (p->reada != READA_NONE) + reada_for_search(fs_info, p, level, slot, key->objectid); + + tmp = read_tree_block(fs_info, blocknr, &check); + if (IS_ERR(tmp)) { + btrfs_release_path(p); + return PTR_ERR(tmp); + } + /* + * If the read above didn't mark this buffer up to date, + * it will never end up being up to date. Set ret to EIO now + * and give up so that our caller doesn't loop forever + * on our EAGAINs. + */ + if (!extent_buffer_uptodate(tmp)) + ret = -EIO; + +out: + if (ret == 0) { + *eb_ret = tmp; + } else { + free_extent_buffer(tmp); + btrfs_release_path(p); + } + + return ret; +} + +/* + * helper function for btrfs_search_slot. This does all of the checks + * for node-level blocks and does any balancing required based on + * the ins_len. + * + * If no extra work was required, zero is returned. If we had to + * drop the path, -EAGAIN is returned and btrfs_search_slot must + * start over + */ +static int +setup_nodes_for_search(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct btrfs_path *p, + struct extent_buffer *b, int level, int ins_len, + int *write_lock_level) +{ + struct btrfs_fs_info *fs_info = root->fs_info; + int ret = 0; + + if ((p->search_for_split || ins_len > 0) && btrfs_header_nritems(b) >= + BTRFS_NODEPTRS_PER_BLOCK(fs_info) - 3) { + + if (*write_lock_level < level + 1) { + *write_lock_level = level + 1; + btrfs_release_path(p); + return -EAGAIN; + } + + reada_for_balance(p, level); + ret = split_node(trans, root, p, level); + + b = p->nodes[level]; + } else if (ins_len < 0 && btrfs_header_nritems(b) < + BTRFS_NODEPTRS_PER_BLOCK(fs_info) / 2) { + + if (*write_lock_level < level + 1) { + *write_lock_level = level + 1; + btrfs_release_path(p); + return -EAGAIN; + } + + reada_for_balance(p, level); + ret = balance_level(trans, root, p, level); + if (ret) + return ret; + + b = p->nodes[level]; + if (!b) { + btrfs_release_path(p); + return -EAGAIN; + } + BUG_ON(btrfs_header_nritems(b) == 1); + } + return ret; +} + +int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *path, u64 iobjectid, u64 ioff, u8 key_type, struct btrfs_key *found_key) { int ret; struct btrfs_key key; struct extent_buffer *eb; - struct btrfs_path *path; + + ASSERT(path); + ASSERT(found_key); key.type = key_type; key.objectid = iobjectid; key.offset = ioff; - if (found_path == NULL) { - path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; - } else - path = found_path; - ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0); - if ((ret < 0) || (found_key == NULL)) - goto out; + if (ret < 0) + return ret; eb = path->nodes[0]; if (ret && path->slots[0] >= btrfs_header_nritems(eb)) { ret = btrfs_next_leaf(fs_root, path); if (ret) - goto out; + return ret; eb = path->nodes[0]; } btrfs_item_key_to_cpu(eb, found_key, path->slots[0]); if (found_key->type != key.type || - found_key->objectid != key.objectid) { - ret = 1; + found_key->objectid != key.objectid) + return 1; + + return 0; +} + +static struct extent_buffer *btrfs_search_slot_get_root(struct btrfs_root *root, + struct btrfs_path *p, + int write_lock_level) +{ + struct extent_buffer *b; + int root_lock = 0; + int level = 0; + + if (p->search_commit_root) { + b = root->commit_root; + atomic_inc(&b->refs); + level = btrfs_header_level(b); + /* + * Ensure that all callers have set skip_locking when + * p->search_commit_root = 1. + */ + ASSERT(p->skip_locking == 1); + goto out; } + if (p->skip_locking) { + b = btrfs_root_node(root); + level = btrfs_header_level(b); + goto out; + } + + /* We try very hard to do read locks on the root */ + root_lock = BTRFS_READ_LOCK; + + /* + * If the level is set to maximum, we can skip trying to get the read + * lock. + */ + if (write_lock_level < BTRFS_MAX_LEVEL) { + /* + * We don't know the level of the root node until we actually + * have it read locked + */ + if (p->nowait) { + b = btrfs_try_read_lock_root_node(root); + if (IS_ERR(b)) + return b; + } else { + b = btrfs_read_lock_root_node(root); + } + level = btrfs_header_level(b); + if (level > write_lock_level) + goto out; + + /* Whoops, must trade for write lock */ + btrfs_tree_read_unlock(b); + free_extent_buffer(b); + } + + b = btrfs_lock_root_node(root); + root_lock = BTRFS_WRITE_LOCK; + + /* The level might have changed, check again */ + level = btrfs_header_level(b); + out: - if (path != found_path) - btrfs_free_path(path); + /* + * The root may have failed to write out at some point, and thus is no + * longer valid, return an error in this case. + */ + if (!extent_buffer_uptodate(b)) { + if (root_lock) + btrfs_tree_unlock_rw(b, root_lock); + free_extent_buffer(b); + return ERR_PTR(-EIO); + } + + p->nodes[level] = b; + if (!p->skip_locking) + p->locks[level] = root_lock; + /* + * Callers are responsible for dropping b's references. + */ + return b; +} + +/* + * Replace the extent buffer at the lowest level of the path with a cloned + * version. The purpose is to be able to use it safely, after releasing the + * commit root semaphore, even if relocation is happening in parallel, the + * transaction used for relocation is committed and the extent buffer is + * reallocated in the next transaction. + * + * This is used in a context where the caller does not prevent transaction + * commits from happening, either by holding a transaction handle or holding + * some lock, while it's doing searches through a commit root. + * At the moment it's only used for send operations. + */ +static int finish_need_commit_sem_search(struct btrfs_path *path) +{ + const int i = path->lowest_level; + const int slot = path->slots[i]; + struct extent_buffer *lowest = path->nodes[i]; + struct extent_buffer *clone; + + ASSERT(path->need_commit_sem); + + if (!lowest) + return 0; + + lockdep_assert_held_read(&lowest->fs_info->commit_root_sem); + + clone = btrfs_clone_extent_buffer(lowest); + if (!clone) + return -ENOMEM; + + btrfs_release_path(path); + path->nodes[i] = clone; + path->slots[i] = slot; + + return 0; +} + +static inline int search_for_key_slot(struct extent_buffer *eb, + int search_low_slot, + const struct btrfs_key *key, + int prev_cmp, + int *slot) +{ + /* + * If a previous call to btrfs_bin_search() on a parent node returned an + * exact match (prev_cmp == 0), we can safely assume the target key will + * always be at slot 0 on lower levels, since each key pointer + * (struct btrfs_key_ptr) refers to the lowest key accessible from the + * subtree it points to. Thus we can skip searching lower levels. + */ + if (prev_cmp == 0) { + *slot = 0; + return 0; + } + + return btrfs_bin_search(eb, search_low_slot, key, slot); +} + +static int search_leaf(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + const struct btrfs_key *key, + struct btrfs_path *path, + int ins_len, + int prev_cmp) +{ + struct extent_buffer *leaf = path->nodes[0]; + int leaf_free_space = -1; + int search_low_slot = 0; + int ret; + bool do_bin_search = true; + + /* + * If we are doing an insertion, the leaf has enough free space and the + * destination slot for the key is not slot 0, then we can unlock our + * write lock on the parent, and any other upper nodes, before doing the + * binary search on the leaf (with search_for_key_slot()), allowing other + * tasks to lock the parent and any other upper nodes. + */ + if (ins_len > 0) { + /* + * Cache the leaf free space, since we will need it later and it + * will not change until then. + */ + leaf_free_space = btrfs_leaf_free_space(leaf); + + /* + * !path->locks[1] means we have a single node tree, the leaf is + * the root of the tree. + */ + if (path->locks[1] && leaf_free_space >= ins_len) { + struct btrfs_disk_key first_key; + + ASSERT(btrfs_header_nritems(leaf) > 0); + btrfs_item_key(leaf, &first_key, 0); + + /* + * Doing the extra comparison with the first key is cheap, + * taking into account that the first key is very likely + * already in a cache line because it immediately follows + * the extent buffer's header and we have recently accessed + * the header's level field. + */ + ret = comp_keys(&first_key, key); + if (ret < 0) { + /* + * The first key is smaller than the key we want + * to insert, so we are safe to unlock all upper + * nodes and we have to do the binary search. + * + * We do use btrfs_unlock_up_safe() and not + * unlock_up() because the later does not unlock + * nodes with a slot of 0 - we can safely unlock + * any node even if its slot is 0 since in this + * case the key does not end up at slot 0 of the + * leaf and there's no need to split the leaf. + */ + btrfs_unlock_up_safe(path, 1); + search_low_slot = 1; + } else { + /* + * The first key is >= then the key we want to + * insert, so we can skip the binary search as + * the target key will be at slot 0. + * + * We can not unlock upper nodes when the key is + * less than the first key, because we will need + * to update the key at slot 0 of the parent node + * and possibly of other upper nodes too. + * If the key matches the first key, then we can + * unlock all the upper nodes, using + * btrfs_unlock_up_safe() instead of unlock_up() + * as stated above. + */ + if (ret == 0) + btrfs_unlock_up_safe(path, 1); + /* + * ret is already 0 or 1, matching the result of + * a btrfs_bin_search() call, so there is no need + * to adjust it. + */ + do_bin_search = false; + path->slots[0] = 0; + } + } + } + + if (do_bin_search) { + ret = search_for_key_slot(leaf, search_low_slot, key, + prev_cmp, &path->slots[0]); + if (ret < 0) + return ret; + } + + if (ins_len > 0) { + /* + * Item key already exists. In this case, if we are allowed to + * insert the item (for example, in dir_item case, item key + * collision is allowed), it will be merged with the original + * item. Only the item size grows, no new btrfs item will be + * added. If search_for_extension is not set, ins_len already + * accounts the size btrfs_item, deduct it here so leaf space + * check will be correct. + */ + if (ret == 0 && !path->search_for_extension) { + ASSERT(ins_len >= sizeof(struct btrfs_item)); + ins_len -= sizeof(struct btrfs_item); + } + + ASSERT(leaf_free_space >= 0); + + if (leaf_free_space < ins_len) { + int err; + + err = split_leaf(trans, root, key, path, ins_len, + (ret == 0)); + ASSERT(err <= 0); + if (WARN_ON(err > 0)) + err = -EUCLEAN; + if (err) + ret = err; + } + } + return ret; } /* - * look for key in the tree. path is filled in with nodes along the way - * if key is found, we return zero and you can find the item in the leaf - * level of the path (level 0) + * btrfs_search_slot - look for a key in a tree and perform necessary + * modifications to preserve tree invariants. * - * If the key isn't found, the path points to the slot where it should - * be inserted, and 1 is returned. If there are other errors during the - * search a negative error number is returned. + * @trans: Handle of transaction, used when modifying the tree + * @p: Holds all btree nodes along the search path + * @root: The root node of the tree + * @key: The key we are looking for + * @ins_len: Indicates purpose of search: + * >0 for inserts it's size of item inserted (*) + * <0 for deletions + * 0 for plain searches, not modifying the tree * - * if ins_len > 0, nodes and leaves will be split as we walk down the - * tree. if ins_len < 0, nodes will be merged as we walk down the tree (if - * possible) + * (*) If size of item inserted doesn't include + * sizeof(struct btrfs_item), then p->search_for_extension must + * be set. + * @cow: boolean should CoW operations be performed. Must always be 1 + * when modifying the tree. + * + * If @ins_len > 0, nodes and leaves will be split as we walk down the tree. + * If @ins_len < 0, nodes will be merged as we walk down the tree (if possible) + * + * If @key is found, 0 is returned and you can find the item in the leaf level + * of the path (level 0) + * + * If @key isn't found, 1 is returned and the leaf level of the path (level 0) + * points to the slot where it should be inserted + * + * If an error is encountered while searching the tree a negative error number + * is returned */ -int btrfs_search_slot(struct btrfs_trans_handle *trans, - struct btrfs_root *root, const struct btrfs_key *key, - struct btrfs_path *p, int ins_len, int cow) +int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root, + const struct btrfs_key *key, struct btrfs_path *p, + int ins_len, int cow) { + struct btrfs_fs_info *fs_info = root->fs_info; struct extent_buffer *b; int slot; int ret; + int err; int level; - int should_reada = p->reada; - struct btrfs_fs_info *fs_info = root->fs_info; + int lowest_unlock = 1; + /* everything at write_lock_level or lower must be write locked */ + int write_lock_level = 0; u8 lowest_level = 0; + int min_write_lock_level; + int prev_cmp; + + might_sleep(); lowest_level = p->lowest_level; WARN_ON(lowest_level && ins_len > 0); WARN_ON(p->nodes[0] != NULL); -again: - b = root->node; - extent_buffer_get(b); - while (b) { - level = btrfs_header_level(b); - if (cow) { - int wret; - wret = btrfs_cow_block(trans, root, b, - p->nodes[level + 1], - p->slots[level + 1], - &b, BTRFS_NESTING_NORMAL); - if (wret) { - free_extent_buffer(b); - return wret; - } - } - BUG_ON(!cow && ins_len); - if (level != btrfs_header_level(b)) - WARN_ON(1); - level = btrfs_header_level(b); - p->nodes[level] = b; - ret = check_block(fs_info, p, level); - if (ret) - return -1; - ret = btrfs_bin_search(b, 0, key, &slot); - if (level != 0) { - if (ret && slot > 0) - slot -= 1; - p->slots[level] = slot; - if ((p->search_for_split || ins_len > 0) && - btrfs_header_nritems(b) >= - BTRFS_NODEPTRS_PER_BLOCK(fs_info) - 3) { - int sret = split_node(trans, root, p, level); - BUG_ON(sret > 0); - if (sret) - return sret; - b = p->nodes[level]; - slot = p->slots[level]; - } else if (ins_len < 0) { - int sret = balance_level(trans, root, p, - level); - if (sret) - return sret; - b = p->nodes[level]; - if (!b) { - btrfs_release_path(p); - goto again; - } - slot = p->slots[level]; - BUG_ON(btrfs_header_nritems(b) == 1); - } - /* this is only true while dropping a snapshot */ - if (level == lowest_level) - break; + BUG_ON(!cow && ins_len); - if (should_reada) - reada_for_search(fs_info, p, level, slot, - key->objectid); + /* + * For now only allow nowait for read only operations. There's no + * strict reason why we can't, we just only need it for reads so it's + * only implemented for reads. + */ + ASSERT(!p->nowait || !cow); - b = btrfs_read_node_slot(b, slot); - if (!extent_buffer_uptodate(b)) - return -EIO; + if (ins_len < 0) { + lowest_unlock = 2; + + /* when we are removing items, we might have to go up to level + * two as we update tree pointers Make sure we keep write + * for those levels as well + */ + write_lock_level = 2; + } else if (ins_len > 0) { + /* + * for inserting items, make sure we have a write lock on + * level 1 so we can update keys + */ + write_lock_level = 1; + } + + if (!cow) + write_lock_level = -1; + + if (cow && (p->keep_locks || p->lowest_level)) + write_lock_level = BTRFS_MAX_LEVEL; + + min_write_lock_level = write_lock_level; + + if (p->need_commit_sem) { + ASSERT(p->search_commit_root); + if (p->nowait) { + if (!down_read_trylock(&fs_info->commit_root_sem)) + return -EAGAIN; } else { - p->slots[level] = slot; - if (ins_len > 0 && - ins_len > btrfs_leaf_free_space(b)) { - int sret = split_leaf(trans, root, key, - p, ins_len, ret == 0); - BUG_ON(sret > 0); - if (sret) - return sret; - } - return ret; + down_read(&fs_info->commit_root_sem); } } + +again: + prev_cmp = -1; + b = btrfs_search_slot_get_root(root, p, write_lock_level); + if (IS_ERR(b)) { + ret = PTR_ERR(b); + goto done; + } + + while (b) { + int dec = 0; + + level = btrfs_header_level(b); + + if (cow) { + bool last_level = (level == (BTRFS_MAX_LEVEL - 1)); + + /* + * if we don't really need to cow this block + * then we don't want to set the path blocking, + * so we test it here + */ + if (!should_cow_block(trans, root, b)) + goto cow_done; + + /* + * must have write locks on this node and the + * parent + */ + if (level > write_lock_level || + (level + 1 > write_lock_level && + level + 1 < BTRFS_MAX_LEVEL && + p->nodes[level + 1])) { + write_lock_level = level + 1; + btrfs_release_path(p); + goto again; + } + + if (last_level) + err = btrfs_cow_block(trans, root, b, NULL, 0, + &b, + BTRFS_NESTING_COW); + else + err = btrfs_cow_block(trans, root, b, + p->nodes[level + 1], + p->slots[level + 1], &b, + BTRFS_NESTING_COW); + if (err) { + ret = err; + goto done; + } + } +cow_done: + p->nodes[level] = b; + + /* + * we have a lock on b and as long as we aren't changing + * the tree, there is no way to for the items in b to change. + * It is safe to drop the lock on our parent before we + * go through the expensive btree search on b. + * + * If we're inserting or deleting (ins_len != 0), then we might + * be changing slot zero, which may require changing the parent. + * So, we can't drop the lock until after we know which slot + * we're operating on. + */ + if (!ins_len && !p->keep_locks) { + int u = level + 1; + + if (u < BTRFS_MAX_LEVEL && p->locks[u]) { + btrfs_tree_unlock_rw(p->nodes[u], p->locks[u]); + p->locks[u] = 0; + } + } + + if (level == 0) { + if (ins_len > 0) + ASSERT(write_lock_level >= 1); + + ret = search_leaf(trans, root, key, p, ins_len, prev_cmp); + if (!p->search_for_split) + unlock_up(p, level, lowest_unlock, + min_write_lock_level, NULL); + goto done; + } + + ret = search_for_key_slot(b, 0, key, prev_cmp, &slot); + if (ret < 0) + goto done; + prev_cmp = ret; + + if (ret && slot > 0) { + dec = 1; + slot--; + } + p->slots[level] = slot; + err = setup_nodes_for_search(trans, root, p, b, level, ins_len, + &write_lock_level); + if (err == -EAGAIN) + goto again; + if (err) { + ret = err; + goto done; + } + b = p->nodes[level]; + slot = p->slots[level]; + + /* + * Slot 0 is special, if we change the key we have to update + * the parent pointer which means we must have a write lock on + * the parent + */ + if (slot == 0 && ins_len && write_lock_level < level + 1) { + write_lock_level = level + 1; + btrfs_release_path(p); + goto again; + } + + unlock_up(p, level, lowest_unlock, min_write_lock_level, + &write_lock_level); + + if (level == lowest_level) { + if (dec) + p->slots[level]++; + goto done; + } + + err = read_block_for_search(root, p, &b, level, slot, key); + if (err == -EAGAIN) + goto again; + if (err) { + ret = err; + goto done; + } + + if (!p->skip_locking) { + level = btrfs_header_level(b); + + btrfs_maybe_reset_lockdep_class(root, b); + + if (level <= write_lock_level) { + btrfs_tree_lock(b); + p->locks[level] = BTRFS_WRITE_LOCK; + } else { + if (p->nowait) { + if (!btrfs_try_tree_read_lock(b)) { + free_extent_buffer(b); + ret = -EAGAIN; + goto done; + } + } else { + btrfs_tree_read_lock(b); + } + p->locks[level] = BTRFS_READ_LOCK; + } + p->nodes[level] = b; + } + } + ret = 1; +done: + if (ret < 0 && !p->skip_release_on_error) + btrfs_release_path(p); + + if (p->need_commit_sem) { + int ret2; + + ret2 = finish_need_commit_sem_search(p); + up_read(&fs_info->commit_root_sem); + if (ret2) + ret = ret2; + } + + return ret; +} +ALLOW_ERROR_INJECTION(btrfs_search_slot, ERRNO); + +/* + * Like btrfs_search_slot, this looks for a key in the given tree. It uses the + * current state of the tree together with the operations recorded in the tree + * modification log to search for the key in a previous version of this tree, as + * denoted by the time_seq parameter. + * + * Naturally, there is no support for insert, delete or cow operations. + * + * The resulting path and return value will be set up as if we called + * btrfs_search_slot at that point in time with ins_len and cow both set to 0. + */ +int btrfs_search_old_slot(struct btrfs_root *root, const struct btrfs_key *key, + struct btrfs_path *p, u64 time_seq) +{ + struct btrfs_fs_info *fs_info = root->fs_info; + struct extent_buffer *b; + int slot; + int ret; + int err; + int level; + int lowest_unlock = 1; + u8 lowest_level = 0; + + lowest_level = p->lowest_level; + WARN_ON(p->nodes[0] != NULL); + ASSERT(!p->nowait); + + if (p->search_commit_root) { + BUG_ON(time_seq); + return btrfs_search_slot(NULL, root, key, p, 0, 0); + } + +again: + b = btrfs_get_old_root(root, time_seq); + if (!b) { + ret = -EIO; + goto done; + } + level = btrfs_header_level(b); + p->locks[level] = BTRFS_READ_LOCK; + + while (b) { + int dec = 0; + + level = btrfs_header_level(b); + p->nodes[level] = b; + + /* + * we have a lock on b and as long as we aren't changing + * the tree, there is no way to for the items in b to change. + * It is safe to drop the lock on our parent before we + * go through the expensive btree search on b. + */ + btrfs_unlock_up_safe(p, level + 1); + + ret = btrfs_bin_search(b, 0, key, &slot); + if (ret < 0) + goto done; + + if (level == 0) { + p->slots[level] = slot; + unlock_up(p, level, lowest_unlock, 0, NULL); + goto done; + } + + if (ret && slot > 0) { + dec = 1; + slot--; + } + p->slots[level] = slot; + unlock_up(p, level, lowest_unlock, 0, NULL); + + if (level == lowest_level) { + if (dec) + p->slots[level]++; + goto done; + } + + err = read_block_for_search(root, p, &b, level, slot, key); + if (err == -EAGAIN) + goto again; + if (err) { + ret = err; + goto done; + } + + level = btrfs_header_level(b); + btrfs_tree_read_lock(b); + b = btrfs_tree_mod_log_rewind(fs_info, p, b, time_seq); + if (!b) { + ret = -ENOMEM; + goto done; + } + p->locks[level] = BTRFS_READ_LOCK; + p->nodes[level] = b; + } + ret = 1; +done: + if (ret < 0) + btrfs_release_path(p); + + return ret; +} + +/* + * Search the tree again to find a leaf with smaller keys. + * Returns 0 if it found something. + * Returns 1 if there are no smaller keys. + * Returns < 0 on error. + * + * This may release the path, and so you may lose any locks held at the + * time you call it. + * + * This is exported for use inside btrfs-progs, don't un-export it. + */ +int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) +{ + struct btrfs_key key; + struct btrfs_key orig_key; + struct btrfs_disk_key found_key; + int ret; + + btrfs_item_key_to_cpu(path->nodes[0], &key, 0); + orig_key = key; + + if (key.offset > 0) { + key.offset--; + } else if (key.type > 0) { + key.type--; + key.offset = (u64)-1; + } else if (key.objectid > 0) { + key.objectid--; + key.type = (u8)-1; + key.offset = (u64)-1; + } else { + return 1; + } + + btrfs_release_path(path); + ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); + if (ret <= 0) + return ret; + + /* + * Previous key not found. Even if we were at slot 0 of the leaf we had + * before releasing the path and calling btrfs_search_slot(), we now may + * be in a slot pointing to the same original key - this can happen if + * after we released the path, one of more items were moved from a + * sibling leaf into the front of the leaf we had due to an insertion + * (see push_leaf_right()). + * If we hit this case and our slot is > 0 and just decrement the slot + * so that the caller does not process the same key again, which may or + * may not break the caller, depending on its logic. + */ + if (path->slots[0] < btrfs_header_nritems(path->nodes[0])) { + btrfs_item_key(path->nodes[0], &found_key, path->slots[0]); + ret = comp_keys(&found_key, &orig_key); + if (ret == 0) { + if (path->slots[0] > 0) { + path->slots[0]--; + return 0; + } + /* + * At slot 0, same key as before, it means orig_key is + * the lowest, leftmost, key in the tree. We're done. + */ + return 1; + } + } + + btrfs_item_key(path->nodes[0], &found_key, 0); + ret = comp_keys(&found_key, &key); + /* + * We might have had an item with the previous key in the tree right + * before we released our path. And after we released our path, that + * item might have been pushed to the first slot (0) of the leaf we + * were holding due to a tree balance. Alternatively, an item with the + * previous key can exist as the only element of a leaf (big fat item). + * Therefore account for these 2 cases, so that our callers (like + * btrfs_previous_item) don't miss an existing item with a key matching + * the previous key we computed above. + */ + if (ret <= 0) + return 0; return 1; } /* - * Helper to use instead of search slot if no exact match is needed but + * helper to use instead of search slot if no exact match is needed but * instead the next or previous item should be returned. * When find_higher is true, the next higher item is returned, the next lower * otherwise. @@ -1288,65 +2519,115 @@ again: * < 0 on error */ int btrfs_search_slot_for_read(struct btrfs_root *root, - const struct btrfs_key *key, - struct btrfs_path *p, int find_higher, - int return_any) + const struct btrfs_key *key, + struct btrfs_path *p, int find_higher, + int return_any) { - int ret; - struct extent_buffer *leaf; + int ret; + struct extent_buffer *leaf; again: - ret = btrfs_search_slot(NULL, root, key, p, 0, 0); - if (ret <= 0) - return ret; - /* - * A return value of 1 means the path is at the position where the item - * should be inserted. Normally this is the next bigger item, but in - * case the previous item is the last in a leaf, path points to the - * first free slot in the previous leaf, i.e. at an invalid item. - */ - leaf = p->nodes[0]; + ret = btrfs_search_slot(NULL, root, key, p, 0, 0); + if (ret <= 0) + return ret; + /* + * a return value of 1 means the path is at the position where the + * item should be inserted. Normally this is the next bigger item, + * but in case the previous item is the last in a leaf, path points + * to the first free slot in the previous leaf, i.e. at an invalid + * item. + */ + leaf = p->nodes[0]; - if (find_higher) { - if (p->slots[0] >= btrfs_header_nritems(leaf)) { - ret = btrfs_next_leaf(root, p); - if (ret <= 0) - return ret; - if (!return_any) - return 1; - /* - * No higher item found, return the next lower instead - */ - return_any = 0; - find_higher = 0; - btrfs_release_path(p); - goto again; - } - } else { - if (p->slots[0] == 0) { - ret = btrfs_prev_leaf(root, p); - if (ret < 0) - return ret; - if (!ret) { - leaf = p->nodes[0]; - if (p->slots[0] == btrfs_header_nritems(leaf)) - p->slots[0]--; - return 0; - } - if (!return_any) - return 1; - /* - * No lower item found, return the next higher instead - */ - return_any = 0; - find_higher = 1; - btrfs_release_path(p); - goto again; - } else { - --p->slots[0]; - } - } - return 0; + if (find_higher) { + if (p->slots[0] >= btrfs_header_nritems(leaf)) { + ret = btrfs_next_leaf(root, p); + if (ret <= 0) + return ret; + if (!return_any) + return 1; + /* + * no higher item found, return the next + * lower instead + */ + return_any = 0; + find_higher = 0; + btrfs_release_path(p); + goto again; + } + } else { + if (p->slots[0] == 0) { + ret = btrfs_prev_leaf(root, p); + if (ret < 0) + return ret; + if (!ret) { + leaf = p->nodes[0]; + if (p->slots[0] == btrfs_header_nritems(leaf)) + p->slots[0]--; + return 0; + } + if (!return_any) + return 1; + /* + * no lower item found, return the next + * higher instead + */ + return_any = 0; + find_higher = 1; + btrfs_release_path(p); + goto again; + } else { + --p->slots[0]; + } + } + return 0; +} + +/* + * Execute search and call btrfs_previous_item to traverse backwards if the item + * was not found. + * + * Return 0 if found, 1 if not found and < 0 if error. + */ +int btrfs_search_backwards(struct btrfs_root *root, struct btrfs_key *key, + struct btrfs_path *path) +{ + int ret; + + ret = btrfs_search_slot(NULL, root, key, path, 0, 0); + if (ret > 0) + ret = btrfs_previous_item(root, path, key->objectid, key->type); + + if (ret == 0) + btrfs_item_key_to_cpu(path->nodes[0], key, path->slots[0]); + + return ret; +} + +/* + * Search for a valid slot for the given path. + * + * @root: The root node of the tree. + * @key: Will contain a valid item if found. + * @path: The starting point to validate the slot. + * + * Return: 0 if the item is valid + * 1 if not found + * <0 if error. + */ +int btrfs_get_next_valid_item(struct btrfs_root *root, struct btrfs_key *key, + struct btrfs_path *path) +{ + if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) { + int ret; + + ret = btrfs_next_leaf(root, path); + if (ret) + return ret; + } + + btrfs_item_key_to_cpu(path->nodes[0], key, path->slots[0]); + return 0; } /* @@ -1355,18 +2636,24 @@ again: * This is used after shifting pointers to the left, so it stops * fixing up pointers when a given leaf/node is not in slot 0 of the * higher levels + * */ -static void fixup_low_keys(struct btrfs_path *path, struct btrfs_disk_key *key, - int level) +static void fixup_low_keys(struct btrfs_path *path, + struct btrfs_disk_key *key, int level) { int i; struct extent_buffer *t; + int ret; for (i = level; i < BTRFS_MAX_LEVEL; i++) { int tslot = path->slots[i]; + if (!path->nodes[i]) break; t = path->nodes[i]; + ret = btrfs_tree_mod_log_insert_key(t, tslot, + BTRFS_MOD_LOG_KEY_REPLACE); + BUG_ON(ret < 0); btrfs_set_node_key(t, key, tslot); btrfs_mark_buffer_dirty(path->nodes[i]); if (tslot != 0) @@ -1392,11 +2679,31 @@ void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info, slot = path->slots[0]; if (slot > 0) { btrfs_item_key(eb, &disk_key, slot - 1); - BUG_ON(btrfs_comp_keys(&disk_key, new_key) >= 0); + if (unlikely(comp_keys(&disk_key, new_key) >= 0)) { + btrfs_print_leaf(eb); + btrfs_crit(fs_info, + "slot %u key (%llu %u %llu) new key (%llu %u %llu)", + slot, btrfs_disk_key_objectid(&disk_key), + btrfs_disk_key_type(&disk_key), + btrfs_disk_key_offset(&disk_key), + new_key->objectid, new_key->type, + new_key->offset); + BUG(); + } } if (slot < btrfs_header_nritems(eb) - 1) { btrfs_item_key(eb, &disk_key, slot + 1); - BUG_ON(btrfs_comp_keys(&disk_key, new_key) <= 0); + if (unlikely(comp_keys(&disk_key, new_key) <= 0)) { + btrfs_print_leaf(eb); + btrfs_crit(fs_info, + "slot %u key (%llu %u %llu) new key (%llu %u %llu)", + slot, btrfs_disk_key_objectid(&disk_key), + btrfs_disk_key_type(&disk_key), + btrfs_disk_key_offset(&disk_key), + new_key->objectid, new_key->type, + new_key->offset); + BUG(); + } } btrfs_cpu_key_to_disk(&disk_key, new_key); @@ -1406,6 +2713,62 @@ void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info, fixup_low_keys(path, &disk_key, 1); } +/* + * Check key order of two sibling extent buffers. + * + * Return true if something is wrong. + * Return false if everything is fine. + * + * Tree-checker only works inside one tree block, thus the following + * corruption can not be detected by tree-checker: + * + * Leaf @left | Leaf @right + * -------------------------------------------------------------- + * | 1 | 2 | 3 | 4 | 5 | f6 | | 7 | 8 | + * + * Key f6 in leaf @left itself is valid, but not valid when the next + * key in leaf @right is 7. + * This can only be checked at tree block merge time. + * And since tree checker has ensured all key order in each tree block + * is correct, we only need to bother the last key of @left and the first + * key of @right. + */ +static bool check_sibling_keys(struct extent_buffer *left, + struct extent_buffer *right) +{ + struct btrfs_key left_last; + struct btrfs_key right_first; + int level = btrfs_header_level(left); + int nr_left = btrfs_header_nritems(left); + int nr_right = btrfs_header_nritems(right); + + /* No key to check in one of the tree blocks */ + if (!nr_left || !nr_right) + return false; + + if (level) { + btrfs_node_key_to_cpu(left, &left_last, nr_left - 1); + btrfs_node_key_to_cpu(right, &right_first, 0); + } else { + btrfs_item_key_to_cpu(left, &left_last, nr_left - 1); + btrfs_item_key_to_cpu(right, &right_first, 0); + } + + if (unlikely(btrfs_comp_cpu_keys(&left_last, &right_first) >= 0)) { + btrfs_crit(left->fs_info, "left extent buffer:"); + btrfs_print_tree(left, false); + btrfs_crit(left->fs_info, "right extent buffer:"); + btrfs_print_tree(right, false); + btrfs_crit(left->fs_info, +"bad key order, sibling blocks, left last (%llu %u %llu) right first (%llu %u %llu)", + left_last.objectid, left_last.type, + left_last.offset, right_first.objectid, + right_first.type, right_first.offset); + return true; + } + return false; +} + /* * try to push data from one node into the next node left in the * tree. @@ -1432,9 +2795,8 @@ static int push_node_left(struct btrfs_trans_handle *trans, if (!empty && src_nritems <= 8) return 1; - if (push_items <= 0) { + if (push_items <= 0) return 1; - } if (empty) { push_items = min(src_nritems, push_items); @@ -1451,12 +2813,27 @@ static int push_node_left(struct btrfs_trans_handle *trans, } else push_items = min(src_nritems - 8, push_items); + /* dst is the left eb, src is the middle eb */ + if (check_sibling_keys(dst, src)) { + ret = -EUCLEAN; + btrfs_abort_transaction(trans, ret); + return ret; + } + ret = btrfs_tree_mod_log_eb_copy(dst, src, dst_nritems, 0, push_items); + if (ret) { + btrfs_abort_transaction(trans, ret); + return ret; + } copy_extent_buffer(dst, src, btrfs_node_key_ptr_offset(dst, dst_nritems), btrfs_node_key_ptr_offset(src, 0), - push_items * sizeof(struct btrfs_key_ptr)); + push_items * sizeof(struct btrfs_key_ptr)); if (push_items < src_nritems) { + /* + * btrfs_tree_mod_log_eb_copy handles logging the move, so we + * don't need to do an explicit tree mod log operation for it. + */ memmove_extent_buffer(src, btrfs_node_key_ptr_offset(src, 0), btrfs_node_key_ptr_offset(src, push_items), (src_nritems - push_items) * @@ -1496,32 +2873,46 @@ static int balance_node_right(struct btrfs_trans_handle *trans, src_nritems = btrfs_header_nritems(src); dst_nritems = btrfs_header_nritems(dst); push_items = BTRFS_NODEPTRS_PER_BLOCK(fs_info) - dst_nritems; - if (push_items <= 0) { + if (push_items <= 0) return 1; - } - if (src_nritems < 4) { + if (src_nritems < 4) return 1; - } max_push = src_nritems / 2 + 1; /* don't try to empty the node */ - if (max_push >= src_nritems) { + if (max_push >= src_nritems) return 1; - } if (max_push < push_items) push_items = max_push; + /* dst is the right eb, src is the middle eb */ + if (check_sibling_keys(src, dst)) { + ret = -EUCLEAN; + btrfs_abort_transaction(trans, ret); + return ret; + } + + /* + * btrfs_tree_mod_log_eb_copy handles logging the move, so we don't + * need to do an explicit tree mod log operation for it. + */ memmove_extent_buffer(dst, btrfs_node_key_ptr_offset(dst, push_items), btrfs_node_key_ptr_offset(dst, 0), (dst_nritems) * sizeof(struct btrfs_key_ptr)); + ret = btrfs_tree_mod_log_eb_copy(dst, src, 0, src_nritems - push_items, + push_items); + if (ret) { + btrfs_abort_transaction(trans, ret); + return ret; + } copy_extent_buffer(dst, src, btrfs_node_key_ptr_offset(dst, 0), btrfs_node_key_ptr_offset(src, src_nritems - push_items), - push_items * sizeof(struct btrfs_key_ptr)); + push_items * sizeof(struct btrfs_key_ptr)); btrfs_set_header_nritems(src, src_nritems - push_items); btrfs_set_header_nritems(dst, dst_nritems + push_items); @@ -1539,15 +2930,17 @@ static int balance_node_right(struct btrfs_trans_handle *trans, * * returns zero on success or < 0 on failure. */ -static int noinline insert_new_root(struct btrfs_trans_handle *trans, +static noinline int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int level) { + struct btrfs_fs_info *fs_info = root->fs_info; u64 lower_gen; struct extent_buffer *lower; struct extent_buffer *c; struct extent_buffer *old; struct btrfs_disk_key lower_key; + int ret; BUG_ON(path->nodes[level]); BUG_ON(path->nodes[level-1] != root->node); @@ -1560,23 +2953,13 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans, c = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid, &lower_key, level, root->node->start, 0, - BTRFS_NESTING_NORMAL); - + BTRFS_NESTING_NEW_ROOT); if (IS_ERR(c)) return PTR_ERR(c); - memset_extent_buffer(c, 0, 0, sizeof(struct btrfs_header)); + root_add_used(root, fs_info->nodesize); + btrfs_set_header_nritems(c, 1); - btrfs_set_header_level(c, level); - btrfs_set_header_bytenr(c, c->start); - btrfs_set_header_generation(c, trans->transid); - btrfs_set_header_backref_rev(c, BTRFS_MIXED_BACKREF_REV); - btrfs_set_header_owner(c, root->root_key.objectid); - - root_add_used(root, root->fs_info->nodesize); - - write_extent_buffer_fsid(c, root->fs_info->fs_devices->metadata_uuid); - write_extent_buffer_chunk_tree_uuid(c, root->fs_info->chunk_tree_uuid); btrfs_set_node_key(c, &lower_key, 0); btrfs_set_node_blockptr(c, 0, lower->start); lower_gen = btrfs_header_generation(lower); @@ -1587,14 +2970,22 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(c); old = root->node; - root->node = c; + ret = btrfs_tree_mod_log_insert_root(root->node, c, false); + if (ret < 0) { + btrfs_free_tree_block(trans, btrfs_root_id(root), c, 0, 1); + btrfs_tree_unlock(c); + free_extent_buffer(c); + return ret; + } + rcu_assign_pointer(root->node, c); /* the super has an extra ref to root->node */ free_extent_buffer(old); add_root_to_dirty_list(root); - extent_buffer_get(c); + atomic_inc(&c->refs); path->nodes[level] = c; + path->locks[level] = BTRFS_WRITE_LOCK; path->slots[level] = 0; return 0; } @@ -1605,36 +2996,51 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans, * * slot and level indicate where you want the key to go, and * blocknr is the block the key points to. - * - * returns zero on success and < 0 on any error */ -static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root - *root, struct btrfs_path *path, struct btrfs_disk_key - *key, u64 bytenr, int slot, int level) +static int insert_ptr(struct btrfs_trans_handle *trans, + struct btrfs_path *path, + struct btrfs_disk_key *key, u64 bytenr, + int slot, int level) { struct extent_buffer *lower; int nritems; + int ret; BUG_ON(!path->nodes[level]); + btrfs_assert_tree_write_locked(path->nodes[level]); lower = path->nodes[level]; nritems = btrfs_header_nritems(lower); - if (slot > nritems) - BUG(); - if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root->fs_info)) - BUG(); - if (slot < nritems) { - /* shift the items */ + BUG_ON(slot > nritems); + BUG_ON(nritems == BTRFS_NODEPTRS_PER_BLOCK(trans->fs_info)); + if (slot != nritems) { + if (level) { + ret = btrfs_tree_mod_log_insert_move(lower, slot + 1, + slot, nritems - slot); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + return ret; + } + } memmove_extent_buffer(lower, btrfs_node_key_ptr_offset(lower, slot + 1), btrfs_node_key_ptr_offset(lower, slot), (nritems - slot) * sizeof(struct btrfs_key_ptr)); } + if (level) { + ret = btrfs_tree_mod_log_insert_key(lower, slot, + BTRFS_MOD_LOG_KEY_ADD); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + return ret; + } + } btrfs_set_node_key(lower, key, slot); btrfs_set_node_blockptr(lower, slot, bytenr); WARN_ON(trans->transid == 0); btrfs_set_node_ptr_generation(lower, slot, trans->transid); btrfs_set_header_nritems(lower, nritems + 1); btrfs_mark_buffer_dirty(lower); + return 0; } @@ -1647,21 +3053,31 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root * * returns 0 on success and < 0 on failure */ -static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root - *root, struct btrfs_path *path, int level) +static noinline int split_node(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, int level) { + struct btrfs_fs_info *fs_info = root->fs_info; struct extent_buffer *c; struct extent_buffer *split; struct btrfs_disk_key disk_key; int mid; int ret; - int wret; u32 c_nritems; c = path->nodes[level]; WARN_ON(btrfs_header_generation(c) != trans->transid); if (c == root->node) { - /* trying to split the root, lets make a new one */ + /* + * trying to split the root, lets make a new one + * + * tree mod log: We don't log_removal old root in + * insert_new_root, because that root buffer will be kept as a + * normal node. We are going to log removal of half of the + * elements below with btrfs_tree_mod_log_eb_copy(). We're + * holding a tree lock on the buffer, which is why we cannot + * race with other tree_mod_log users. + */ ret = insert_new_root(trans, root, path, level + 1); if (ret) return ret; @@ -1669,7 +3085,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root ret = push_nodes_for_insert(trans, root, path, level); c = path->nodes[level]; if (!ret && btrfs_header_nritems(c) < - BTRFS_NODEPTRS_PER_BLOCK(root->fs_info) - 3) + BTRFS_NODEPTRS_PER_BLOCK(fs_info) - 3) return 0; if (ret < 0) return ret; @@ -1681,47 +3097,49 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root split = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid, &disk_key, level, c->start, 0, - BTRFS_NESTING_NORMAL); + BTRFS_NESTING_SPLIT); if (IS_ERR(split)) return PTR_ERR(split); - memset_extent_buffer(split, 0, 0, sizeof(struct btrfs_header)); - btrfs_set_header_level(split, btrfs_header_level(c)); - btrfs_set_header_bytenr(split, split->start); - btrfs_set_header_generation(split, trans->transid); - btrfs_set_header_backref_rev(split, BTRFS_MIXED_BACKREF_REV); - btrfs_set_header_owner(split, root->root_key.objectid); - write_extent_buffer_fsid(split, root->fs_info->fs_devices->metadata_uuid); - write_extent_buffer_chunk_tree_uuid(split, root->fs_info->chunk_tree_uuid); - - root_add_used(root, root->fs_info->nodesize); + root_add_used(root, fs_info->nodesize); + ASSERT(btrfs_header_level(c) == level); + ret = btrfs_tree_mod_log_eb_copy(split, c, 0, mid, c_nritems - mid); + if (ret) { + btrfs_tree_unlock(split); + free_extent_buffer(split); + btrfs_abort_transaction(trans, ret); + return ret; + } copy_extent_buffer(split, c, btrfs_node_key_ptr_offset(split, 0), btrfs_node_key_ptr_offset(c, mid), (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); btrfs_set_header_nritems(split, c_nritems - mid); btrfs_set_header_nritems(c, mid); - ret = 0; btrfs_mark_buffer_dirty(c); btrfs_mark_buffer_dirty(split); - wret = insert_ptr(trans, root, path, &disk_key, split->start, - path->slots[level + 1] + 1, - level + 1); - if (wret) - ret = wret; + ret = insert_ptr(trans, path, &disk_key, split->start, + path->slots[level + 1] + 1, level + 1); + if (ret < 0) { + btrfs_tree_unlock(split); + free_extent_buffer(split); + return ret; + } if (path->slots[level] >= mid) { path->slots[level] -= mid; + btrfs_tree_unlock(c); free_extent_buffer(c); path->nodes[level] = split; path->slots[level + 1] += 1; } else { + btrfs_tree_unlock(split); free_extent_buffer(split); } - return ret; + return 0; } /* @@ -1737,7 +3155,7 @@ static int leaf_space_used(const struct extent_buffer *l, int start, int nr) if (!nr) return 0; - data_len = btrfs_item_data_end(l, start); + data_len = btrfs_item_offset(l, start) + btrfs_item_size(l, start); data_len = data_len - btrfs_item_offset(l, end); data_len += sizeof(struct btrfs_item) * nr; WARN_ON(data_len < 0); @@ -1751,101 +3169,76 @@ static int leaf_space_used(const struct extent_buffer *l, int start, int nr) */ int btrfs_leaf_free_space(const struct extent_buffer *leaf) { + struct btrfs_fs_info *fs_info = leaf->fs_info; int nritems = btrfs_header_nritems(leaf); - u32 leaf_data_size; int ret; - BUG_ON(!leaf->fs_info); - BUG_ON(leaf->fs_info->nodesize != leaf->len); - leaf_data_size = BTRFS_LEAF_DATA_SIZE(leaf->fs_info); - ret = leaf_data_size - leaf_space_used(leaf, 0 ,nritems); + ret = BTRFS_LEAF_DATA_SIZE(fs_info) - leaf_space_used(leaf, 0, nritems); if (ret < 0) { - printk("leaf free space ret %d, leaf data size %u, used %d nritems %d\n", - ret, leaf_data_size, leaf_space_used(leaf, 0, nritems), - nritems); + btrfs_crit(fs_info, + "leaf free space ret %d, leaf data size %lu, used %d nritems %d", + ret, + (unsigned long) BTRFS_LEAF_DATA_SIZE(fs_info), + leaf_space_used(leaf, 0, nritems), nritems); } return ret; } /* - * push some data in the path leaf to the right, trying to free up at - * least data_size bytes. returns zero if the push worked, nonzero otherwise - * - * returns 1 if the push failed because the other node didn't have enough - * room, 0 if everything worked out and < 0 if there were major errors. + * min slot controls the lowest index we're willing to push to the + * right. We'll push up to and including min_slot, but no lower */ -static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root - *root, struct btrfs_path *path, int data_size, - int empty) +static noinline int __push_leaf_right(struct btrfs_trans_handle *trans, + struct btrfs_path *path, + int data_size, int empty, + struct extent_buffer *right, + int free_space, u32 left_nritems, + u32 min_slot) { + struct btrfs_fs_info *fs_info = right->fs_info; struct extent_buffer *left = path->nodes[0]; - struct extent_buffer *right; - struct extent_buffer *upper; + struct extent_buffer *upper = path->nodes[1]; + struct btrfs_map_token token; struct btrfs_disk_key disk_key; int slot; u32 i; - int free_space; int push_space = 0; int push_items = 0; - u32 left_nritems; u32 nr; u32 right_nritems; u32 data_end; u32 this_item_size; - int ret; - - slot = path->slots[1]; - if (!path->nodes[1]) { - return 1; - } - upper = path->nodes[1]; - if (slot >= btrfs_header_nritems(upper) - 1) - return 1; - - right = btrfs_read_node_slot(upper, slot + 1); - if (!extent_buffer_uptodate(right)) { - if (IS_ERR(right)) - return PTR_ERR(right); - return -EIO; - } - free_space = btrfs_leaf_free_space(right); - if (free_space < data_size) { - free_extent_buffer(right); - return 1; - } - - /* cow and double check */ - ret = btrfs_cow_block(trans, root, right, upper, - slot + 1, &right, BTRFS_NESTING_NORMAL); - if (ret) { - free_extent_buffer(right); - return 1; - } - free_space = btrfs_leaf_free_space(right); - if (free_space < data_size) { - free_extent_buffer(right); - return 1; - } - - left_nritems = btrfs_header_nritems(left); - if (left_nritems == 0) { - free_extent_buffer(right); - return 1; - } if (empty) nr = 0; else - nr = 1; + nr = max_t(u32, 1, min_slot); + if (path->slots[0] >= left_nritems) + push_space += data_size; + + slot = path->slots[1]; i = left_nritems - 1; while (i >= nr) { + if (!empty && push_items > 0) { + if (path->slots[0] > i) + break; + if (path->slots[0] == i) { + int space = btrfs_leaf_free_space(left); + + if (space + push_space * 2 > free_space) + break; + } + } + if (path->slots[0] == i) - push_space += data_size + sizeof(struct btrfs_item); + push_space += data_size; this_item_size = btrfs_item_size(left, i); - if (this_item_size + sizeof(struct btrfs_item) + push_space > free_space) + if (this_item_size + sizeof(struct btrfs_item) + + push_space > free_space) break; + push_items++; push_space += this_item_size + sizeof(struct btrfs_item); if (i == 0) @@ -1853,13 +3246,10 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root i--; } - if (push_items == 0) { - free_extent_buffer(right); - return 1; - } + if (push_items == 0) + goto out_unlock; - if (!empty && push_items == left_nritems) - WARN_ON(1); + WARN_ON(!empty && push_items == left_nritems); /* push left to right */ right_nritems = btrfs_header_nritems(right); @@ -1869,32 +3259,26 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root /* make room in the right data area */ data_end = leaf_data_end(right); - memmove_extent_buffer(right, - btrfs_item_nr_offset(right, 0) + data_end - push_space, - btrfs_item_nr_offset(right, 0) + data_end, - BTRFS_LEAF_DATA_SIZE(root->fs_info) - data_end); + memmove_leaf_data(right, data_end - push_space, data_end, + BTRFS_LEAF_DATA_SIZE(fs_info) - data_end); /* copy from the left data area */ - copy_extent_buffer(right, left, btrfs_item_nr_offset(right, 0) + - BTRFS_LEAF_DATA_SIZE(root->fs_info) - push_space, - btrfs_item_nr_offset(left, 0) + leaf_data_end(left), push_space); + copy_leaf_data(right, left, BTRFS_LEAF_DATA_SIZE(fs_info) - push_space, + leaf_data_end(left), push_space); - memmove_extent_buffer(right, btrfs_item_nr_offset(right, push_items), - btrfs_item_nr_offset(right, 0), - right_nritems * sizeof(struct btrfs_item)); + memmove_leaf_items(right, push_items, 0, right_nritems); /* copy the items from left to right */ - copy_extent_buffer(right, left, btrfs_item_nr_offset(right, 0), - btrfs_item_nr_offset(left, left_nritems - push_items), - push_items * sizeof(struct btrfs_item)); + copy_leaf_items(right, left, 0, left_nritems - push_items, push_items); /* update the item pointers */ + btrfs_init_map_token(&token, right); right_nritems += push_items; btrfs_set_header_nritems(right, right_nritems); - push_space = BTRFS_LEAF_DATA_SIZE(root->fs_info); + push_space = BTRFS_LEAF_DATA_SIZE(fs_info); for (i = 0; i < right_nritems; i++) { - push_space -= btrfs_item_size(right, i); - btrfs_set_item_offset(right, i, push_space); + push_space -= btrfs_token_item_size(&token, i); + btrfs_set_token_item_offset(&token, i, push_space); } left_nritems -= push_items; @@ -1902,6 +3286,9 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root if (left_nritems) btrfs_mark_buffer_dirty(left); + else + btrfs_clear_buffer_dirty(trans, left); + btrfs_mark_buffer_dirty(right); btrfs_item_key(right, &disk_key, 0); @@ -1911,36 +3298,260 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root /* then fixup the leaf pointer in the path */ if (path->slots[0] >= left_nritems) { path->slots[0] -= left_nritems; + if (btrfs_header_nritems(path->nodes[0]) == 0) + btrfs_clear_buffer_dirty(trans, path->nodes[0]); + btrfs_tree_unlock(path->nodes[0]); free_extent_buffer(path->nodes[0]); path->nodes[0] = right; path->slots[1] += 1; } else { + btrfs_tree_unlock(right); free_extent_buffer(right); } return 0; + +out_unlock: + btrfs_tree_unlock(right); + free_extent_buffer(right); + return 1; } + +/* + * push some data in the path leaf to the right, trying to free up at + * least data_size bytes. returns zero if the push worked, nonzero otherwise + * + * returns 1 if the push failed because the other node didn't have enough + * room, 0 if everything worked out and < 0 if there were major errors. + * + * this will push starting from min_slot to the end of the leaf. It won't + * push any slot lower than min_slot + */ +static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root + *root, struct btrfs_path *path, + int min_data_size, int data_size, + int empty, u32 min_slot) +{ + struct extent_buffer *left = path->nodes[0]; + struct extent_buffer *right; + struct extent_buffer *upper; + int slot; + int free_space; + u32 left_nritems; + int ret; + + if (!path->nodes[1]) + return 1; + + slot = path->slots[1]; + upper = path->nodes[1]; + if (slot >= btrfs_header_nritems(upper) - 1) + return 1; + + btrfs_assert_tree_write_locked(path->nodes[1]); + + right = btrfs_read_node_slot(upper, slot + 1); + if (IS_ERR(right)) + return PTR_ERR(right); + + __btrfs_tree_lock(right, BTRFS_NESTING_RIGHT); + + free_space = btrfs_leaf_free_space(right); + if (free_space < data_size) + goto out_unlock; + + ret = btrfs_cow_block(trans, root, right, upper, + slot + 1, &right, BTRFS_NESTING_RIGHT_COW); + if (ret) + goto out_unlock; + + left_nritems = btrfs_header_nritems(left); + if (left_nritems == 0) + goto out_unlock; + + if (check_sibling_keys(left, right)) { + ret = -EUCLEAN; + btrfs_abort_transaction(trans, ret); + btrfs_tree_unlock(right); + free_extent_buffer(right); + return ret; + } + if (path->slots[0] == left_nritems && !empty) { + /* Key greater than all keys in the leaf, right neighbor has + * enough room for it and we're not emptying our leaf to delete + * it, therefore use right neighbor to insert the new item and + * no need to touch/dirty our left leaf. */ + btrfs_tree_unlock(left); + free_extent_buffer(left); + path->nodes[0] = right; + path->slots[0] = 0; + path->slots[1]++; + return 0; + } + + return __push_leaf_right(trans, path, min_data_size, empty, right, + free_space, left_nritems, min_slot); +out_unlock: + btrfs_tree_unlock(right); + free_extent_buffer(right); + return 1; +} + /* * push some data in the path leaf to the left, trying to free up at * least data_size bytes. returns zero if the push worked, nonzero otherwise + * + * max_slot can put a limit on how far into the leaf we'll push items. The + * item at 'max_slot' won't be touched. Use (u32)-1 to make us do all the + * items */ -static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root - *root, struct btrfs_path *path, int data_size, - int empty) +static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, + struct btrfs_path *path, int data_size, + int empty, struct extent_buffer *left, + int free_space, u32 right_nritems, + u32 max_slot) { + struct btrfs_fs_info *fs_info = left->fs_info; struct btrfs_disk_key disk_key; struct extent_buffer *right = path->nodes[0]; - struct extent_buffer *left; - int slot; int i; - int free_space; int push_space = 0; int push_items = 0; u32 old_left_nritems; - u32 right_nritems; u32 nr; int ret = 0; u32 this_item_size; u32 old_left_item_size; + struct btrfs_map_token token; + + if (empty) + nr = min(right_nritems, max_slot); + else + nr = min(right_nritems - 1, max_slot); + + for (i = 0; i < nr; i++) { + if (!empty && push_items > 0) { + if (path->slots[0] < i) + break; + if (path->slots[0] == i) { + int space = btrfs_leaf_free_space(right); + + if (space + push_space * 2 > free_space) + break; + } + } + + if (path->slots[0] == i) + push_space += data_size; + + this_item_size = btrfs_item_size(right, i); + if (this_item_size + sizeof(struct btrfs_item) + push_space > + free_space) + break; + + push_items++; + push_space += this_item_size + sizeof(struct btrfs_item); + } + + if (push_items == 0) { + ret = 1; + goto out; + } + WARN_ON(!empty && push_items == btrfs_header_nritems(right)); + + /* push data from right to left */ + copy_leaf_items(left, right, btrfs_header_nritems(left), 0, push_items); + + push_space = BTRFS_LEAF_DATA_SIZE(fs_info) - + btrfs_item_offset(right, push_items - 1); + + copy_leaf_data(left, right, leaf_data_end(left) - push_space, + btrfs_item_offset(right, push_items - 1), push_space); + old_left_nritems = btrfs_header_nritems(left); + BUG_ON(old_left_nritems <= 0); + + btrfs_init_map_token(&token, left); + old_left_item_size = btrfs_item_offset(left, old_left_nritems - 1); + for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { + u32 ioff; + + ioff = btrfs_token_item_offset(&token, i); + btrfs_set_token_item_offset(&token, i, + ioff - (BTRFS_LEAF_DATA_SIZE(fs_info) - old_left_item_size)); + } + btrfs_set_header_nritems(left, old_left_nritems + push_items); + + /* fixup right node */ + if (push_items > right_nritems) + WARN(1, KERN_CRIT "push items %d nr %u\n", push_items, + right_nritems); + + if (push_items < right_nritems) { + push_space = btrfs_item_offset(right, push_items - 1) - + leaf_data_end(right); + memmove_leaf_data(right, + BTRFS_LEAF_DATA_SIZE(fs_info) - push_space, + leaf_data_end(right), push_space); + + memmove_leaf_items(right, 0, push_items, + btrfs_header_nritems(right) - push_items); + } + + btrfs_init_map_token(&token, right); + right_nritems -= push_items; + btrfs_set_header_nritems(right, right_nritems); + push_space = BTRFS_LEAF_DATA_SIZE(fs_info); + for (i = 0; i < right_nritems; i++) { + push_space = push_space - btrfs_token_item_size(&token, i); + btrfs_set_token_item_offset(&token, i, push_space); + } + + btrfs_mark_buffer_dirty(left); + if (right_nritems) + btrfs_mark_buffer_dirty(right); + else + btrfs_clear_buffer_dirty(trans, right); + + btrfs_item_key(right, &disk_key, 0); + fixup_low_keys(path, &disk_key, 1); + + /* then fixup the leaf pointer in the path */ + if (path->slots[0] < push_items) { + path->slots[0] += old_left_nritems; + btrfs_tree_unlock(path->nodes[0]); + free_extent_buffer(path->nodes[0]); + path->nodes[0] = left; + path->slots[1] -= 1; + } else { + btrfs_tree_unlock(left); + free_extent_buffer(left); + path->slots[0] -= push_items; + } + BUG_ON(path->slots[0] < 0); + return ret; +out: + btrfs_tree_unlock(left); + free_extent_buffer(left); + return ret; +} + +/* + * push some data in the path leaf to the left, trying to free up at + * least data_size bytes. returns zero if the push worked, nonzero otherwise + * + * max_slot can put a limit on how far into the leaf we'll push items. The + * item at 'max_slot' won't be touched. Use (u32)-1 to make us push all the + * items + */ +static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root + *root, struct btrfs_path *path, int min_data_size, + int data_size, int empty, u32 max_slot) +{ + struct extent_buffer *right = path->nodes[0]; + struct extent_buffer *left; + int slot; + int free_space; + u32 right_nritems; + int ret = 0; slot = path->slots[1]; if (slot == 0) @@ -1949,199 +3560,171 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root return 1; right_nritems = btrfs_header_nritems(right); - if (right_nritems == 0) { + if (right_nritems == 0) return 1; - } + + btrfs_assert_tree_write_locked(path->nodes[1]); left = btrfs_read_node_slot(path->nodes[1], slot - 1); + if (IS_ERR(left)) + return PTR_ERR(left); + + __btrfs_tree_lock(left, BTRFS_NESTING_LEFT); + free_space = btrfs_leaf_free_space(left); if (free_space < data_size) { - free_extent_buffer(left); - return 1; + ret = 1; + goto out; } - /* cow and double check */ ret = btrfs_cow_block(trans, root, left, path->nodes[1], slot - 1, &left, - BTRFS_NESTING_NORMAL); + BTRFS_NESTING_LEFT_COW); if (ret) { /* we hit -ENOSPC, but it isn't fatal here */ - free_extent_buffer(left); - return 1; + if (ret == -ENOSPC) + ret = 1; + goto out; } - free_space = btrfs_leaf_free_space(left); - if (free_space < data_size) { - free_extent_buffer(left); - return 1; + if (check_sibling_keys(left, right)) { + ret = -EUCLEAN; + btrfs_abort_transaction(trans, ret); + goto out; } - - if (empty) - nr = right_nritems; - else - nr = right_nritems - 1; - - for (i = 0; i < nr; i++) { - if (path->slots[0] == i) - push_space += data_size + sizeof(struct btrfs_item); - - this_item_size = btrfs_item_size(right, i); - if (this_item_size + sizeof(struct btrfs_item) + push_space > free_space) - break; - - push_items++; - push_space += this_item_size + sizeof(struct btrfs_item); - } - - if (push_items == 0) { - free_extent_buffer(left); - return 1; - } - if (!empty && push_items == btrfs_header_nritems(right)) - WARN_ON(1); - - /* push data from right to left */ - copy_extent_buffer(left, right, - btrfs_item_nr_offset(left, btrfs_header_nritems(left)), - btrfs_item_nr_offset(right, 0), - push_items * sizeof(struct btrfs_item)); - - push_space = BTRFS_LEAF_DATA_SIZE(root->fs_info) - - btrfs_item_offset(right, push_items -1); - - copy_extent_buffer(left, right, btrfs_item_nr_offset(left, 0) + - leaf_data_end(left) - push_space, - btrfs_item_nr_offset(right, 0) + - btrfs_item_offset(right, push_items - 1), - push_space); - old_left_nritems = btrfs_header_nritems(left); - BUG_ON(old_left_nritems == 0); - - old_left_item_size = btrfs_item_offset(left, old_left_nritems - 1); - for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { - u32 ioff; - - ioff = btrfs_item_offset(left, i); - btrfs_set_item_offset(left, i, - ioff - (BTRFS_LEAF_DATA_SIZE(root->fs_info) - - old_left_item_size)); - } - btrfs_set_header_nritems(left, old_left_nritems + push_items); - - /* fixup right node */ - if (push_items > right_nritems) { - printk("push items %d nr %u\n", push_items, right_nritems); - WARN_ON(1); - } - - if (push_items < right_nritems) { - push_space = btrfs_item_offset(right, push_items - 1) - - leaf_data_end(right); - memmove_extent_buffer(right, btrfs_item_nr_offset(right, 0) + - BTRFS_LEAF_DATA_SIZE(root->fs_info) - - push_space, - btrfs_item_nr_offset(right, 0) + - leaf_data_end(right), push_space); - - memmove_extent_buffer(right, btrfs_item_nr_offset(right, 0), - btrfs_item_nr_offset(right, push_items), - (btrfs_header_nritems(right) - push_items) * - sizeof(struct btrfs_item)); - } - right_nritems -= push_items; - btrfs_set_header_nritems(right, right_nritems); - push_space = BTRFS_LEAF_DATA_SIZE(root->fs_info); - for (i = 0; i < right_nritems; i++) { - push_space = push_space - btrfs_item_size(right, i); - btrfs_set_item_offset(right, i, push_space); - } - - btrfs_mark_buffer_dirty(left); - if (right_nritems) - btrfs_mark_buffer_dirty(right); - - btrfs_item_key(right, &disk_key, 0); - fixup_low_keys(path, &disk_key, 1); - - /* then fixup the leaf pointer in the path */ - if (path->slots[0] < push_items) { - path->slots[0] += old_left_nritems; - free_extent_buffer(path->nodes[0]); - path->nodes[0] = left; - path->slots[1] -= 1; - } else { - free_extent_buffer(left); - path->slots[0] -= push_items; - } - BUG_ON(path->slots[0] < 0); + return __push_leaf_left(trans, path, min_data_size, empty, left, + free_space, right_nritems, max_slot); +out: + btrfs_tree_unlock(left); + free_extent_buffer(left); return ret; } /* * split the path's leaf in two, making sure there is at least data_size * available for the resulting leaf level of the path. - * - * returns 0 if all went well and < 0 on failure. */ static noinline int copy_for_split(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - struct extent_buffer *l, - struct extent_buffer *right, - int slot, int mid, int nritems) + struct btrfs_path *path, + struct extent_buffer *l, + struct extent_buffer *right, + int slot, int mid, int nritems) { + struct btrfs_fs_info *fs_info = trans->fs_info; int data_copy_size; int rt_data_off; int i; - int ret = 0; - int wret; + int ret; struct btrfs_disk_key disk_key; + struct btrfs_map_token token; nritems = nritems - mid; btrfs_set_header_nritems(right, nritems); data_copy_size = btrfs_item_data_end(l, mid) - leaf_data_end(l); - copy_extent_buffer(right, l, btrfs_item_nr_offset(right, 0), - btrfs_item_nr_offset(l, mid), - nritems * sizeof(struct btrfs_item)); + copy_leaf_items(right, l, 0, mid, nritems); - copy_extent_buffer(right, l, - btrfs_item_nr_offset(right, 0) + - BTRFS_LEAF_DATA_SIZE(root->fs_info) - data_copy_size, - btrfs_item_nr_offset(l, 0) + leaf_data_end(l), data_copy_size); + copy_leaf_data(right, l, BTRFS_LEAF_DATA_SIZE(fs_info) - data_copy_size, + leaf_data_end(l), data_copy_size); - rt_data_off = BTRFS_LEAF_DATA_SIZE(root->fs_info) - - btrfs_item_data_end(l, mid); + rt_data_off = BTRFS_LEAF_DATA_SIZE(fs_info) - btrfs_item_data_end(l, mid); + btrfs_init_map_token(&token, right); for (i = 0; i < nritems; i++) { - u32 ioff = btrfs_item_offset(right, i); - btrfs_set_item_offset(right, i, ioff + rt_data_off); + u32 ioff; + + ioff = btrfs_token_item_offset(&token, i); + btrfs_set_token_item_offset(&token, i, ioff + rt_data_off); } btrfs_set_header_nritems(l, mid); - ret = 0; btrfs_item_key(right, &disk_key, 0); - wret = insert_ptr(trans, root, path, &disk_key, right->start, - path->slots[1] + 1, 1); - if (wret) - ret = wret; + ret = insert_ptr(trans, path, &disk_key, right->start, path->slots[1] + 1, 1); + if (ret < 0) + return ret; btrfs_mark_buffer_dirty(right); btrfs_mark_buffer_dirty(l); BUG_ON(path->slots[0] != slot); if (mid <= slot) { + btrfs_tree_unlock(path->nodes[0]); free_extent_buffer(path->nodes[0]); path->nodes[0] = right; path->slots[0] -= mid; path->slots[1] += 1; } else { + btrfs_tree_unlock(right); free_extent_buffer(right); } BUG_ON(path->slots[0] < 0); - return ret; + return 0; +} + +/* + * double splits happen when we need to insert a big item in the middle + * of a leaf. A double split can leave us with 3 mostly empty leaves: + * leaf: [ slots 0 - N] [ our target ] [ N + 1 - total in leaf ] + * A B C + * + * We avoid this by trying to push the items on either side of our target + * into the adjacent leaves. If all goes well we can avoid the double split + * completely. + */ +static noinline int push_for_double_split(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + int data_size) +{ + int ret; + int progress = 0; + int slot; + u32 nritems; + int space_needed = data_size; + + slot = path->slots[0]; + if (slot < btrfs_header_nritems(path->nodes[0])) + space_needed -= btrfs_leaf_free_space(path->nodes[0]); + + /* + * try to push all the items after our slot into the + * right leaf + */ + ret = push_leaf_right(trans, root, path, 1, space_needed, 0, slot); + if (ret < 0) + return ret; + + if (ret == 0) + progress++; + + nritems = btrfs_header_nritems(path->nodes[0]); + /* + * our goal is to get our slot at the start or end of a leaf. If + * we've done so we're done + */ + if (path->slots[0] == 0 || path->slots[0] == nritems) + return 0; + + if (btrfs_leaf_free_space(path->nodes[0]) >= data_size) + return 0; + + /* try to push all the items before our slot into the next leaf */ + slot = path->slots[0]; + space_needed = data_size; + if (slot > 0) + space_needed -= btrfs_leaf_free_space(path->nodes[0]); + ret = push_leaf_left(trans, root, path, 1, space_needed, 0, slot); + if (ret < 0) + return ret; + + if (ret == 0) + progress++; + + if (progress) + return 0; + return 1; } /* @@ -2162,24 +3745,36 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, int mid; int slot; struct extent_buffer *right; + struct btrfs_fs_info *fs_info = root->fs_info; int ret = 0; int wret; int split; int num_doubles = 0; + int tried_avoid_double = 0; l = path->nodes[0]; slot = path->slots[0]; if (extend && data_size + btrfs_item_size(l, slot) + - sizeof(struct btrfs_item) > BTRFS_LEAF_DATA_SIZE(root->fs_info)) + sizeof(struct btrfs_item) > BTRFS_LEAF_DATA_SIZE(fs_info)) return -EOVERFLOW; /* first try to make some room by pushing left and right */ - if (data_size && ins_key->type != BTRFS_DIR_ITEM_KEY) { - wret = push_leaf_right(trans, root, path, data_size, 0); + if (data_size && path->nodes[1]) { + int space_needed = data_size; + + if (slot < btrfs_header_nritems(l)) + space_needed -= btrfs_leaf_free_space(l); + + wret = push_leaf_right(trans, root, path, space_needed, + space_needed, 0, 0); if (wret < 0) return wret; if (wret) { - wret = push_leaf_left(trans, root, path, data_size, 0); + space_needed = data_size; + if (slot > 0) + space_needed -= btrfs_leaf_free_space(l); + wret = push_leaf_left(trans, root, path, space_needed, + space_needed, 0, (u32)-1); if (wret < 0) return wret; } @@ -2205,22 +3800,23 @@ again: if (mid <= slot) { if (nritems == 1 || leaf_space_used(l, mid, nritems - mid) + data_size > - BTRFS_LEAF_DATA_SIZE(root->fs_info)) { + BTRFS_LEAF_DATA_SIZE(fs_info)) { if (slot >= nritems) { split = 0; } else { mid = slot; if (mid != nritems && leaf_space_used(l, mid, nritems - mid) + - data_size > - BTRFS_LEAF_DATA_SIZE(root->fs_info)) { + data_size > BTRFS_LEAF_DATA_SIZE(fs_info)) { + if (data_size && !tried_avoid_double) + goto push_for_double; split = 2; } } } } else { if (leaf_space_used(l, 0, mid) + data_size > - BTRFS_LEAF_DATA_SIZE(root->fs_info)) { + BTRFS_LEAF_DATA_SIZE(fs_info)) { if (!extend && data_size && slot == 0) { split = 0; } else if ((extend || !data_size) && slot == 0) { @@ -2229,9 +3825,10 @@ again: mid = slot; if (mid != nritems && leaf_space_used(l, mid, nritems - mid) + - data_size > - BTRFS_LEAF_DATA_SIZE(root->fs_info)) { - split = 2 ; + data_size > BTRFS_LEAF_DATA_SIZE(fs_info)) { + if (data_size && !tried_avoid_double) + goto push_for_double; + split = 2; } } } @@ -2242,58 +3839,68 @@ again: else btrfs_item_key(l, &disk_key, mid); + /* + * We have to about BTRFS_NESTING_NEW_ROOT here if we've done a double + * split, because we're only allowed to have MAX_LOCKDEP_SUBCLASSES + * subclasses, which is 8 at the time of this patch, and we've maxed it + * out. In the future we could add a + * BTRFS_NESTING_SPLIT_THE_SPLITTENING if we need to, but for now just + * use BTRFS_NESTING_NEW_ROOT. + */ right = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid, &disk_key, 0, l->start, 0, - BTRFS_NESTING_NORMAL); - if (IS_ERR(right)) { - BUG_ON(1); + num_doubles ? BTRFS_NESTING_NEW_ROOT : + BTRFS_NESTING_SPLIT); + if (IS_ERR(right)) return PTR_ERR(right); - } - memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header)); - btrfs_set_header_bytenr(right, right->start); - btrfs_set_header_generation(right, trans->transid); - btrfs_set_header_backref_rev(right, BTRFS_MIXED_BACKREF_REV); - btrfs_set_header_owner(right, root->root_key.objectid); - btrfs_set_header_level(right, 0); - write_extent_buffer_fsid(right, root->fs_info->fs_devices->metadata_uuid); - write_extent_buffer_chunk_tree_uuid(right, root->fs_info->chunk_tree_uuid); - - root_add_used(root, root->fs_info->nodesize); + root_add_used(root, fs_info->nodesize); if (split == 0) { if (mid <= slot) { btrfs_set_header_nritems(right, 0); - wret = insert_ptr(trans, root, path, - &disk_key, right->start, - path->slots[1] + 1, 1); - if (wret) - ret = wret; - + ret = insert_ptr(trans, path, &disk_key, + right->start, path->slots[1] + 1, 1); + if (ret < 0) { + btrfs_tree_unlock(right); + free_extent_buffer(right); + return ret; + } + btrfs_tree_unlock(path->nodes[0]); free_extent_buffer(path->nodes[0]); path->nodes[0] = right; path->slots[0] = 0; path->slots[1] += 1; } else { btrfs_set_header_nritems(right, 0); - wret = insert_ptr(trans, root, path, - &disk_key, - right->start, - path->slots[1], 1); - if (wret) - ret = wret; + ret = insert_ptr(trans, path, &disk_key, + right->start, path->slots[1], 1); + if (ret < 0) { + btrfs_tree_unlock(right); + free_extent_buffer(right); + return ret; + } + btrfs_tree_unlock(path->nodes[0]); free_extent_buffer(path->nodes[0]); path->nodes[0] = right; path->slots[0] = 0; if (path->slots[1] == 0) fixup_low_keys(path, &disk_key, 1); } - btrfs_mark_buffer_dirty(right); + /* + * We create a new leaf 'right' for the required ins_len and + * we'll do btrfs_mark_buffer_dirty() on this leaf after copying + * the content of ins_len to 'right'. + */ return ret; } - ret = copy_for_split(trans, root, path, l, right, slot, mid, nritems); - BUG_ON(ret); + ret = copy_for_split(trans, path, l, right, slot, mid, nritems); + if (ret < 0) { + btrfs_tree_unlock(right); + free_extent_buffer(right); + return ret; + } if (split == 2) { BUG_ON(num_doubles != 0); @@ -2301,9 +3908,148 @@ again: goto again; } + return 0; + +push_for_double: + push_for_double_split(trans, root, path, data_size); + tried_avoid_double = 1; + if (btrfs_leaf_free_space(path->nodes[0]) >= data_size) + return 0; + goto again; +} + +static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, int ins_len) +{ + struct btrfs_key key; + struct extent_buffer *leaf; + struct btrfs_file_extent_item *fi; + u64 extent_len = 0; + u32 item_size; + int ret; + + leaf = path->nodes[0]; + btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); + + BUG_ON(key.type != BTRFS_EXTENT_DATA_KEY && + key.type != BTRFS_EXTENT_CSUM_KEY); + + if (btrfs_leaf_free_space(leaf) >= ins_len) + return 0; + + item_size = btrfs_item_size(leaf, path->slots[0]); + if (key.type == BTRFS_EXTENT_DATA_KEY) { + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + extent_len = btrfs_file_extent_num_bytes(leaf, fi); + } + btrfs_release_path(path); + + path->keep_locks = 1; + path->search_for_split = 1; + ret = btrfs_search_slot(trans, root, &key, path, 0, 1); + path->search_for_split = 0; + if (ret > 0) + ret = -EAGAIN; + if (ret < 0) + goto err; + + ret = -EAGAIN; + leaf = path->nodes[0]; + /* if our item isn't there, return now */ + if (item_size != btrfs_item_size(leaf, path->slots[0])) + goto err; + + /* the leaf has changed, it now has room. return now */ + if (btrfs_leaf_free_space(path->nodes[0]) >= ins_len) + goto err; + + if (key.type == BTRFS_EXTENT_DATA_KEY) { + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + if (extent_len != btrfs_file_extent_num_bytes(leaf, fi)) + goto err; + } + + ret = split_leaf(trans, root, &key, path, ins_len, 1); + if (ret) + goto err; + + path->keep_locks = 0; + btrfs_unlock_up_safe(path, 1); + return 0; +err: + path->keep_locks = 0; return ret; } +static noinline int split_item(struct btrfs_path *path, + const struct btrfs_key *new_key, + unsigned long split_offset) +{ + struct extent_buffer *leaf; + int orig_slot, slot; + char *buf; + u32 nritems; + u32 item_size; + u32 orig_offset; + struct btrfs_disk_key disk_key; + + leaf = path->nodes[0]; + /* + * Shouldn't happen because the caller must have previously called + * setup_leaf_for_split() to make room for the new item in the leaf. + */ + if (WARN_ON(btrfs_leaf_free_space(leaf) < sizeof(struct btrfs_item))) + return -ENOSPC; + + orig_slot = path->slots[0]; + orig_offset = btrfs_item_offset(leaf, path->slots[0]); + item_size = btrfs_item_size(leaf, path->slots[0]); + + buf = kmalloc(item_size, GFP_NOFS); + if (!buf) + return -ENOMEM; + + read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf, + path->slots[0]), item_size); + + slot = path->slots[0] + 1; + nritems = btrfs_header_nritems(leaf); + if (slot != nritems) { + /* shift the items */ + memmove_leaf_items(leaf, slot + 1, slot, nritems - slot); + } + + btrfs_cpu_key_to_disk(&disk_key, new_key); + btrfs_set_item_key(leaf, &disk_key, slot); + + btrfs_set_item_offset(leaf, slot, orig_offset); + btrfs_set_item_size(leaf, slot, item_size - split_offset); + + btrfs_set_item_offset(leaf, orig_slot, + orig_offset + item_size - split_offset); + btrfs_set_item_size(leaf, orig_slot, split_offset); + + btrfs_set_header_nritems(leaf, nritems + 1); + + /* write the data for the start of the original item */ + write_extent_buffer(leaf, buf, + btrfs_item_ptr_offset(leaf, path->slots[0]), + split_offset); + + /* write the data for the new item */ + write_extent_buffer(leaf, buf + split_offset, + btrfs_item_ptr_offset(leaf, slot), + item_size - split_offset); + btrfs_mark_buffer_dirty(leaf); + + BUG_ON(btrfs_leaf_free_space(leaf) < 0); + kfree(buf); + return 0; +} + /* * This function splits a single item into two items, * giving 'new_key' to the new item and splitting the @@ -2325,96 +4071,22 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, const struct btrfs_key *new_key, unsigned long split_offset) { - u32 item_size; - struct extent_buffer *leaf; - struct btrfs_key orig_key; - int ret = 0; - int slot; - u32 nritems; - u32 orig_offset; - struct btrfs_disk_key disk_key; - char *buf; + int ret; + ret = setup_leaf_for_split(trans, root, path, + sizeof(struct btrfs_item)); + if (ret) + return ret; - leaf = path->nodes[0]; - btrfs_item_key_to_cpu(leaf, &orig_key, path->slots[0]); - if (btrfs_leaf_free_space(leaf) >= - sizeof(struct btrfs_item)) - goto split; - - item_size = btrfs_item_size(leaf, path->slots[0]); - btrfs_release_path(path); - - path->search_for_split = 1; - - ret = btrfs_search_slot(trans, root, &orig_key, path, 0, 1); - path->search_for_split = 0; - - /* if our item isn't there or got smaller, return now */ - if (ret != 0 || item_size != btrfs_item_size(path->nodes[0], - path->slots[0])) { - return -EAGAIN; - } - - ret = split_leaf(trans, root, &orig_key, path, 0, 0); - BUG_ON(ret); - - BUG_ON(btrfs_leaf_free_space(leaf) < sizeof(struct btrfs_item)); - leaf = path->nodes[0]; - -split: - orig_offset = btrfs_item_offset(leaf, path->slots[0]); - item_size = btrfs_item_size(leaf, path->slots[0]); - - - buf = kmalloc(item_size, GFP_NOFS); - BUG_ON(!buf); - read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf, - path->slots[0]), item_size); - slot = path->slots[0] + 1; - leaf = path->nodes[0]; - - nritems = btrfs_header_nritems(leaf); - - if (slot < nritems) { - /* shift the items */ - memmove_extent_buffer(leaf, btrfs_item_nr_offset(leaf, slot + 1), - btrfs_item_nr_offset(leaf, slot), - (nritems - slot) * sizeof(struct btrfs_item)); - - } - - btrfs_cpu_key_to_disk(&disk_key, new_key); - btrfs_set_item_key(leaf, &disk_key, slot); - - btrfs_set_item_offset(leaf, slot, orig_offset); - btrfs_set_item_size(leaf, slot, item_size - split_offset); - - btrfs_set_item_offset(leaf, path->slots[0], - orig_offset + item_size - split_offset); - btrfs_set_item_size(leaf, path->slots[0], split_offset); - - btrfs_set_header_nritems(leaf, nritems + 1); - - /* write the data for the start of the original item */ - write_extent_buffer(leaf, buf, - btrfs_item_ptr_offset(leaf, path->slots[0]), - split_offset); - - /* write the data for the new item */ - write_extent_buffer(leaf, buf + split_offset, - btrfs_item_ptr_offset(leaf, slot), - item_size - split_offset); - btrfs_mark_buffer_dirty(leaf); - - ret = 0; - if (btrfs_leaf_free_space(leaf) < 0) { - btrfs_print_leaf(leaf); - BUG(); - } - kfree(buf); + ret = split_item(path, new_key, split_offset); return ret; } +/* + * make the item pointed to by the path smaller. new_size indicates + * how small to make it, and from_end tells us if we just chop bytes + * off the end of the item or if we shift the item to chop bytes off + * the front. + */ void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) { int slot; @@ -2425,6 +4097,7 @@ void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) unsigned int old_size; unsigned int size_diff; int i; + struct btrfs_map_token token; leaf = path->nodes[0]; slot = path->slots[0]; @@ -2447,17 +4120,18 @@ void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) * item0..itemN ... dataN.offset..dataN.size .. data0.size */ /* first correct the data pointers */ + btrfs_init_map_token(&token, leaf); for (i = slot; i < nritems; i++) { u32 ioff; - ioff = btrfs_item_offset(leaf, i); - btrfs_set_item_offset(leaf, i, ioff + size_diff); + + ioff = btrfs_token_item_offset(&token, i); + btrfs_set_token_item_offset(&token, i, ioff + size_diff); } /* shift the data */ if (from_end) { - memmove_extent_buffer(leaf, btrfs_item_nr_offset(leaf, 0) + - data_end + size_diff, btrfs_item_nr_offset(leaf, 0) + - data_end, old_data_start + new_size - data_end); + memmove_leaf_data(leaf, data_end + size_diff, data_end, + old_data_start + new_size - data_end); } else { struct btrfs_disk_key disk_key; u64 offset; @@ -2477,15 +4151,13 @@ void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) BTRFS_FILE_EXTENT_INLINE) { ptr = btrfs_item_ptr_offset(leaf, slot); memmove_extent_buffer(leaf, ptr, - (unsigned long)fi, - offsetof(struct btrfs_file_extent_item, - disk_bytenr)); + (unsigned long)fi, + BTRFS_FILE_EXTENT_INLINE_DATA_START); } } - memmove_extent_buffer(leaf, btrfs_item_nr_offset(leaf, 0) + - data_end + size_diff, btrfs_item_nr_offset(leaf, 0) + - data_end, old_data_start - data_end); + memmove_leaf_data(leaf, data_end + size_diff, data_end, + old_data_start - data_end); offset = btrfs_disk_key_offset(&disk_key); btrfs_set_disk_key_offset(&disk_key, offset + size_diff); @@ -2503,6 +4175,9 @@ void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) } } +/* + * make the item pointed to by the path bigger, data_size is the added size. + */ void btrfs_extend_item(struct btrfs_path *path, u32 data_size) { int slot; @@ -2512,6 +4187,7 @@ void btrfs_extend_item(struct btrfs_path *path, u32 data_size) unsigned int old_data; unsigned int old_size; int i; + struct btrfs_map_token token; leaf = path->nodes[0]; @@ -2528,24 +4204,26 @@ void btrfs_extend_item(struct btrfs_path *path, u32 data_size) BUG_ON(slot < 0); if (slot >= nritems) { btrfs_print_leaf(leaf); - printk("slot %d too large, nritems %u\n", slot, nritems); - BUG_ON(1); + btrfs_crit(leaf->fs_info, "slot %d too large, nritems %d", + slot, nritems); + BUG(); } /* * item0..itemN ... dataN.offset..dataN.size .. data0.size */ /* first correct the data pointers */ + btrfs_init_map_token(&token, leaf); for (i = slot; i < nritems; i++) { u32 ioff; - ioff = btrfs_item_offset(leaf, i); - btrfs_set_item_offset(leaf, i, ioff - data_size); + + ioff = btrfs_token_item_offset(&token, i); + btrfs_set_token_item_offset(&token, i, ioff - data_size); } /* shift the data */ - memmove_extent_buffer(leaf, btrfs_item_nr_offset(leaf, 0) + - data_end - data_size, btrfs_item_nr_offset(leaf, 0) + - data_end, old_data - data_end); + memmove_leaf_data(leaf, data_end - data_size, data_end, + old_data - data_end); data_end = old_data; old_size = btrfs_item_size(leaf, slot); @@ -2559,59 +4237,63 @@ void btrfs_extend_item(struct btrfs_path *path, u32 data_size) } /* - * Given a key and some data, insert an item into the tree. - * This does all the path init required, making room in the tree if needed. + * Make space in the node before inserting one or more items. + * + * @root: root we are inserting items to + * @path: points to the leaf/slot where we are going to insert new items + * @batch: information about the batch of items to insert + * + * Main purpose is to save stack depth by doing the bulk of the work in a + * function that doesn't call btrfs_search_slot */ -int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - const struct btrfs_item_batch *batch) +static void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path, + const struct btrfs_item_batch *batch) { - struct extent_buffer *leaf; - int ret = 0; - int slot; + struct btrfs_fs_info *fs_info = root->fs_info; int i; u32 nritems; - u32 total_size = 0; unsigned int data_end; struct btrfs_disk_key disk_key; + struct extent_buffer *leaf; + int slot; + struct btrfs_map_token token; + u32 total_size; - /* create a root if there isn't one */ - if (!root->node) - BUG(); - - total_size = batch->total_data_size + - (batch->nr * sizeof(struct btrfs_item)); - ret = btrfs_search_slot(trans, root, &batch->keys[0], path, total_size, 1); - if (ret == 0) { - return -EEXIST; + /* + * Before anything else, update keys in the parent and other ancestors + * if needed, then release the write locks on them, so that other tasks + * can use them while we modify the leaf. + */ + if (path->slots[0] == 0) { + btrfs_cpu_key_to_disk(&disk_key, &batch->keys[0]); + fixup_low_keys(path, &disk_key, 1); } - if (ret < 0) - goto out; + btrfs_unlock_up_safe(path, 1); leaf = path->nodes[0]; + slot = path->slots[0]; nritems = btrfs_header_nritems(leaf); data_end = leaf_data_end(leaf); + total_size = batch->total_data_size + (batch->nr * sizeof(struct btrfs_item)); if (btrfs_leaf_free_space(leaf) < total_size) { btrfs_print_leaf(leaf); - printk("not enough freespace need %u have %d\n", - total_size, btrfs_leaf_free_space(leaf)); + btrfs_crit(fs_info, "not enough freespace need %u have %d", + total_size, btrfs_leaf_free_space(leaf)); BUG(); } - slot = path->slots[0]; - BUG_ON(slot < 0); - - if (slot < nritems) { + btrfs_init_map_token(&token, leaf); + if (slot != nritems) { unsigned int old_data = btrfs_item_data_end(leaf, slot); if (old_data < data_end) { btrfs_print_leaf(leaf); - printk("slot %d old_data %u data_end %u\n", - slot, old_data, data_end); - BUG_ON(1); + btrfs_crit(fs_info, + "item at slot %d with data offset %u beyond data end of leaf %u", + slot, old_data, data_end); + BUG(); } /* * item0..itemN ... dataN.offset..dataN.size .. data0.size @@ -2620,22 +4302,16 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, for (i = slot; i < nritems; i++) { u32 ioff; - ioff = btrfs_item_offset(leaf, i); - btrfs_set_item_offset(leaf, i, - ioff - batch->total_data_size); + ioff = btrfs_token_item_offset(&token, i); + btrfs_set_token_item_offset(&token, i, + ioff - batch->total_data_size); } - /* shift the items */ - memmove_extent_buffer(leaf, - btrfs_item_nr_offset(leaf, slot + batch->nr), - btrfs_item_nr_offset(leaf, slot), - (nritems - slot) * sizeof(struct btrfs_item)); + memmove_leaf_items(leaf, slot + batch->nr, slot, nritems - slot); /* shift the data */ - memmove_extent_buffer(leaf, btrfs_item_nr_offset(leaf, 0) + - data_end - batch->total_data_size, - btrfs_item_nr_offset(leaf, 0) + - data_end, old_data - data_end); + memmove_leaf_data(leaf, data_end - batch->total_data_size, + data_end, old_data - data_end); data_end = old_data; } @@ -2644,34 +4320,76 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, btrfs_cpu_key_to_disk(&disk_key, &batch->keys[i]); btrfs_set_item_key(leaf, &disk_key, slot + i); data_end -= batch->data_sizes[i]; - btrfs_set_item_offset(leaf, slot + i, data_end); - btrfs_set_item_size(leaf, slot + i, batch->data_sizes[i]); + btrfs_set_token_item_offset(&token, slot + i, data_end); + btrfs_set_token_item_size(&token, slot + i, batch->data_sizes[i]); } + btrfs_set_header_nritems(leaf, nritems + batch->nr); btrfs_mark_buffer_dirty(leaf); - ret = 0; - if (slot == 0) { - btrfs_cpu_key_to_disk(&disk_key, &batch->keys[0]); - fixup_low_keys(path, &disk_key, 1); - } - if (btrfs_leaf_free_space(leaf) < 0) { btrfs_print_leaf(leaf); BUG(); } +} -out: - return ret; +/* + * Insert a new item into a leaf. + * + * @root: The root of the btree. + * @path: A path pointing to the target leaf and slot. + * @key: The key of the new item. + * @data_size: The size of the data associated with the new key. + */ +void btrfs_setup_item_for_insert(struct btrfs_root *root, + struct btrfs_path *path, + const struct btrfs_key *key, + u32 data_size) +{ + struct btrfs_item_batch batch; + + batch.keys = key; + batch.data_sizes = &data_size; + batch.total_data_size = data_size; + batch.nr = 1; + + setup_items_for_insert(root, path, &batch); +} + +/* + * Given a key and some data, insert items into the tree. + * This does all the path init required, making room in the tree if needed. + */ +int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + const struct btrfs_item_batch *batch) +{ + int ret = 0; + int slot; + u32 total_size; + + total_size = batch->total_data_size + (batch->nr * sizeof(struct btrfs_item)); + ret = btrfs_search_slot(trans, root, &batch->keys[0], path, total_size, 1); + if (ret == 0) + return -EEXIST; + if (ret < 0) + return ret; + + slot = path->slots[0]; + BUG_ON(slot < 0); + + setup_items_for_insert(root, path, batch); + return 0; } /* * Given a key and some data, insert an item into the tree. * This does all the path init required, making room in the tree if needed. */ -int btrfs_insert_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, const struct btrfs_key *cpu_key, - void *data, u32 data_size) +int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, + const struct btrfs_key *cpu_key, void *data, + u32 data_size) { int ret = 0; struct btrfs_path *path; @@ -2681,7 +4399,6 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, path = btrfs_alloc_path(); if (!path) return -ENOMEM; - ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); if (!ret) { leaf = path->nodes[0]; @@ -2693,28 +4410,79 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, return ret; } +/* + * This function duplicates an item, giving 'new_key' to the new item. + * It guarantees both items live in the same tree leaf and the new item is + * contiguous with the original item. + * + * This allows us to split a file extent in place, keeping a lock on the leaf + * the entire time. + */ +int btrfs_duplicate_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + const struct btrfs_key *new_key) +{ + struct extent_buffer *leaf; + int ret; + u32 item_size; + + leaf = path->nodes[0]; + item_size = btrfs_item_size(leaf, path->slots[0]); + ret = setup_leaf_for_split(trans, root, path, + item_size + sizeof(struct btrfs_item)); + if (ret) + return ret; + + path->slots[0]++; + btrfs_setup_item_for_insert(root, path, new_key, item_size); + leaf = path->nodes[0]; + memcpy_extent_buffer(leaf, + btrfs_item_ptr_offset(leaf, path->slots[0]), + btrfs_item_ptr_offset(leaf, path->slots[0] - 1), + item_size); + return 0; +} + /* * delete the pointer from a given node. * - * If the delete empties a node, the node is removed from the tree, - * continuing all the way the root if required. The root is converted into - * a leaf if all the nodes are emptied. + * the tree should have been previously balanced so the deletion does not + * empty a node. + * + * This is exported for use inside btrfs-progs, don't un-export it. */ int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int level, int slot) { struct extent_buffer *parent = path->nodes[level]; u32 nritems; + int ret; nritems = btrfs_header_nritems(parent); - if (slot < nritems - 1) { - /* shift the items */ + if (slot != nritems - 1) { + if (level) { + ret = btrfs_tree_mod_log_insert_move(parent, slot, + slot + 1, nritems - slot - 1); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + return ret; + } + } memmove_extent_buffer(parent, btrfs_node_key_ptr_offset(parent, slot), btrfs_node_key_ptr_offset(parent, slot + 1), sizeof(struct btrfs_key_ptr) * (nritems - slot - 1)); + } else if (level) { + ret = btrfs_tree_mod_log_insert_key(parent, slot, + BTRFS_MOD_LOG_KEY_REMOVE); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + return ret; + } } + nritems--; btrfs_set_header_nritems(parent, nritems); if (nritems == 0 && parent == root->node) { @@ -2728,7 +4496,6 @@ int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, fixup_low_keys(path, &disk_key, level + 1); } btrfs_mark_buffer_dirty(parent); - return 0; } @@ -2750,15 +4517,23 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, int ret; WARN_ON(btrfs_header_generation(leaf) != trans->transid); - btrfs_del_ptr(trans, root, path, 1, path->slots[1]); + ret = btrfs_del_ptr(trans, root, path, 1, path->slots[1]); + if (ret < 0) + return ret; + + /* + * btrfs_free_extent is expensive, we want to make sure we + * aren't holding any locks when we call it + */ + btrfs_unlock_up_safe(path, 0); root_sub_used(root, leaf->len); - ret = btrfs_free_extent(trans, leaf->start, leaf->len, 0, - root->root_key.objectid, 0, 0); - return ret; + atomic_inc(&leaf->refs); + btrfs_free_tree_block(trans, btrfs_root_id(root), leaf, 0, 1); + free_extent_buffer_stale(leaf); + return 0; } - /* * delete the item at the leaf level in path. If that empties * the leaf, remove it from the tree @@ -2766,41 +4541,37 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int slot, int nr) { + struct btrfs_fs_info *fs_info = root->fs_info; struct extent_buffer *leaf; - int last_off; - int dsize = 0; int ret = 0; int wret; - int i; u32 nritems; leaf = path->nodes[0]; - last_off = btrfs_item_offset(leaf, slot + nr - 1); - - for (i = 0; i < nr; i++) - dsize += btrfs_item_size(leaf, slot + i); - nritems = btrfs_header_nritems(leaf); if (slot + nr != nritems) { - int data_end = leaf_data_end(leaf); + const u32 last_off = btrfs_item_offset(leaf, slot + nr - 1); + const int data_end = leaf_data_end(leaf); + struct btrfs_map_token token; + u32 dsize = 0; + int i; - memmove_extent_buffer(leaf, btrfs_item_nr_offset(leaf, 0) + - data_end + dsize, - btrfs_item_nr_offset(leaf, 0) + data_end, - last_off - data_end); + for (i = 0; i < nr; i++) + dsize += btrfs_item_size(leaf, slot + i); + memmove_leaf_data(leaf, data_end + dsize, data_end, + last_off - data_end); + + btrfs_init_map_token(&token, leaf); for (i = slot + nr; i < nritems; i++) { u32 ioff; - ioff = btrfs_item_offset(leaf, i); - btrfs_set_item_offset(leaf, i, ioff + dsize); + ioff = btrfs_token_item_offset(&token, i); + btrfs_set_token_item_offset(&token, i, ioff + dsize); } - memmove_extent_buffer(leaf, btrfs_item_nr_offset(leaf, slot), - btrfs_item_nr_offset(leaf, slot + nr), - sizeof(struct btrfs_item) * - (nritems - slot - nr)); + memmove_leaf_items(leaf, slot, slot + nr, nritems - slot - nr); } btrfs_set_header_nritems(leaf, nritems - nr); nritems -= nr; @@ -2811,10 +4582,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, btrfs_set_header_level(leaf, 0); } else { btrfs_clear_buffer_dirty(trans, leaf); - wret = btrfs_del_leaf(trans, root, path, leaf); - BUG_ON(ret); - if (wret) - ret = wret; + ret = btrfs_del_leaf(trans, root, path, leaf); + if (ret < 0) + return ret; } } else { int used = leaf_space_used(leaf, 0, nritems); @@ -2825,35 +4595,69 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, fixup_low_keys(path, &disk_key, 1); } - /* delete the leaf if it is mostly empty */ - if (used < BTRFS_LEAF_DATA_SIZE(root->fs_info) / 4) { + /* + * Try to delete the leaf if it is mostly empty. We do this by + * trying to move all its items into its left and right neighbours. + * If we can't move all the items, then we don't delete it - it's + * not ideal, but future insertions might fill the leaf with more + * items, or items from other leaves might be moved later into our + * leaf due to deletions on those leaves. + */ + if (used < BTRFS_LEAF_DATA_SIZE(fs_info) / 3) { + u32 min_push_space; + /* push_leaf_left fixes the path. * make sure the path still points to our leaf - * for possible call to del_ptr below + * for possible call to btrfs_del_ptr below */ slot = path->slots[1]; - extent_buffer_get(leaf); - - wret = push_leaf_left(trans, root, path, 1, 1); + atomic_inc(&leaf->refs); + /* + * We want to be able to at least push one item to the + * left neighbour leaf, and that's the first item. + */ + min_push_space = sizeof(struct btrfs_item) + + btrfs_item_size(leaf, 0); + wret = push_leaf_left(trans, root, path, 0, + min_push_space, 1, (u32)-1); if (wret < 0 && wret != -ENOSPC) ret = wret; if (path->nodes[0] == leaf && btrfs_header_nritems(leaf)) { - wret = push_leaf_right(trans, root, path, 1, 1); + /* + * If we were not able to push all items from our + * leaf to its left neighbour, then attempt to + * either push all the remaining items to the + * right neighbour or none. There's no advantage + * in pushing only some items, instead of all, as + * it's pointless to end up with a leaf having + * too few items while the neighbours can be full + * or nearly full. + */ + nritems = btrfs_header_nritems(leaf); + min_push_space = leaf_space_used(leaf, 0, nritems); + wret = push_leaf_right(trans, root, path, 0, + min_push_space, 1, 0); if (wret < 0 && wret != -ENOSPC) ret = wret; } if (btrfs_header_nritems(leaf) == 0) { - btrfs_clear_buffer_dirty(trans, leaf); path->slots[1] = slot; ret = btrfs_del_leaf(trans, root, path, leaf); - BUG_ON(ret); + if (ret < 0) + return ret; free_extent_buffer(leaf); - + ret = 0; } else { - btrfs_mark_buffer_dirty(leaf); + /* if we're still in the path, make sure + * we're dirty. Otherwise, one of the + * push_leaf functions must have already + * dirtied this buffer + */ + if (path->nodes[0] == leaf) + btrfs_mark_buffer_dirty(leaf); free_extent_buffer(leaf); } } else { @@ -2864,124 +4668,419 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, } /* - * walk up the tree as far as required to find the previous leaf. - * returns 0 if it found something or 1 if there are no lesser leaves. - * returns < 0 on io errors. + * A helper function to walk down the tree starting at min_key, and looking + * for nodes or leaves that are have a minimum transaction id. + * This is used by the btree defrag code, and tree logging + * + * This does not cow, but it does stuff the starting key it finds back + * into min_key, so you can call btrfs_search_slot with cow=1 on the + * key and get a writable path. + * + * This honors path->lowest_level to prevent descent past a given level + * of the tree. + * + * min_trans indicates the oldest transaction that you are interested + * in walking through. Any nodes or leaves older than min_trans are + * skipped over (without reading them). + * + * returns zero if something useful was found, < 0 on error and 1 if there + * was nothing in the tree that matched the search criteria. */ -int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) +int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, + struct btrfs_path *path, + u64 min_trans) { + struct extent_buffer *cur; + struct btrfs_key found_key; int slot; - int level = 1; - struct extent_buffer *c; - struct extent_buffer *next = NULL; + int sret; + u32 nritems; + int level; + int ret = 1; + int keep_locks = path->keep_locks; - while(level < BTRFS_MAX_LEVEL) { - if (!path->nodes[level]) - return 1; + ASSERT(!path->nowait); + path->keep_locks = 1; +again: + cur = btrfs_read_lock_root_node(root); + level = btrfs_header_level(cur); + WARN_ON(path->nodes[level]); + path->nodes[level] = cur; + path->locks[level] = BTRFS_READ_LOCK; - slot = path->slots[level]; - c = path->nodes[level]; - if (slot == 0) { - level++; - if (level == BTRFS_MAX_LEVEL) - return 1; - continue; - } - slot--; - - next = btrfs_read_node_slot(c, slot); - if (!extent_buffer_uptodate(next)) { - if (IS_ERR(next)) - return PTR_ERR(next); - return -EIO; - } - break; + if (btrfs_header_generation(cur) < min_trans) { + ret = 1; + goto out; } - path->slots[level] = slot; - while(1) { - level--; - c = path->nodes[level]; - free_extent_buffer(c); - slot = btrfs_header_nritems(next); - if (slot != 0) + while (1) { + nritems = btrfs_header_nritems(cur); + level = btrfs_header_level(cur); + sret = btrfs_bin_search(cur, 0, min_key, &slot); + if (sret < 0) { + ret = sret; + goto out; + } + + /* at the lowest level, we're done, setup the path and exit */ + if (level == path->lowest_level) { + if (slot >= nritems) + goto find_next_key; + ret = 0; + path->slots[level] = slot; + btrfs_item_key_to_cpu(cur, &found_key, slot); + goto out; + } + if (sret && slot > 0) slot--; - path->nodes[level] = next; - path->slots[level] = slot; - if (!level) + /* + * check this node pointer against the min_trans parameters. + * If it is too old, skip to the next one. + */ + while (slot < nritems) { + u64 gen; + + gen = btrfs_node_ptr_generation(cur, slot); + if (gen < min_trans) { + slot++; + continue; + } break; - next = btrfs_read_node_slot(next, slot); - if (!extent_buffer_uptodate(next)) { - if (IS_ERR(next)) - return PTR_ERR(next); - return -EIO; } +find_next_key: + /* + * we didn't find a candidate key in this node, walk forward + * and find another one + */ + if (slot >= nritems) { + path->slots[level] = slot; + sret = btrfs_find_next_key(root, path, min_key, level, + min_trans); + if (sret == 0) { + btrfs_release_path(path); + goto again; + } else { + goto out; + } + } + /* save our key for returning back */ + btrfs_node_key_to_cpu(cur, &found_key, slot); + path->slots[level] = slot; + if (level == path->lowest_level) { + ret = 0; + goto out; + } + cur = btrfs_read_node_slot(cur, slot); + if (IS_ERR(cur)) { + ret = PTR_ERR(cur); + goto out; + } + + btrfs_tree_read_lock(cur); + + path->locks[level - 1] = BTRFS_READ_LOCK; + path->nodes[level - 1] = cur; + unlock_up(path, level, 1, 0, NULL); } - return 0; +out: + path->keep_locks = keep_locks; + if (ret == 0) { + btrfs_unlock_up_safe(path, path->lowest_level + 1); + memcpy(min_key, &found_key, sizeof(found_key)); + } + return ret; } /* - * Walk up the tree as far as necessary to find the next sibling tree block. - * More generic version of btrfs_next_leaf(), as it could find sibling nodes - * if @path->lowest_level is not 0. + * this is similar to btrfs_next_leaf, but does not try to preserve + * and fixup the path. It looks for and returns the next key in the + * tree based on the current path and the min_trans parameters. * - * returns 0 if it found something or 1 if there are no greater leaves. - * returns < 0 on io errors. + * 0 is returned if another key is found, < 0 if there are any errors + * and 1 is returned if there are no higher keys in the tree + * + * path->keep_locks should be set to 1 on the search made before + * calling this function. */ -int btrfs_next_sibling_tree_block(struct btrfs_fs_info *fs_info, - struct btrfs_path *path) +int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, + struct btrfs_key *key, int level, u64 min_trans) { int slot; - int level = path->lowest_level + 1; struct extent_buffer *c; - struct extent_buffer *next = NULL; - BUG_ON(path->lowest_level + 1 >= BTRFS_MAX_LEVEL); - do { + WARN_ON(!path->keep_locks && !path->skip_locking); + while (level < BTRFS_MAX_LEVEL) { if (!path->nodes[level]) return 1; + slot = path->slots[level] + 1; + c = path->nodes[level]; +next: + if (slot >= btrfs_header_nritems(c)) { + int ret; + int orig_lowest; + struct btrfs_key cur_key; + if (level + 1 >= BTRFS_MAX_LEVEL || + !path->nodes[level + 1]) + return 1; + + if (path->locks[level + 1] || path->skip_locking) { + level++; + continue; + } + + slot = btrfs_header_nritems(c) - 1; + if (level == 0) + btrfs_item_key_to_cpu(c, &cur_key, slot); + else + btrfs_node_key_to_cpu(c, &cur_key, slot); + + orig_lowest = path->lowest_level; + btrfs_release_path(path); + path->lowest_level = level; + ret = btrfs_search_slot(NULL, root, &cur_key, path, + 0, 0); + path->lowest_level = orig_lowest; + if (ret < 0) + return ret; + + c = path->nodes[level]; + slot = path->slots[level]; + if (ret == 0) + slot++; + goto next; + } + + if (level == 0) + btrfs_item_key_to_cpu(c, key, slot); + else { + u64 gen = btrfs_node_ptr_generation(c, slot); + + if (gen < min_trans) { + slot++; + goto next; + } + btrfs_node_key_to_cpu(c, key, slot); + } + return 0; + } + return 1; +} + +int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path, + u64 time_seq) +{ + int slot; + int level; + struct extent_buffer *c; + struct extent_buffer *next; + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_key key; + bool need_commit_sem = false; + u32 nritems; + int ret; + int i; + + /* + * The nowait semantics are used only for write paths, where we don't + * use the tree mod log and sequence numbers. + */ + if (time_seq) + ASSERT(!path->nowait); + + nritems = btrfs_header_nritems(path->nodes[0]); + if (nritems == 0) + return 1; + + btrfs_item_key_to_cpu(path->nodes[0], &key, nritems - 1); +again: + level = 1; + next = NULL; + btrfs_release_path(path); + + path->keep_locks = 1; + + if (time_seq) { + ret = btrfs_search_old_slot(root, &key, path, time_seq); + } else { + if (path->need_commit_sem) { + path->need_commit_sem = 0; + need_commit_sem = true; + if (path->nowait) { + if (!down_read_trylock(&fs_info->commit_root_sem)) { + ret = -EAGAIN; + goto done; + } + } else { + down_read(&fs_info->commit_root_sem); + } + } + ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); + } + path->keep_locks = 0; + + if (ret < 0) + goto done; + + nritems = btrfs_header_nritems(path->nodes[0]); + /* + * by releasing the path above we dropped all our locks. A balance + * could have added more items next to the key that used to be + * at the very end of the block. So, check again here and + * advance the path if there are now more items available. + */ + if (nritems > 0 && path->slots[0] < nritems - 1) { + if (ret == 0) + path->slots[0]++; + ret = 0; + goto done; + } + /* + * So the above check misses one case: + * - after releasing the path above, someone has removed the item that + * used to be at the very end of the block, and balance between leafs + * gets another one with bigger key.offset to replace it. + * + * This one should be returned as well, or we can get leaf corruption + * later(esp. in __btrfs_drop_extents()). + * + * And a bit more explanation about this check, + * with ret > 0, the key isn't found, the path points to the slot + * where it should be inserted, so the path->slots[0] item must be the + * bigger one. + */ + if (nritems > 0 && ret > 0 && path->slots[0] == nritems - 1) { + ret = 0; + goto done; + } + + while (level < BTRFS_MAX_LEVEL) { + if (!path->nodes[level]) { + ret = 1; + goto done; + } + slot = path->slots[level] + 1; c = path->nodes[level]; if (slot >= btrfs_header_nritems(c)) { level++; - if (level == BTRFS_MAX_LEVEL) - return 1; + if (level == BTRFS_MAX_LEVEL) { + ret = 1; + goto done; + } continue; } - if (path->reada) - reada_for_search(fs_info, path, level, slot, 0); - next = btrfs_read_node_slot(c, slot); - if (!extent_buffer_uptodate(next)) - return -EIO; + /* + * Our current level is where we're going to start from, and to + * make sure lockdep doesn't complain we need to drop our locks + * and nodes from 0 to our current level. + */ + for (i = 0; i < level; i++) { + if (path->locks[level]) { + btrfs_tree_read_unlock(path->nodes[i]); + path->locks[i] = 0; + } + free_extent_buffer(path->nodes[i]); + path->nodes[i] = NULL; + } + + next = c; + ret = read_block_for_search(root, path, &next, level, + slot, &key); + if (ret == -EAGAIN && !path->nowait) + goto again; + + if (ret < 0) { + btrfs_release_path(path); + goto done; + } + + if (!path->skip_locking) { + ret = btrfs_try_tree_read_lock(next); + if (!ret && path->nowait) { + ret = -EAGAIN; + goto done; + } + if (!ret && time_seq) { + /* + * If we don't get the lock, we may be racing + * with push_leaf_left, holding that lock while + * itself waiting for the leaf we've currently + * locked. To solve this situation, we give up + * on our lock and cycle. + */ + free_extent_buffer(next); + btrfs_release_path(path); + cond_resched(); + goto again; + } + if (!ret) + btrfs_tree_read_lock(next); + } break; - } while (level < BTRFS_MAX_LEVEL); + } path->slots[level] = slot; - while(1) { + while (1) { level--; - c = path->nodes[level]; - free_extent_buffer(c); path->nodes[level] = next; path->slots[level] = 0; - /* - * Fsck will happily load corrupt blocks in order to fix them, - * so we need an extra check just to make sure this block isn't - * marked uptodate but invalid. - */ - if (check_block(fs_info, path, level)) - return -EIO; - if (level == path->lowest_level) + if (!path->skip_locking) + path->locks[level] = BTRFS_READ_LOCK; + if (!level) break; - if (path->reada) - reada_for_search(fs_info, path, level, 0, 0); - next = btrfs_read_node_slot(next, 0); - if (!extent_buffer_uptodate(next)) - return -EIO; + + ret = read_block_for_search(root, path, &next, level, + 0, &key); + if (ret == -EAGAIN && !path->nowait) + goto again; + + if (ret < 0) { + btrfs_release_path(path); + goto done; + } + + if (!path->skip_locking) { + if (path->nowait) { + if (!btrfs_try_tree_read_lock(next)) { + ret = -EAGAIN; + goto done; + } + } else { + btrfs_tree_read_lock(next); + } + } } + ret = 0; +done: + unlock_up(path, 0, 1, 0, NULL); + if (need_commit_sem) { + int ret2; + + path->need_commit_sem = 1; + ret2 = finish_need_commit_sem_search(path); + up_read(&fs_info->commit_root_sem); + if (ret2) + ret = ret2; + } + + return ret; +} + +int btrfs_next_old_item(struct btrfs_root *root, struct btrfs_path *path, u64 time_seq) +{ + path->slots[0]++; + if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) + return btrfs_next_old_leaf(root, path, time_seq); return 0; } +/* + * this uses btrfs_prev_leaf to walk backwards in the tree, and keeps + * searching until it gets past min_objectid or finds an item of 'type' + * + * returns 0 if something is found, 1 if nothing was found and < 0 on error + */ int btrfs_previous_item(struct btrfs_root *root, struct btrfs_path *path, u64 min_objectid, int type) @@ -2991,7 +5090,7 @@ int btrfs_previous_item(struct btrfs_root *root, u32 nritems; int ret; - while(1) { + while (1) { if (path->slots[0] == 0) { ret = btrfs_prev_leaf(root, path); if (ret != 0) @@ -3020,7 +5119,7 @@ int btrfs_previous_item(struct btrfs_root *root, /* * search in extent tree to find a previous Metadata/Data extent item with - * min objectid. + * min objecitd. * * returns 0 if something is found, 1 if nothing was found and < 0 on error */ @@ -3059,3 +5158,18 @@ int btrfs_previous_extent_item(struct btrfs_root *root, } return 1; } + +int __init btrfs_ctree_init(void) +{ + btrfs_path_cachep = kmem_cache_create("btrfs_path", + sizeof(struct btrfs_path), 0, + SLAB_MEM_SPREAD, NULL); + if (!btrfs_path_cachep) + return -ENOMEM; + return 0; +} + +void __cold btrfs_ctree_exit(void) +{ + kmem_cache_destroy(btrfs_path_cachep); +} diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index fbdf3aef..a0a85d92 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -1057,8 +1057,9 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, return btrfs_insert_empty_items(trans, root, path, &batch); } -int btrfs_next_sibling_tree_block(struct btrfs_fs_info *fs_info, - struct btrfs_path *path); +int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path, + u64 time_seq); +int btrfs_next_old_item(struct btrfs_root *root, struct btrfs_path *path, u64 time_seq); /* * Walk up the tree as far as necessary to find the next leaf. @@ -1069,33 +1070,48 @@ int btrfs_next_sibling_tree_block(struct btrfs_fs_info *fs_info, static inline int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) { - path->lowest_level = 0; - return btrfs_next_sibling_tree_block(root->fs_info, path); + return btrfs_next_old_leaf(root, path, 0); } static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) { - ++p->slots[0]; - if (p->slots[0] >= btrfs_header_nritems(p->nodes[0])) { - int ret; - ret = btrfs_next_leaf(root, p); - /* - * Revert the increased slot, or the path may point to - * an invalid item. - */ - if (ret) - p->slots[0]--; - return ret; - } - return 0; + return btrfs_next_old_item(root, p, 0); } +int btrfs_block_can_be_shared(struct btrfs_root *root, + struct extent_buffer *buf); int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_leaf_free_space(const struct extent_buffer *leaf); void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info, struct btrfs_path *path, const struct btrfs_key *new_key); +struct extent_buffer *btrfs_root_node(struct btrfs_root *root); +int btrfs_realloc_node(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct extent_buffer *parent, + int start_slot, u64 *last_ret, + struct btrfs_key *progress); +int btrfs_search_old_slot(struct btrfs_root *root, const struct btrfs_key *key, + struct btrfs_path *p, u64 time_seq); +int btrfs_search_backwards(struct btrfs_root *root, struct btrfs_key *key, + struct btrfs_path *path); +int btrfs_get_next_valid_item(struct btrfs_root *root, struct btrfs_key *key, + struct btrfs_path *path); +void btrfs_setup_item_for_insert(struct btrfs_root *root, + struct btrfs_path *path, + const struct btrfs_key *key, + u32 data_size); +int btrfs_duplicate_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + const struct btrfs_key *new_key); +int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, + struct btrfs_path *path, + u64 min_trans); +int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, + struct btrfs_key *key, int level, u64 min_trans); +int __init btrfs_ctree_init(void); +void __cold btrfs_ctree_exit(void); int btrfs_super_csum_size(const struct btrfs_super_block *sb); const char *btrfs_super_csum_name(u16 csum_type);