diff options
author | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:49:57 -0500 |
---|---|---|
committer | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:50:29 -0500 |
commit | 34286d6662308d82aed891852d04c7c3a2649b16 (patch) | |
tree | c4b7311404d302e7cb94df7a4690298e1059910a /Documentation/filesystems | |
parent | 44a7d7a878c9cbb74f236ea755b25b6b2e26a9a9 (diff) |
fs: rcu-walk aware d_revalidate method
Require filesystems be aware of .d_revalidate being called in rcu-walk
mode (nd->flags & LOOKUP_RCU). For now do a simple push down, returning
-ECHILD from all implementations.
Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Diffstat (limited to 'Documentation/filesystems')
-rw-r--r-- | Documentation/filesystems/Locking | 18 | ||||
-rw-r--r-- | Documentation/filesystems/path-lookup.txt | 5 | ||||
-rw-r--r-- | Documentation/filesystems/porting | 20 | ||||
-rw-r--r-- | Documentation/filesystems/vfs.txt | 9 |
4 files changed, 40 insertions, 12 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index bdad6414dfa0..e90ffe61eb65 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -9,7 +9,7 @@ be able to use diff(1). | |||
9 | 9 | ||
10 | --------------------------- dentry_operations -------------------------- | 10 | --------------------------- dentry_operations -------------------------- |
11 | prototypes: | 11 | prototypes: |
12 | int (*d_revalidate)(struct dentry *, int); | 12 | int (*d_revalidate)(struct dentry *, struct nameidata *); |
13 | int (*d_hash)(const struct dentry *, const struct inode *, | 13 | int (*d_hash)(const struct dentry *, const struct inode *, |
14 | struct qstr *); | 14 | struct qstr *); |
15 | int (*d_compare)(const struct dentry *, const struct inode *, | 15 | int (*d_compare)(const struct dentry *, const struct inode *, |
@@ -21,14 +21,14 @@ prototypes: | |||
21 | char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); | 21 | char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); |
22 | 22 | ||
23 | locking rules: | 23 | locking rules: |
24 | rename_lock ->d_lock may block | 24 | rename_lock ->d_lock may block rcu-walk |
25 | d_revalidate: no no yes | 25 | d_revalidate: no no yes (ref-walk) maybe |
26 | d_hash no no no | 26 | d_hash no no no maybe |
27 | d_compare: yes no no | 27 | d_compare: yes no no maybe |
28 | d_delete: no yes no | 28 | d_delete: no yes no no |
29 | d_release: no no yes | 29 | d_release: no no yes no |
30 | d_iput: no no yes | 30 | d_iput: no no yes no |
31 | d_dname: no no no | 31 | d_dname: no no no no |
32 | 32 | ||
33 | --------------------------- inode_operations --------------------------- | 33 | --------------------------- inode_operations --------------------------- |
34 | prototypes: | 34 | prototypes: |
diff --git a/Documentation/filesystems/path-lookup.txt b/Documentation/filesystems/path-lookup.txt index 09b2878724a1..8789d1810bed 100644 --- a/Documentation/filesystems/path-lookup.txt +++ b/Documentation/filesystems/path-lookup.txt | |||
@@ -317,11 +317,10 @@ The detailed design for rcu-walk is like this: | |||
317 | The cases where rcu-walk cannot continue are: | 317 | The cases where rcu-walk cannot continue are: |
318 | * NULL dentry (ie. any uncached path element) | 318 | * NULL dentry (ie. any uncached path element) |
319 | * parent with d_inode->i_op->permission or ACLs | 319 | * parent with d_inode->i_op->permission or ACLs |
320 | * dentries with d_revalidate | ||
321 | * Following links | 320 | * Following links |
322 | 321 | ||
323 | In future patches, permission checks and d_revalidate become rcu-walk aware. It | 322 | In future patches, permission checks become rcu-walk aware. It may be possible |
324 | may be possible eventually to make following links rcu-walk aware. | 323 | eventually to make following links rcu-walk aware. |
325 | 324 | ||
326 | Uncached path elements will always require dropping to ref-walk mode, at the | 325 | Uncached path elements will always require dropping to ref-walk mode, at the |
327 | very least because i_mutex needs to be grabbed, and objects allocated. | 326 | very least because i_mutex needs to be grabbed, and objects allocated. |
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index ccf0ce7866b9..cd9756a2709d 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting | |||
@@ -360,3 +360,23 @@ i_dentry to be reinitialized before it is freed, so an: | |||
360 | INIT_LIST_HEAD(&inode->i_dentry); | 360 | INIT_LIST_HEAD(&inode->i_dentry); |
361 | 361 | ||
362 | must be done in the RCU callback. | 362 | must be done in the RCU callback. |
363 | |||
364 | -- | ||
365 | [recommended] | ||
366 | vfs now tries to do path walking in "rcu-walk mode", which avoids | ||
367 | atomic operations and scalability hazards on dentries and inodes (see | ||
368 | Documentation/filesystems/path-walk.txt). d_hash and d_compare changes (above) | ||
369 | are examples of the changes required to support this. For more complex | ||
370 | filesystem callbacks, the vfs drops out of rcu-walk mode before the fs call, so | ||
371 | no changes are required to the filesystem. However, this is costly and loses | ||
372 | the benefits of rcu-walk mode. We will begin to add filesystem callbacks that | ||
373 | are rcu-walk aware, shown below. Filesystems should take advantage of this | ||
374 | where possible. | ||
375 | |||
376 | -- | ||
377 | [mandatory] | ||
378 | d_revalidate is a callback that is made on every path element (if | ||
379 | the filesystem provides it), which requires dropping out of rcu-walk mode. This | ||
380 | may now be called in rcu-walk mode (nd->flags & LOOKUP_RCU). -ECHILD should be | ||
381 | returned if the filesystem cannot handle rcu-walk. See | ||
382 | Documentation/filesystems/vfs.txt for more details. | ||
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 69b10ff5ec81..c936b4912383 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -863,6 +863,15 @@ struct dentry_operations { | |||
863 | dcache. Most filesystems leave this as NULL, because all their | 863 | dcache. Most filesystems leave this as NULL, because all their |
864 | dentries in the dcache are valid | 864 | dentries in the dcache are valid |
865 | 865 | ||
866 | d_revalidate may be called in rcu-walk mode (nd->flags & LOOKUP_RCU). | ||
867 | If in rcu-walk mode, the filesystem must revalidate the dentry without | ||
868 | blocking or storing to the dentry, d_parent and d_inode should not be | ||
869 | used without care (because they can go NULL), instead nd->inode should | ||
870 | be used. | ||
871 | |||
872 | If a situation is encountered that rcu-walk cannot handle, return | ||
873 | -ECHILD and it will be called again in ref-walk mode. | ||
874 | |||
866 | d_hash: called when the VFS adds a dentry to the hash table. The first | 875 | d_hash: called when the VFS adds a dentry to the hash table. The first |
867 | dentry passed to d_hash is the parent directory that the name is | 876 | dentry passed to d_hash is the parent directory that the name is |
868 | to be hashed into. The inode is the dentry's inode. | 877 | to be hashed into. The inode is the dentry's inode. |