minix/minix/lib/libsffs/lookup.c
Lionel Sambuc 41a30155b9 Fix gcc -O1 builds for ARM
The builds are failing as GCC somehow thinks ino might be
uninitialized before use.

Change-Id: Id99fd5e46bcbaafd5001752e16c3f77c1d568556
2015-10-04 03:47:57 -07:00

151 lines
3.5 KiB
C

/* This file provides path-to-inode lookup functionality.
*
* The entry points into this file are:
* do_lookup perform the LOOKUP file system call
*
* Created:
* April 2009 (D.C. van Moolenbroek)
*/
#include "inc.h"
/*===========================================================================*
* go_up *
*===========================================================================*/
static int go_up(
char path[PATH_MAX], /* path to take the last part from */
struct inode *ino, /* inode of the current directory */
struct inode **res_ino, /* place to store resulting inode */
struct sffs_attr *attr /* place to store inode attributes */
)
{
/* Given an inode, progress into the parent directory.
*/
struct inode *parent;
int r;
pop_path(path);
parent = ino->i_parent;
assert(parent != NULL);
if ((r = verify_path(path, parent, attr, NULL)) != OK)
return r;
get_inode(parent);
*res_ino = parent;
return r;
}
/*===========================================================================*
* go_down *
*===========================================================================*/
static int go_down(
char path[PATH_MAX], /* path to add the name to */
struct inode *parent, /* inode of the current directory */
char *name, /* name of the directory entry */
struct inode **res_ino, /* place to store resulting inode */
struct sffs_attr *attr /* place to store inode attributes */
)
{
/* Given a directory inode and a name, progress into a directory entry.
*/
struct inode *ino;
int r, stale = 0;
if ((r = push_path(path, name)) != OK)
return r;
dprintf(("%s: go_down: name '%s', path now '%s'\n", sffs_name, name, path));
ino = lookup_dentry(parent, name);
dprintf(("%s: lookup_dentry('%s') returned %p\n", sffs_name, name, ino));
if (ino != NULL)
r = verify_path(path, ino, attr, &stale);
else
r = sffs_table->t_getattr(path, attr);
dprintf(("%s: path query returned %d\n", sffs_name, r));
if (r != OK) {
if (ino != NULL) {
put_inode(ino);
ino = NULL;
}
if (!stale)
return r;
}
dprintf(("%s: name '%s'\n", sffs_name, name));
if (ino == NULL) {
if ((ino = get_free_inode()) == NULL)
return ENFILE;
dprintf(("%s: inode %p ref %d\n", sffs_name, ino, ino->i_ref));
ino->i_flags = MODE_TO_DIRFLAG(attr->a_mode);
add_dentry(parent, name, ino);
}
*res_ino = ino;
return OK;
}
/*===========================================================================*
* do_lookup *
*===========================================================================*/
int do_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node,
int *is_mountpt)
{
/* Resolve a path string to an inode.
*/
struct inode *dir_ino, *ino = NULL;
struct sffs_attr attr;
char path[PATH_MAX];
int r;
dprintf(("%s: lookup: got query for %"PRIu64", '%s'\n",
sffs_name, dir_nr, name));
if ((dir_ino = find_inode(dir_nr)) == NULL)
return EINVAL;
attr.a_mask = SFFS_ATTR_MODE | SFFS_ATTR_SIZE;
if ((r = verify_inode(dir_ino, path, &attr)) != OK)
return r;
if (!IS_DIR(dir_ino))
return ENOTDIR;
r = OK;
if (!strcmp(name, "."))
get_inode(ino = dir_ino);
else if (!strcmp(name, ".."))
r = go_up(path, dir_ino, &ino, &attr);
else
r = go_down(path, dir_ino, name, &ino, &attr);
if (r != OK)
return r;
node->fn_ino_nr = INODE_NR(ino);
node->fn_mode = get_mode(ino, attr.a_mode);
node->fn_size = attr.a_size;
node->fn_uid = sffs_params->p_uid;
node->fn_gid = sffs_params->p_gid;
node->fn_dev = NO_DEV;
*is_mountpt = FALSE;
return OK;
}