Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 177412
b: refs/heads/master
c: 39159de
h: refs/heads/master
v: v3
  • Loading branch information
Jeff Layton authored and Al Viro committed Dec 16, 2009
1 parent 2903ec8 commit e544a61
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d1625436b4fe526fa463bc0519ba37d7e4b37bbc
refs/heads/master: 39159de2a091a35ea86b188ebdc5e642f5cfc832
45 changes: 45 additions & 0 deletions trunk/fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,46 @@ do_revalidate(struct dentry *dentry, struct nameidata *nd)
return dentry;
}

/*
* force_reval_path - force revalidation of a dentry
*
* In some situations the path walking code will trust dentries without
* revalidating them. This causes problems for filesystems that depend on
* d_revalidate to handle file opens (e.g. NFSv4). When FS_REVAL_DOT is set
* (which indicates that it's possible for the dentry to go stale), force
* a d_revalidate call before proceeding.
*
* Returns 0 if the revalidation was successful. If the revalidation fails,
* either return the error returned by d_revalidate or -ESTALE if the
* revalidation it just returned 0. If d_revalidate returns 0, we attempt to
* invalidate the dentry. It's up to the caller to handle putting references
* to the path if necessary.
*/
static int
force_reval_path(struct path *path, struct nameidata *nd)
{
int status;
struct dentry *dentry = path->dentry;

/*
* only check on filesystems where it's possible for the dentry to
* become stale. It's assumed that if this flag is set then the
* d_revalidate op will also be defined.
*/
if (!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT))
return 0;

status = dentry->d_op->d_revalidate(dentry, nd);
if (status > 0)
return 0;

if (!status) {
d_invalidate(dentry);
status = -ESTALE;
}
return status;
}

/*
* Short-cut version of permission(), for calling on directories
* during pathname resolution. Combines parts of permission()
Expand Down Expand Up @@ -529,6 +569,11 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata
error = 0;
if (s)
error = __vfs_follow_link(nd, s);
else if (nd->last_type == LAST_BIND) {
error = force_reval_path(&nd->path, nd);
if (error)
path_put(&nd->path);
}
if (dentry->d_inode->i_op->put_link)
dentry->d_inode->i_op->put_link(dentry, nd, cookie);
}
Expand Down

0 comments on commit e544a61

Please sign in to comment.