aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 32fd9655485b..01e67dddcc3d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -581,15 +581,13 @@ static __always_inline int link_path_walk(const char *name, struct nameidata *nd
581 int result; 581 int result;
582 582
583 /* make sure the stuff we saved doesn't go away */ 583 /* make sure the stuff we saved doesn't go away */
584 dget(save.dentry); 584 path_get(&save);
585 mntget(save.mnt);
586 585
587 result = __link_path_walk(name, nd); 586 result = __link_path_walk(name, nd);
588 if (result == -ESTALE) { 587 if (result == -ESTALE) {
589 /* nd->path had been dropped */ 588 /* nd->path had been dropped */
590 nd->path = save; 589 nd->path = save;
591 dget(nd->path.dentry); 590 path_get(&nd->path);
592 mntget(nd->path.mnt);
593 nd->flags |= LOOKUP_REVAL; 591 nd->flags |= LOOKUP_REVAL;
594 result = __link_path_walk(name, nd); 592 result = __link_path_walk(name, nd);
595 } 593 }
@@ -1216,8 +1214,9 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
1216 nd->flags = flags; 1214 nd->flags = flags;
1217 nd->depth = 0; 1215 nd->depth = 0;
1218 1216
1219 nd->path.mnt = mntget(mnt); 1217 nd->path.dentry = dentry;
1220 nd->path.dentry = dget(dentry); 1218 nd->path.mnt = mnt;
1219 path_get(&nd->path);
1221 1220
1222 retval = path_walk(name, nd); 1221 retval = path_walk(name, nd);
1223 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && 1222 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
@@ -2003,18 +2002,22 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir)
2003 if (IS_ERR(dentry)) 2002 if (IS_ERR(dentry))
2004 goto fail; 2003 goto fail;
2005 2004
2005 if (dentry->d_inode)
2006 goto eexist;
2006 /* 2007 /*
2007 * Special case - lookup gave negative, but... we had foo/bar/ 2008 * Special case - lookup gave negative, but... we had foo/bar/
2008 * From the vfs_mknod() POV we just have a negative dentry - 2009 * From the vfs_mknod() POV we just have a negative dentry -
2009 * all is fine. Let's be bastards - you had / on the end, you've 2010 * all is fine. Let's be bastards - you had / on the end, you've
2010 * been asking for (non-existent) directory. -ENOENT for you. 2011 * been asking for (non-existent) directory. -ENOENT for you.
2011 */ 2012 */
2012 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) 2013 if (unlikely(!is_dir && nd->last.name[nd->last.len])) {
2013 goto enoent; 2014 dput(dentry);
2015 dentry = ERR_PTR(-ENOENT);
2016 }
2014 return dentry; 2017 return dentry;
2015enoent: 2018eexist:
2016 dput(dentry); 2019 dput(dentry);
2017 dentry = ERR_PTR(-ENOENT); 2020 dentry = ERR_PTR(-EEXIST);
2018fail: 2021fail:
2019 return dentry; 2022 return dentry;
2020} 2023}
@@ -2853,16 +2856,17 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
2853{ 2856{
2854 struct nameidata nd; 2857 struct nameidata nd;
2855 void *cookie; 2858 void *cookie;
2859 int res;
2856 2860
2857 nd.depth = 0; 2861 nd.depth = 0;
2858 cookie = dentry->d_inode->i_op->follow_link(dentry, &nd); 2862 cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
2859 if (!IS_ERR(cookie)) { 2863 if (IS_ERR(cookie))
2860 int res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd)); 2864 return PTR_ERR(cookie);
2861 if (dentry->d_inode->i_op->put_link) 2865
2862 dentry->d_inode->i_op->put_link(dentry, &nd, cookie); 2866 res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
2863 cookie = ERR_PTR(res); 2867 if (dentry->d_inode->i_op->put_link)
2864 } 2868 dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
2865 return PTR_ERR(cookie); 2869 return res;
2866} 2870}
2867 2871
2868int vfs_follow_link(struct nameidata *nd, const char *link) 2872int vfs_follow_link(struct nameidata *nd, const char *link)