AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
lookup.c File Reference

Path lookup: walking a path one component at a time, from vnode to vnode. More...

#include <core/system.h>
#include <core/string.h>
#include <fs/vfs.h>
#include <aquila/fcntl.h>

Go to the source code of this file.

Macros

#define SYMLOOP_MAX   8
#define NAME_MAX   255
#define WALK_PARENT   1

Functions

static struct vnode * vref (struct vnode *vnode)
 Adds a reference to a vnode, and returns it.
static struct vnode * walk_root (struct uio *uio)
 Returns where absolute paths start: the process's root directory, or the system's.
static struct vnode * cross_down (struct vnode *vnode)
 Returns the root of what's mounted on vnode (all the way down, if a mount is mounted on too), or vnode itself.
int vfs_parent (struct vnode *dir, struct vnode **ref)
 Finds a directory's parent in its own filesystem, through its .. entry.
static int dotdot (struct vnode *dir, struct uio *uio, struct vnode **ref)
 Finds where .. goes from dir during a walk, up through mounts; the walk's root's .. is itself.
static int lookup_name (struct vnode *dir, const char *name, size_t len, struct vnode **ref)
 Finds the entry name (len bytes) of dir, and crosses into what is mounted on it.
static char * link_path (struct vnode *link, const char *rest, int *err)
 Returns the path a walk goes on with at a symbolic link: the link's target, then rest (what's left of the path, starting with its slash).
static int is_dot (const char *c, size_t len)
 Says whether a path component of len bytes is a single dot, the name of a directory itself.
static int is_dotdot (const char *c, size_t len)
 Says whether a component (len bytes) is ...
static int walk (struct vnode *dir, const char *path, struct uio *uio, int flags, int *links, struct vnode **ref, char **name, struct vnode **where)
 Walks path from dir, whose reference the walk takes.
static struct vnode * walk_start (struct uio *uio)
 Returns where a relative path starts (with a reference): the current directory.
int vfs_lookup (const char *path, struct uio *uio, struct vnode **ref)
 Finds the vnode a path names.
int vfs_lookup_dir (const char *path, struct uio *uio, struct vnode **ref, struct vnode **dir)
 Finds the vnode a path names, as vfs_lookup() does, and the directory it was found in.
int vfs_lookup_parent (const char *path, struct uio *uio, struct vnode **dir, char **name)
 Finds the directory of a path's last component, and the component's name, to make or remove an entry there.
struct vnode * vfs_mount_root_of (struct vnode *vnode)
 Finds the root of the mounted filesystem a vnode is in.
int vfs_under (struct vnode *vnode, struct vnode *dir)
 Says whether a vnode is a directory or under it, in the same filesystem: rename() can't move a directory under itself.
static int entry_name (struct vnode *parent, struct vnode *child, char *name)
 Finds the name child has in parent (into name, NAME_MAX + 1 bytes).
int vfs_vnode_path (struct vnode *vnode, struct vnode *root, char *buf, size_t size)
 Computes a vnode's path, for getcwd() and /proc/mounts: it goes up through .., and finds each directory's name in its parent.

Detailed Description

Path lookup: walking a path one component at a time, from vnode to vnode.

An absolute path is walked from the root, and a relative one from the uio's current directory (or a directory descriptor's, for the *at() calls). Each component is one of:

. the directory itself; .. its parent, the filesystem's own ".." entry; at the root of a mounted filesystem, the parent of the directory it's mounted on; at the root, the root itself; name the directory's entry (finddir, then vget), if the uio's user may search the directory (x); if a filesystem is mounted on the entry, that filesystem's root.

A symbolic link is followed where it's found (the last component isn't followed with O_NOFOLLOW, unless a slash comes after it): the walk goes on from the link's directory, with the link's target, then what was left of the path. A trailing slash asks for a directory.

Only the path itself is a string: a renamed directory is still a process's current directory, ".." after a symbolic link is the parent of where the link went, and a path is only computed when one is asked for (vfs_vnode_path(), for getcwd() and /proc/mounts).

Definition in file lookup.c.

Macro Definition Documentation

◆ NAME_MAX

#define NAME_MAX   255

Definition at line 37 of file lookup.c.

Referenced by lookup_name(), vfs_vnode_path(), and walk().

◆ SYMLOOP_MAX

#define SYMLOOP_MAX   8

Definition at line 34 of file lookup.c.

Referenced by walk().

◆ WALK_PARENT

#define WALK_PARENT   1

Definition at line 41 of file lookup.c.

Referenced by vfs_lookup_parent(), and walk().

Function Documentation

◆ cross_down()

struct vnode * cross_down ( struct vnode * vnode)
static

Returns the root of what's mounted on vnode (all the way down, if a mount is mounted on too), or vnode itself.

The caller's reference moves to the vnode returned.

Definition at line 60 of file lookup.c.

References cross_down(), vnode::mounted, vfs_close(), and vref().

Referenced by cross_down(), dotdot(), and lookup_name().

◆ dotdot()

int dotdot ( struct vnode * dir,
struct uio * uio,
struct vnode ** ref )
static

Finds where .. goes from dir during a walk, up through mounts; the walk's root's .. is itself.

The result in *ref has a reference.

Definition at line 107 of file lookup.c.

References vnode::covered, cross_down(), dotdot(), vnode::ref, vfs_parent(), vref(), and walk_root().

Referenced by dotdot(), pseudofs_readdir(), pseudofs_vmknod(), pseudofs_vrename(), and walk().

◆ entry_name()

int entry_name ( struct vnode * parent,
struct vnode * child,
char * name )
static

Finds the name child has in parent (into name, NAME_MAX + 1 bytes).

Returns 0, -ENOENT if it has none (it was removed), or a negative errno.

Definition at line 498 of file lookup.c.

References entry_name(), vnode::ino, vfs_finddir(), and vfs_readdir().

Referenced by entry_name(), and vfs_vnode_path().

◆ is_dot()

int is_dot ( const char * c,
size_t len )
static

Says whether a path component of len bytes is a single dot, the name of a directory itself.

Definition at line 182 of file lookup.c.

References is_dot().

Referenced by is_dot(), and walk().

◆ is_dotdot()

int is_dotdot ( const char * c,
size_t len )
static

Says whether a component (len bytes) is ...

Definition at line 188 of file lookup.c.

References is_dotdot().

Referenced by is_dotdot(), and walk().

◆ link_path()

char * link_path ( struct vnode * link,
const char * rest,
int * err )
static

Returns the path a walk goes on with at a symbolic link: the link's target, then rest (what's left of the path, starting with its slash).

The caller frees it. On failure it returns NULL, with the error in *err.

Definition at line 158 of file lookup.c.

References kfree(), kmalloc(), link_path(), NULL, and vfs_read().

Referenced by link_path(), and walk().

◆ lookup_name()

int lookup_name ( struct vnode * dir,
const char * name,
size_t len,
struct vnode ** ref )
static

Finds the entry name (len bytes) of dir, and crosses into what is mounted on it.

The result in *ref has a reference.

Definition at line 131 of file lookup.c.

References cross_down(), lookup_name(), memcpy(), NAME_MAX, vnode::ref, vfs_finddir(), and vfs_vget().

Referenced by lookup_name(), and walk().

◆ vfs_lookup()

int vfs_lookup ( const char * path,
struct uio * uio,
struct vnode ** ref )

Finds the vnode a path names.

A symbolic link at the end is followed, unless the uio has O_NOFOLLOW.

Parameters
paththe path
uiowho is asking, and where relative paths start
refif not NULL, set to the vnode (with a reference for the caller), on success only
Returns
0, -ENOENT, -ENOTDIR, -EACCES, -ELOOP, or another negative errno

Definition at line 349 of file lookup.c.

References LOG_DEBUG, NULL, vnode::ref, vfs_close(), vfs_lookup(), walk(), and walk_start().

Referenced by at_lookup(), binfmt_load(), creat_path(), do_openat(), exec_script(), ext2_mount(), minix_mount(), socket_unix_bind(), socket_unix_connect(), sys_chdir(), vfs_lookup(), vfs_mount(), and vfs_readlink().

◆ vfs_lookup_dir()

int vfs_lookup_dir ( const char * path,
struct uio * uio,
struct vnode ** ref,
struct vnode ** dir )

Finds the vnode a path names, as vfs_lookup() does, and the directory it was found in.

Parameters
paththe path
uiowho is asking, and where relative paths start
refset to the vnode (with a reference for the caller)
dirset to its directory (with a reference), or to the vnode again if the path ends with no name (/)
Returns
0, or a negative errno

Definition at line 381 of file lookup.c.

References NULL, vnode::ref, vfs_close(), vfs_lookup_dir(), vref(), walk(), and walk_start().

Referenced by vfs_link(), and vfs_lookup_dir().

◆ vfs_lookup_parent()

int vfs_lookup_parent ( const char * path,
struct uio * uio,
struct vnode ** dir,
char ** name )

Finds the directory of a path's last component, and the component's name, to make or remove an entry there.

Parameters
paththe path
uiowho is asking, and where relative paths start
dirset to the directory (with a reference for the caller)
nameset to the last component's name (the caller frees it)
Returns
0, -EBUSY if the path names a mount point (or /), -EINVAL if it ends with . or .., or another negative errno

Definition at line 414 of file lookup.c.

References vnode::covered, kfree(), vnode::mounted, NULL, vfs_close(), vfs_finddir(), vfs_lookup_parent(), vfs_vget(), walk(), WALK_PARENT, and walk_start().

Referenced by vfs_link(), vfs_lookup_parent(), vfs_mknod(), vfs_remove(), and vfs_rename().

◆ vfs_mount_root_of()

struct vnode * vfs_mount_root_of ( struct vnode * vnode)

Finds the root of the mounted filesystem a vnode is in.

Parameters
vnodethe vnode
Returns
the root (without a reference: the mount keeps one)

Definition at line 452 of file lookup.c.

References vnode::covered, vfs_close(), vfs_mount_root_of(), vfs_parent(), vfs_root, and vref().

Referenced by vfs_link(), vfs_mount_root_of(), and vfs_rename().

◆ vfs_parent()

int vfs_parent ( struct vnode * dir,
struct vnode ** ref )

Finds a directory's parent in its own filesystem, through its .. entry.

Parameters
dirthe directory
refset to the parent, with a reference for the caller, or to NULL at the filesystem's root
Returns
0, or a negative errno

Definition at line 80 of file lookup.c.

References NULL, vnode::ref, vfs_close(), vfs_finddir(), vfs_parent(), and vfs_vget().

Referenced by dotdot(), vfs_mount_root_of(), vfs_parent(), vfs_under(), and vfs_vnode_path().

◆ vfs_under()

int vfs_under ( struct vnode * vnode,
struct vnode * dir )

Says whether a vnode is a directory or under it, in the same filesystem: rename() can't move a directory under itself.

Parameters
vnodethe vnode
dirthe directory
Returns
1 if vnode is dir or under it, 0 otherwise

Definition at line 473 of file lookup.c.

References vfs_close(), vfs_parent(), vfs_under(), and vref().

Referenced by vfs_rename(), and vfs_under().

◆ vfs_vnode_path()

int vfs_vnode_path ( struct vnode * vnode,
struct vnode * root,
char * buf,
size_t size )

Computes a vnode's path, for getcwd() and /proc/mounts: it goes up through .., and finds each directory's name in its parent.

Parameters
vnodethe vnode
rootwhere the path starts, or NULL for the system's root
bufwhere the path goes
sizethe buffer's size
Returns
0, -ENOENT if a directory on the way was removed, -ERANGE if the path doesn't fit, or another negative errno

Definition at line 532 of file lookup.c.

References vnode::covered, entry_name(), memcpy(), memmove(), NAME_MAX, vnode::size, vfs_close(), vfs_parent(), vfs_root, vfs_vnode_path(), and vref().

Referenced by procfs_proc_status(), sys_getcwd(), vfs_mount(), and vfs_vnode_path().

◆ vref()

struct vnode * vref ( struct vnode * vnode)
static

Adds a reference to a vnode, and returns it.

Definition at line 44 of file lookup.c.

References vnode::ref, and vref().

Referenced by cross_down(), dotdot(), vfs_lookup_dir(), vfs_mount_root_of(), vfs_under(), vfs_vnode_path(), vref(), walk(), and walk_start().

◆ walk()

int walk ( struct vnode * dir,
const char * path,
struct uio * uio,
int flags,
int * links,
struct vnode ** ref,
char ** name,
struct vnode ** where )
static

Walks path from dir, whose reference the walk takes.

It returns what the path names in *ref (with a reference) and, if where isn't NULL, the directory its last component was found in (with a reference, or NULL if there's none).

With WALK_PARENT, it stops at the last component instead: *ref is that component's directory, and *name the component (the caller frees it). Then a path with no last component (/) is -EBUSY, and a last component of . or .. is -EINVAL.

Definition at line 204 of file lookup.c.

References dotdot(), uio::flags, is_dot(), is_dotdot(), kfree(), kmalloc(), link_path(), lookup_name(), memcpy(), vnode::mode, NAME_MAX, NULL, vnode::p, vnode::ref, SYMLOOP_MAX, vfs_access(), vfs_close(), VFS_X, vref(), walk(), WALK_PARENT, and walk_root().

Referenced by vfs_lookup(), vfs_lookup_dir(), vfs_lookup_parent(), and walk().

◆ walk_root()

struct vnode * walk_root ( struct uio * uio)
static

Returns where absolute paths start: the process's root directory, or the system's.

Definition at line 52 of file lookup.c.

References uio::root, vfs_root, and walk_root().

Referenced by dotdot(), walk(), walk_root(), and walk_start().

◆ walk_start()

struct vnode * walk_start ( struct uio * uio)
static

Returns where a relative path starts (with a reference): the current directory.

Definition at line 333 of file lookup.c.

References uio::cwd, vref(), walk_root(), and walk_start().

Referenced by vfs_lookup(), vfs_lookup_dir(), vfs_lookup_parent(), and walk_start().