diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-02-15 01:35:28 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-02-15 02:26:54 -0500 |
commit | f60aef7ec625236a6366722bb1be7b37596bf0ae (patch) | |
tree | 9ac12873b513fdb820eda3bf7c2894edac384901 /fs/namei.c | |
parent | f5e1c1c1afc1d979e2ac6a24cc99ba7143639f4d (diff) |
drop out of RCU in return_reval
... thus killing the need to handle drop-from-RCU in d_revalidate()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 25 |
1 files changed, 6 insertions, 19 deletions
diff --git a/fs/namei.c b/fs/namei.c index a98f7f141780..10635d329175 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -571,25 +571,9 @@ void release_open_intent(struct nameidata *nd) | |||
571 | } | 571 | } |
572 | } | 572 | } |
573 | 573 | ||
574 | /* | 574 | static inline int d_revalidate(struct dentry *dentry, struct nameidata *nd) |
575 | * Call d_revalidate and handle filesystems that request rcu-walk | ||
576 | * to be dropped. This may be called and return in rcu-walk mode, | ||
577 | * regardless of success or error. If -ECHILD is returned, the caller | ||
578 | * must return -ECHILD back up the path walk stack so path walk may | ||
579 | * be restarted in ref-walk mode. | ||
580 | */ | ||
581 | static int d_revalidate(struct dentry *dentry, struct nameidata *nd) | ||
582 | { | 575 | { |
583 | int status; | 576 | return dentry->d_op->d_revalidate(dentry, nd); |
584 | |||
585 | status = dentry->d_op->d_revalidate(dentry, nd); | ||
586 | if (status == -ECHILD) { | ||
587 | if (nameidata_dentry_drop_rcu(nd, dentry)) | ||
588 | return status; | ||
589 | status = dentry->d_op->d_revalidate(dentry, nd); | ||
590 | } | ||
591 | |||
592 | return status; | ||
593 | } | 577 | } |
594 | 578 | ||
595 | static struct dentry * | 579 | static struct dentry * |
@@ -617,7 +601,7 @@ do_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
617 | static inline struct dentry * | 601 | static inline struct dentry * |
618 | do_revalidate_rcu(struct dentry *dentry, struct nameidata *nd) | 602 | do_revalidate_rcu(struct dentry *dentry, struct nameidata *nd) |
619 | { | 603 | { |
620 | int status = dentry->d_op->d_revalidate(dentry, nd); | 604 | int status = d_revalidate(dentry, nd); |
621 | if (likely(status > 0)) | 605 | if (likely(status > 0)) |
622 | return dentry; | 606 | return dentry; |
623 | if (status == -ECHILD) { | 607 | if (status == -ECHILD) { |
@@ -1517,12 +1501,15 @@ return_reval: | |||
1517 | * We may need to check the cached dentry for staleness. | 1501 | * We may need to check the cached dentry for staleness. |
1518 | */ | 1502 | */ |
1519 | if (need_reval_dot(nd->path.dentry)) { | 1503 | if (need_reval_dot(nd->path.dentry)) { |
1504 | if (nameidata_drop_rcu_last_maybe(nd)) | ||
1505 | return -ECHILD; | ||
1520 | /* Note: we do not d_invalidate() */ | 1506 | /* Note: we do not d_invalidate() */ |
1521 | err = d_revalidate(nd->path.dentry, nd); | 1507 | err = d_revalidate(nd->path.dentry, nd); |
1522 | if (!err) | 1508 | if (!err) |
1523 | err = -ESTALE; | 1509 | err = -ESTALE; |
1524 | if (err < 0) | 1510 | if (err < 0) |
1525 | break; | 1511 | break; |
1512 | return 0; | ||
1526 | } | 1513 | } |
1527 | return_base: | 1514 | return_base: |
1528 | if (nameidata_drop_rcu_last_maybe(nd)) | 1515 | if (nameidata_drop_rcu_last_maybe(nd)) |