diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/fs/namei.c b/fs/namei.c index eaf07f87cba5..53d815415810 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2296,13 +2296,16 @@ static const char *path_init(struct nameidata *nd, unsigned flags) nd->m_seq = read_seqbegin(&mount_lock); - /* Figure out the starting path and root (if needed). */ - if (*s == '/') { + /* Absolute pathname -- fetch the root (LOOKUP_IN_ROOT uses nd->dfd). */ + if (*s == '/' && !(flags & LOOKUP_IN_ROOT)) { error = nd_jump_root(nd); if (unlikely(error)) return ERR_PTR(error); return s; - } else if (nd->dfd == AT_FDCWD) { + } + + /* Relative pathname -- get the starting-point it is relative to. */ + if (nd->dfd == AT_FDCWD) { if (flags & LOOKUP_RCU) { struct fs_struct *fs = current->fs; unsigned seq; @@ -2342,6 +2345,7 @@ static const char *path_init(struct nameidata *nd, unsigned flags) } fdput(f); } + /* For scoped-lookups we need to set the root to the dirfd as well. */ if (flags & LOOKUP_IS_SCOPED) { nd->root = nd->path; |