Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
d42b3868
Commit
d42b3868
authored
May 26, 2016
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update D/f/directory-locking
Signed-off-by:
Al Viro
<
viro@zeniv.linux.org.uk
>
parent
0985b65d
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
20 additions
and
12 deletions
+20
-12
Documentation/filesystems/directory-locking
Documentation/filesystems/directory-locking
+20
-12
No files found.
Documentation/filesystems/directory-locking
View file @
d42b3868
Locking scheme used for directory operations is based on two
Locking scheme used for directory operations is based on two
kinds of locks - per-inode (->i_
mutex
) and per-filesystem
kinds of locks - per-inode (->i_
rwsem
) and per-filesystem
(->s_vfs_rename_mutex).
(->s_vfs_rename_mutex).
When taking the i_
mutex
on multiple non-directory objects, we
When taking the i_
rwsem
on multiple non-directory objects, we
always acquire the locks in order by increasing address. We'll call
always acquire the locks in order by increasing address. We'll call
that "inode pointer" order in the following.
that "inode pointer" order in the following.
For our purposes all operations fall in 5 classes:
For our purposes all operations fall in 5 classes:
1) read access. Locking rules: caller locks directory we are accessing.
1) read access. Locking rules: caller locks directory we are accessing.
The lock is taken shared.
2) object creation. Locking rules: same as above.
2) object creation. Locking rules: same as above, but the lock is taken
exclusive.
3) object removal. Locking rules: caller locks parent, finds victim,
3) object removal. Locking rules: caller locks parent, finds victim,
locks victim and calls the method.
locks victim and calls the method.
Locks are exclusive.
4) rename() that is _not_ cross-directory. Locking rules: caller locks
4) rename() that is _not_ cross-directory. Locking rules: caller locks
the parent and finds source and target. If target already exists, lock
the parent and finds source and target. In case of exchange (with
it. If source is a non-directory, lock it. If that means we need to
RENAME_EXCHANGE in rename2() flags argument) lock both. In any case,
lock both, lock them in inode pointer order.
if the target already exists, lock it. If the source is a non-directory,
lock it. If we need to lock both, lock them in inode pointer order.
Then call the method. All locks are exclusive.
NB: we might get away with locking the the source (and target in exchange
case) shared.
5) link creation. Locking rules:
5) link creation. Locking rules:
* lock parent
* lock parent
* check that source is not a directory
* check that source is not a directory
* lock source
* lock source
* call the method.
* call the method.
All locks are exclusive.
6) cross-directory rename. The trickiest in the whole bunch. Locking
6) cross-directory rename. The trickiest in the whole bunch. Locking
rules:
rules:
...
@@ -35,11 +42,12 @@ rules:
...
@@ -35,11 +42,12 @@ rules:
fail with -ENOTEMPTY
fail with -ENOTEMPTY
* if new parent is equal to or is a descendent of source
* if new parent is equal to or is a descendent of source
fail with -ELOOP
fail with -ELOOP
* If
target exists, lock it. If source is a non-directory, lock
* If
it's an exchange, lock both the source and the target.
it. In case that means we need to lock both source and target
,
* If the target exists, lock it. If the source is a non-directory
,
do so in inode pointer order.
lock it. If we need to lock both,
do so in inode pointer order.
* call the method.
* call the method.
All ->i_rwsem are taken exclusive. Again, we might get away with locking
the the source (and target in exchange case) shared.
The rules above obviously guarantee that all directories that are going to be
The rules above obviously guarantee that all directories that are going to be
read, modified or removed by method will be locked by caller.
read, modified or removed by method will be locked by caller.
...
@@ -73,7 +81,7 @@ objects - A < B iff A is an ancestor of B.
...
@@ -73,7 +81,7 @@ objects - A < B iff A is an ancestor of B.
attempt to acquire some lock and already holds at least one lock. Let's
attempt to acquire some lock and already holds at least one lock. Let's
consider the set of contended locks. First of all, filesystem lock is
consider the set of contended locks. First of all, filesystem lock is
not contended, since any process blocked on it is not holding any locks.
not contended, since any process blocked on it is not holding any locks.
Thus all processes are blocked on ->i_
mutex
.
Thus all processes are blocked on ->i_
rwsem
.
By (3), any process holding a non-directory lock can only be
By (3), any process holding a non-directory lock can only be
waiting on another non-directory lock with a larger address. Therefore
waiting on another non-directory lock with a larger address. Therefore
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment