Changeset 5bcd5b7 in mainline for uspace/srv/vfs/vfs_lookup.c
- Timestamp:
- 2013-07-29T14:36:57Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4636a60
- Parents:
- 677745a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_lookup.c
r677745a r5bcd5b7 153 153 } 154 154 155 int vfs_link_internal(vfs_ triplet_t *base, char *path, vfs_triplet_t *child)155 int vfs_link_internal(vfs_node_t *base, char *path, vfs_triplet_t *child) 156 156 { 157 157 assert(base != NULL); … … 173 173 path = npath; 174 174 175 vfs_triplet_t *triplet; 176 175 177 char *slash = _strrchr(path, '/'); 176 178 if (slash && slash != path) { … … 187 189 goto out; 188 190 } 189 base= &res.triplet;191 triplet = &res.triplet; 190 192 191 193 *slash = '/'; 192 194 } else { 195 if (base->mount != NULL) { 196 rc = EINVAL; 197 goto out; 198 } 199 193 200 memcpy(component, path + 1, str_size(path)); 194 } 195 196 if (base->fs_handle != child->fs_handle || base->service_id != child->service_id) { 201 triplet = (vfs_triplet_t *) base; 202 } 203 204 if (triplet->fs_handle != child->fs_handle || triplet->service_id != child->service_id) { 197 205 rc = EXDEV; 198 206 goto out; 199 207 } 200 208 201 async_exch_t *exch = vfs_exchange_grab( base->fs_handle);202 aid_t req = async_send_3(exch, VFS_OUT_LINK, base->service_id, base->index, child->index, NULL);209 async_exch_t *exch = vfs_exchange_grab(triplet->fs_handle); 210 aid_t req = async_send_3(exch, VFS_OUT_LINK, triplet->service_id, triplet->index, child->index, NULL); 203 211 204 212 rc = async_data_write_start(exch, component, str_size(component) + 1); … … 215 223 } 216 224 225 static int out_lookup(vfs_triplet_t *base, unsigned *pfirst, unsigned *plen, 226 int lflag, vfs_lookup_res_t *result) 227 { 228 assert(base); 229 assert(result); 230 231 sysarg_t rc; 232 ipc_call_t answer; 233 async_exch_t *exch = vfs_exchange_grab(base->fs_handle); 234 aid_t req = async_send_5(exch, VFS_OUT_LOOKUP, (sysarg_t) *pfirst, (sysarg_t) *plen, 235 (sysarg_t) base->service_id, (sysarg_t) base->index, (sysarg_t) lflag, &answer); 236 async_wait_for(req, &rc); 237 vfs_exchange_release(exch); 238 239 if ((int) rc < 0) { 240 return (int) rc; 241 } 242 243 unsigned last = *pfirst + *plen; 244 *pfirst = IPC_GET_ARG3(answer); 245 *plen = last - *pfirst; 246 247 result->triplet.fs_handle = (fs_handle_t) rc; 248 result->triplet.service_id = (service_id_t) IPC_GET_ARG1(answer); 249 result->triplet.index = (fs_index_t) IPC_GET_ARG2(answer); 250 result->size = (int64_t)(int32_t) IPC_GET_ARG4(answer); 251 result->type = IPC_GET_ARG5(answer); 252 return EOK; 253 } 254 217 255 /** Perform a path lookup. 218 256 * … … 227 265 * 228 266 */ 229 int vfs_lookup_internal(vfs_ triplet_t *base, char *path, int lflag, vfs_lookup_res_t *result)267 int vfs_lookup_internal(vfs_node_t *base, char *path, int lflag, vfs_lookup_res_t *result) 230 268 { 231 269 assert(base != NULL); 232 270 assert(path != NULL); 233 271 234 sysarg_t rc;235 236 if (!base->fs_handle) {237 rc = ENOENT;238 goto out;239 }240 241 272 size_t len; 273 int rc; 242 274 char *npath = canonify(path, &len); 243 275 if (!npath) { 276 DPRINTF("vfs_lookup_internal() can't canonify path: %s\n", path); 244 277 rc = EINVAL; 245 goto out;278 return rc; 246 279 } 247 280 path = npath; … … 254 287 rc = plb_insert_entry(&entry, path, &first, len); 255 288 if (rc != EOK) { 256 goto out; 257 } 258 259 ipc_call_t answer; 260 async_exch_t *exch = vfs_exchange_grab(base->fs_handle); 261 aid_t req = async_send_5(exch, VFS_OUT_LOOKUP, (sysarg_t) first, (sysarg_t) len, 262 (sysarg_t) base->service_id, (sysarg_t) base->index, (sysarg_t) lflag, &answer); 263 async_wait_for(req, &rc); 264 vfs_exchange_release(exch); 265 289 DPRINTF("vfs_lookup_internal() can't insert entry into PLB: %d\n", rc); 290 return rc; 291 } 292 293 size_t next = first; 294 size_t nlen = len; 295 296 vfs_lookup_res_t res; 297 298 /* Resolve path as long as there are mount points to cross. */ 299 while (nlen > 0) { 300 while (base->mount != NULL) { 301 if (lflag & L_DISABLE_MOUNTS) { 302 rc = EXDEV; 303 goto out; 304 } 305 306 base = base->mount; 307 } 308 309 rc = out_lookup((vfs_triplet_t *) base, &next, &nlen, lflag, &res); 310 if (rc != EOK) { 311 goto out; 312 } 313 314 if (nlen > 0) { 315 base = vfs_node_peek(&res); 316 if (base == NULL || base->mount == NULL) { 317 rc = ENOENT; 318 goto out; 319 } 320 if (lflag & L_DISABLE_MOUNTS) { 321 rc = EXDEV; 322 goto out; 323 } 324 } 325 } 326 327 assert(nlen == 0); 328 rc = EOK; 329 330 if (result != NULL) { 331 /* The found file may be a mount point. Try to cross it. */ 332 if (!(lflag & L_MP)) { 333 base = vfs_node_peek(&res); 334 if (base != NULL && base->mount != NULL) { 335 while (base->mount != NULL) { 336 base = base->mount; 337 } 338 339 result->triplet = *(vfs_triplet_t *)base; 340 result->type = base->type; 341 result->size = base->size; 342 goto out; 343 } 344 } 345 346 __builtin_memcpy(result, &res, sizeof(vfs_lookup_res_t)); 347 } 348 349 out: 266 350 plb_clear_entry(&entry, first, len); 267 268 if ((int) rc < 0) {269 goto out;270 }271 272 unsigned last = IPC_GET_ARG3(answer);273 if (last != first + len) {274 /* The path wasn't processed entirely. */275 rc = ENOENT;276 goto out;277 }278 279 if (!result) {280 rc = EOK;281 goto out;282 }283 284 result->triplet.fs_handle = (fs_handle_t) rc;285 result->triplet.service_id = (service_id_t) IPC_GET_ARG1(answer);286 result->triplet.index = (fs_index_t) IPC_GET_ARG2(answer);287 result->size = (int64_t)(int32_t) IPC_GET_ARG4(answer);288 result->type = IPC_GET_ARG5(answer);289 rc = EOK;290 291 out:292 351 DPRINTF("vfs_lookup_internal() with path '%s' returns %d\n", path, rc); 293 352 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.