diff options
| -rw-r--r-- | fs/namei.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/fs/namei.c b/fs/namei.c index 19433cdba011..0f02359ce685 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -583,6 +583,13 @@ void release_open_intent(struct nameidata *nd) | |||
| 583 | fput(nd->intent.open.file); | 583 | fput(nd->intent.open.file); |
| 584 | } | 584 | } |
| 585 | 585 | ||
| 586 | /* | ||
| 587 | * Call d_revalidate and handle filesystems that request rcu-walk | ||
| 588 | * to be dropped. This may be called and return in rcu-walk mode, | ||
| 589 | * regardless of success or error. If -ECHILD is returned, the caller | ||
| 590 | * must return -ECHILD back up the path walk stack so path walk may | ||
| 591 | * be restarted in ref-walk mode. | ||
| 592 | */ | ||
| 586 | static int d_revalidate(struct dentry *dentry, struct nameidata *nd) | 593 | static int d_revalidate(struct dentry *dentry, struct nameidata *nd) |
| 587 | { | 594 | { |
| 588 | int status; | 595 | int status; |
| @@ -673,6 +680,9 @@ force_reval_path(struct path *path, struct nameidata *nd) | |||
| 673 | return 0; | 680 | return 0; |
| 674 | 681 | ||
| 675 | if (!status) { | 682 | if (!status) { |
| 683 | /* Don't d_invalidate in rcu-walk mode */ | ||
| 684 | if (nameidata_drop_rcu(nd)) | ||
| 685 | return -ECHILD; | ||
| 676 | d_invalidate(dentry); | 686 | d_invalidate(dentry); |
| 677 | status = -ESTALE; | 687 | status = -ESTALE; |
| 678 | } | 688 | } |
