@@ -2980,20 +2980,10 @@ static inline int may_create(struct mnt_idmap *idmap,
29802980 return inode_permission (idmap , dir , MAY_WRITE | MAY_EXEC );
29812981}
29822982
2983- /*
2984- * p1 and p2 should be directories on the same fs.
2985- */
2986- struct dentry * lock_rename (struct dentry * p1 , struct dentry * p2 )
2983+ static struct dentry * lock_two_directories (struct dentry * p1 , struct dentry * p2 )
29872984{
29882985 struct dentry * p ;
29892986
2990- if (p1 == p2 ) {
2991- inode_lock_nested (p1 -> d_inode , I_MUTEX_PARENT );
2992- return NULL ;
2993- }
2994-
2995- mutex_lock (& p1 -> d_sb -> s_vfs_rename_mutex );
2996-
29972987 p = d_ancestor (p2 , p1 );
29982988 if (p ) {
29992989 inode_lock_nested (p2 -> d_inode , I_MUTEX_PARENT );
@@ -3012,8 +3002,64 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
30123002 inode_lock_nested (p2 -> d_inode , I_MUTEX_PARENT2 );
30133003 return NULL ;
30143004}
3005+
3006+ /*
3007+ * p1 and p2 should be directories on the same fs.
3008+ */
3009+ struct dentry * lock_rename (struct dentry * p1 , struct dentry * p2 )
3010+ {
3011+ if (p1 == p2 ) {
3012+ inode_lock_nested (p1 -> d_inode , I_MUTEX_PARENT );
3013+ return NULL ;
3014+ }
3015+
3016+ mutex_lock (& p1 -> d_sb -> s_vfs_rename_mutex );
3017+ return lock_two_directories (p1 , p2 );
3018+ }
30153019EXPORT_SYMBOL (lock_rename );
30163020
3021+ /*
3022+ * c1 and p2 should be on the same fs.
3023+ */
3024+ struct dentry * lock_rename_child (struct dentry * c1 , struct dentry * p2 )
3025+ {
3026+ if (READ_ONCE (c1 -> d_parent ) == p2 ) {
3027+ /*
3028+ * hopefully won't need to touch ->s_vfs_rename_mutex at all.
3029+ */
3030+ inode_lock_nested (p2 -> d_inode , I_MUTEX_PARENT );
3031+ /*
3032+ * now that p2 is locked, nobody can move in or out of it,
3033+ * so the test below is safe.
3034+ */
3035+ if (likely (c1 -> d_parent == p2 ))
3036+ return NULL ;
3037+
3038+ /*
3039+ * c1 got moved out of p2 while we'd been taking locks;
3040+ * unlock and fall back to slow case.
3041+ */
3042+ inode_unlock (p2 -> d_inode );
3043+ }
3044+
3045+ mutex_lock (& c1 -> d_sb -> s_vfs_rename_mutex );
3046+ /*
3047+ * nobody can move out of any directories on this fs.
3048+ */
3049+ if (likely (c1 -> d_parent != p2 ))
3050+ return lock_two_directories (c1 -> d_parent , p2 );
3051+
3052+ /*
3053+ * c1 got moved into p2 while we were taking locks;
3054+ * we need p2 locked and ->s_vfs_rename_mutex unlocked,
3055+ * for consistency with lock_rename().
3056+ */
3057+ inode_lock_nested (p2 -> d_inode , I_MUTEX_PARENT );
3058+ mutex_unlock (& c1 -> d_sb -> s_vfs_rename_mutex );
3059+ return NULL ;
3060+ }
3061+ EXPORT_SYMBOL (lock_rename_child );
3062+
30173063void unlock_rename (struct dentry * p1 , struct dentry * p2 )
30183064{
30193065 inode_unlock (p1 -> d_inode );
0 commit comments