From nobody Sat Jun 27 16:16:19 2026 Received: from mail-qk1-f178.google.com (mail-qk1-f178.google.com [209.85.222.178]) (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 A3ADC33A9E1 for ; Mon, 8 Jun 2026 16:08:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780934895; cv=none; b=p6749kG3AYzf7i+QYUaGH4Sv3U+O8KAk43P79+bQed17eNXzq3zWMHMKgeezlAAuSkXJ27FdZxxpPqEXprAcz3r60ZTLWZz/elFUSsGLvw3e/4SmMjm6Kxs7ijFqBKBiwbZ2G1nV90FLQ+B/X7ITD/qZRmW4+7+Gx52owBJxhSM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780934895; c=relaxed/simple; bh=2GhRHyVAlyUGenZyKYbrYLs63DlEoRgcYFmu+i/5cCM=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=mm7MllOIVT+8ZtLZT9bRTqji91KYMzOEuqGkiHmEoKKv1jxS4lB5IaljYd8NFt01DqTZ+ZTc2bd3sQMWBjEPQst9rkvzMk4FbSs4db2ZL7r94uG7WKpAhFQzDqs5TznpK+tyd8nw6wWabWgg0ta6UJD/jQo/KNYXnSFmXtsm8UM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=trailofbits.com; spf=pass smtp.mailfrom=trailofbits.com; dkim=pass (2048-bit key) header.d=trailofbits.com header.i=@trailofbits.com header.b=Qk3ZCeaq; arc=none smtp.client-ip=209.85.222.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=trailofbits.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=trailofbits.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=trailofbits.com header.i=@trailofbits.com header.b="Qk3ZCeaq" Received: by mail-qk1-f178.google.com with SMTP id af79cd13be357-915b5ce94c7so300822985a.2 for ; Mon, 08 Jun 2026 09:08:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=trailofbits.com; s=google; t=1780934893; x=1781539693; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=NmTLhb4vOLAl9gtjuNKa9IpLiHeFhQUx7aBr9QenpC8=; b=Qk3ZCeaqIc5R+jbgNfFpSJjV7tkfT5RfSBRqg0d91rVXZbbfzGq6mZWhiDTYabZkfg yRT9NGV7pL67HgBF3yv3fpOpmQjZDm6kxgXrlCrxoezu/0o05sJBuMVzM8Dv+XA51hyP 0SIab77K0rNX815ESVQKX2RHuV6DzxuvL55F0lPPlMH+qrXOepy4XV0RPSIj0+ygRSCw fHj1UTQMIrUg0NRtdT61Fi6JFThKsYdmz0e291OVtkdf4MJAOAaa44D38erZeVRTvXt7 YE6lr9WaM/RJVQfw0k7GSWbmHA5tzf7Gefb2WNLnSF5XPzpyv+7bb38b6BrwoSfFpRQf y5jQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780934893; x=1781539693; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=NmTLhb4vOLAl9gtjuNKa9IpLiHeFhQUx7aBr9QenpC8=; b=KpjphiprCBLrrGZLtlw1PXMTR7d5iYTgM8wxO4qfV9X/X/fU5Uo9QmWcHEtZ6+nagr FKIt++mc+drfgWX+Tw2a8GcxDX3Zo6LcsEBQ2NzBFgR9n1KHV2pmxA3+9UFXWN2wjdBL u7XSX2MHOebM5oDa7vjIZ5CBAfGaTh7KjKw2H6Zit89Z1QVkhIK920kWuzB7y3GTxgfL Mb6e9LWGafcTib37qdsQVTEtVpPZ9xfmDAHPznXw7HfgRHi1ySRI8mp5pnLentxDYi6E +ZCCxFMIX3vd4JVL3lTuJRDlKydefg7w9mBXmnpFyLhMlyg3ZV0GDQqdIkaVaGqFVmm0 620A== X-Forwarded-Encrypted: i=1; AFNElJ+dQzJDBsXiB3rynIiKnuDuUQEyV/ndszc+XgrFV7mGjGWLjahDh1z6pe6KwfRlJAVFiLA30PKCyAq37Uc=@vger.kernel.org X-Gm-Message-State: AOJu0YwalRqYufnc1o4stHnxiExbH1ylcm+GZX26LL26NDn7VGv1dNio EH2iV9S7Qa4HSBv2xNtO5YC/WMurYHjRycTzjpJY1tgP86TfTGvxK8JHnewbhNWZ9Z4= X-Gm-Gg: Acq92OEN2acUxW9pnbD9qQU5Kj9BuyQN5oz925I0YHp19afOqL1XnOE0LpWsvDRYYqf oGupIuLHJGvMGzMdSp0ZXG3mcGoOaCncc0JDda5DnoyeyDEklQKmLPR7AdvA1tybtOMG5DvxZG6 EOYsyP0T+NX6t8YwYAEHqxJ3O69zBQ8lfxEz4Pbxy3BC1SpUjMMRo3Syore57aRmfOie3FXslNt 5EDQvzVBDemcwSa1bpYJLtDIZicJa6ZTvWwAWeRV6Xypm1GS9wk4Q0TqODPSknr0ddfWyIG5iJI WEjpPFPhUh2k/Wz8JKh4UsP12JhDA+RE0kmE9sLQsKE3TPeJ5MYInS0trAYz4IrKFVMimjVuWx3 nc5thMAc4D8QfHngcRF0AEhJceAzajVc4Q5E/mvB3bJQW69J6tz+L69LfVBw4QRlVZsMf/kGscg tkDF3Wuen1YfacUuG3yEk+0rJcTb8tZFh+Oa3xvbh00ufZfY5s X-Received: by 2002:a05:620a:1794:b0:915:a4c1:8c55 with SMTP id af79cd13be357-915a9d7d4b5mr2561594585a.34.1780934892611; Mon, 08 Jun 2026 09:08:12 -0700 (PDT) Received: from localhost ([161.35.96.86]) by smtp.gmail.com with UTF8SMTPSA id af79cd13be357-9158a3d3a0esm1800744785a.40.2026.06.08.09.08.11 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 08 Jun 2026 09:08:12 -0700 (PDT) From: Samuel Moelius To: Alasdair Kergon Cc: Samuel Moelius , Mike Snitzer , Mikulas Patocka , Benjamin Marzinski , dm-devel@lists.linux.dev (open list:DEVICE-MAPPER (LVM)), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v2] dm ebs: drop dirty bufio state when discarding blocks Date: Mon, 8 Jun 2026 16:06:07 +0000 Message-ID: <20260608160606.1134881.c0f6c631029b.dm-ebs-discard-dirty-buffer-resurrection@trailofbits.com> X-Mailer: git-send-email 2.43.0 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" dm-ebs can discard a block while a dirty dm-bufio buffer for the same block is still cached. If that buffer is later written back, stale data can be written over the discarded state. That resurrects data that userspace explicitly discarded and breaks the expected discard semantics of the target. Flush pending dirty buffers before processing a following discard, then forget the matching bufio state and issue the discard. Keep writeback errors separate from the discard result so a flush failure is reported to the write bios that dirtied the buffers, while the discard bio reports only the discard operation's own status. Assisted-by: Codex:gpt-5.5-cyber-preview Signed-off-by: Samuel Moelius --- Changes in v2 - fix how dirty bios are handled and how errors are reported drivers/md/dm-ebs-target.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/md/dm-ebs-target.c b/drivers/md/dm-ebs-target.c index 1e52bde48b91..5bdd1bf6c206 100644 --- a/drivers/md/dm-ebs-target.c +++ b/drivers/md/dm-ebs-target.c @@ -176,8 +176,8 @@ static void __ebs_forget_bio(struct ebs_c *ec, struct b= io *bio) /* Worker function to process incoming bios. */ static void __ebs_process_bios(struct work_struct *ws) { - int r; - bool write =3D false; + int r, rr, write_r =3D 0; + bool dirty =3D false; sector_t block1, block2; struct ebs_c *ec =3D container_of(ws, struct ebs_c, ws); struct bio *bio; @@ -209,9 +209,15 @@ static void __ebs_process_bios(struct work_struct *ws) if (bio_op(bio) =3D=3D REQ_OP_READ) r =3D __ebs_rw_bio(ec, REQ_OP_READ, bio); else if (bio_op(bio) =3D=3D REQ_OP_WRITE) { - write =3D true; r =3D __ebs_rw_bio(ec, REQ_OP_WRITE, bio); + dirty =3D true; } else if (bio_op(bio) =3D=3D REQ_OP_DISCARD) { + if (dirty) { + rr =3D dm_bufio_write_dirty_buffers(ec->bufio); + dirty =3D false; + if (rr && !write_r) + write_r =3D rr; + } __ebs_forget_bio(ec, bio); r =3D __ebs_discard_bio(ec, bio); } @@ -224,11 +230,15 @@ static void __ebs_process_bios(struct work_struct *ws) * We write dirty buffers after processing I/O on them * but before we endio thus addressing REQ_FUA/REQ_SYNC. */ - r =3D write ? dm_bufio_write_dirty_buffers(ec->bufio) : 0; + if (dirty) { + r =3D dm_bufio_write_dirty_buffers(ec->bufio); + if (r && !write_r) + write_r =3D r; + } =20 while ((bio =3D bio_list_pop(&bios))) { /* Any other request is endioed. */ - if (unlikely(r && bio_op(bio) =3D=3D REQ_OP_WRITE)) + if (unlikely(write_r && bio_op(bio) =3D=3D REQ_OP_WRITE)) bio_io_error(bio); else bio_endio(bio); --=20 2.43.0