Skip to content

Support RENAME_EXCHANGE in tmpfs and overlayfs - #14416

Open
copybara-service[bot] wants to merge 1 commit into
masterfrom
test/cl970791991
Open

Support RENAME_EXCHANGE in tmpfs and overlayfs#14416
copybara-service[bot] wants to merge 1 commit into
masterfrom
test/cl970791991

Conversation

@copybara-service

Copy link
Copy Markdown

Support RENAME_EXCHANGE in tmpfs and overlayfs

renameat2(2) support was added in 2c1c4a5 ("Implement renameat2."), but only for the gofer filesystem; tmpfs and overlayfs still return EINVAL for RENAME_EXCHANGE.

Implement RENAME_EXCHANGE in tmpfs by swapping the two dentries between their parent directories. When the exchanged files differ in type, the parents' link counts (for "..") and the exchanged directory's reference on its parent are transferred.

Implement RENAME_EXCHANGE in overlayfs by copying up the destination file (and its descendants, if it is a directory) in addition to the source, and then exchanging both files on the upper layer. Unlike a regular rename, no whiteout is created at the source location, since both locations remain occupied. Exchanged directories are marked opaque at their new locations to prevent merging with lower layer directories there.

RENAME_EXCHANGE permits the two files to differ in type and does not require a directory being exchanged to be empty, but exchanging a file with an ancestor directory must fail with EINVAL; see Linux's fs/namei.c:__start_renaming(). The gofer filesystem previously required both files to have the same type; lift that restriction, and update parent link counts when files of different types are exchanged across directories.

The RENAME_EXCHANGE syscall tests no longer accept EINVAL (except on FUSE, which does not support the flag), and new tests cover mixed-type exchanges and exchanges with ancestor directories.

Fixes #7895

FUTURE_COPYBARA_INTEGRATE_REVIEW=#14221 from ayushr2:rename 26ca2a3

renameat2(2) support was added in 2c1c4a5 ("Implement renameat2."), but only for the gofer filesystem; tmpfs and overlayfs still return EINVAL for RENAME_EXCHANGE.

Implement RENAME_EXCHANGE in tmpfs by swapping the two dentries between their parent directories. When the exchanged files differ in type, the parents' link counts (for "..") and the exchanged directory's reference on its parent are transferred.

Implement RENAME_EXCHANGE in overlayfs by copying up the destination file (and its descendants, if it is a directory) in addition to the source, and then exchanging both files on the upper layer. Unlike a regular rename, no whiteout is created at the source location, since both locations remain occupied. Exchanged directories are marked opaque at their new locations to prevent merging with lower layer directories there.

RENAME_EXCHANGE permits the two files to differ in type and does not require a directory being exchanged to be empty, but exchanging a file with an ancestor directory must fail with EINVAL; see Linux's fs/namei.c:__start_renaming(). The gofer filesystem previously required both files to have the same type; lift that restriction, and update parent link counts when files of different types are exchanged across directories.

The RENAME_EXCHANGE syscall tests no longer accept EINVAL (except on FUSE, which does not support the flag), and new tests cover mixed-type exchanges and exchanges with ancestor directories.

Fixes #7895

FUTURE_COPYBARA_INTEGRATE_REVIEW=#14221 from ayushr2:rename 26ca2a3
PiperOrigin-RevId: 970791991
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

exported Issue was exported automatically

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement renameat2(2) for real

1 participant