From nobody Sun Jun 14 06:08:24 2026 Received: from mail-qv1-f100.google.com (mail-qv1-f100.google.com [209.85.219.100]) (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 60AAE37EFF4 for ; Fri, 1 May 2026 23:27:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.100 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777678070; cv=none; b=PhbXwb0N04CN1P4PfK8fkwiT8IDpk0qopybQYMv07S8rYZ9fQRIh17PZWN0yF184yi+q8D07MNyT87MrkSF9dj/PGOWZ6apYKcMmAprCc+6DXioScF5DIsSP76OSWAtNRrgF26lpWwxiYRoRGMAqoN5IHRmWtoV8wk/qY1WhTG0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777678070; c=relaxed/simple; bh=IzsHTZd6P6eYxd9Efo/a+pL4VeFLJKPvFGqGLptMSas=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=gMW0TyFlMojOznXDk9FvpaIUX0/Y9sPaUy6M0l9x96KGqjP+KfeykIRgSRJMnmSGDOkMBvMocq9UIDLaONkSIEUX4Ab6B+wANvpK84zS/lYHQ7aEJdTKGChw9Wa780eYfwQCrTz+pvvMdYRkI+LaYmVY8i2fU87k0CsGSBHast8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=amlalabs.com; spf=pass smtp.mailfrom=amlalabs.com; dkim=pass (2048-bit key) header.d=amlalabs-com.20251104.gappssmtp.com header.i=@amlalabs-com.20251104.gappssmtp.com header.b=a5rLOY7H; arc=none smtp.client-ip=209.85.219.100 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=amlalabs.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amlalabs.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=amlalabs-com.20251104.gappssmtp.com header.i=@amlalabs-com.20251104.gappssmtp.com header.b="a5rLOY7H" Received: by mail-qv1-f100.google.com with SMTP id 6a1803df08f44-8b5232009a6so13466996d6.1 for ; Fri, 01 May 2026 16:27:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amlalabs-com.20251104.gappssmtp.com; s=20251104; t=1777678067; x=1778282867; 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=PIMoo2xEXf7dASzi8yK3wgyb6uWnPH179QZ1IGul6o0=; b=a5rLOY7HOyhrAzO/IcTwgTXnfYNKbOHSJHVEwCg7pLMv16Ta78Ore9X4ROM6qd/XAB bJeQW21ljJAWVs1ALYJZ+Q14T2ERUiiyRKWmNnY1xv1Jw59RJkvraYM15mXIQPZeSDDJ 9SYUHeuQQetbvww8XuoBMBIpsWNvYtV8XHdBDByzDCpykLRDqK60tyO0yF1o87eZJaYo 5eKeUz0BTaxi/Irs/xnjzE3MP9MuV5oHPSYc4ZmLReW2joVYvLJ4zmJwtKvfKSiQn224 oxA3oejr3qmPR5eUf9qe7FS4kXCmDV5MJnOgd6qSjZRxPxxi+46SYj2K0EpOUBPHNbF/ NqKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777678067; x=1778282867; 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=PIMoo2xEXf7dASzi8yK3wgyb6uWnPH179QZ1IGul6o0=; b=RpqjyoBWOMj3ZAtdQjxx5z4V1/+6WCbjqUdeUbEpEW3irn+2tiIgy/K3Fd5mhyHXBQ SOXA2N5wk8NsQgSbVA9iD2DeKYm3F4T8wpfj4ACpbcsC2POLMe1WNJcStP4LIWIOTZj/ E5tTiPP2jZN4twA8zCP71nQay8+IPbGk6Q2eX3UK4lWU8wPlq6dwwUHpkRY8uePK+YIK Zi/LdSS+BoT82NfNxMVA7PcTmAf1DLhMdzSryVuIny+wzG6V6LPSs3LvNjXb/TUOvyme k52NMMue+nK6WEKAUHYlNk/tvsI1DwW36M2uEp7T3U4eZU4cefhxTZinrvViaiqtL06k 8sVg== X-Forwarded-Encrypted: i=1; AFNElJ/w/F74MumHkgJW9Pb1OoA+caALJ1nyzHs1+/ra4ZKvEEx92MNa5mnZcbnwOw5Nh61SX4ogQHkiw4d8NE8=@vger.kernel.org X-Gm-Message-State: AOJu0YzjIVqLyTvbeN8Wz8tCYzWJmpd8F9Hpu8uYo7AfD0OPa5EaS4G6 +E2gJnFYxc3xC5lcQkIDsokHJ0u8lx+m+R6aVPKgoQMJ3AxY0tCeEghMBWDRlFoLkgtueM8a5E9 ERcqunRqrOAE+95SpETYC6JOYxs6G9u3U9r6XyYE= X-Gm-Gg: AeBDievWiBjI4mmZuX1tiDe6IGbRfjVZdjdkIE8KFWx0pYVbOhnQ9R1yKLOjqVM9NFF 2P/RzFGnQBT0O7E9FRHfGj4+Ja6YwReq6erU/vA/m4L2l9OhfnCHnt0WSPU5UqEvHnYBCgu0qIW Lb0p9QQ0Q/KyE6I8IyzTCJhbY49oS9WamlTsVmW96aSc1mUQBx2w2QMdfnqZWH8C1UiSMpzurZP HYPd9I64D31OqLp3MWv1NE1I5+pxeq4uQoUFoxUT7tqCY2dtCj6/SZoavgPAH32TNWdyFK2rjF8 52to8CdimDD8lGzKF4PAyvniAR0OWepL1kgUb2eXyZlUFHqlnwoZW1qBwLfXC/IHloDSjKvYDN6 evRIHuUR9l5JbNiS7ujniAY2sd839yMiQY5ggXTpiU75hv7CzEuZa9VegZxfVTzZurdFAPUSCCu Z85yhcK2Zb X-Received: by 2002:a0c:e001:0:b0:89c:d50e:b57 with SMTP id 6a1803df08f44-8b6665f1489mr23648016d6.15.1777678067303; Fri, 01 May 2026 16:27:47 -0700 (PDT) Received: from amlalabs.com (104-10-255-95.lightspeed.sntcca.sbcglobal.net. [104.10.255.95]) by smtp-relay.gmail.com with ESMTPS id 6a1803df08f44-8b53b918281sm3200306d6.19.2026.05.01.16.27.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 May 2026 16:27:47 -0700 (PDT) X-Relaying-Domain: amlalabs.com From: Souvik Banerjee To: miklos@szeredi.hu, amir73il@gmail.com Cc: linux-unionfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Souvik Banerjee Subject: [PATCH] ovl: use linked upper dentry in copy-up tmpfile Date: Fri, 1 May 2026 23:27:35 +0000 Message-ID: <20260501232735.2610824-1-souvik@amlalabs.com> X-Mailer: git-send-email 2.51.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable ovl_copy_up_tmpfile() stores the disconnected O_TMPFILE dentry as the overlay's upper dentry reference via ovl_inode_update(). vfs_tmpfile() allocated this dentry via d_alloc(parentpath->dentry, &slash_name), so d_name is "/" and d_parent is c->workdir. Local upper filesystems (ext4, btrfs, xfs, ...) immediately rename it to "#" via d_mark_tmpfile() inside their ->tmpfile() op; FUSE and virtiofs do not, so both fields stay that way. Neither identifies the destination directory and filename where ovl_do_link() actually linked the file. When the upper filesystem implements ->d_revalidate() (e.g. FUSE or virtiofs), ovl_revalidate_real() calls it with the dentry's parent inode and a snapshot of d_name. The server tries to look up "/" inside c->workdir, fails, and overlayfs reports -ESTALE. This causes persistent ESTALE errors for any file that was copied up via the tmpfile path, breaking dpkg, apt, and other tools that do rename-over-existing on overlayfs with a FUSE/virtiofs upper. Before commit 6b52243f633e ("ovl: fold copy-up helpers into callers"), the tmpfile copy-up path used a dedicated helper ovl_link_tmpfile() that captured the linked destination dentry returned by ovl_do_link(): err =3D ovl_do_link(temp, udir, upper); ... if (!err) *newdentry =3D dget(upper); and published it via ovl_inode_update(d_inode(c->dentry), newdentry). The fold inlined ovl_do_link() into ovl_copy_up_tmpfile() but dropped the dget(upper) capture, and rewrote the publish line as ovl_inode_update(d_inode(c->dentry), dget(temp)) =E2=80=94 where temp is the disconnected O_TMPFILE dentry. Fix by keeping a reference to the linked destination dentry after ovl_do_link() succeeds, and publishing that dentry at the existing ovl_inode_update() call site. The non-tmpfile/workdir path continues to publish the renamed temporary dentry. Reproducer: - Mount overlayfs with virtiofs (or a FUSE fs whose server advertises FUSE_TMPFILE) as upper - Run: dpkg -i - Observe: "error installing new file '...': Stale file handle" Fixes: 6b52243f633e ("ovl: fold copy-up helpers into callers") Cc: stable@vger.kernel.org # v4.20+ Signed-off-by: Souvik Banerjee Reviewed-by: Amir Goldstein Reviewed-by: Miklos Szeredi --- fs/overlayfs/copy_up.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 13cb60b52bd6..e963701b4c87 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -853,7 +853,7 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *= c) { struct ovl_fs *ofs =3D OVL_FS(c->dentry->d_sb); struct inode *udir =3D d_inode(c->destdir); - struct dentry *temp, *upper; + struct dentry *temp, *upper, *newdentry =3D NULL; struct file *tmpfile; int err; =20 @@ -889,6 +889,14 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx = *c) err =3D PTR_ERR(upper); if (!IS_ERR(upper)) { err =3D ovl_do_link(ofs, temp, udir, upper); + if (!err) { + /* + * Record the linked dentry -- not the disconnected + * O_TMPFILE dentry -- so that ->d_revalidate() on + * the upper fs sees the real parent/name. + */ + newdentry =3D dget(upper); + } end_creating(upper); } =20 @@ -903,7 +911,7 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *= c) =20 if (!c->metacopy) ovl_set_upperdata(d_inode(c->dentry)); - ovl_inode_update(d_inode(c->dentry), dget(temp)); + ovl_inode_update(d_inode(c->dentry), newdentry); =20 out: ovl_end_write(c->dentry); --=20 2.51.1