Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 185929
b: refs/heads/master
c: 806b681
h: refs/heads/master
i:
  185927: 0c26612
v: v3
  • Loading branch information
Al Viro committed Mar 5, 2010
1 parent 4fd4cfe commit af26eae
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 46 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 10fa8e62f2bc33c452516585911f151d88389e4c
refs/heads/master: 806b681cbe588bebe8fe47dd24da62f2d1c55851
83 changes: 38 additions & 45 deletions trunk/fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -1844,17 +1844,38 @@ struct file *do_filp_open(int dfd, const char *pathname,
if (open_flag & O_EXCL)
nd.flags |= LOOKUP_EXCL;
filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
if (!filp)
goto do_link;
goto out;

exit_dput:
path_put_conditional(&path, &nd);
if (!IS_ERR(nd.intent.open.file))
release_open_intent(&nd);
exit_parent:
path_put(&nd.path);
filp = ERR_PTR(error);
while (unlikely(!filp)) { /* trailing symlink */
error = -ELOOP;
if ((open_flag & O_NOFOLLOW) || count++ == 32)
goto exit_dput;
/*
* This is subtle. Instead of calling do_follow_link() we do
* the thing by hands. The reason is that this way we have zero
* link_count and path_walk() (called from ->follow_link)
* honoring LOOKUP_PARENT. After that we have the parent and
* last component, i.e. we are in the same situation as after
* the first path_walk(). Well, almost - if the last component
* is normal we get its copy stored in nd->last.name and we will
* have to putname() it when we are done. Procfs-like symlinks
* just set LAST_BIND.
*/
nd.flags |= LOOKUP_PARENT;
error = security_inode_follow_link(path.dentry, &nd);
if (error)
goto exit_dput;
error = __do_follow_link(&path, &nd);
path_put(&path);
if (error) {
/* nd.path had been dropped */
release_open_intent(&nd);
filp = ERR_PTR(error);
goto out;
}
nd.flags &= ~LOOKUP_PARENT;
filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
if (nd.last_type == LAST_NORM)
__putname(nd.last.name);
}
out:
if (nd.root.mnt)
path_put(&nd.root);
Expand All @@ -1864,41 +1885,13 @@ struct file *do_filp_open(int dfd, const char *pathname,
}
return filp;

do_link:
error = -ELOOP;
if ((open_flag & O_NOFOLLOW) || count++ == 32)
goto exit_dput;
/*
* This is subtle. Instead of calling do_follow_link() we do the
* thing by hands. The reason is that this way we have zero link_count
* and path_walk() (called from ->follow_link) honoring LOOKUP_PARENT.
* After that we have the parent and last component, i.e.
* we are in the same situation as after the first path_walk().
* Well, almost - if the last component is normal we get its copy
* stored in nd->last.name and we will have to putname() it when we
* are done. Procfs-like symlinks just set LAST_BIND.
*/
nd.flags |= LOOKUP_PARENT;
error = security_inode_follow_link(path.dentry, &nd);
if (error)
goto exit_dput;
error = __do_follow_link(&path, &nd);
path_put(&path);
if (error) {
/* Does someone understand code flow here? Or it is only
* me so stupid? Anathema to whoever designed this non-sense
* with "intent.open".
*/
exit_dput:
path_put_conditional(&path, &nd);
if (!IS_ERR(nd.intent.open.file))
release_open_intent(&nd);
filp = ERR_PTR(error);
goto out;
}
nd.flags &= ~LOOKUP_PARENT;
filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
if (nd.last_type == LAST_NORM)
__putname(nd.last.name);
if (!filp)
goto do_link;
exit_parent:
path_put(&nd.path);
filp = ERR_PTR(error);
goto out;
}

Expand Down

0 comments on commit af26eae

Please sign in to comment.