source: mainline/uspace/srv/vfs/vfs_lookup.c@ 1fe186f

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1fe186f was ae78b530, checked in by Jakub Jermar <jakub@…>, 18 years ago

Introduce the notion of lflag (i.e. lookup flags) to support the ability to
limit the scope of VFS node types that can be opened by open() and opendir(). In
the future, lflag will also specify actions for VFS_LOOKUP handlers that will be
carried out in situations such as the VFS node is not found (e.g. implementation
of mkdir() and open() with O_CREAT in oflag).

  • Property mode set to 100644
File size: 4.6 KB
RevLine 
[62da45a]1/*
2 * Copyright (c) 2008 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup fs
30 * @{
31 */
32
33/**
34 * @file vfs_lookup.c
35 * @brief
36 */
37
38#include <ipc/ipc.h>
39#include <async.h>
40#include <errno.h>
41#include <string.h>
42#include <bool.h>
43#include <futex.h>
44#include <libadt/list.h>
45#include <atomic.h>
46#include "vfs.h"
47
48#define min(a, b) ((a) < (b) ? (a) : (b))
49
50atomic_t plb_futex = FUTEX_INITIALIZER;
51link_t plb_head; /**< PLB entry ring buffer. */
52uint8_t *plb = NULL;
53
54/** Perform a path lookup.
55 *
56 * @param path Path to be resolved; it needn't be an ASCIIZ string.
57 * @param len Number of path characters pointed by path.
[ae78b530]58 * @param lflag Flags to be used during lookup.
[62da45a]59 * @param result Empty structure where the lookup result will be stored.
60 * @param altroot If non-empty, will be used instead of rootfs as the root
61 * of the whole VFS tree.
62 *
63 * @return EOK on success or an error code from errno.h.
64 */
[ae78b530]65int vfs_lookup_internal(char *path, size_t len, int lflag,
66 vfs_lookup_res_t *result, vfs_pair_t *altroot)
[62da45a]67{
68 vfs_pair_t *root;
69
70 if (!len)
71 return EINVAL;
72
73 if (altroot)
74 root = altroot;
75 else
76 root = (vfs_pair_t *) &rootfs;
77
78 if (!root->fs_handle)
79 return ENOENT;
80
81 futex_down(&plb_futex);
82
83 plb_entry_t entry;
84 link_initialize(&entry.plb_link);
85 entry.len = len;
86
87 off_t first; /* the first free index */
88 off_t last; /* the last free index */
89
90 if (list_empty(&plb_head)) {
91 first = 0;
92 last = PLB_SIZE - 1;
93 } else {
94 plb_entry_t *oldest = list_get_instance(plb_head.next,
95 plb_entry_t, plb_link);
96 plb_entry_t *newest = list_get_instance(plb_head.prev,
97 plb_entry_t, plb_link);
98
99 first = (newest->index + newest->len) % PLB_SIZE;
100 last = (oldest->index - 1) % PLB_SIZE;
101 }
102
103 if (first <= last) {
104 if ((last - first) + 1 < len) {
105 /*
106 * The buffer cannot absorb the path.
107 */
108 futex_up(&plb_futex);
109 return ELIMIT;
110 }
111 } else {
112 if (PLB_SIZE - ((first - last) + 1) < len) {
113 /*
114 * The buffer cannot absorb the path.
115 */
116 futex_up(&plb_futex);
117 return ELIMIT;
118 }
119 }
120
121 /*
122 * We know the first free index in PLB and we also know that there is
123 * enough space in the buffer to hold our path.
124 */
125
126 entry.index = first;
127 entry.len = len;
128
129 /*
130 * Claim PLB space by inserting the entry into the PLB entry ring
131 * buffer.
132 */
133 list_append(&entry.plb_link, &plb_head);
134
135 futex_up(&plb_futex);
136
137 /*
138 * Copy the path into PLB.
139 */
140 size_t cnt1 = min(len, (PLB_SIZE - first) + 1);
141 size_t cnt2 = len - cnt1;
142
143 memcpy(&plb[first], path, cnt1);
144 memcpy(plb, &path[cnt1], cnt2);
145
146 ipc_call_t answer;
147 int phone = vfs_grab_phone(root->fs_handle);
[ae78b530]148 aid_t req = async_send_4(phone, VFS_LOOKUP, (ipcarg_t) first,
[62da45a]149 (ipcarg_t) (first + len - 1) % PLB_SIZE,
[ae78b530]150 (ipcarg_t) root->dev_handle, (ipcarg_t) lflag, &answer);
[62da45a]151 vfs_release_phone(phone);
152
153 ipcarg_t rc;
154 async_wait_for(req, &rc);
155
156 futex_down(&plb_futex);
157 list_remove(&entry.plb_link);
158 /*
159 * Erasing the path from PLB will come handy for debugging purposes.
160 */
161 memset(&plb[first], 0, cnt1);
162 memset(plb, 0, cnt2);
163 futex_up(&plb_futex);
164
165 if (rc == EOK) {
166 result->triplet.fs_handle = (int) IPC_GET_ARG1(answer);
167 result->triplet.dev_handle = (int) IPC_GET_ARG2(answer);
168 result->triplet.index = (int) IPC_GET_ARG3(answer);
169 result->size = (size_t) IPC_GET_ARG4(answer);
170 }
171
172 return rc;
173}
174
175/**
176 * @}
177 */
Note: See TracBrowser for help on using the repository browser.