summaryrefslogtreecommitdiff
path: root/tools/perf/scripts/python
diff options
context:
space:
mode:
authorChris Mason <mason@kernel.org>2026-10-16 21:17:22 +0000
committerAmir Goldstein <amir73il@gmail.com>2026-11-04 21:34:20 +0100
commit520ef67f47f69255695859b0008281a384d0bc20 (patch)
treed5f596aa17c9f40cee2692144498b13428106c3d /tools/perf/scripts/python
parent9ff338af0e002fe217cfa16b1289b76f6b21fc72 (diff)
ovl: look up the index by the decoded origin
A file opened by file handle on an overlay with nfs_export=on can show the stale lower data of a file that was copied up to the upper layer. While the file opened this way stays in the inode cache, a lookup of the copied up file by path fails with ESTALE for all users. The open can also succeed for a file that was removed, where it has to fail with ESTALE. This happens with a handle that has one byte changed. The handle comes from an NFS client, or from a process that calls open_by_handle_at() with CAP_DAC_READ_SEARCH in the initial user namespace. When a file in a lower layer is about to be modified, overlayfs first copies it to the upper layer (copy up). With nfs_export=on, each copy up also creates an entry in the index directory, a directory that overlayfs keeps for itself on the upper filesystem. The handle of an overlay file that comes from a lower layer wraps the handle of its lower inode. Overlayfs calls this lower inode the origin. The overlay handle stays valid after a copy up. To decode such a handle, ovl_lower_fh_to_d() first decodes the wrapped handle to the origin. If no overlay inode is cached for the origin, it looks in the index directory: - An index entry there leads to the upper file. - A whiteout, the marker that overlayfs uses for a removed file, means that the overlay file was removed. The name of an index entry is the handle that copy up encoded for the origin, as a hex string. ovl_lower_fh_to_d() builds the name for this lookup from the bytes that the caller passed in. But handles with different bytes can decode to the same inode: - Overlayfs ignores some flag bits of the handle. - A lower filesystem can accept a different fid type, extra bytes, or generation 0 for any generation. Such a handle decodes to the origin but misses the index entry or the whiteout. So the decode returns an overlay inode that has only the lower file. While that inode is cached, a path lookup of a copied up file fails with ESTALE, since the upper file that the lookup finds does not match the cached inode, which has none. Reproduced on tmpfs and on ext4 with open_by_handle_at(), after a copy up and a mount cycle. A handle in which one flag bit, the fid type, the length or the generation was changed read the old lower data, and path lookups returned ESTALE. Fix this by re-encoding the decoded origin and building the index name from that handle. Fixes: f71bd9cfb692 ("ovl: decode indexed non-dir file handles") Cc: stable@vger.kernel.org Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Diffstat (limited to 'tools/perf/scripts/python')
0 files changed, 0 insertions, 0 deletions