.. | .. |
---|
22 | 22 | 3) object removal. Locking rules: caller locks parent, finds victim, |
---|
23 | 23 | locks victim and calls the method. Locks are exclusive. |
---|
24 | 24 | |
---|
25 | | -4) rename() that is _not_ cross-directory. Locking rules: caller locks |
---|
26 | | -the parent and finds source and target. In case of exchange (with |
---|
27 | | -RENAME_EXCHANGE in flags argument) lock both. In any case, |
---|
28 | | -if the target already exists, lock it. If the source is a non-directory, |
---|
29 | | -lock it. If we need to lock both, lock them in inode pointer order. |
---|
30 | | -Then call the method. All locks are exclusive. |
---|
| 25 | +4) rename() that is _not_ cross-directory. Locking rules: caller locks the |
---|
| 26 | +parent and finds source and target. We lock both (provided they exist). If we |
---|
| 27 | +need to lock two inodes of different type (dir vs non-dir), we lock directory |
---|
| 28 | +first. If we need to lock two inodes of the same type, lock them in inode |
---|
| 29 | +pointer order. Then call the method. All locks are exclusive. |
---|
31 | 30 | NB: we might get away with locking the source (and target in exchange |
---|
32 | 31 | case) shared. |
---|
33 | 32 | |
---|
.. | .. |
---|
44 | 43 | rules: |
---|
45 | 44 | |
---|
46 | 45 | * lock the filesystem |
---|
47 | | - * lock parents in "ancestors first" order. |
---|
| 46 | + * lock parents in "ancestors first" order. If one is not ancestor of |
---|
| 47 | + the other, lock them in inode pointer order. |
---|
48 | 48 | * find source and target. |
---|
49 | 49 | * if old parent is equal to or is a descendent of target |
---|
50 | 50 | fail with -ENOTEMPTY |
---|
51 | 51 | * if new parent is equal to or is a descendent of source |
---|
52 | 52 | fail with -ELOOP |
---|
53 | | - * If it's an exchange, lock both the source and the target. |
---|
54 | | - * If the target exists, lock it. If the source is a non-directory, |
---|
55 | | - lock it. If we need to lock both, do so in inode pointer order. |
---|
| 53 | + * Lock both the source and the target provided they exist. If we |
---|
| 54 | + need to lock two inodes of different type (dir vs non-dir), we lock |
---|
| 55 | + the directory first. If we need to lock two inodes of the same type, |
---|
| 56 | + lock them in inode pointer order. |
---|
56 | 57 | * call the method. |
---|
57 | 58 | |
---|
58 | 59 | All ->i_rwsem are taken exclusive. Again, we might get away with locking |
---|
.. | .. |
---|
66 | 67 | |
---|
67 | 68 | Proof: |
---|
68 | 69 | |
---|
69 | | - First of all, at any moment we have a partial ordering of the |
---|
70 | | - objects - A < B iff A is an ancestor of B. |
---|
| 70 | + First of all, at any moment we have a linear ordering of the |
---|
| 71 | + objects - A < B iff (A is an ancestor of B) or (B is not an ancestor |
---|
| 72 | + of A and ptr(A) < ptr(B)). |
---|
71 | 73 | |
---|
72 | 74 | That ordering can change. However, the following is true: |
---|
73 | 75 | |
---|