2014-11-06 14:36:45 +01:00
|
|
|
/* VTreeFS - path.c - name resolution */
|
2010-08-10 22:05:51 +02:00
|
|
|
|
|
|
|
#include "inc.h"
|
|
|
|
|
2014-11-06 14:36:45 +01:00
|
|
|
/*
|
|
|
|
* Resolve a path string to an inode.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
fs_lookup(ino_t dir_nr, char * name, struct fsdriver_node * node_details,
|
|
|
|
int * is_mountpt)
|
2010-08-10 22:05:51 +02:00
|
|
|
{
|
2014-08-24 11:55:05 +02:00
|
|
|
struct inode *node, *child;
|
|
|
|
int r;
|
2010-08-10 22:05:51 +02:00
|
|
|
|
2014-08-24 11:55:05 +02:00
|
|
|
if ((node = find_inode(dir_nr)) == NULL)
|
2010-08-10 22:05:51 +02:00
|
|
|
return EINVAL;
|
|
|
|
|
2014-08-24 11:55:05 +02:00
|
|
|
if (!S_ISDIR(node->i_stat.mode))
|
|
|
|
return ENOTDIR;
|
2010-08-10 22:05:51 +02:00
|
|
|
|
2014-12-31 02:15:44 +01:00
|
|
|
if (strlen(name) > NAME_MAX)
|
2014-08-24 11:55:05 +02:00
|
|
|
return ENAMETOOLONG;
|
2010-08-10 22:05:51 +02:00
|
|
|
|
2014-08-24 11:55:05 +02:00
|
|
|
if (!strcmp(name, ".")) {
|
|
|
|
/* Stay in the given directory. */
|
|
|
|
child = node;
|
|
|
|
} else if (!strcmp(name, "..")) {
|
|
|
|
/* Progress into the parent directory. */
|
|
|
|
if ((child = get_parent_inode(node)) == NULL)
|
|
|
|
return ENOENT; /* deleted? should not be possible */
|
|
|
|
} else {
|
2014-11-06 14:36:45 +01:00
|
|
|
/* Progress into a directory entry. Call the lookup hook, if
|
2014-08-24 11:55:05 +02:00
|
|
|
* present, before doing the actual lookup.
|
2010-08-10 22:05:51 +02:00
|
|
|
*/
|
2014-08-24 11:55:05 +02:00
|
|
|
if (!is_inode_deleted(node) &&
|
|
|
|
vtreefs_hooks->lookup_hook != NULL) {
|
|
|
|
r = vtreefs_hooks->lookup_hook(node, name,
|
2014-11-06 14:36:45 +01:00
|
|
|
get_inode_cbdata(node));
|
2014-08-24 11:55:05 +02:00
|
|
|
if (r != OK) return r;
|
2010-08-10 22:05:51 +02:00
|
|
|
}
|
|
|
|
|
2014-08-24 11:55:05 +02:00
|
|
|
if ((child = get_inode_by_name(node, name)) == NULL)
|
|
|
|
return ENOENT;
|
2010-08-10 22:05:51 +02:00
|
|
|
}
|
|
|
|
|
2014-08-24 11:55:05 +02:00
|
|
|
/* On success, open the resulting file and return its details. */
|
|
|
|
ref_inode(child);
|
2010-08-10 22:05:51 +02:00
|
|
|
|
2014-08-24 11:55:05 +02:00
|
|
|
node_details->fn_ino_nr = get_inode_number(child);
|
|
|
|
node_details->fn_mode = child->i_stat.mode;
|
|
|
|
node_details->fn_size = child->i_stat.size;
|
|
|
|
node_details->fn_uid = child->i_stat.uid;
|
|
|
|
node_details->fn_gid = child->i_stat.gid;
|
|
|
|
node_details->fn_dev = child->i_stat.dev;
|
2010-08-10 22:05:51 +02:00
|
|
|
|
2014-08-24 11:55:05 +02:00
|
|
|
*is_mountpt = FALSE;
|
2010-08-10 22:05:51 +02:00
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|