41a30155b9
The builds are failing as GCC somehow thinks ino might be uninitialized before use. Change-Id: Id99fd5e46bcbaafd5001752e16c3f77c1d568556
151 lines
3.5 KiB
C
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;
|
|
}
|