summaryrefslogtreecommitdiff
path: root/Documentation/filesystems/porting.rst
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2023-11-20 20:02:11 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2023-11-25 02:54:14 -0500
commita8b0026847b8c43445c921ad2c85521c92eb175f (patch)
tree39078ede8594fab57ee0486e522655df86cb131f /Documentation/filesystems/porting.rst
parentdbd4540df2b2857a91593754275c02f3e415fc30 (diff)
rename(): avoid a deadlock in the case of parents having no common ancestor
... and fix the directory locking documentation and proof of correctness. Holding ->s_vfs_rename_mutex *almost* prevents ->d_parent changes; the case where we really don't want it is splicing the root of disconnected tree to somewhere. In other words, ->s_vfs_rename_mutex is sufficient to stabilize "X is an ancestor of Y" only if X and Y are already in the same tree. Otherwise it can go from false to true, and one can construct a deadlock on that. Make lock_two_directories() report an error in such case and update the callers of lock_rename()/lock_rename_child() to handle such errors. And yes, such conditions are not impossible to create ;-/ Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'Documentation/filesystems/porting.rst')
-rw-r--r--Documentation/filesystems/porting.rst9
1 files changed, 9 insertions, 0 deletions
diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst
index 9100969e7de6..33cd56e2ca1a 100644
--- a/Documentation/filesystems/porting.rst
+++ b/Documentation/filesystems/porting.rst
@@ -1079,3 +1079,12 @@ On same-directory ->rename() the (tautological) update of .. is not protected
by any locks; just don't do it if the old parent is the same as the new one.
We really can't lock two subdirectories in same-directory rename - not without
deadlocks.
+
+---
+
+**mandatory**
+
+lock_rename() and lock_rename_child() may fail in cross-directory case, if
+their arguments do not have a common ancestor. In that case ERR_PTR(-EXDEV)
+is returned, with no locks taken. In-tree users updated; out-of-tree ones
+would need to do so.