Merge branch 'vfs-scale-working' of git://git.kernel.org/pub/scm/linux/kernel/git/npiggin/linux-npiggin
* 'vfs-scale-working' of git://git.kernel.org/pub/scm/linux/kernel/git/npiggin/linux-npiggin: fs: fix do_last error case when need_reval_dot nfs: add missing rcu-walk check fs: hlist UP debug fixup fs: fix dropping of rcu-walk from force_reval_path fs: force_reval_path drop rcu-walk before d_invalidate fs: small rcu-walk documentation fixes Fixed up trivial conflicts in Documentation/filesystems/porting
This commit is contained in:
28
fs/namei.c
28
fs/namei.c
@@ -479,6 +479,14 @@ static int nameidata_dentry_drop_rcu(struct nameidata *nd, struct dentry *dentry
|
||||
struct fs_struct *fs = current->fs;
|
||||
struct dentry *parent = nd->path.dentry;
|
||||
|
||||
/*
|
||||
* It can be possible to revalidate the dentry that we started
|
||||
* the path walk with. force_reval_path may also revalidate the
|
||||
* dentry already committed to the nameidata.
|
||||
*/
|
||||
if (unlikely(parent == dentry))
|
||||
return nameidata_drop_rcu(nd);
|
||||
|
||||
BUG_ON(!(nd->flags & LOOKUP_RCU));
|
||||
if (nd->root.mnt) {
|
||||
spin_lock(&fs->lock);
|
||||
@@ -583,6 +591,13 @@ void release_open_intent(struct nameidata *nd)
|
||||
fput(nd->intent.open.file);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call d_revalidate and handle filesystems that request rcu-walk
|
||||
* to be dropped. This may be called and return in rcu-walk mode,
|
||||
* regardless of success or error. If -ECHILD is returned, the caller
|
||||
* must return -ECHILD back up the path walk stack so path walk may
|
||||
* be restarted in ref-walk mode.
|
||||
*/
|
||||
static int d_revalidate(struct dentry *dentry, struct nameidata *nd)
|
||||
{
|
||||
int status;
|
||||
@@ -673,6 +688,9 @@ force_reval_path(struct path *path, struct nameidata *nd)
|
||||
return 0;
|
||||
|
||||
if (!status) {
|
||||
/* Don't d_invalidate in rcu-walk mode */
|
||||
if (nameidata_drop_rcu(nd))
|
||||
return -ECHILD;
|
||||
d_invalidate(dentry);
|
||||
status = -ESTALE;
|
||||
}
|
||||
@@ -2105,11 +2123,13 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
|
||||
dir = nd->path.dentry;
|
||||
case LAST_DOT:
|
||||
if (need_reval_dot(dir)) {
|
||||
error = d_revalidate(nd->path.dentry, nd);
|
||||
if (!error)
|
||||
error = -ESTALE;
|
||||
if (error < 0)
|
||||
int status = d_revalidate(nd->path.dentry, nd);
|
||||
if (!status)
|
||||
status = -ESTALE;
|
||||
if (status < 0) {
|
||||
error = status;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
/* fallthrough */
|
||||
case LAST_ROOT:
|
||||
|
||||
Reference in New Issue
Block a user