aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 4c4f95ac8aa5..6a82fb7e2127 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1416,21 +1416,28 @@ static void follow_mount(struct path *path)
1416 } 1416 }
1417} 1417}
1418 1418
1419static int path_parent_directory(struct path *path)
1420{
1421 struct dentry *old = path->dentry;
1422 /* rare case of legitimate dget_parent()... */
1423 path->dentry = dget_parent(path->dentry);
1424 dput(old);
1425 if (unlikely(!path_connected(path)))
1426 return -ENOENT;
1427 return 0;
1428}
1429
1419static int follow_dotdot(struct nameidata *nd) 1430static int follow_dotdot(struct nameidata *nd)
1420{ 1431{
1421 while(1) { 1432 while(1) {
1422 struct dentry *old = nd->path.dentry;
1423
1424 if (nd->path.dentry == nd->root.dentry && 1433 if (nd->path.dentry == nd->root.dentry &&
1425 nd->path.mnt == nd->root.mnt) { 1434 nd->path.mnt == nd->root.mnt) {
1426 break; 1435 break;
1427 } 1436 }
1428 if (nd->path.dentry != nd->path.mnt->mnt_root) { 1437 if (nd->path.dentry != nd->path.mnt->mnt_root) {
1429 /* rare case of legitimate dget_parent()... */ 1438 int ret = path_parent_directory(&nd->path);
1430 nd->path.dentry = dget_parent(nd->path.dentry); 1439 if (ret)
1431 dput(old); 1440 return ret;
1432 if (unlikely(!path_connected(&nd->path)))
1433 return -ENOENT;
1434 break; 1441 break;
1435 } 1442 }
1436 if (!follow_up(&nd->path)) 1443 if (!follow_up(&nd->path))
@@ -2514,6 +2521,34 @@ struct dentry *lookup_one_len_unlocked(const char *name,
2514} 2521}
2515EXPORT_SYMBOL(lookup_one_len_unlocked); 2522EXPORT_SYMBOL(lookup_one_len_unlocked);
2516 2523
2524#ifdef CONFIG_UNIX98_PTYS
2525int path_pts(struct path *path)
2526{
2527 /* Find something mounted on "pts" in the same directory as
2528 * the input path.
2529 */
2530 struct dentry *child, *parent;
2531 struct qstr this;
2532 int ret;
2533
2534 ret = path_parent_directory(path);
2535 if (ret)
2536 return ret;
2537
2538 parent = path->dentry;
2539 this.name = "pts";
2540 this.len = 3;
2541 child = d_hash_and_lookup(parent, &this);
2542 if (!child)
2543 return -ENOENT;
2544
2545 path->dentry = child;
2546 dput(parent);
2547 follow_mount(path);
2548 return 0;
2549}
2550#endif
2551
2517int user_path_at_empty(int dfd, const char __user *name, unsigned flags, 2552int user_path_at_empty(int dfd, const char __user *name, unsigned flags,
2518 struct path *path, int *empty) 2553 struct path *path, int *empty)
2519{ 2554{