2 * This file contains the procedures that look up path names in the directory
3 * system and determine the pnode number that goes with a given path name.
5 * Created (based on MFS):
6 * June 2011 (Evgeniy Ivanov)
11 #include <sys/cdefs.h>
13 #include <sys/types.h>
15 /*===========================================================================*
17 *===========================================================================*/
18 int fs_lookup(ino_t dir_nr
, char *name
, struct fsdriver_node
*node
,
21 struct puffs_node
*pn
, *pn_dir
;
23 /* Find the pnode of the directory node. */
24 if ((pn_dir
= puffs_pn_nodewalk(global_pu
, find_inode_cb
, &dir_nr
)) == NULL
) {
25 lpuffs_debug("nodewalk failed\n");
29 if (!S_ISDIR(pn_dir
->pn_va
.va_mode
))
32 if ((pn
= advance(pn_dir
, name
)) == NULL
)
35 pn
->pn_count
++; /* open pnode */
37 node
->fn_ino_nr
= pn
->pn_va
.va_fileid
;
38 node
->fn_mode
= pn
->pn_va
.va_mode
;
39 node
->fn_size
= pn
->pn_va
.va_size
;
40 node
->fn_uid
= pn
->pn_va
.va_uid
;
41 node
->fn_gid
= pn
->pn_va
.va_gid
;
42 node
->fn_dev
= pn
->pn_va
.va_rdev
;
44 *is_mountpt
= pn
->pn_mountpoint
;
50 /*===========================================================================*
52 *===========================================================================*/
53 struct puffs_node
*advance(
54 struct puffs_node
*pn_dir
, /* pnode for directory to be searched */
55 char string
[NAME_MAX
+ 1] /* component name to look for */
58 /* Given a directory and a component of a path, look up the component in
59 * the directory, find the pnode, open it, and return a pointer to its pnode
61 * TODO: instead of string, should get pcn.
63 struct puffs_node
*pn
;
65 struct puffs_newinfo pni
;
67 struct puffs_kcn pkcnp
;
68 PUFFS_MAKECRED(pcr
, &global_kcred
);
69 struct puffs_cn pcn
= {&pkcnp
, (struct puffs_cred
*) __UNCONST(pcr
), {0,0,0}};
71 enum vtype node_vtype
;
76 assert(pn_dir
!= NULL
);
80 /* If 'string' is empty, return an error. */
81 if (string
[0] == '\0') {
86 /* If dir has been removed return ENOENT. */
87 if (pn_dir
->pn_va
.va_nlink
== NO_LINK
) {
92 if (strcmp(string
, ".") == 0) {
93 /* Otherwise we will fall into trouble: path for pnode to be looked up
94 * will be parent path (same pnode as the one to be looked up) +
95 * requested path. E.g. after several lookups we might get advance
96 * for "." with parent path "/././././././././.".
97 * FIXME: how is ".." handled then?
99 * Another problem is that after lookup pnode will be added
100 * to the pu_pnodelst, which already contains pnode instance for this
101 * pnode. It will cause lot of troubles.
102 * FIXME: check if this is actually correct, because if it is, we are
103 * in lots of trouble; there are many ways to reach already-open pnodes
108 pni
.pni_cookie
= (void** )&pn
;
109 pni
.pni_vtype
= &node_vtype
;
110 pni
.pni_size
= &size
;
111 pni
.pni_rdev
= &rdev
;
113 pcn
.pcn_namelen
= strlen(string
);
114 assert(pcn
.pcn_namelen
<= MAXPATHLEN
);
115 strcpy(pcn
.pcn_name
, string
);
118 if (puffs_path_pcnbuild(global_pu
, &pcn
, pn_dir
) != 0) {
119 lpuffs_debug("pathbuild error\n");
125 /* lookup *must* be present */
126 error
= global_pu
->pu_ops
.puffs_node_lookup(global_pu
, pn_dir
, &pni
, &pcn
);
130 global_pu
->pu_pathfree(global_pu
, &pcn
.pcn_po_full
);
134 struct puffs_node
*_pn
;
137 * did we get a new node or a
140 _pn
= PU_CMAP(global_pu
, pn
);
141 if (_pn
->pn_po
.po_path
== NULL
)
142 _pn
->pn_po
= pcn
.pcn_po_full
;
144 global_pu
->pu_pathfree(global_pu
, &pcn
.pcn_po_full
);
149 err_code
= error
< 0 ? error
: -error
;