diff options
author | Ahmad Fatoum <a.fatoum@pengutronix.de> | 2024-03-04 19:59:22 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2024-03-05 16:28:05 +0100 |
commit | 127f7b809e0c8079b4d8636e3f345d52eebd4875 (patch) | |
tree | fbe14bdc1fa7b3c5adcbb7c21747f61141a09ecb /fs | |
parent | 049b0e98ded7230e83fa5ae9420159db8a98d97a (diff) | |
download | barebox-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.c | 14 |
1 files changed, 8 insertions, 6 deletions
@@ -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; } |