aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/namei.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 519900d83bcb..18ea0606145e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -498,12 +498,15 @@ struct path {
498 struct dentry *dentry; 498 struct dentry *dentry;
499}; 499};
500 500
501static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) 501static inline int __do_follow_link(struct path *path, struct nameidata *nd)
502{ 502{
503 int error; 503 int error;
504 struct dentry *dentry = path->dentry;
504 505
505 touch_atime(nd->mnt, dentry); 506 touch_atime(nd->mnt, dentry);
506 nd_set_link(nd, NULL); 507 nd_set_link(nd, NULL);
508
509 mntget(path->mnt);
507 error = dentry->d_inode->i_op->follow_link(dentry, nd); 510 error = dentry->d_inode->i_op->follow_link(dentry, nd);
508 if (!error) { 511 if (!error) {
509 char *s = nd_get_link(nd); 512 char *s = nd_get_link(nd);
@@ -512,6 +515,8 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
512 if (dentry->d_inode->i_op->put_link) 515 if (dentry->d_inode->i_op->put_link)
513 dentry->d_inode->i_op->put_link(dentry, nd); 516 dentry->d_inode->i_op->put_link(dentry, nd);
514 } 517 }
518 dput(dentry);
519 mntput(path->mnt);
515 520
516 return error; 521 return error;
517} 522}
@@ -538,10 +543,7 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd)
538 current->link_count++; 543 current->link_count++;
539 current->total_link_count++; 544 current->total_link_count++;
540 nd->depth++; 545 nd->depth++;
541 mntget(path->mnt); 546 err = __do_follow_link(path, nd);
542 err = __do_follow_link(path->dentry, nd);
543 dput(path->dentry);
544 mntput(path->mnt);
545 current->link_count--; 547 current->link_count--;
546 nd->depth--; 548 nd->depth--;
547 return err; 549 return err;
@@ -1523,10 +1525,7 @@ do_link:
1523 error = security_inode_follow_link(path.dentry, nd); 1525 error = security_inode_follow_link(path.dentry, nd);
1524 if (error) 1526 if (error)
1525 goto exit_dput; 1527 goto exit_dput;
1526 mntget(path.mnt); 1528 error = __do_follow_link(&path, nd);
1527 error = __do_follow_link(path.dentry, nd);
1528 dput(path.dentry);
1529 mntput(path.mnt);
1530 path.mnt = nd->mnt; 1529 path.mnt = nd->mnt;
1531 if (error) 1530 if (error)
1532 return error; 1531 return error;