etc/services - sync with NetBSD-8
[minix.git] / minix / lib / libsffs / lookup.c
blobfbc786b080be2c9dad1eebc0fad601c9136731b8
1 /* This file provides path-to-inode lookup functionality.
3 * The entry points into this file are:
4 * do_lookup perform the LOOKUP file system call
6 * Created:
7 * April 2009 (D.C. van Moolenbroek)
8 */
10 #include "inc.h"
12 /*===========================================================================*
13 * go_up *
14 *===========================================================================*/
15 static int go_up(
16 char path[PATH_MAX], /* path to take the last part from */
17 struct inode *ino, /* inode of the current directory */
18 struct inode **res_ino, /* place to store resulting inode */
19 struct sffs_attr *attr /* place to store inode attributes */
22 /* Given an inode, progress into the parent directory.
24 struct inode *parent;
25 int r;
27 pop_path(path);
29 parent = ino->i_parent;
30 assert(parent != NULL);
32 if ((r = verify_path(path, parent, attr, NULL)) != OK)
33 return r;
35 get_inode(parent);
37 *res_ino = parent;
39 return r;
42 /*===========================================================================*
43 * go_down *
44 *===========================================================================*/
45 static int go_down(
46 char path[PATH_MAX], /* path to add the name to */
47 struct inode *parent, /* inode of the current directory */
48 char *name, /* name of the directory entry */
49 struct inode **res_ino, /* place to store resulting inode */
50 struct sffs_attr *attr /* place to store inode attributes */
53 /* Given a directory inode and a name, progress into a directory entry.
55 struct inode *ino;
56 int r, stale = 0;
58 if ((r = push_path(path, name)) != OK)
59 return r;
61 dprintf(("%s: go_down: name '%s', path now '%s'\n", sffs_name, name, path));
63 ino = lookup_dentry(parent, name);
65 dprintf(("%s: lookup_dentry('%s') returned %p\n", sffs_name, name, ino));
67 if (ino != NULL)
68 r = verify_path(path, ino, attr, &stale);
69 else
70 r = sffs_table->t_getattr(path, attr);
72 dprintf(("%s: path query returned %d\n", sffs_name, r));
74 if (r != OK) {
75 if (ino != NULL) {
76 put_inode(ino);
78 ino = NULL;
81 if (!stale)
82 return r;
85 dprintf(("%s: name '%s'\n", sffs_name, name));
87 if (ino == NULL) {
88 if ((ino = get_free_inode()) == NULL)
89 return ENFILE;
91 dprintf(("%s: inode %p ref %d\n", sffs_name, ino, ino->i_ref));
93 ino->i_flags = MODE_TO_DIRFLAG(attr->a_mode);
95 add_dentry(parent, name, ino);
98 *res_ino = ino;
99 return OK;
102 /*===========================================================================*
103 * do_lookup *
104 *===========================================================================*/
105 int do_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node,
106 int *is_mountpt)
108 /* Resolve a path string to an inode.
110 struct inode *dir_ino, *ino = NULL;
111 struct sffs_attr attr;
112 char path[PATH_MAX];
113 int r;
115 dprintf(("%s: lookup: got query for %"PRIu64", '%s'\n",
116 sffs_name, dir_nr, name));
118 if ((dir_ino = find_inode(dir_nr)) == NULL)
119 return EINVAL;
121 attr.a_mask = SFFS_ATTR_MODE | SFFS_ATTR_SIZE;
123 if ((r = verify_inode(dir_ino, path, &attr)) != OK)
124 return r;
126 if (!IS_DIR(dir_ino))
127 return ENOTDIR;
129 r = OK;
130 if (!strcmp(name, "."))
131 get_inode(ino = dir_ino);
132 else if (!strcmp(name, ".."))
133 r = go_up(path, dir_ino, &ino, &attr);
134 else
135 r = go_down(path, dir_ino, name, &ino, &attr);
137 if (r != OK)
138 return r;
140 node->fn_ino_nr = INODE_NR(ino);
141 node->fn_mode = get_mode(ino, attr.a_mode);
142 node->fn_size = attr.a_size;
143 node->fn_uid = sffs_params->p_uid;
144 node->fn_gid = sffs_params->p_gid;
145 node->fn_dev = NO_DEV;
147 *is_mountpt = FALSE;
149 return OK;