diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-04 14:44:37 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-14 09:15:26 -0400 |
commit | 951361f954596bd134d4270df834f47d151f98a6 (patch) | |
tree | 719622960d2ec96473636333ddc8b85ab8151505 /fs/namei.c | |
parent | a7472baba22dd5d68580f528374f93421b33667e (diff) |
get rid of the last LOOKUP_RCU dependencies in link_path_walk()
New helper: terminate_walk(). An error has happened during pathname
resolution and we either drop nd->path or terminate RCU, depending
the mode we had been in. After that, nd is essentially empty.
Switch link_path_walk() to using that for cleanup.
Now the top-level logics in link_path_walk() is back to sanity. RCU
dependencies are in the lower-level functions.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/fs/namei.c b/fs/namei.c index 53bba7c1a520..85f6e39b4034 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1343,6 +1343,18 @@ static inline int handle_dots(struct nameidata *nd, int type) | |||
1343 | return 0; | 1343 | return 0; |
1344 | } | 1344 | } |
1345 | 1345 | ||
1346 | static void terminate_walk(struct nameidata *nd) | ||
1347 | { | ||
1348 | if (!(nd->flags & LOOKUP_RCU)) { | ||
1349 | path_put(&nd->path); | ||
1350 | } else { | ||
1351 | nd->flags &= ~LOOKUP_RCU; | ||
1352 | nd->root.mnt = NULL; | ||
1353 | rcu_read_unlock(); | ||
1354 | br_read_unlock(vfsmount_lock); | ||
1355 | } | ||
1356 | } | ||
1357 | |||
1346 | /* | 1358 | /* |
1347 | * Name resolution. | 1359 | * Name resolution. |
1348 | * This is the basic name resolution function, turning a pathname into | 1360 | * This is the basic name resolution function, turning a pathname into |
@@ -1482,14 +1494,7 @@ lookup_parent: | |||
1482 | nd->last_type = type; | 1494 | nd->last_type = type; |
1483 | return 0; | 1495 | return 0; |
1484 | } | 1496 | } |
1485 | if (!(nd->flags & LOOKUP_RCU)) | 1497 | terminate_walk(nd); |
1486 | path_put(&nd->path); | ||
1487 | if (nd->flags & LOOKUP_RCU) { | ||
1488 | nd->flags &= ~LOOKUP_RCU; | ||
1489 | nd->root.mnt = NULL; | ||
1490 | rcu_read_unlock(); | ||
1491 | br_read_unlock(vfsmount_lock); | ||
1492 | } | ||
1493 | return err; | 1498 | return err; |
1494 | } | 1499 | } |
1495 | 1500 | ||