[PATCH] md/md-bitmap: bitmap pages leaked after recovery

Nigel Croxon <[email protected]>
Newsgroups org.kernel.vger.linux-raid
Message-ID <[email protected]>
The bitmap pages leaked after recovery if successful writes occur
concurrently during array degradation/recovery.

We performed write I/Os to an MD RAID1 array while it was in a degraded
state or actively undergoing recovery. Even after the array recovery
successfully reached 100%, the disk status returned to normal ([UU]),
and all I/Os completely stopped, the number of bitmap pages
(bitmap: n/N pages in /proc/mdstat) never dropped back to 0, resulting
in a persistent memory leak of bitmap pages.

Bitmap pages remain permanently allocated in the kernel memory even after
the array has fully returned to a healthy state, leading to a kernel
memory leak.

When a disk is re-added and recovery starts, MD_RECOVERY_RUNNING is set
in mddev->recovery.  The else if condition evaluates to false for normal
concurrent writes during recovery. NEEDED_MASK is never applied to these
blocks.

Fixes: 4f0e7d0e03b7
md/md-bitmap: remove the last parameter for bimtap_ops->endwrite()
This is becauses removing success caused bitmap_endwrite()
to treat mddev->degraded as a blanket trigger for NEEDED_MASK.

Signed-off-by: Nigel Croxon <[email protected]>
---
  drivers/md/md-bitmap.c | 9 ++++++++-
  1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index 1d4a050dab3a..b8be0d079780 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -1756,7 +1756,14 @@ static void bitmap_end_write(struct mddev *mddev, 
sector_t offset,
                  sysfs_notify_dirent_safe(
                          bitmap->sysfs_can_clear);
              }
-        } else if (!NEEDED(*bmc)) {
+        /*
+         * Do not set NEEDED_MASK if recovery is actively running.
+         * Writes completing during recovery/resync are already covered by
+         * the recovery thread and setting NEEDED_MASK will cause orphaned
+         * bitmap flags and memory leaks after recovery finishes.
+         */
+        } else if (!test_bit(MD_RECOVERY_RUNNING,
+                &bitmap->mddev->recovery) && !NEEDED(*bmc)) {
              *bmc |= NEEDED_MASK;
          }

-- 
2.47.3
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.