aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2009-08-08 17:41:57 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2009-12-16 12:16:43 -0500
commit6de88d72927dc85297b3075024487313c4ba3a2e (patch)
tree278609d97c5635bb3922634b274689739fbf09d6 /fs/namei.c
parent258fa99905f704afed1a43f195bc5235a56fb895 (diff)
kill __link_path_walk()/link_path_walk() distinction
put retry logics into path_walk() and do_filp_open() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c68
1 files changed, 34 insertions, 34 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 30c61c298b4c..89e380583ab8 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -108,8 +108,6 @@
108 * any extra contention... 108 * any extra contention...
109 */ 109 */
110 110
111static int __link_path_walk(const char *name, struct nameidata *nd);
112
113/* In order to reduce some races, while at the same time doing additional 111/* In order to reduce some races, while at the same time doing additional
114 * checking and hopefully speeding things up, we copy filenames to the 112 * checking and hopefully speeding things up, we copy filenames to the
115 * kernel data space before using them.. 113 * kernel data space before using them..
@@ -529,35 +527,6 @@ out_unlock:
529 return result; 527 return result;
530} 528}
531 529
532/*
533 * Wrapper to retry pathname resolution whenever the underlying
534 * file system returns an ESTALE.
535 *
536 * Retry the whole path once, forcing real lookup requests
537 * instead of relying on the dcache.
538 */
539static __always_inline int link_path_walk(const char *name, struct nameidata *nd)
540{
541 struct path save = nd->path;
542 int result;
543
544 /* make sure the stuff we saved doesn't go away */
545 path_get(&save);
546
547 result = __link_path_walk(name, nd);
548 if (result == -ESTALE) {
549 /* nd->path had been dropped */
550 nd->path = save;
551 path_get(&nd->path);
552 nd->flags |= LOOKUP_REVAL;
553 result = __link_path_walk(name, nd);
554 }
555
556 path_put(&save);
557
558 return result;
559}
560
561static __always_inline void set_root(struct nameidata *nd) 530static __always_inline void set_root(struct nameidata *nd)
562{ 531{
563 if (!nd->root.mnt) { 532 if (!nd->root.mnt) {
@@ -569,6 +538,8 @@ static __always_inline void set_root(struct nameidata *nd)
569 } 538 }
570} 539}
571 540
541static int link_path_walk(const char *, struct nameidata *);
542
572static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link) 543static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
573{ 544{
574 int res = 0; 545 int res = 0;
@@ -834,7 +805,7 @@ fail:
834 * Returns 0 and nd will have valid dentry and mnt on success. 805 * Returns 0 and nd will have valid dentry and mnt on success.
835 * Returns error and drops reference to input namei data on failure. 806 * Returns error and drops reference to input namei data on failure.
836 */ 807 */
837static int __link_path_walk(const char *name, struct nameidata *nd) 808static int link_path_walk(const char *name, struct nameidata *nd)
838{ 809{
839 struct path next; 810 struct path next;
840 struct inode *inode; 811 struct inode *inode;
@@ -1016,8 +987,27 @@ return_err:
1016 987
1017static int path_walk(const char *name, struct nameidata *nd) 988static int path_walk(const char *name, struct nameidata *nd)
1018{ 989{
990 struct path save = nd->path;
991 int result;
992
1019 current->total_link_count = 0; 993 current->total_link_count = 0;
1020 return link_path_walk(name, nd); 994
995 /* make sure the stuff we saved doesn't go away */
996 path_get(&save);
997
998 result = link_path_walk(name, nd);
999 if (result == -ESTALE) {
1000 /* nd->path had been dropped */
1001 current->total_link_count = 0;
1002 nd->path = save;
1003 path_get(&nd->path);
1004 nd->flags |= LOOKUP_REVAL;
1005 result = link_path_walk(name, nd);
1006 }
1007
1008 path_put(&save);
1009
1010 return result;
1021} 1011}
1022 1012
1023static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd) 1013static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd)
@@ -1649,7 +1639,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
1649 struct file *filp; 1639 struct file *filp;
1650 struct nameidata nd; 1640 struct nameidata nd;
1651 int error; 1641 int error;
1652 struct path path; 1642 struct path path, save;
1653 struct dentry *dir; 1643 struct dentry *dir;
1654 int count = 0; 1644 int count = 0;
1655 int will_write; 1645 int will_write;
@@ -1862,7 +1852,17 @@ do_link:
1862 error = security_inode_follow_link(path.dentry, &nd); 1852 error = security_inode_follow_link(path.dentry, &nd);
1863 if (error) 1853 if (error)
1864 goto exit_dput; 1854 goto exit_dput;
1855 save = nd.path;
1856 path_get(&save);
1865 error = __do_follow_link(&path, &nd); 1857 error = __do_follow_link(&path, &nd);
1858 if (error == -ESTALE) {
1859 /* nd.path had been dropped */
1860 nd.path = save;
1861 path_get(&nd.path);
1862 nd.flags |= LOOKUP_REVAL;
1863 error = __do_follow_link(&path, &nd);
1864 }
1865 path_put(&save);
1866 path_put(&path); 1866 path_put(&path);
1867 if (error) { 1867 if (error) {
1868 /* Does someone understand code flow here? Or it is only 1868 /* Does someone understand code flow here? Or it is only