On Wed, Oct 11, 2023 at 10:11:42PM +0800, Mo Zou wrote: > > Consider directories objects A, B, C. The pointer orders are that A < B > and C < A. And B is ancestor to C, so B < C. Thus we have A < B < C > < A! > > A concrete deadlock example can be constructed as follows. Suppose > the tree has following edges /A and /B/C and A < B and C < A. There are > three operations forming a deadlock. > > rename(/A, /B) executes: lock /; lock A; (about to lock B) > unlink(/B/C) executes: lock B; (about to lock C) > rename(/A/x, /C/y) executes: lock C; (about to lock A) Nope - your C in line 2 is not C in line 3. There *IS* a deadlock, but it's more subtle than that. Look: # address(/X/A) < address(C) < address(X) T_1: rename /C/D /X/A/B T_2: exchange /X /C T_3: rmdir /X/A T_1: looked up /X/A and /C (all in dcache) T_2: looked up / T_3: looked up /X T_1: grabbed ->s_vfs_rename_mutex T_1: grabbed /X/A T_2: grabbed / T_2: grabbed /C T_3: grabbed /X T_2: tries to grab /X T_3: tries to grab /X/A T_1: tries to grab /C