1 /* This file provides path-to-inode lookup functionality.
2 *
3 * The entry points into this file are:
4 * do_lookup perform the LOOKUP file system call
5 *
6 * Created:
7 * April 2009 (D.C. van Moolenbroek)
8 */
9
10 #include "inc.h"
11
12 /*===========================================================================*
13 * go_up *
14 *===========================================================================*/
go_up(char path[PATH_MAX],struct inode * ino,struct inode ** res_ino,struct sffs_attr * attr)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 */
20 )
21 {
22 /* Given an inode, progress into the parent directory.
23 */
24 struct inode *parent;
25 int r;
26
27 pop_path(path);
28
29 parent = ino->i_parent;
30 assert(parent != NULL);
31
32 if ((r = verify_path(path, parent, attr, NULL)) != OK)
33 return r;
34
35 get_inode(parent);
36
37 *res_ino = parent;
38
39 return r;
40 }
41
42 /*===========================================================================*
43 * go_down *
44 *===========================================================================*/
go_down(char path[PATH_MAX],struct inode * parent,char * name,struct inode ** res_ino,struct sffs_attr * attr)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 */
51 )
52 {
53 /* Given a directory inode and a name, progress into a directory entry.
54 */
55 struct inode *ino;
56 int r, stale = 0;
57
58 if ((r = push_path(path, name)) != OK)
59 return r;
60
61 dprintf(("%s: go_down: name '%s', path now '%s'\n", sffs_name, name, path));
62
63 ino = lookup_dentry(parent, name);
64
65 dprintf(("%s: lookup_dentry('%s') returned %p\n", sffs_name, name, ino));
66
67 if (ino != NULL)
68 r = verify_path(path, ino, attr, &stale);
69 else
70 r = sffs_table->t_getattr(path, attr);
71
72 dprintf(("%s: path query returned %d\n", sffs_name, r));
73
74 if (r != OK) {
75 if (ino != NULL) {
76 put_inode(ino);
77
78 ino = NULL;
79 }
80
81 if (!stale)
82 return r;
83 }
84
85 dprintf(("%s: name '%s'\n", sffs_name, name));
86
87 if (ino == NULL) {
88 if ((ino = get_free_inode()) == NULL)
89 return ENFILE;
90
91 dprintf(("%s: inode %p ref %d\n", sffs_name, ino, ino->i_ref));
92
93 ino->i_flags = MODE_TO_DIRFLAG(attr->a_mode);
94
95 add_dentry(parent, name, ino);
96 }
97
98 *res_ino = ino;
99 return OK;
100 }
101
102 /*===========================================================================*
103 * do_lookup *
104 *===========================================================================*/
do_lookup(ino_t dir_nr,char * name,struct fsdriver_node * node,int * is_mountpt)105 int do_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node,
106 int *is_mountpt)
107 {
108 /* Resolve a path string to an inode.
109 */
110 struct inode *dir_ino, *ino = NULL;
111 struct sffs_attr attr;
112 char path[PATH_MAX];
113 int r;
114
115 dprintf(("%s: lookup: got query for %"PRIu64", '%s'\n",
116 sffs_name, dir_nr, name));
117
118 if ((dir_ino = find_inode(dir_nr)) == NULL)
119 return EINVAL;
120
121 attr.a_mask = SFFS_ATTR_MODE | SFFS_ATTR_SIZE;
122
123 if ((r = verify_inode(dir_ino, path, &attr)) != OK)
124 return r;
125
126 if (!IS_DIR(dir_ino))
127 return ENOTDIR;
128
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);
136
137 if (r != OK)
138 return r;
139
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;
146
147 *is_mountpt = FALSE;
148
149 return OK;
150 }
151