From nobody Sat Jul 25 03:47:43 2026 Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44]) (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 5C3C8274B5F for ; Sun, 19 Jul 2026 14:42:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784472172; cv=none; b=Tgplb5MzKQutTVAOtWOysREMn7zdmq0NZf8ZaJGKXOoz0QaQDdwJfnuesqy6kJPagWQnpd5SBbT+cI8YdVTTADt/wwfWwMrCqhA9vHt/C/4Ky/+Lx0e7ZSOpRFhUdL+TdUX5woIcNa/hJdS4IjkuTgB25X219WO6ArkGp4U59QI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784472172; c=relaxed/simple; bh=Bk71AvQGQHwUw59EDZ3761+DgNEr6QYowbdMEYI9BA4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YmBdfo3rDeLKQPF6/7m/Qq5Xhmh6vBJic/u3s6lj35eSBZ0UrZzRJY37pFBTTKTIqQxsnnm2dYXKIAnyMoFj9tWX63p2oyOOD2+5jRFGSy8b+EHeSez+2elnKODnBPGyheUuOzokFdfS420hQG6noNXhMovLuTfIb948YkHimWE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meshstor.io; spf=pass smtp.mailfrom=meshstor.io; dkim=pass (2048-bit key) header.d=meshstor.io header.i=@meshstor.io header.b=eJ2vpjqm; arc=none smtp.client-ip=209.85.221.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meshstor.io Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meshstor.io Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=meshstor.io header.i=@meshstor.io header.b="eJ2vpjqm" Received: by mail-wr1-f44.google.com with SMTP id ffacd0b85a97d-47ddf7b09e5so5459425f8f.1 for ; Sun, 19 Jul 2026 07:42:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meshstor.io; s=google; t=1784472169; x=1785076969; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=3K8n6jI6tFj+NJRJQMh98XTSOTl584f3VQxcTV8N3dk=; b=eJ2vpjqmjBl7s9EsZOzdmSyQ3/67VhRbEjTk/2vX/StzyCHfL/Kqa6lAJ1dF2nJYyu lgewADMT+NxMotR5zEZrjzvZvpliacrNEWceOIZ5q210Spc8pqihqKDrw29sjRxlbTVs tQ5OeEowvXM5pmyUzQNBWyvxekA0FQmTlGaNiZeSSqpCNzHeZtAc1zlCdFaawqrJzUu4 GUmS6uiZ+tk0ZMK6vGnZSQNYpMwHe1Xs+6j6ieCsr7EGD9dR4F4nECo1DE6q6bpC1h/S fBGADlcBFtuJAAWq8XxOLUwBCh8V1vCLiaarQyMIeUec8c1c7Ot4bfBP74OLJ6K844H1 UO9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784472170; x=1785076970; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=3K8n6jI6tFj+NJRJQMh98XTSOTl584f3VQxcTV8N3dk=; b=MDo+/7YwGpdjexUXCMuV9PU0VQb+hRP1yafK/tgH/2gVfVZzrtFRiA3ijMGZtQNCVa Kc4NGRRwyn90ZEWhjtjWdUG5Nghe7xss8igSGFLTTK+V+O+QNIXigIfesvJ5G/gKK/Mg XfhewnMfuFOf1mUIRJwIYWc10558w6ttB0ZdXmqbQNZCnqMaytKBTyegaOmjf1ho8cJF AQQAFtlfiYge8zbI1EtEc71apsjEUodBV8exCdI3P6h7i5YkQ/9ojixTE6yp4nJ7+RKE R/fHftxSdV9LvGeV0UnGQU5bBKr0vCZ0NXG4lt3HNayi/QWuppJuNAQDPCURl4Po55mK U7Mw== X-Forwarded-Encrypted: i=1; AHgh+Rr+gPB420OHdRsAe6m4lm3oKDcufX8gaWhqb6wV9ZWMohKLxnl/hR9WI2csfJlNODJxLmu2kt5Ax/i0J0c=@vger.kernel.org X-Gm-Message-State: AOJu0YzFQSNN/qLxGOOXJmJsOjRqp0hqt7WXYXpMB/DMuXgWvOCzYczG InNHMhXdRvW00gKcxj0qa9llTjUgn7kHXkkZym5b9iew5TJ9NGPfLPVq4AwrJyX4hg== X-Gm-Gg: AfdE7cmtWJYwAxk+5GVtwqreCApEHQoLISbC+t64dPyUx00po9ZDppJ6B6lLIm4Gbql d5SabiKvocUORyWSIhYvOjV+j9sw6Rnb4H1AcGshSY9W/kJaoZcW9bGDfNLSKoCGiecU4im6Fug MwzAEivBQQc20G4Kx5U9E8bM1B7QjNpE4sWDKe5vYl4q+0BuXq/9S2yH3TF+L6ENIb+YDeIn9e/ 7/Bo9ZmVfJ473O6TvuLL0nHZ606jGwVp+9q5iotDBKR4StFqzPIhgXCuEZmVlFaI+lq2fqx/nAI 4NDW+sfOGgqNHY3wuUxluzOsoqznYfw2xAdO8wD5ANGng000goceXwSkqHd3nEZ1AY4uaVdvXft zhwkaeEBA1PpMrVpYNkjk8w3JkUu1aCWci5hz8i+yEHiEjP1Z9FgDYz69B3ELhw== X-Received: by 2002:a05:6000:4b0e:b0:473:6e8d:7f3 with SMTP id ffacd0b85a97d-47f622f1c09mr11670359f8f.1.1784472169232; Sun, 19 Jul 2026 07:42:49 -0700 (PDT) Received: from mf-00-01.. ([194.220.239.180]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47f63ec7c69sm22668895f8f.17.2026.07.19.07.42.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jul 2026 07:42:48 -0700 (PDT) From: Mykola Marzhan To: Song Liu , Yu Kuai Cc: Li Nan , Xiao Ni , Hannes Reinecke , linux-raid@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/3] md/raid10: restore still_degraded detection in recovery Date: Sun, 19 Jul 2026 14:42:25 +0000 Message-ID: <20260719144227.940444-2-mykola@meshstor.io> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260719144227.940444-1-mykola@meshstor.io> References: <20260719144227.940444-1-mykola@meshstor.io> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" raid10_sync_request()'s recovery arm passes still_degraded -- "will the array still be degraded after this recovery completes?" -- to md_bitmap_start_sync(), whose !degraded branch consumes the chunk's NEEDED marker, the write-intent record. That is only safe when the recovery restores full redundancy; otherwise the record still describes writes an absent member missed. Commit fe6a19d40ceb ("md/md-bitmap: merge md_bitmap_start_sync() into bitmap_operations") turned the detection loop's only assignment from "still_degraded =3D 1" into "still_degraded =3D false" in its int-to-bool styling pass, so the flag has been constant false ever since. raid1 and raid5 were converted to "=3D true"; only raid10 was inverted. The result is silent data loss on a classic-bitmap raid10 that stays degraded across a recovery. With mirror pairs {A,B} and {C,D}: lose D, keep writing, lose B, add a spare. The rebuild into B's slot strips NEEDED from every chunk -- including chunks whose only unsatisfied intent belonged to D -- so a later --re-add of D sees an empty intent record, completes instantly, and serves stale data. Restore the pre-conversion assignment. Only the classic-bitmap recovery arm is affected: llbitmap ignores the degraded parameter, and the resync arm passes mddev->degraded directly. Fixes: fe6a19d40ceb ("md/md-bitmap: merge md_bitmap_start_sync() into bitma= p_operations") Cc: stable@vger.kernel.org # v6.12+ Assisted-by: Claude-Code:claude-opus-4-8 Signed-off-by: Mykola Marzhan Reviewed-by: Paul Menzel Reviewed-by: Yu Kuai --- drivers/md/raid10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 0a3cfdd3f5df..54cddb3a98cd 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3365,7 +3365,7 @@ static sector_t raid10_sync_request(struct mddev *mdd= ev, sector_t sector_nr, struct md_rdev *rdev =3D conf->mirrors[j].rdev; =20 if (rdev =3D=3D NULL || test_bit(Faulty, &rdev->flags)) { - still_degraded =3D false; + still_degraded =3D true; break; } } --=20 2.43.0 From nobody Sat Jul 25 03:47:43 2026 Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) (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 313C539D6DD for ; Sun, 19 Jul 2026 14:42:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784472174; cv=none; b=IkQQUznRreyzBhG4qHb0XZbpPMIJ4ApaV7x0L6Q27dhA9k0dGk5k+wL2hfcQOnckfR3ZNsY2osnTeUQKxxYueVTG+s2jghK9pG/jLNZMY9HJ7vz5f97wIrJuVMNW6F7UdPAi2IV+1XXJeW8GWQAMw9wFN7rvpntwE40Gb+WgHLc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784472174; c=relaxed/simple; bh=o8yK1BIABrv2zPcdOZVgFZY711CWX+q3hnyZiP1Aeyg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rcMBjWFEtJSUM8QnYvkz0TtFDjeuG7Fnctfbe81oPqSvCuD4b0dhEgSvc91QDFbuKuTAmT1RuwnXoxKk3ImSDJ/rQakT1KLcrLhp5+MUFlesCArinrkkb51LKMqLepAM8Ci3ys+wL6lRz9Z5vAkYRXc6vg9KgRiv8HgeCI+SFTc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meshstor.io; spf=pass smtp.mailfrom=meshstor.io; dkim=pass (2048-bit key) header.d=meshstor.io header.i=@meshstor.io header.b=pNjDvta3; arc=none smtp.client-ip=209.85.221.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meshstor.io Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meshstor.io Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=meshstor.io header.i=@meshstor.io header.b="pNjDvta3" Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-475881b9a4bso6186006f8f.3 for ; Sun, 19 Jul 2026 07:42:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meshstor.io; s=google; t=1784472170; x=1785076970; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=ifPOK1LZi5TyJ6an+wjdH7bzo7jEagkKF5FxRxrk+U0=; b=pNjDvta3t30cRWwCH0EAewj9snn0+b6xF8Pj9AMfhDD7SaxDbNpjXEDH3t27jx+S8Q yfMuq6dixz4Vax8feZ5mgxrYcy5qHHr5BSNLQDVsg7z8K2YixVwGzKBmXxEC/HDllS4K 99mVxf+u2CrTD8tcoPu5RgGtejDyV/Rny2E/MoWgb5Dh706yXBc2bGvBcG/4HHiCOchp htt3XdEPFM8KfccR4yDALd65JeNnqZLUqS4NZuw+h3ZMRbzzdZqwwBElbetvEAFPVIA1 cp9Xj/wn2qs6KUmjHRwz4UWFKx+J4CHO0fh3anUq7Sz7OXrfQ8JpEmcRJPKg/+fMBkrZ x89A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784472170; x=1785076970; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=ifPOK1LZi5TyJ6an+wjdH7bzo7jEagkKF5FxRxrk+U0=; b=DM7Fl1x9+8YcPPgAbGdheYXZrcIv51EYsTpzEFaQXEpRE0ThnB3qkS0ckef3nIcvMz 0W8nmWCHtTs3X5Yqk+55VtpNhcbBqwTlFVqZnkUfxaNG2WElD+OxIb1pcPmF7aCvw9ur WlLQtUqC1DNHCtkfSXEG7vKPNAnEhIdU7xxJ/G3ASpm4Q3dD1mDwMDEVE0K3s+U29AH8 nryfmQsuI1C95Yhv7bXxsw0yBaKdpnBWLqjV/udc86lR8FgLuP4H3wgpUUI+R9S4jb3X 5dZaoh+02yARZ8foBLfttkcnoezYqt8xZqEmcgXAeP1NuQRXLuCTM+GysjjsCp9eDzBa 5bqg== X-Forwarded-Encrypted: i=1; AHgh+RqpOwdf/TAejTvWn7pGgRHLCyngSOJeFZT3olpcg+49zOC9EDrxdxj1N2KyVpmQcvjsUySBAAXB6wqWJ40=@vger.kernel.org X-Gm-Message-State: AOJu0Yy2WBWCpzUuqcw7uzOqrBFIJ/xnXItN+G6fSoP4GOeU4teVspji UjtMAexL+i4lmE3dg/EgH+Gcl6/6OsjYSukm4h1YhOpM74lH/fQPoYaXx1P/LD/CZlVbl7KXSW2 IBAcdXkIC X-Gm-Gg: AfdE7ckIdz4KMjtgC58z1YWTML+YAushKIf8Uu6oNRkxwid4VsDcq2oid7sxqk9JbhV tW992DCYGpsDB2gaF3gY0FKMDxaDm0ltwjO2dGQvJ119FMYzKTHNAy+/eSKpigaszMwusDV9Xle WsuHW2KfaY7OGugWE5bWqRcsd2/fl6d5oVAAeYhp3XIHbSfc08CBiM5DwnNmYNEj9cFs1SPYZ1B AfPvYN8+g2xtmFsXWFRHkNQ/IX7VbRDf2aIyusd/ni5eKiMuKCtSzjvlwgAYJMQXnQlqwRXgxRd 8bar605iOeg1DkZG08yq912Z4625whO7kN8c9j1SHW/qgRDAk+vFTHNEQTLIA5C3FhQ2dbQXSN8 CGh6i9No3Kz6AGaTxmLP1B7MJGONUuUqPgY5N5+YwDqZEKXGft692yBL3KQ5T8g== X-Received: by 2002:a5d:5885:0:b0:46e:1815:6a83 with SMTP id ffacd0b85a97d-47f62318f12mr11444557f8f.29.1784472170320; Sun, 19 Jul 2026 07:42:50 -0700 (PDT) Received: from mf-00-01.. ([194.220.239.180]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47f63ec7c69sm22668895f8f.17.2026.07.19.07.42.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jul 2026 07:42:49 -0700 (PDT) From: Mykola Marzhan To: Song Liu , Yu Kuai Cc: Li Nan , Xiao Ni , Hannes Reinecke , linux-raid@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/3] md: only consult skip_sync_blocks when 'j' is in the bitmap's domain Date: Sun, 19 Jul 2026 14:42:26 +0000 Message-ID: <20260719144227.940444-3-mykola@meshstor.io> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260719144227.940444-1-mykola@meshstor.io> References: <20260719144227.940444-1-mykola@meshstor.io> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rebuilding a raid10 member with llbitmap can complete in a few hundred milliseconds having copied nothing: md_do_sync() offers every position 'j' to bitmap_ops->skip_sync_blocks(), the bitmap answers for the wrong chunks, the whole rebuild is skipped as "unwritten", and the array reports optimal with a stale member. The staleness is typically noticed only when the mirror partner fails; writes made while the array was degraded vanish. The bitmap spans [0, resync_max_sectors) in the personality's sync-cursor space. Resync walks exactly that range for every personality and may always consult the bitmap. Recovery walks per-device offsets, which match the bitmap's space only for raid1 (device space is array space) and raid456 (the bitmap is indexed by the per-device sync cursor; bitmap_sector() translates array IO into it). raid10's bitmap is in array space -- near-2 on four disks spans twice a member's size; far-2 on two disks puts array chunk 2c+d at device chunk c of disk d -- so llbitmap_skip_sync_blocks() was consulted with offsets it cannot interpret. Only call the hook when the offsets match what the bitmap expects. Reshape must visit every stripe regardless of bitmap state -- skipping would desync reshape_position from 'j' -- so never skip there. For recovery, add an md_personality capability, recovery_in_bitmap_space, set by raid1 and raid456. raid10 leaves it unset (raid10_find_virt() needs the disk number, which md_do_sync() does not have); raid0 and linear too, but no recovery path of theirs reaches the hook. No performance is lost against any released kernel: the hook is llbitmap-only and new in v6.18, so raid10 recovery returns to its earlier path -- walk every stripe, skip clean chunks inside raid10_sync_request(). A capability rather than a geometry test: for raid10 layouts with raid_disks =3D=3D near_copies * far_copies, resync_max_sectors equals dev_sectors while the spaces can still differ (far and offset variants), so an arithmetic proxy reopens the same hole on those layouts. Disabling the hook for all recovery instead would forfeit llbitmap's fast-forward over unwritten chunks for raid1 and raid456 rebuilds. Opt-in is also the safe default: a new personality gets no bitmap consultation during recovery until it declares otherwise. Verified for near-2 and far-2 layouts: a rebuild onto an added spare copies the writes made while the array was degraded. Fixes: f196d7288864 ("md/md-bitmap: add a new method skip_sync_blocks() in = bitmap_operations") Cc: stable@vger.kernel.org # v6.18+ Assisted-by: Claude-Code:claude-opus-4-8 Signed-off-by: Mykola Marzhan --- drivers/md/md.c | 13 ++++++++++++- drivers/md/md.h | 11 +++++++++++ drivers/md/raid1.c | 1 + drivers/md/raid5.c | 3 +++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index d1465bcd86c8..d60ea7aaca3a 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -9846,7 +9846,18 @@ void md_do_sync(struct md_thread *thread) if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) break; =20 - if (mddev->bitmap_ops && mddev->bitmap_ops->skip_sync_blocks) { + /* + * The bitmap may be consulted with 'j' for a plain resync, + * but for recovery only when the personality declares that + * its recovery cursor addresses the bitmap's space; raid10 + * recovery walks per-device offsets the bitmap cannot + * interpret. Reshape must relocate every stripe regardless + * of bitmap state, so never skip there either. + */ + if (mddev->bitmap_ops && mddev->bitmap_ops->skip_sync_blocks && + !test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && + (!test_bit(MD_RECOVERY_RECOVER, &mddev->recovery) || + mddev->pers->recovery_in_bitmap_space)) { sectors =3D mddev->bitmap_ops->skip_sync_blocks(mddev, j); if (sectors) goto update; diff --git a/drivers/md/md.h b/drivers/md/md.h index d8daf0f75cbb..a490a47736b0 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -798,6 +798,17 @@ struct md_personality /* convert io ranges from array to bitmap */ void (*bitmap_sector)(struct mddev *mddev, sector_t *offset, unsigned long *sectors); + /* + * The position md_do_sync() walks during MD_RECOVERY_RECOVER + * addresses the space the write-intent bitmap is indexed by, so + * recovery may consult bitmap_ops->skip_sync_blocks() directly. + * True for raid1 (device space is array space) and raid456 (the + * bitmap is indexed by the per-device sync cursor). raid10 must + * leave this unset: its recovery walks per-device offsets while + * its bitmap is indexed by array sectors, and translating needs + * the disk number, which md_do_sync() does not have. + */ + bool recovery_in_bitmap_space; }; =20 struct md_sysfs_entry { diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index afe2ca96ad8c..1222c0470ab6 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -3518,6 +3518,7 @@ static struct md_personality raid1_personality =3D .check_reshape =3D raid1_reshape, .quiesce =3D raid1_quiesce, .takeover =3D raid1_takeover, + .recovery_in_bitmap_space =3D true, }; =20 static int __init raid1_init(void) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index ffb5fcde54a9..25f8d829a986 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -9078,6 +9078,7 @@ static struct md_personality raid6_personality =3D .change_consistency_policy =3D raid5_change_consistency_policy, .prepare_suspend =3D raid5_prepare_suspend, .bitmap_sector =3D raid5_bitmap_sector, + .recovery_in_bitmap_space =3D true, }; static struct md_personality raid5_personality =3D { @@ -9108,6 +9109,7 @@ static struct md_personality raid5_personality =3D .change_consistency_policy =3D raid5_change_consistency_policy, .prepare_suspend =3D raid5_prepare_suspend, .bitmap_sector =3D raid5_bitmap_sector, + .recovery_in_bitmap_space =3D true, }; =20 static struct md_personality raid4_personality =3D @@ -9139,6 +9141,7 @@ static struct md_personality raid4_personality =3D .change_consistency_policy =3D raid5_change_consistency_policy, .prepare_suspend =3D raid5_prepare_suspend, .bitmap_sector =3D raid5_bitmap_sector, + .recovery_in_bitmap_space =3D true, }; =20 static int __init raid5_init(void) --=20 2.43.0 From nobody Sat Jul 25 03:47:43 2026 Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.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 13EA539DBD0 for ; Sun, 19 Jul 2026 14:42:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784472174; cv=none; b=uo5ijCPTJj+N/dFQnUVjT3s+zQzb1pP6TDyEeLDTNF1TLGAPp/Iijq6DGRl9zvw37U3L0apVJnvuvnTP7oWaTLMfjVXlw+ux8TZYmi58Ns+NN1XEk8BA7vVnpFEUJn1mufbEx62cHREwCs+OrlwfKYM+hTANIkxiGbHbrkITLO4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784472174; c=relaxed/simple; bh=oQUTr6CYoMz+3KkQKXqfB9kRiMcFrW/5MVb+DqECyZ4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ix2goxjMEx8g6maArVvzZm4YkcUhBuHRIgB4wzywoy7mWu1+jj0GSswp6sW1UhDFCvn1FMBUN6HpzUk+gmSuq7/5vhM+U1yVuPPxJs9gdvilIK2UGw9OPnRp7Tk5EJhkQG93dEjOjxiRJl/Ap8y8C+tYBq765OdQ3iD6UE7LaK8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meshstor.io; spf=pass smtp.mailfrom=meshstor.io; dkim=pass (2048-bit key) header.d=meshstor.io header.i=@meshstor.io header.b=HNi7dwL8; arc=none smtp.client-ip=209.85.221.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=meshstor.io Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meshstor.io Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=meshstor.io header.i=@meshstor.io header.b="HNi7dwL8" Received: by mail-wr1-f43.google.com with SMTP id ffacd0b85a97d-4720f3bf164so1588221f8f.1 for ; Sun, 19 Jul 2026 07:42:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=meshstor.io; s=google; t=1784472171; x=1785076971; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=DWI2J+oPgO3qtXoFlpsHSDdFhAykwJO3OpAhzswB1nY=; b=HNi7dwL8MTR9pkOqCng0f3F75SU3qM6iVPqoHxafH6uMCpke4/YlmvvEXvUXdZfayF 9hT62FIxjoBb0SXH1+SHidIqmQWh7hDGIItLGZEtgriT8WTKAPRvAQcBdwSj2FNp3qYJ isZ7s/XsWzITe5woiu4WI6wdYzZEDduqL1mDb6xH4ZVSOqs7N9NT9ykRwpqjByNZ+1JQ Yx4pGlsVXr+P4XPPvxjLcpBHtiA5rAVak1NH8yRY03nqyve8PYOV70GVJFjzRl17Qvvm 1Ax4RfSMmLpuerJxIul4nAc8ygve9RNsllLM63v088P1beFamqB4if1oKQEx+fXY+vL6 44mA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784472171; x=1785076971; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=DWI2J+oPgO3qtXoFlpsHSDdFhAykwJO3OpAhzswB1nY=; b=SdGDqJSddn2UVKYY89TLq8OeiCBh09M4VJXpKsYG072gAfMV1N8bPweqzkIKN3SJHg 7ecBtET7YeLVw+2zH+oB/k9NDPHsi/LSIz5jogqod5a4EJhtsZ+Irydefi1CVEJPcs1O DLT55fdtgcsQbHFnrul89ZRifJAFLpgIGgU+QYtbUeIXXHT1q/ixOdeaXn+5WiS5ZmdT EY8Jm7byq/aE0WTORVdEGJskwr2/FfLjO+KGKK0f5Fraq6wV/0T+dSwmx+DzSqxh4VS8 XUBI6v7fgvE4Q5qoNmLlYM6OCtXIQKJ408t8Eetro87FEpjzBDiyPBqBl0eDPPp3oy9V 5DYQ== X-Forwarded-Encrypted: i=1; AHgh+Rq/sOt0ND0JofKc16v/Ri2CquLgUt/d3Od+V4HR2WJOUCQEQK3uUKj32b95HJpLkuZKdsIkqCQ3/BtiGkY=@vger.kernel.org X-Gm-Message-State: AOJu0YwPjsUhw/IqKMFujmxV7mRMpC7TnVYWwO6EapC+XY2vDPd0Kkhr aVM3gTpsZStFjwacAy2Ed7BTKdSJmqx85kIDJsWsYxawSRmR+c0l5OcbSDbd35oUkg== X-Gm-Gg: AfdE7clnK8110E+Kd99XBynH+TWcBK4JTpqh3Avrq+vMQOBFHPNhA5go6MJzARypBYc RQjb0BqwNiOlky83pFZ4qf4hii1YKe9rZe5eKIMj2GFDuT96m52+9phbqJyGWcdCVgue/aH2MEy o7lfZ+RJWSCG849fNdS/S+Q5xHl5KV9ajUl9ESMlEcs8HAAweNyufKmwZDqK/xJkhtuDzu8OYhp XQ/Xn0tboSIHjbJ9PKVBvHM2uqX/nbd5zXXNUhGs+8Vglfx7d8Iimq9CFi62n0qyAoNDI+hQBPC C5hthVqHluJ1diYpQ38cevMDYNci+35N+w8x2laATjpVDBpETdOc83VT8VsJXxCcfDRJTPCPU4V GZAqwcHFkAbBorcjKCWiaeWIufYj93nzXdee6NkNCmq7zWhx/OCwexS+3XdXK1WeTyLu3Eza4 X-Received: by 2002:a05:6000:25f1:b0:475:c578:b62f with SMTP id ffacd0b85a97d-47f5a419656mr17652936f8f.5.1784472171340; Sun, 19 Jul 2026 07:42:51 -0700 (PDT) Received: from mf-00-01.. ([194.220.239.180]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47f63ec7c69sm22668895f8f.17.2026.07.19.07.42.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jul 2026 07:42:50 -0700 (PDT) From: Mykola Marzhan To: Song Liu , Yu Kuai Cc: Li Nan , Xiao Ni , Hannes Reinecke , linux-raid@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/3] md/md-llbitmap: fail resize that needs more bitmap pages Date: Sun, 19 Jul 2026 14:42:27 +0000 Message-ID: <20260719144227.940444-4-mykola@meshstor.io> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260719144227.940444-1-mykola@meshstor.io> References: <20260719144227.940444-1-mykola@meshstor.io> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" llbitmap_resize() only updates chunkshift/chunksize/chunks. The page cache backing the bitmap (pctl[] and nr_pages) is sized at creation and never grown, so a grow whose chunk count crosses into a never-allocated page leaves the data path indexing past the end of pctl[]. And when the reserved bitmap space is too small for the new size, the chunksize-doubling loop silently changes the chunk-to-sector mapping without remapping any on-disk bit, so the existing intent state describes the wrong sectors afterwards. Fail such resizes before anything is mutated: -EINVAL for a resize that needs a different chunksize, -ENOSPC for a grow that needs more bitmap pages than were allocated at create time. Shrinks, grows within the allocated pages, and assemble-time sizing keep working. "mdadm --grow --size" past the boundary now fails with an error instead of corrupting memory, and a raid10 disk-add reshape crossing it fails cleanly in raid10_start_reshape(), which calls bitmap_ops->resize() directly and reverts the geometry on error. Grows within the last allocated page can still expose per-chunk bytes that are stale (after a shrink) or never initialised (the tail of the last page: llbitmap_init() covers only [0, chunks - 1]). That window closes once the bitmap page cache can actually grow -- the subject of separate work under review. Fixes: 5ab829f1971d ("md/md-llbitmap: introduce new lockless bitmap") Cc: stable@vger.kernel.org # v6.18+ Assisted-by: Claude-Code:claude-opus-4-8 Signed-off-by: Mykola Marzhan --- drivers/md/md-llbitmap.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c index 5a4e2abaa757..e8f853e8461d 100644 --- a/drivers/md/md-llbitmap.c +++ b/drivers/md/md-llbitmap.c @@ -1150,6 +1150,32 @@ static int llbitmap_resize(struct mddev *mddev, sect= or_t blocks, int chunksize) chunks =3D DIV_ROUND_UP_SECTOR_T(blocks, chunksize); } =20 + /* + * A changed chunksize would require remapping every on-disk bit: + * each chunk would cover a different sector range. Refuse rather + * than corrupt the existing intent record. + */ + if (chunksize !=3D llbitmap->chunksize) { + pr_warn("md/llbitmap: %s: cannot resize to %llu sectors: bitmap space (%= lu sectors) requires chunksize %u, current is %lu\n", + mdname(mddev), (unsigned long long)blocks, + mddev->bitmap_info.space, (unsigned int)chunksize, + llbitmap->chunksize); + return -EINVAL; + } + + /* + * pctl[]/nr_pages are sized at creation and not grown here; a + * grow past the last allocated page would index past pctl[]. + */ + if (DIV_ROUND_UP(chunks + BITMAP_DATA_OFFSET, PAGE_SIZE) > + llbitmap->nr_pages) { + pr_warn("md/llbitmap: %s: cannot grow to %lu chunks: needs %lu bitmap pa= ges, only %u allocated; growing the bitmap is not yet supported\n", + mdname(mddev), chunks, + DIV_ROUND_UP(chunks + BITMAP_DATA_OFFSET, PAGE_SIZE), + llbitmap->nr_pages); + return -ENOSPC; + } + llbitmap->chunkshift =3D ffz(~chunksize); llbitmap->chunksize =3D chunksize; llbitmap->chunks =3D chunks; --=20 2.43.0