[PATCH 037/112] fs: support different root directories

Ahmad Fatoum a.fatoum at pengutronix.de
Wed Jan 3 10:11:57 PST 2024


A root directory is a directory that has itself as the parent.
There is only one such directory, but for chroot support we will want to
stop path resolution at a non-root directory as well.

We do this by giving struct nameidata a d_root field, which serves as a
root directory for the lookup. As we initialize it to the global root
directory, this introduces no functional change.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 fs/fs.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index 54f38aa2e63b..7fc638451f13 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -1623,6 +1623,7 @@ struct nameidata {
 	} *stack, internal[EMBEDDED_LEVELS];
 	struct filename	*name;
 	struct inode	*link_inode;
+	struct dentry   *d_root;
 };
 
 struct filename {
@@ -1635,6 +1636,7 @@ static void set_nameidata(struct nameidata *p, struct filename *name)
 	p->stack = p->internal;
 	p->name = name;
 	p->total_link_count = 0;
+	p->d_root = d_root;
 }
 
 static void path_get(const struct path *path)
@@ -1820,16 +1822,16 @@ static int lookup_fast(struct nameidata *nd, struct path *path)
  * Return 1 if we went up a level and 0 if we were already at the
  * root.
  */
-static int follow_up(struct path *path)
+static int follow_up(struct nameidata *nd)
 {
-	struct vfsmount *parent, *mnt = path->mnt;
+	struct path *path = &nd->path;
+	struct vfsmount *mnt = path->mnt;
 	struct dentry *mountpoint;
 
-	parent = mnt->parent;
-	if (parent == mnt)
+	if (nd->d_root == path->dentry)
 		return 0;
 
-	mntget(parent);
+	mntget(mnt->parent);
 	mountpoint = dget(mnt->mountpoint);
 	dput(path->dentry);
 	path->dentry = mountpoint;
@@ -1871,7 +1873,7 @@ static int follow_dotdot(struct nameidata *nd)
 			break;
 		}
 
-		if (!follow_up(&nd->path))
+		if (!follow_up(nd))
 			break;
 	}
 
-- 
2.39.2




More information about the barebox mailing list