From patchwork Wed Jun 19 15:34:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Thumshirn X-Patchwork-Id: 13704099 Received: from mail-lj1-f175.google.com (mail-lj1-f175.google.com [209.85.208.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0874D152166; Wed, 19 Jun 2024 15:35:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718811306; cv=none; b=EXRsacQJqWAX2lqFG312oUCWhgKtNULk1c6SkT9CcldmQ0nXianqPgcfvkfozp9G3xDiHpQD96pHSedxBXKhTVdqC+5+cGp68XB3l0iHgXVdIIMm/eui65zKpYdhQFG5Uj6DMEOdvnyFtJH05ETOAQHM6jztR2/GFK1mC48mTEI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718811306; c=relaxed/simple; bh=oTC81cnH+dN3orzjDOYHiTXmmqEyLCQ0I7spUOgtIWQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nUz5CjkUGOzU5MCB3fZ6SPlEKf0LwO1S6PD02/0USs25WydBhoDqpz5MadtQQI7HhJdj+ADHZN3Z22wgQbfE7GaViIoE5VRbp1EHbbhCrJqsa8Uro7y5/STlKJIyuXHe3o/K5yhpopKGYNjoHrouTzupM11fse2Glob3LoYwwYs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.208.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-lj1-f175.google.com with SMTP id 38308e7fff4ca-2ebeefb9a6eso71071311fa.1; Wed, 19 Jun 2024 08:35:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718811302; x=1719416102; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=53k60xnWItFNxouNmEA4t5IllOjqQs9+VoFJtvADyds=; b=AJ4K9nQrJVuGzE7njyjsau/ynEQC/BbYXpm3crYryErqoRrn5fAIj3+MpyBlHaR9nE MrDYBkgovXw8To9xAkrCdKETSpIWJzFiZMokePWA1U2OMwEkpioH1/v6133d3WLcNQHO dbn2CzbDuEz4d80IrP4w6NRBamqEAq+4/uGSqEkgtWZUiWRQpwzGOng0FaecQ9UgzByM wCI2lGgHMjsr0EDPVMTmsMrXh9PR7wo/moLQHd2hPpKHedCzRpeGqpXHKrcr+LvtGEgM Ym2F9IG5uQTm+gv0tugpJtPcpsukqZ3c5fDu+qTq+GqqRC66B7axuvo37jPjoG0gzAKA MELw== X-Forwarded-Encrypted: i=1; AJvYcCV8fIBRvBspJ0w7IfMbBX/VWseGpB75fjHnIy5S0jQSR54xdT8YIFh1TUNlxSN+cjrb9BZTR4MU25I+8z1enSXbYupEFgCgD5cxZxqh X-Gm-Message-State: AOJu0YxguEoR3UjXQZiD8LmKLsvI9GTS/ZsdniM3cUhGL4hUY2cwGSg4 3W8u2OAr5UUrcguq20hrt/a7YjZshvSmMx+V4SkEPiKzBtKwGYZmp+Cvrw== X-Google-Smtp-Source: AGHT+IGfTX0unf2WOkKR8sms1DcdbEpCT/3cHVuQWHIXFlVJrV1J5W3LA+F1J08FQmFFVWVNKMqsFQ== X-Received: by 2002:a2e:7a02:0:b0:2ec:476:7c60 with SMTP id 38308e7fff4ca-2ec3cec59c3mr18572821fa.27.1718811299813; Wed, 19 Jun 2024 08:34:59 -0700 (PDT) Received: from [127.0.0.1] (p200300f6f7110500fa633ffffe02074c.dip0.t-ipconnect.de. [2003:f6:f711:500:fa63:3fff:fe02:74c]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42286fe9263sm268882135e9.15.2024.06.19.08.34.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jun 2024 08:34:59 -0700 (PDT) From: Johannes Thumshirn Date: Wed, 19 Jun 2024 17:34:51 +0200 Subject: [PATCH v2 1/4] btrfs: rst: remove encoding field from stripe_extent Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240619-b4-rst-updates-v2-1-89c34d0d5298@kernel.org> References: <20240619-b4-rst-updates-v2-0-89c34d0d5298@kernel.org> In-Reply-To: <20240619-b4-rst-updates-v2-0-89c34d0d5298@kernel.org> To: Chris Mason , Josef Bacik , David Sterba Cc: linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org, Johannes Thumshirn X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=7154; i=jth@kernel.org; h=from:subject:message-id; bh=nkXv4Jnd8z+PDnUnu1iNOeMHcBjG1Vc7IEHf3d1s/9M=; b=owGbwMvMwCV2ad4npfVdsu8YT6slMaQV/VqY+Cteq/vOkRmT+YquM7afZ5WZbXnmiteKFpP9/ drvNumt7yhlYRDjYpAVU2Q5Hmq7X8L0CPuUQ6/NYOawMoEMYeDiFICJmFYxMvRNbJHP/28gL71+ 1xK591xOf58fNp57TIWjwTnqZdmbiwwM/3OP7F+y0D3aOoBzU30b3963v4/YbAtVrf8tYNGpL7x oHRcA X-Developer-Key: i=jth@kernel.org; a=openpgp; fpr=EC389CABC2C4F25D8600D0D00393969D2D760850 From: Johannes Thumshirn Remove the encoding field from 'struct btrfs_stripe_extent'. It was originally intended to encode the RAID type as well as if we're a data or a parity stripe. But the RAID type can be inferred form the block-group and the data vs. parity differentiation can be done easier with adding a new key type for parity stripes in the RAID stripe tree. Signed-off-by: Johannes Thumshirn --- fs/btrfs/accessors.h | 3 --- fs/btrfs/print-tree.c | 5 ----- fs/btrfs/raid-stripe-tree.c | 13 ------------- fs/btrfs/raid-stripe-tree.h | 3 +-- fs/btrfs/tree-checker.c | 19 ------------------- include/uapi/linux/btrfs_tree.h | 14 +------------- 6 files changed, 2 insertions(+), 55 deletions(-) diff --git a/fs/btrfs/accessors.h b/fs/btrfs/accessors.h index 6c3deaa3e878..b2eb9cde2c5d 100644 --- a/fs/btrfs/accessors.h +++ b/fs/btrfs/accessors.h @@ -315,11 +315,8 @@ BTRFS_SETGET_FUNCS(timespec_nsec, struct btrfs_timespec, nsec, 32); BTRFS_SETGET_STACK_FUNCS(stack_timespec_sec, struct btrfs_timespec, sec, 64); BTRFS_SETGET_STACK_FUNCS(stack_timespec_nsec, struct btrfs_timespec, nsec, 32); -BTRFS_SETGET_FUNCS(stripe_extent_encoding, struct btrfs_stripe_extent, encoding, 8); BTRFS_SETGET_FUNCS(raid_stride_devid, struct btrfs_raid_stride, devid, 64); BTRFS_SETGET_FUNCS(raid_stride_physical, struct btrfs_raid_stride, physical, 64); -BTRFS_SETGET_STACK_FUNCS(stack_stripe_extent_encoding, - struct btrfs_stripe_extent, encoding, 8); BTRFS_SETGET_STACK_FUNCS(stack_raid_stride_devid, struct btrfs_raid_stride, devid, 64); BTRFS_SETGET_STACK_FUNCS(stack_raid_stride_physical, struct btrfs_raid_stride, physical, 64); diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index 7e46aa8a0444..9f1e5e11bf71 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c @@ -208,11 +208,6 @@ static void print_raid_stripe_key(const struct extent_buffer *eb, u32 item_size, struct btrfs_stripe_extent *stripe) { const int num_stripes = btrfs_num_raid_stripes(item_size); - const u8 encoding = btrfs_stripe_extent_encoding(eb, stripe); - - pr_info("\t\t\tencoding: %s\n", - (encoding && encoding < BTRFS_NR_RAID_TYPES) ? - btrfs_raid_array[encoding].raid_name : "unknown"); for (int i = 0; i < num_stripes; i++) pr_info("\t\t\tstride %d devid %llu physical %llu\n", diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c index 6af6b4b9a32e..e6f7a234b8f6 100644 --- a/fs/btrfs/raid-stripe-tree.c +++ b/fs/btrfs/raid-stripe-tree.c @@ -80,7 +80,6 @@ static int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans, struct btrfs_key stripe_key; struct btrfs_root *stripe_root = fs_info->stripe_root; const int num_stripes = btrfs_bg_type_to_factor(bioc->map_type); - u8 encoding = btrfs_bg_flags_to_raid_index(bioc->map_type); struct btrfs_stripe_extent *stripe_extent; const size_t item_size = struct_size(stripe_extent, strides, num_stripes); int ret; @@ -94,7 +93,6 @@ static int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans, trace_btrfs_insert_one_raid_extent(fs_info, bioc->logical, bioc->size, num_stripes); - btrfs_set_stack_stripe_extent_encoding(stripe_extent, encoding); for (int i = 0; i < num_stripes; i++) { u64 devid = bioc->stripes[i].dev->devid; u64 physical = bioc->stripes[i].physical; @@ -159,7 +157,6 @@ int btrfs_get_raid_extent_offset(struct btrfs_fs_info *fs_info, struct extent_buffer *leaf; const u64 end = logical + *length; int num_stripes; - u8 encoding; u64 offset; u64 found_logical; u64 found_length; @@ -222,16 +219,6 @@ int btrfs_get_raid_extent_offset(struct btrfs_fs_info *fs_info, num_stripes = btrfs_num_raid_stripes(btrfs_item_size(leaf, slot)); stripe_extent = btrfs_item_ptr(leaf, slot, struct btrfs_stripe_extent); - encoding = btrfs_stripe_extent_encoding(leaf, stripe_extent); - - if (encoding != btrfs_bg_flags_to_raid_index(map_type)) { - ret = -EUCLEAN; - btrfs_handle_fs_error(fs_info, ret, - "on-disk stripe encoding %d doesn't match RAID index %d", - encoding, - btrfs_bg_flags_to_raid_index(map_type)); - goto out; - } for (int i = 0; i < num_stripes; i++) { struct btrfs_raid_stride *stride = &stripe_extent->strides[i]; diff --git a/fs/btrfs/raid-stripe-tree.h b/fs/btrfs/raid-stripe-tree.h index c9c258f84903..1ac1c21aac2f 100644 --- a/fs/btrfs/raid-stripe-tree.h +++ b/fs/btrfs/raid-stripe-tree.h @@ -48,8 +48,7 @@ static inline bool btrfs_need_stripe_tree_update(struct btrfs_fs_info *fs_info, static inline int btrfs_num_raid_stripes(u32 item_size) { - return (item_size - offsetof(struct btrfs_stripe_extent, strides)) / - sizeof(struct btrfs_raid_stride); + return item_size / sizeof(struct btrfs_raid_stride); } #endif diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index a2c3651a3d8f..1e140f6dabc6 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c @@ -1682,9 +1682,6 @@ static int check_inode_ref(struct extent_buffer *leaf, static int check_raid_stripe_extent(const struct extent_buffer *leaf, const struct btrfs_key *key, int slot) { - struct btrfs_stripe_extent *stripe_extent = - btrfs_item_ptr(leaf, slot, struct btrfs_stripe_extent); - if (unlikely(!IS_ALIGNED(key->objectid, leaf->fs_info->sectorsize))) { generic_err(leaf, slot, "invalid key objectid for raid stripe extent, have %llu expect aligned to %u", @@ -1698,22 +1695,6 @@ static int check_raid_stripe_extent(const struct extent_buffer *leaf, return -EUCLEAN; } - switch (btrfs_stripe_extent_encoding(leaf, stripe_extent)) { - case BTRFS_STRIPE_RAID0: - case BTRFS_STRIPE_RAID1: - case BTRFS_STRIPE_DUP: - case BTRFS_STRIPE_RAID10: - case BTRFS_STRIPE_RAID5: - case BTRFS_STRIPE_RAID6: - case BTRFS_STRIPE_RAID1C3: - case BTRFS_STRIPE_RAID1C4: - break; - default: - generic_err(leaf, slot, "invalid raid stripe encoding %u", - btrfs_stripe_extent_encoding(leaf, stripe_extent)); - return -EUCLEAN; - } - return 0; } diff --git a/include/uapi/linux/btrfs_tree.h b/include/uapi/linux/btrfs_tree.h index c7636331e566..fc29d273845d 100644 --- a/include/uapi/linux/btrfs_tree.h +++ b/include/uapi/linux/btrfs_tree.h @@ -747,21 +747,9 @@ struct btrfs_raid_stride { __le64 physical; } __attribute__ ((__packed__)); -/* The stripe_extent::encoding, 1:1 mapping of enum btrfs_raid_types. */ -#define BTRFS_STRIPE_RAID0 1 -#define BTRFS_STRIPE_RAID1 2 -#define BTRFS_STRIPE_DUP 3 -#define BTRFS_STRIPE_RAID10 4 -#define BTRFS_STRIPE_RAID5 5 -#define BTRFS_STRIPE_RAID6 6 -#define BTRFS_STRIPE_RAID1C3 7 -#define BTRFS_STRIPE_RAID1C4 8 - struct btrfs_stripe_extent { - __u8 encoding; - __u8 reserved[7]; /* An array of raid strides this stripe is composed of. */ - struct btrfs_raid_stride strides[]; + __DECLARE_FLEX_ARRAY(struct btrfs_raid_stride, strides); } __attribute__ ((__packed__)); #define BTRFS_HEADER_FLAG_WRITTEN (1ULL << 0) From patchwork Wed Jun 19 15:34:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Thumshirn X-Patchwork-Id: 13704100 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7B26615217F; Wed, 19 Jun 2024 15:35:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718811306; cv=none; b=nuueFtTDqlzsCUUa8Kwb/pkWeNsHZW+ZxCsqztMZf70sD/wyWVhY36sE1fjlSlpJDOkNawp0yAC/eAx4ycV9G5q/Ytgu14YLuaxVoVAu004JMmlgqlqFxmyXNJZLW/gwi6LEIrcEAYINOhulZSDokpnFvZvGp+7e2W0i/J1IUmE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718811306; c=relaxed/simple; bh=pdLAdw8AbZIIIqEbHF3B9lATObRLtWTBZcl4cyl+jVA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=H+ZDbrZEG94FkBizrtHsw7fweIGxsF6TLkV5d6WoM6B3kx+knGv2AEtrlgjl9U0C4ozHP9+xqikAhQVhryRsspuMwrCWyDnhKEhqAog8bZAFFTvdv4sdIjRofSn55GMsw1Lh8YinM8ScsXVPyb6Ql5P29WjM7WQF+vOlnvWuRjM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.128.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-4217926991fso60251035e9.3; Wed, 19 Jun 2024 08:35:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718811303; x=1719416103; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=c3M8GIwcTP2w6CaI85iIBf+6uE7YDXide+uxJUTmFVs=; b=J5jPl8xcJwd8C287XXY+A9hnc4H6bEVinnkBAvQyVBBUZpfVV7uuj1fSF0wxE8B+FT i7bJIcQKg+XNKcAuTm1iAV1cA976AS7H68rBEyRLs/tO9ggXH2bU3DOHNjO3bolpdPsc znvt8YXbAf4xDNgcnRAf6U2TfxdVYqNdYsR6+z2Z1N2OWXQzKdQLiRoDT4XSbZhRFySG 9wuNCrP8LEDhvMFR8kGTlm3GUzDVXy5HrhCjDHPUMVj4WDv75coCnGPh4RKl937urgtm tUhcUt4MiZaLxMAaVV6Za4SHB1fGgKZyLskcQ+xcXcZvuidDquHrgpxikkb3knBbLbHq ix0A== X-Forwarded-Encrypted: i=1; AJvYcCXIDu1bhspjygtIYH73mnt6eXW8WMzTf8ylVRH1+52hjaCU6YtiwhlfIUo88totB/I8/BxyTULYIYYNNhHVyj7GAlT9dGUNgEeXd9Zd X-Gm-Message-State: AOJu0YylhBYkIreEfIXkgO5YtGLGQoRwLgYpGEC7fhPCreCpxwkwGUtn +jq8wvWS4MVwwaeRVD0UT282xri2wGl5yTK002xS5oOunZO8G4qDV/qgRA== X-Google-Smtp-Source: AGHT+IHH7PwUv8S1iCYF3J3uQVXx9HoQ7MA56Uvt4zifcynRnlfRoYPhwNv5yEMIHiW0MsMCat1ZWw== X-Received: by 2002:a05:600c:6a9a:b0:422:50d7:ff0 with SMTP id 5b1f17b1804b1-4247507a6f6mr19328995e9.3.1718811302938; Wed, 19 Jun 2024 08:35:02 -0700 (PDT) Received: from [127.0.0.1] (p200300f6f7110500fa633ffffe02074c.dip0.t-ipconnect.de. [2003:f6:f711:500:fa63:3fff:fe02:74c]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42286fe9263sm268882135e9.15.2024.06.19.08.35.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jun 2024 08:35:02 -0700 (PDT) From: Johannes Thumshirn Date: Wed, 19 Jun 2024 17:34:52 +0200 Subject: [PATCH v2 2/4] btrfs: replace stripe extents Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240619-b4-rst-updates-v2-2-89c34d0d5298@kernel.org> References: <20240619-b4-rst-updates-v2-0-89c34d0d5298@kernel.org> In-Reply-To: <20240619-b4-rst-updates-v2-0-89c34d0d5298@kernel.org> To: Chris Mason , Josef Bacik , David Sterba Cc: linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org, Johannes Thumshirn X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=2025; i=jth@kernel.org; h=from:subject:message-id; bh=3H78qr1E4CM/iN5I9YPMUD81FD/yCQ/9SOrHfoxgDzI=; b=owGbwMvMwCV2ad4npfVdsu8YT6slMaQV/Vp42zFll1rEtHOZSd9WFFpP5PXRvBQR9kSLKWj9x +t72DJUO0pZGMS4GGTFFFmOh9rulzA9wj7l0GszmDmsTCBDGLg4BWAifUGMDIeENGJCQlsnLTJZ 8uNwMMN1no72mjK1Ny1q+9PPXmdv82NkmPT5prngw4k/9Y/uP3360z31eH+Bm5b+5W+epr6LmS5 5mRsA X-Developer-Key: i=jth@kernel.org; a=openpgp; fpr=EC389CABC2C4F25D8600D0D00393969D2D760850 From: Johannes Thumshirn If we can't insert a stripe extent in the RAID stripe tree, because the key that points to the specific position in the stripe tree is already existing, we have to remove the item and then replace it by a new item. This can happen for example on device replace operations. Signed-off-by: Johannes Thumshirn --- fs/btrfs/raid-stripe-tree.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c index e6f7a234b8f6..3020820dd6e2 100644 --- a/fs/btrfs/raid-stripe-tree.c +++ b/fs/btrfs/raid-stripe-tree.c @@ -73,6 +73,37 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le return ret; } +static int replace_raid_extent_item(struct btrfs_trans_handle *trans, + struct btrfs_key *key, + struct btrfs_stripe_extent *stripe_extent, + const size_t item_size) +{ + struct btrfs_fs_info *fs_info = trans->fs_info; + struct btrfs_root *stripe_root = fs_info->stripe_root; + struct btrfs_path *path; + int ret; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + ret = btrfs_search_slot(trans, stripe_root, key, path, -1, 1); + if (ret) + goto err; + + ret = btrfs_del_item(trans, stripe_root, path); + if (ret) + goto err; + + btrfs_free_path(path); + + return btrfs_insert_item(trans, stripe_root, key, stripe_extent, + item_size); + err: + btrfs_free_path(path); + return ret; +} + static int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans, struct btrfs_io_context *bioc) { @@ -112,6 +143,9 @@ static int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans, ret = btrfs_insert_item(trans, stripe_root, &stripe_key, stripe_extent, item_size); + if (ret == -EEXIST) + ret = replace_raid_extent_item(trans, &stripe_key, + stripe_extent, item_size); if (ret) btrfs_abort_transaction(trans, ret); From patchwork Wed Jun 19 15:34:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Thumshirn X-Patchwork-Id: 13704101 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C8EC3152188; Wed, 19 Jun 2024 15:35:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718811307; cv=none; b=omSrqTA8SkeOuUyJL+t1FSZ8yISvTRYOt3mhwDX2WZCuQibP5Om64UCTJzGPlTeJiO5G3MGeW3hLFsrPrunDyb01OShVTQU6JMoSi4v3wkvbJVotLqmi9P3cA+oXhqO/755tibMtmcQS64B6eOdy+bqzMwIfTZj4c60TJ4rdzfc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718811307; c=relaxed/simple; bh=2izMZ3dmor0xUWSLs/SzVt/Jl5DktPXrWE1qLh60XaQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MZNnFkIoETTf0Kh1lisdz0qGBWO+W6+JMY4mmXdlLPWAHNWVyopcuQVgbaC/gnT6FpvG6A+R5+og7WW/Hryz1wtnv4mvm7FvPYoRPSQIxiWJw1s4E3/sVKmfSavTadonWdWSY0puZW3PASBlCwsnVZxH/A/1NXxzanHme0VTFBs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-4217d451f69so54736265e9.0; Wed, 19 Jun 2024 08:35:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718811304; x=1719416104; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=a6WFl7aFlMAKF2BVC3/LiVx3aK8vlI/C/B6IWyQb8e0=; b=M/q3Bs/OgY32qfaWor3JDHGXkMc7yv3pHSktdueNZOYaCOoSrZCs5ilvNxAyxVMyl9 f2tWwI2F0PWPo30y68JO+wPq4CTrDjMCwh+eMeJWzW6LyEiVztH/n203uT4PYztHJH7c GLgzLa2WaGPfPV6JupkVS/OoSkroG76rE4KIXWVwhvX1j62kwtJhaKUti+LG6aX9mWx0 S1gnFpB2lKUvycwdvSEpEXKChwIMYt8F+GVp8FXgbIf3FSNeFsvAHQTCpgMxsxPBr4N2 Q6Y98pS9RnyDjx+kaWAksalJ7Um57caHL8GhTjOpN/dRLuGOpSaBkQf1BC/kpcFFEroT lpNA== X-Forwarded-Encrypted: i=1; AJvYcCUkovrutX99KXiy53uvxzf+7OH/8lce/Nycfsxi3moFFr1eeVy+AAL8EuyN1i8l7B2cG+2GWChBPo14g4PjUUc2B0FfXrxtBMTaB5cf X-Gm-Message-State: AOJu0YxiH0/KPrjd521yA74Dh7mFoARH4hPH2zLNY0KzBABrvE5Ooee4 ubfQ8V2IoePGs8dIuKKCTfLUV0nnRf1Z39HPInUhUdTpKgOh7XjGsoD2JA== X-Google-Smtp-Source: AGHT+IGaFvzQamYUwBbfkH/SAlM6S1Fikeh5YeEum5r+73ZJBuVbdtOMscA/6C8KNyOBpUsg6pYLwA== X-Received: by 2002:a05:600c:1c0e:b0:423:4c2:7a80 with SMTP id 5b1f17b1804b1-42475078676mr20342285e9.5.1718811303951; Wed, 19 Jun 2024 08:35:03 -0700 (PDT) Received: from [127.0.0.1] (p200300f6f7110500fa633ffffe02074c.dip0.t-ipconnect.de. [2003:f6:f711:500:fa63:3fff:fe02:74c]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42286fe9263sm268882135e9.15.2024.06.19.08.35.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jun 2024 08:35:03 -0700 (PDT) From: Johannes Thumshirn Date: Wed, 19 Jun 2024 17:34:53 +0200 Subject: [PATCH v2 3/4] btrfs: split RAID stripes on deletion Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240619-b4-rst-updates-v2-3-89c34d0d5298@kernel.org> References: <20240619-b4-rst-updates-v2-0-89c34d0d5298@kernel.org> In-Reply-To: <20240619-b4-rst-updates-v2-0-89c34d0d5298@kernel.org> To: Chris Mason , Josef Bacik , David Sterba Cc: linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org, Johannes Thumshirn X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=4283; i=jth@kernel.org; h=from:subject:message-id; bh=LHvwAE7uLPXkoCP95RNbChA7GHz/3kVK1zWwXyZuU7M=; b=owGbwMvMwCV2ad4npfVdsu8YT6slMaQV/Vo4u8f1wMN15s0PbzXP/nxq1xm7JYt5b8nv2/Wgt WLfphOlbR2lLAxiXAyyYoosx0Nt90uYHmGfcui1GcwcViaQIQxcnAIwkaOmjAx3OFe2nrr/1GcB z8oXSaxGk25G7/fYxREy+cSLF31/gyX/MPyvC+B+XmhkyCoz53N6t7BWY4uNVrnT4YaP67557m7 wsOEBAA== X-Developer-Key: i=jth@kernel.org; a=openpgp; fpr=EC389CABC2C4F25D8600D0D00393969D2D760850 From: Johannes Thumshirn The current RAID stripe code assumes, that we will always remove a whole stripe entry. But if we're only removing a part of a RAID stripe we're hitting the ASSERT()ion checking for this condition. Instead of assuming the complete deletion of a RAID stripe, split the stripe if we need to. Signed-off-by: Johannes Thumshirn --- fs/btrfs/ctree.c | 1 + fs/btrfs/raid-stripe-tree.c | 100 +++++++++++++++++++++++++++++++++----------- 2 files changed, 77 insertions(+), 24 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 763b9a1da428..a5c841da0357 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -3858,6 +3858,7 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans, btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); BUG_ON(key.type != BTRFS_EXTENT_DATA_KEY && + key.type != BTRFS_RAID_STRIPE_KEY && key.type != BTRFS_EXTENT_CSUM_KEY); if (btrfs_leaf_free_space(leaf) >= ins_len) diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c index 3020820dd6e2..64e36b46cbab 100644 --- a/fs/btrfs/raid-stripe-tree.c +++ b/fs/btrfs/raid-stripe-tree.c @@ -33,42 +33,94 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le if (!path) return -ENOMEM; - while (1) { - key.objectid = start; - key.type = BTRFS_RAID_STRIPE_KEY; - key.offset = length; +again: + key.objectid = start; + key.type = BTRFS_RAID_STRIPE_KEY; + key.offset = length; - ret = btrfs_search_slot(trans, stripe_root, &key, path, -1, 1); - if (ret < 0) - break; - if (ret > 0) { - ret = 0; - if (path->slots[0] == 0) - break; - path->slots[0]--; - } + ret = btrfs_search_slot(trans, stripe_root, &key, path, -1, 1); + if (ret < 0) + goto out; + if (ret > 0) { + ret = 0; + if (path->slots[0] == 0) + goto out; + path->slots[0]--; + } + + leaf = path->nodes[0]; + slot = path->slots[0]; + btrfs_item_key_to_cpu(leaf, &key, slot); + found_start = key.objectid; + found_end = found_start + key.offset; + + /* That stripe ends before we start, we're done. */ + if (found_end <= start) + goto out; + + trace_btrfs_raid_extent_delete(fs_info, start, end, + found_start, found_end); + + if (found_start < start) { + u64 diff = start - found_start; + struct btrfs_key new_key; + int num_stripes; + struct btrfs_stripe_extent *stripe_extent; + + new_key.objectid = start; + new_key.type = BTRFS_RAID_STRIPE_KEY; + new_key.offset = length - diff; + + ret = btrfs_duplicate_item(trans, stripe_root, path, + &new_key); + if (ret) + goto out; leaf = path->nodes[0]; slot = path->slots[0]; - btrfs_item_key_to_cpu(leaf, &key, slot); - found_start = key.objectid; - found_end = found_start + key.offset; - /* That stripe ends before we start, we're done. */ - if (found_end <= start) - break; + num_stripes = + btrfs_num_raid_stripes(btrfs_item_size(leaf, slot)); + stripe_extent = + btrfs_item_ptr(leaf, slot, struct btrfs_stripe_extent); + + for (int i = 0; i < num_stripes; i++) { + struct btrfs_raid_stride *raid_stride = + &stripe_extent->strides[i]; + u64 physical = + btrfs_raid_stride_physical(leaf, raid_stride); + + btrfs_set_raid_stride_physical(leaf, raid_stride, + physical + diff); + } + + btrfs_mark_buffer_dirty(trans, leaf); + btrfs_release_path(path); + goto again; + } + + if (found_end > end) { + u64 diff = found_end - end; + struct btrfs_key new_key; - trace_btrfs_raid_extent_delete(fs_info, start, end, - found_start, found_end); + new_key.objectid = found_start; + new_key.type = BTRFS_RAID_STRIPE_KEY; + new_key.offset = length - diff; - ASSERT(found_start >= start && found_end <= end); - ret = btrfs_del_item(trans, stripe_root, path); + ret = btrfs_duplicate_item(trans, stripe_root, path, + &new_key); if (ret) - break; + goto out; + btrfs_mark_buffer_dirty(trans, leaf); btrfs_release_path(path); + goto again; + } + ret = btrfs_del_item(trans, stripe_root, path); + + out: btrfs_free_path(path); return ret; } From patchwork Wed Jun 19 15:34:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Thumshirn X-Patchwork-Id: 13704102 Received: from mail-lf1-f51.google.com (mail-lf1-f51.google.com [209.85.167.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5046152787; Wed, 19 Jun 2024 15:35:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718811308; cv=none; b=L/SEAjqaTTRRbdmJyrFF35OFUGrabqfa6cfIq51RlC+vcjIKGaMBYvnZhKNHmynJBfQSzM4mikCDimmpBo3qVJF2DNhJXzVDfPg/XUfJyU1SBAUjUuGTeijFsF59tK402qfhamz5WAt8YB18L0gXjZ0oMmnVrX+OWnzhwkbGf8Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718811308; c=relaxed/simple; bh=PqGfVgSKEswFDJImaCkU9nFS8FadtWNV9A7d+JcshWI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FFRKNu0sItDU0t+ClA0whrSdRbQEZdfzFY9Af9mv6Uy2HyWIapKtwcQi2of+73+vrDwgewDjh8GTicC/fMduinx9HR/U/ATWzVcHiSVgqKY6MbVLFDHgp6cYvL3RBstOhVKdZF8SU++jl8mVsyRXXUbe4hvdVPtN1IwT9XqA4Y4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.167.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-lf1-f51.google.com with SMTP id 2adb3069b0e04-52bbf73f334so6450665e87.2; Wed, 19 Jun 2024 08:35:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718811305; x=1719416105; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qWmeWy8UxjtIb9YgNlFSXTYkhGxKGeO3sXg54+ZDFxY=; b=dKyUwCZkbdYrbE7MgYpDp3enewE6e7U1+HFDVkWPEWjOMRtXjSbPG00oXhlYSlCy67 5kh9ypjDZZQWtr5TsnOyxmdNxDDVfbwramsGj570Z1rhqwVw+fHttPduPis5CFhygIUC kTJxGjfDmuH7e0J2yGUrqnvmFq3ZsLKBLUB2XPyQ4Nt79iYbxtVo+L3lUyUiLE7t3UNA 0OxqQiXKsN2ATKHl2COzke776YzDEfzaQcgoKqzOIB59TFgCfJ57yoP+nTJb5xpmrjO6 7oqGPSzHicgoXOTny2QGWM2Hu1Lw0xE4ELP4n33a5bpn3b3jx59pz22/czxGM287xb5x k/5Q== X-Forwarded-Encrypted: i=1; AJvYcCWiuz/ZPKanTSDQEnv7avKPVZKGFTejF5VaDwat8vIQZvWG/m7BLRSxQKHrIm2qi2t1fjNO7nfn37nWtGc3w1jOHUYTDhXTrf2EV2wI X-Gm-Message-State: AOJu0YzlFP/4TuL6BGahnu0pKbRUkJRSsHRiqrL0rWtBrkpBfqvUUC+l s68B/Y5CYJooosvrpSWTDGBeq/NJa057RREac3h5lyiMSKxsHbCFZPtFjQ== X-Google-Smtp-Source: AGHT+IFaNkddFO//wttWe5Ej93KWbro2csj+NV8Gvzw+iKJ9ZL5kGcXpIXSj3X9i8V04Nl/NewgvqA== X-Received: by 2002:ac2:5a0c:0:b0:52c:785f:ae23 with SMTP id 2adb3069b0e04-52ccaa5cff4mr1611830e87.24.1718811304989; Wed, 19 Jun 2024 08:35:04 -0700 (PDT) Received: from [127.0.0.1] (p200300f6f7110500fa633ffffe02074c.dip0.t-ipconnect.de. [2003:f6:f711:500:fa63:3fff:fe02:74c]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42286fe9263sm268882135e9.15.2024.06.19.08.35.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jun 2024 08:35:04 -0700 (PDT) From: Johannes Thumshirn Date: Wed, 19 Jun 2024 17:34:54 +0200 Subject: [PATCH v2 4/4] btrfs: stripe-tree: add selftests Precedence: bulk X-Mailing-List: linux-btrfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240619-b4-rst-updates-v2-4-89c34d0d5298@kernel.org> References: <20240619-b4-rst-updates-v2-0-89c34d0d5298@kernel.org> In-Reply-To: <20240619-b4-rst-updates-v2-0-89c34d0d5298@kernel.org> To: Chris Mason , Josef Bacik , David Sterba Cc: linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org, Johannes Thumshirn X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=10060; i=jth@kernel.org; h=from:subject:message-id; bh=dcEj42HcJ3gyL1dHjpCKO791Dhsa/HLhBapf/qaKJgE=; b=owGbwMvMwCV2ad4npfVdsu8YT6slMaQV/VqoxK15SZr1UeVUrZntC/9klk3NvDRJxSV/f59X0 XYm7+LsjlIWBjEuBlkxRZbjobb7JUyPsE859NoMZg4rE8gQBi5OAZiIVCIjw65LVtdzmpxjVBKc OIosds1V6zzGpL/gldHb1O51Njsn3WBk2H2+JmMfXzF3Z8ZBg5BHPM8Z22X/3o84vM3Rpv7FtlX yzAA= X-Developer-Key: i=jth@kernel.org; a=openpgp; fpr=EC389CABC2C4F25D8600D0D00393969D2D760850 From: Johannes Thumshirn Add self-tests for the RAID stripe tree code. Signed-off-by: Johannes Thumshirn --- fs/btrfs/Makefile | 3 +- fs/btrfs/raid-stripe-tree.c | 3 +- fs/btrfs/raid-stripe-tree.h | 5 + fs/btrfs/tests/btrfs-tests.c | 3 + fs/btrfs/tests/btrfs-tests.h | 1 + fs/btrfs/tests/raid-stripe-tree-tests.c | 258 ++++++++++++++++++++++++++++++++ 6 files changed, 271 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index 50b19d15e956..79690d746781 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile @@ -43,4 +43,5 @@ btrfs-$(CONFIG_FS_VERITY) += verity.o btrfs-$(CONFIG_BTRFS_FS_RUN_SANITY_TESTS) += tests/free-space-tests.o \ tests/extent-buffer-tests.o tests/btrfs-tests.o \ tests/extent-io-tests.o tests/inode-tests.o tests/qgroup-tests.o \ - tests/free-space-tree-tests.o tests/extent-map-tests.o + tests/free-space-tree-tests.o tests/extent-map-tests.o \ + tests/raid-stripe-tree-tests.o diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c index 64e36b46cbab..c5c2f19387ff 100644 --- a/fs/btrfs/raid-stripe-tree.c +++ b/fs/btrfs/raid-stripe-tree.c @@ -156,7 +156,8 @@ static int replace_raid_extent_item(struct btrfs_trans_handle *trans, return ret; } -static int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans, +EXPORT_FOR_TESTS +int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans, struct btrfs_io_context *bioc) { struct btrfs_fs_info *fs_info = trans->fs_info; diff --git a/fs/btrfs/raid-stripe-tree.h b/fs/btrfs/raid-stripe-tree.h index 1ac1c21aac2f..541836421778 100644 --- a/fs/btrfs/raid-stripe-tree.h +++ b/fs/btrfs/raid-stripe-tree.h @@ -28,6 +28,11 @@ int btrfs_get_raid_extent_offset(struct btrfs_fs_info *fs_info, int btrfs_insert_raid_extent(struct btrfs_trans_handle *trans, struct btrfs_ordered_extent *ordered_extent); +#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS +int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans, + struct btrfs_io_context *bioc); +#endif + static inline bool btrfs_need_stripe_tree_update(struct btrfs_fs_info *fs_info, u64 map_type) { diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c index ce50847e1e01..18e1ab4a0914 100644 --- a/fs/btrfs/tests/btrfs-tests.c +++ b/fs/btrfs/tests/btrfs-tests.c @@ -291,6 +291,9 @@ int btrfs_run_sanity_tests(void) ret = btrfs_test_free_space_tree(sectorsize, nodesize); if (ret) goto out; + ret = btrfs_test_raid_stripe_tree(sectorsize, nodesize); + if (ret) + goto out; } } ret = btrfs_test_extent_map(); diff --git a/fs/btrfs/tests/btrfs-tests.h b/fs/btrfs/tests/btrfs-tests.h index dc2f2ab15fa5..61bcadaf2036 100644 --- a/fs/btrfs/tests/btrfs-tests.h +++ b/fs/btrfs/tests/btrfs-tests.h @@ -37,6 +37,7 @@ int btrfs_test_extent_io(u32 sectorsize, u32 nodesize); int btrfs_test_inodes(u32 sectorsize, u32 nodesize); int btrfs_test_qgroups(u32 sectorsize, u32 nodesize); int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize); +int btrfs_test_raid_stripe_tree(u32 sectorsize, u32 nodesize); int btrfs_test_extent_map(void); struct inode *btrfs_new_test_inode(void); struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize); diff --git a/fs/btrfs/tests/raid-stripe-tree-tests.c b/fs/btrfs/tests/raid-stripe-tree-tests.c new file mode 100644 index 000000000000..9a5848c4a1c4 --- /dev/null +++ b/fs/btrfs/tests/raid-stripe-tree-tests.c @@ -0,0 +1,258 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024 Western Digital Corporation. All rights reserved. + */ +#include +#include +#include +#include +#include +#include +#include +#include "btrfs-tests.h" +#include "../disk-io.h" +#include "../transaction.h" +#include "../volumes.h" +#include "../raid-stripe-tree.h" +#include "../block-group.h" + +static struct btrfs_io_context *alloc_dummy_bioc(struct btrfs_fs_info *fs_info, + u64 logical, u16 total_stripes) +{ + struct btrfs_io_context *bioc; + + bioc = kzalloc(sizeof(struct btrfs_io_context) + + sizeof(struct btrfs_io_stripe) * total_stripes, + GFP_KERNEL); + + if (!bioc) + return NULL; + + refcount_set(&bioc->refs, 1); + + bioc->fs_info = fs_info; + bioc->replace_stripe_src = -1; + bioc->full_stripe_logical = (u64)-1; + bioc->logical = logical; + + return bioc; +} + +typedef int (*test_func_t)(struct btrfs_fs_info *); + +static int test_stripe_tree_delete_tail(struct btrfs_fs_info *fs_info) +{ + struct btrfs_trans_handle trans; + struct btrfs_io_context *bioc; + const u64 map_type = BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_RAID1; + const int total_stripes = btrfs_bg_type_to_factor(map_type); + u64 logical = SZ_8K; + u64 length = SZ_64K; + int i; + int ret; + + btrfs_init_dummy_trans(&trans, fs_info); + + bioc = alloc_dummy_bioc(fs_info, logical, total_stripes); + if (!bioc) + return -ENOMEM; + + bioc->size = length; + bioc->map_type = map_type; + for (i = 0; i < total_stripes; ++i) { + struct btrfs_device *dev; + + dev = kzalloc(sizeof(struct btrfs_device), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto out; + } + dev->devid = i; + bioc->stripes[i].dev = dev; + bioc->stripes[i].length = length; + bioc->stripes[i].physical = i * SZ_8K; + } + + ret = btrfs_insert_one_raid_extent(&trans, bioc); + if (ret) + goto out; + + ret = btrfs_delete_raid_extent(&trans, logical, SZ_16K); + +out: + for (i = 0; i < total_stripes; i++) + kfree(bioc->stripes[i].dev); + + kfree(bioc); + return ret; +} + +static int test_stripe_tree_delete_front(struct btrfs_fs_info *fs_info) +{ + struct btrfs_trans_handle trans; + struct btrfs_io_context *bioc; + const u64 map_type = BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_RAID1; + const int total_stripes = btrfs_bg_type_to_factor(map_type); + u64 logical = SZ_8K; + u64 length = SZ_64K; + int i; + int ret; + + btrfs_init_dummy_trans(&trans, fs_info); + + bioc = alloc_dummy_bioc(fs_info, logical, total_stripes); + if (!bioc) + return -ENOMEM; + + bioc->size = length; + bioc->map_type = map_type; + for (i = 0; i < total_stripes; i++) { + struct btrfs_device *dev; + + dev = kzalloc(sizeof(struct btrfs_device), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto out; + } + dev->devid = i; + bioc->stripes[i].dev = dev; + bioc->stripes[i].length = length; + bioc->stripes[i].physical = i * SZ_8K; + } + + ret = btrfs_insert_one_raid_extent(&trans, bioc); + if (ret) + goto out; + ret = btrfs_delete_raid_extent(&trans, logical, SZ_8K); +out: + for (i = 0; i < total_stripes; i++) + kfree(bioc->stripes[i].dev); + + kfree(bioc); + return ret; + +} + +static int test_stripe_tree_delete_whole(struct btrfs_fs_info *fs_info) +{ + struct btrfs_trans_handle trans; + struct btrfs_io_context *bioc; + const u64 map_type = BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_RAID1; + const int total_stripes = btrfs_bg_type_to_factor(map_type); + u64 logical = SZ_8K; + u64 length = SZ_64K; + int i; + int ret; + + btrfs_init_dummy_trans(&trans, fs_info); + + bioc = alloc_dummy_bioc(fs_info, logical, total_stripes); + if (!bioc) + return -ENOMEM; + + bioc->size = length; + bioc->map_type = map_type; + for (i = 0; i < total_stripes; ++i) { + struct btrfs_device *dev; + + dev = kzalloc(sizeof(struct btrfs_device), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto out; + } + dev->devid = i; + bioc->stripes[i].dev = dev; + bioc->stripes[i].length = length; + bioc->stripes[i].physical = i * SZ_8K; + } + + ret = btrfs_insert_one_raid_extent(&trans, bioc); + if (ret) + goto out; + + ret = btrfs_delete_raid_extent(&trans, logical, length); + +out: + for (i = 0; i < total_stripes; i++) + kfree(bioc->stripes[i].dev); + + kfree(bioc); + return ret; +} + +static int test_stripe_tree_delete(struct btrfs_fs_info *fs_info) +{ + test_func_t delete_tests[] = { + test_stripe_tree_delete_whole, + test_stripe_tree_delete_front, + test_stripe_tree_delete_tail, + }; + int ret; + + for (int i = 0; i < ARRAY_SIZE(delete_tests); i++) { + test_func_t test = delete_tests[i]; + + ret = test(fs_info); + if (ret) + goto out; + } + +out: + return ret; +} + +int btrfs_test_raid_stripe_tree(u32 sectorsize, u32 nodesize) +{ + test_func_t tests[] = { + test_stripe_tree_delete, + }; + struct btrfs_fs_info *fs_info; + struct btrfs_root *root = NULL; + int ret = 0; + + test_msg("running raid-stripe-tree tests"); + + fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize); + if (!fs_info) { + test_std_err(TEST_ALLOC_FS_INFO); + ret = -ENOMEM; + goto out; + } + + root = btrfs_alloc_dummy_root(fs_info); + if (IS_ERR(root)) { + test_std_err(TEST_ALLOC_ROOT); + ret = PTR_ERR(root); + goto out; + } + + btrfs_set_super_incompat_flags(fs_info->super_copy, + BTRFS_FEATURE_INCOMPAT_RAID_STRIPE_TREE); + root->root_key.objectid = BTRFS_RAID_STRIPE_TREE_OBJECTID; + root->root_key.type = BTRFS_ROOT_ITEM_KEY; + root->root_key.offset = 0; + btrfs_global_root_insert(root); + fs_info->stripe_root = root; + + root->node = alloc_test_extent_buffer(fs_info, nodesize); + if (IS_ERR(root->node)) { + test_std_err(TEST_ALLOC_EXTENT_BUFFER); + ret = PTR_ERR(root->node); + goto out; + } + btrfs_set_header_level(root->node, 0); + btrfs_set_header_nritems(root->node, 0); + root->alloc_bytenr += 2 * nodesize; + + for (int i = 0; i < ARRAY_SIZE(tests); i++) { + test_func_t test = tests[i]; + + ret = test(fs_info); + if (ret) + goto out; + } +out: + btrfs_free_dummy_root(root); + btrfs_free_dummy_fs_info(fs_info); + return ret; +}