summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2024-03-04 19:59:22 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2024-03-05 16:28:05 +0100
commit127f7b809e0c8079b4d8636e3f345d52eebd4875 (patch)
treefbe14bdc1fa7b3c5adcbb7c21747f61141a09ecb /fs
parent049b0e98ded7230e83fa5ae9420159db8a98d97a (diff)
downloadbarebox-127f7b809e0c8079b4d8636e3f345d52eebd4875.tar.gz
barebox-127f7b809e0c8079b4d8636e3f345d52eebd4875.tar.xz
fs: support different root directories
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@pengutronix.de> Link: https://lore.barebox.org/20240304190038.3486881-38-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'fs')
-rw-r--r--fs/fs.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/fs/fs.c b/fs/fs.c
index cda1f39519..7aa8a5d69b 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;
}