aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2009-12-07 12:01:50 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2009-12-16 12:16:48 -0500
commit39159de2a091a35ea86b188ebdc5e642f5cfc832 (patch)
tree793c0c95fe22ddb06c4cc4271428ad41386ccf6b /fs
parentd1625436b4fe526fa463bc0519ba37d7e4b37bbc (diff)
vfs: force reval of target when following LAST_BIND symlinks (try #7)
procfs-style symlinks return a last_type of LAST_BIND without an actual path string. This causes __follow_link to skip calling __vfs_follow_link and so the dentry isn't revalidated. This is a problem when the link target sits on NFSv4 as it depends on the VFS to revalidate the dentry before using it on an open call. Ensure that this occurs by forcing a revalidation of the target dentry of LAST_BIND symlinks. Signed-off-by: Jeff Layton <jlayton@redhat.com> Acked-by: "Eric W. Biederman" <ebiederm@xmission.com> Acked-by: Miklos Szeredi <mszeredi@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/namei.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/fs/namei.c b/fs/namei.c
index a765e7a741f..d2783c8a770 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -414,6 +414,46 @@ do_revalidate(struct dentry *dentry, struct nameidata *nd)
414} 414}
415 415
416/* 416/*
417 * force_reval_path - force revalidation of a dentry
418 *
419 * In some situations the path walking code will trust dentries without
420 * revalidating them. This causes problems for filesystems that depend on
421 * d_revalidate to handle file opens (e.g. NFSv4). When FS_REVAL_DOT is set
422 * (which indicates that it's possible for the dentry to go stale), force
423 * a d_revalidate call before proceeding.
424 *
425 * Returns 0 if the revalidation was successful. If the revalidation fails,
426 * either return the error returned by d_revalidate or -ESTALE if the
427 * revalidation it just returned 0. If d_revalidate returns 0, we attempt to
428 * invalidate the dentry. It's up to the caller to handle putting references
429 * to the path if necessary.
430 */
431static int
432force_reval_path(struct path *path, struct nameidata *nd)
433{
434 int status;
435 struct dentry *dentry = path->dentry;
436
437 /*
438 * only check on filesystems where it's possible for the dentry to
439 * become stale. It's assumed that if this flag is set then the
440 * d_revalidate op will also be defined.
441 */
442 if (!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT))
443 return 0;
444
445 status = dentry->d_op->d_revalidate(dentry, nd);
446 if (status > 0)
447 return 0;
448
449 if (!status) {
450 d_invalidate(dentry);
451 status = -ESTALE;
452 }
453 return status;
454}
455
456/*
417 * Short-cut version of permission(), for calling on directories 457 * Short-cut version of permission(), for calling on directories
418 * during pathname resolution. Combines parts of permission() 458 * during pathname resolution. Combines parts of permission()
419 * and generic_permission(), and tests ONLY for MAY_EXEC permission. 459 * and generic_permission(), and tests ONLY for MAY_EXEC permission.
@@ -529,6 +569,11 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata
529 error = 0; 569 error = 0;
530 if (s) 570 if (s)
531 error = __vfs_follow_link(nd, s); 571 error = __vfs_follow_link(nd, s);
572 else if (nd->last_type == LAST_BIND) {
573 error = force_reval_path(&nd->path, nd);
574 if (error)
575 path_put(&nd->path);
576 }
532 if (dentry->d_inode->i_op->put_link) 577 if (dentry->d_inode->i_op->put_link)
533 dentry->d_inode->i_op->put_link(dentry, nd, cookie); 578 dentry->d_inode->i_op->put_link(dentry, nd, cookie);
534 } 579 }