aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c52
1 files changed, 24 insertions, 28 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 6ec1f0fefc5b..145e852c4bd0 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -525,6 +525,22 @@ static inline int __do_follow_link(struct path *path, struct nameidata *nd)
525 return error; 525 return error;
526} 526}
527 527
528static inline void dput_path(struct path *path, struct nameidata *nd)
529{
530 dput(path->dentry);
531 if (path->mnt != nd->mnt)
532 mntput(path->mnt);
533}
534
535static inline void path_to_nameidata(struct path *path, struct nameidata *nd)
536{
537 dput(nd->dentry);
538 if (nd->mnt != path->mnt)
539 mntput(nd->mnt);
540 nd->mnt = path->mnt;
541 nd->dentry = path->dentry;
542}
543
528/* 544/*
529 * This limits recursive symlink follows to 8, while 545 * This limits recursive symlink follows to 8, while
530 * limiting consecutive symlinks to 40. 546 * limiting consecutive symlinks to 40.
@@ -552,9 +568,7 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd)
552 nd->depth--; 568 nd->depth--;
553 return err; 569 return err;
554loop: 570loop:
555 dput(path->dentry); 571 dput_path(path, nd);
556 if (path->mnt != nd->mnt)
557 mntput(path->mnt);
558 path_release(nd); 572 path_release(nd);
559 return err; 573 return err;
560} 574}
@@ -813,13 +827,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
813 err = -ENOTDIR; 827 err = -ENOTDIR;
814 if (!inode->i_op) 828 if (!inode->i_op)
815 break; 829 break;
816 } else { 830 } else
817 dput(nd->dentry); 831 path_to_nameidata(&next, nd);
818 if (nd->mnt != next.mnt)
819 mntput(nd->mnt);
820 nd->mnt = next.mnt;
821 nd->dentry = next.dentry;
822 }
823 err = -ENOTDIR; 832 err = -ENOTDIR;
824 if (!inode->i_op->lookup) 833 if (!inode->i_op->lookup)
825 break; 834 break;
@@ -859,13 +868,8 @@ last_component:
859 if (err) 868 if (err)
860 goto return_err; 869 goto return_err;
861 inode = nd->dentry->d_inode; 870 inode = nd->dentry->d_inode;
862 } else { 871 } else
863 dput(nd->dentry); 872 path_to_nameidata(&next, nd);
864 if (nd->mnt != next.mnt)
865 mntput(nd->mnt);
866 nd->mnt = next.mnt;
867 nd->dentry = next.dentry;
868 }
869 err = -ENOENT; 873 err = -ENOENT;
870 if (!inode) 874 if (!inode)
871 break; 875 break;
@@ -901,9 +905,7 @@ return_reval:
901return_base: 905return_base:
902 return 0; 906 return 0;
903out_dput: 907out_dput:
904 dput(next.dentry); 908 dput_path(&next, nd);
905 if (nd->mnt != next.mnt)
906 mntput(next.mnt);
907 break; 909 break;
908 } 910 }
909 path_release(nd); 911 path_release(nd);
@@ -1507,11 +1509,7 @@ do_last:
1507 if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) 1509 if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link)
1508 goto do_link; 1510 goto do_link;
1509 1511
1510 dput(nd->dentry); 1512 path_to_nameidata(&path, nd);
1511 nd->dentry = path.dentry;
1512 if (nd->mnt != path.mnt)
1513 mntput(nd->mnt);
1514 nd->mnt = path.mnt;
1515 error = -EISDIR; 1513 error = -EISDIR;
1516 if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) 1514 if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode))
1517 goto exit; 1515 goto exit;
@@ -1522,9 +1520,7 @@ ok:
1522 return 0; 1520 return 0;
1523 1521
1524exit_dput: 1522exit_dput:
1525 dput(path.dentry); 1523 dput_path(&path, nd);
1526 if (nd->mnt != path.mnt)
1527 mntput(path.mnt);
1528exit: 1524exit:
1529 path_release(nd); 1525 path_release(nd);
1530 return error; 1526 return error;