Skip to content

Commit

Permalink
[PATCH] VFS: Ensure LOOKUP_CONTINUE flag is preserved by link_path_wa…
Browse files Browse the repository at this point in the history
…lk()

When walking a path, the LOOKUP_CONTINUE flag is used by some filesystems
(for instance NFS) in order to determine whether or not it is looking up
the last component of the path.  It this is the case, it may have to look
at the intent information in order to perform various tasks such as atomic
open.

A problem currently occurs when link_path_walk() hits a symlink.  In this
case LOOKUP_CONTINUE may be cleared prematurely when we hit the end of the
path passed by __vfs_follow_link() (i.e.  the end of the symlink path)
rather than when we hit the end of the path passed by the user.

The solution is to have link_path_walk() clear LOOKUP_CONTINUE if and only
if that flag was unset when we entered the function.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: Al Viro <viro@ftp.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Trond Myklebust authored and Linus Torvalds committed Feb 5, 2006
1 parent 4484ebf commit f55eab8
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)

inode = nd->dentry->d_inode;
if (nd->depth)
lookup_flags = LOOKUP_FOLLOW;
lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE);

/* At this point we know we have a real path component. */
for(;;) {
Expand Down Expand Up @@ -885,7 +885,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
last_with_slashes:
lookup_flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
last_component:
nd->flags &= ~LOOKUP_CONTINUE;
/* Clear LOOKUP_CONTINUE iff it was previously unset */
nd->flags &= lookup_flags | ~LOOKUP_CONTINUE;
if (lookup_flags & LOOKUP_PARENT)
goto lookup_parent;
if (this.name[0] == '.') switch (this.len) {
Expand Down

0 comments on commit f55eab8

Please sign in to comment.