source: mainline/uspace/srv/vfs/vfs_lookup.c@ 24d6efc

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

Split the 'mount another filesystem here' and 'you are being mounted and the
device is this' mount semantics. Add VFS_MOUNTED VFS operation that corresponds
to the latter and reserve VFS_MOUNT only for the former. Because of this
change, the VFS server does not maintain the mr_node VFS node for the name space
root anymore and the VFS_LOOKUP operation is now not meant to be used on
unmounted file system, not even for looking up the root node of unmounted file
systems. In the light of these changes, TMPFS is now initialized from
tmpfs_mounted() function.

  • Property mode set to 100644
File size: 4.9 KB
Line 
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 "vfs.h"
39#include <ipc/ipc.h>
40#include <async.h>
41#include <errno.h>
42#include <string.h>
43#include <stdarg.h>
44#include <bool.h>
45#include <futex.h>
46#include <libadt/list.h>
47#include <vfs/canonify.h>
48
49#define min(a, b) ((a) < (b) ? (a) : (b))
50
51futex_t plb_futex = FUTEX_INITIALIZER;
52link_t plb_head; /**< PLB entry ring buffer. */
53uint8_t *plb = NULL;
54
55/** Perform a path lookup.
56 *
57 * @param path Path to be resolved; it must be a NULL-terminated
58 * string.
59 * @param lflag Flags to be used during lookup.
60 * @param result Empty structure where the lookup result will be stored.
61 * Can be NULL.
62 * @param altroot If non-empty, will be used instead of rootfs as the root
63 * of the whole VFS tree.
64 *
65 * @return EOK on success or an error code from errno.h.
66 */
67int vfs_lookup_internal(char *path, int lflag, vfs_lookup_res_t *result,
68 vfs_pair_t *altroot, ...)
69{
70 vfs_pair_t *root;
71
72 if (altroot)
73 root = altroot;
74 else
75 root = &rootfs;
76
77 if (!root->fs_handle)
78 return ENOENT;
79
80 size_t len;
81 path = canonify(path, &len);
82 if (!path)
83 return EINVAL;
84
85 fs_index_t index = 0;
86 if (lflag & L_LINK) {
87 va_list ap;
88
89 va_start(ap, altroot);
90 index = va_arg(ap, fs_index_t);
91 va_end(ap);
92 }
93
94 futex_down(&plb_futex);
95
96 plb_entry_t entry;
97 link_initialize(&entry.plb_link);
98 entry.len = len;
99
100 off_t first; /* the first free index */
101 off_t last; /* the last free index */
102
103 if (list_empty(&plb_head)) {
104 first = 0;
105 last = PLB_SIZE - 1;
106 } else {
107 plb_entry_t *oldest = list_get_instance(plb_head.next,
108 plb_entry_t, plb_link);
109 plb_entry_t *newest = list_get_instance(plb_head.prev,
110 plb_entry_t, plb_link);
111
112 first = (newest->index + newest->len) % PLB_SIZE;
113 last = (oldest->index - 1) % PLB_SIZE;
114 }
115
116 if (first <= last) {
117 if ((last - first) + 1 < len) {
118 /*
119 * The buffer cannot absorb the path.
120 */
121 futex_up(&plb_futex);
122 return ELIMIT;
123 }
124 } else {
125 if (PLB_SIZE - ((first - last) + 1) < len) {
126 /*
127 * The buffer cannot absorb the path.
128 */
129 futex_up(&plb_futex);
130 return ELIMIT;
131 }
132 }
133
134 /*
135 * We know the first free index in PLB and we also know that there is
136 * enough space in the buffer to hold our path.
137 */
138
139 entry.index = first;
140 entry.len = len;
141
142 /*
143 * Claim PLB space by inserting the entry into the PLB entry ring
144 * buffer.
145 */
146 list_append(&entry.plb_link, &plb_head);
147
148 futex_up(&plb_futex);
149
150 /*
151 * Copy the path into PLB.
152 */
153 size_t cnt1 = min(len, (PLB_SIZE - first) + 1);
154 size_t cnt2 = len - cnt1;
155
156 memcpy(&plb[first], path, cnt1);
157 memcpy(plb, &path[cnt1], cnt2);
158
159 ipc_call_t answer;
160 int phone = vfs_grab_phone(root->fs_handle);
161 aid_t req = async_send_5(phone, VFS_LOOKUP, (ipcarg_t) first,
162 (ipcarg_t) (first + len - 1) % PLB_SIZE,
163 (ipcarg_t) root->dev_handle, (ipcarg_t) lflag, (ipcarg_t) index,
164 &answer);
165 vfs_release_phone(phone);
166
167 ipcarg_t rc;
168 async_wait_for(req, &rc);
169
170 futex_down(&plb_futex);
171 list_remove(&entry.plb_link);
172 /*
173 * Erasing the path from PLB will come handy for debugging purposes.
174 */
175 memset(&plb[first], 0, cnt1);
176 memset(plb, 0, cnt2);
177 futex_up(&plb_futex);
178
179 if ((rc == EOK) && result) {
180 result->triplet.fs_handle = (fs_handle_t) IPC_GET_ARG1(answer);
181 result->triplet.dev_handle = (dev_handle_t) IPC_GET_ARG2(answer);
182 result->triplet.index = (fs_index_t) IPC_GET_ARG3(answer);
183 result->size = (size_t) IPC_GET_ARG4(answer);
184 result->lnkcnt = (unsigned) IPC_GET_ARG5(answer);
185 }
186
187 return rc;
188}
189
190/**
191 * @}
192 */
Note: See TracBrowser for help on using the repository browser.