Changes in uspace/lib/libfs/libfs.c [1313ee9:2e983c7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libfs/libfs.c
r1313ee9 r2e983c7 1 1 /* 2 * Copyright (c) 2009 Jakub Jermar 2 * Copyright (c) 2009 Jakub Jermar 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup libfs 29 /** @addtogroup libfs 30 30 * @{ 31 */ 31 */ 32 32 /** 33 33 * @file 34 * Glue code which is common to all FS implementations.34 * Glue code which is commonod to all FS implementations. 35 35 */ 36 36 37 #include "libfs.h" 37 #include "libfs.h" 38 38 #include "../../srv/vfs/vfs.h" 39 39 #include <errno.h> … … 67 67 * code. 68 68 * 69 * @param vfs_phone Open phone for communication with VFS. 70 * @param reg File system registration structure. It will be 71 * initialized by this function. 72 * @param info VFS info structure supplied by the file system 73 * implementation. 74 * @param conn Connection fibril for handling all calls originating in 75 * VFS. 76 * 77 * @return EOK on success or a non-zero error code on errror. 78 * 69 * @param vfs_phone Open phone for communication with VFS. 70 * @param reg File system registration structure. It will be 71 * initialized by this function. 72 * @param info VFS info structure supplied by the file system 73 * implementation. 74 * @param conn Connection fibril for handling all calls originating in 75 * VFS. 76 * 77 * @return EOK on success or a non-zero error code on errror. 79 78 */ 80 79 int fs_register(int vfs_phone, fs_reg_t *reg, vfs_info_t *info, … … 88 87 ipc_call_t answer; 89 88 aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer); 90 89 91 90 /* 92 91 * Send our VFS info structure to VFS. … … 97 96 return rc; 98 97 } 99 98 100 99 /* 101 100 * Ask VFS for callback connection. 102 101 */ 103 102 ipc_connect_to_me(vfs_phone, 0, 0, 0, ®->vfs_phonehash); 104 103 105 104 /* 106 105 * Allocate piece of address space for PLB. … … 111 110 return ENOMEM; 112 111 } 113 112 114 113 /* 115 114 * Request sharing the Path Lookup Buffer with VFS. … … 137 136 */ 138 137 async_set_client_connection(conn); 139 138 140 139 return IPC_GET_RETVAL(answer); 141 140 } … … 155 154 int res; 156 155 ipcarg_t rc; 157 156 158 157 ipc_call_t call; 159 158 ipc_callid_t callid; 160 161 /* Accept the phone */159 160 /* accept the phone */ 162 161 callid = async_get_call(&call); 163 162 int mountee_phone = (int)IPC_GET_ARG1(call); 164 163 if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) || 165 (mountee_phone < 0)) {164 mountee_phone < 0) { 166 165 ipc_answer_0(callid, EINVAL); 167 166 ipc_answer_0(rid, EINVAL); 168 167 return; 169 168 } 170 171 /* Acknowledge the mountee_phone */ 172 ipc_answer_0(callid, EOK); 169 ipc_answer_0(callid, EOK); /* acknowledge the mountee_phone */ 173 170 174 171 res = async_data_write_receive(&callid, NULL); … … 179 176 return; 180 177 } 181 178 182 179 fs_node_t *fn; 183 180 res = ops->node_get(&fn, mp_dev_handle, mp_fs_index); 184 if ( (res != EOK) || (!fn)) {181 if (res != EOK || !fn) { 185 182 ipc_hangup(mountee_phone); 186 183 ipc_answer_0(callid, combine_rc(res, ENOENT)); … … 188 185 return; 189 186 } 190 187 191 188 if (fn->mp_data.mp_active) { 192 189 ipc_hangup(mountee_phone); … … 196 193 return; 197 194 } 198 195 199 196 rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME); 200 197 if (rc != EOK) { … … 218 215 fn->mp_data.phone = mountee_phone; 219 216 } 220 221 217 /* 222 218 * Do not release the FS node so that it stays in memory. … … 242 238 ipc_call_t *request) 243 239 { 244 unsigned intfirst = IPC_GET_ARG1(*request);245 unsigned intlast = IPC_GET_ARG2(*request);246 unsigned intnext = first;240 unsigned first = IPC_GET_ARG1(*request); 241 unsigned last = IPC_GET_ARG2(*request); 242 unsigned next = first; 247 243 dev_handle_t dev_handle = IPC_GET_ARG3(*request); 248 244 int lflag = IPC_GET_ARG4(*request); 249 fs_index_t index = IPC_GET_ARG5(*request); 245 fs_index_t index = IPC_GET_ARG5(*request); /* when L_LINK specified */ 250 246 char component[NAME_MAX + 1]; 251 247 int len; 252 248 int rc; 253 249 254 250 if (last < next) 255 251 last += PLB_SIZE; 256 252 257 253 fs_node_t *par = NULL; 258 254 fs_node_t *cur = NULL; 259 255 fs_node_t *tmp = NULL; 260 256 261 257 rc = ops->root_get(&cur, dev_handle); 262 258 on_error(rc, goto out_with_answer); 263 259 264 260 if (cur->mp_data.mp_active) { 265 261 ipc_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP, … … 269 265 return; 270 266 } 271 272 /* Eat slash */ 267 273 268 if (ops->plb_get_char(next) == '/') 274 next++; 269 next++; /* eat slash */ 275 270 276 271 while (next <= last) { 277 272 bool has_children; 278 273 279 274 rc = ops->has_children(&has_children, cur); 280 275 on_error(rc, goto out_with_answer); 281 276 if (!has_children) 282 277 break; 283 284 /* Collect the component */278 279 /* collect the component */ 285 280 len = 0; 286 while ((next <= last) && (ops->plb_get_char(next) != '/')) {281 while ((next <= last) && (ops->plb_get_char(next) != '/')) { 287 282 if (len + 1 == NAME_MAX) { 288 /* Component length overflow */283 /* component length overflow */ 289 284 ipc_answer_0(rid, ENAMETOOLONG); 290 285 goto out; 291 286 } 292 287 component[len++] = ops->plb_get_char(next); 293 /* Process next character */ 294 next++; 288 next++; /* process next character */ 295 289 } 296 290 297 291 assert(len); 298 292 component[len] = '\0'; 299 /* Eat slash */ 300 next++; 301 302 /* Match the component */ 293 next++; /* eat slash */ 294 295 /* match the component */ 303 296 rc = ops->match(&tmp, cur, component); 304 297 on_error(rc, goto out_with_answer); 305 306 if ( (tmp) && (tmp->mp_data.mp_active)) {298 299 if (tmp && tmp->mp_data.mp_active) { 307 300 if (next > last) 308 301 next = last = first; 309 302 else 310 303 next--; 311 304 312 305 ipc_forward_slow(rid, tmp->mp_data.phone, 313 306 VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle, … … 319 312 return; 320 313 } 321 322 /* Handle miss: match amongst siblings */314 315 /* handle miss: match amongst siblings */ 323 316 if (!tmp) { 324 317 if (next <= last) { 325 /* There are unprocessed components */318 /* there are unprocessed components */ 326 319 ipc_answer_0(rid, ENOENT); 327 320 goto out; 328 321 } 329 330 /* Miss in the last component */ 331 if (lflag & (L_CREATE | L_LINK)) { 332 /* Request to create a new link */ 322 /* miss in the last component */ 323 if (lflag & (L_CREATE | L_LINK)) { 324 /* request to create a new link */ 333 325 if (!ops->is_directory(cur)) { 334 326 ipc_answer_0(rid, ENOTDIR); 335 327 goto out; 336 328 } 337 338 329 fs_node_t *fn; 339 330 if (lflag & L_CREATE) … … 344 335 index); 345 336 on_error(rc, goto out_with_answer); 346 347 337 if (fn) { 348 338 rc = ops->link(cur, fn, component); … … 359 349 (void) ops->node_put(fn); 360 350 } 361 } else 351 } else { 362 352 ipc_answer_0(rid, ENOSPC); 363 353 } 364 354 goto out; 365 } 366 355 } 367 356 ipc_answer_0(rid, ENOENT); 368 357 goto out; 369 358 } 370 359 371 360 if (par) { 372 361 rc = ops->node_put(par); 373 362 on_error(rc, goto out_with_answer); 374 363 } 375 376 /* Descend one level */364 365 /* descend one level */ 377 366 par = cur; 378 367 cur = tmp; 379 368 tmp = NULL; 380 369 } 381 382 /* Handle miss: excessive components */370 371 /* handle miss: excessive components */ 383 372 if (next <= last) { 384 373 bool has_children; 374 385 375 rc = ops->has_children(&has_children, cur); 386 376 on_error(rc, goto out_with_answer); 387 388 377 if (has_children) 389 378 goto skip_miss; 390 379 391 380 if (lflag & (L_CREATE | L_LINK)) { 392 381 if (!ops->is_directory(cur)) { … … 394 383 goto out; 395 384 } 396 397 /* Collect next component */385 386 /* collect next component */ 398 387 len = 0; 399 388 while (next <= last) { 400 389 if (ops->plb_get_char(next) == '/') { 401 /* More than one component */390 /* more than one component */ 402 391 ipc_answer_0(rid, ENOENT); 403 392 goto out; 404 393 } 405 406 394 if (len + 1 == NAME_MAX) { 407 /* Component length overflow */395 /* component length overflow */ 408 396 ipc_answer_0(rid, ENAMETOOLONG); 409 397 goto out; 410 398 } 411 412 399 component[len++] = ops->plb_get_char(next); 413 /* Process next character */ 414 next++; 400 next++; /* process next character */ 415 401 } 416 417 402 assert(len); 418 403 component[len] = '\0'; 419 404 420 405 fs_node_t *fn; 421 406 if (lflag & L_CREATE) … … 424 409 rc = ops->node_get(&fn, dev_handle, index); 425 410 on_error(rc, goto out_with_answer); 426 427 411 if (fn) { 428 412 rc = ops->link(cur, fn, component); … … 439 423 (void) ops->node_put(fn); 440 424 } 441 } else 425 } else { 442 426 ipc_answer_0(rid, ENOSPC); 443 427 } 444 428 goto out; 445 429 } 446 447 430 ipc_answer_0(rid, ENOENT); 448 431 goto out; 449 432 } 450 451 433 skip_miss: 452 453 /* Handle hit */434 435 /* handle hit */ 454 436 if (lflag & L_UNLINK) { 455 unsigned intold_lnkcnt = ops->lnkcnt_get(cur);437 unsigned old_lnkcnt = ops->lnkcnt_get(cur); 456 438 rc = ops->unlink(par, cur, component); 457 ipc_answer_5(rid, (ipcarg_t) 439 ipc_answer_5(rid, (ipcarg_t)rc, fs_handle, dev_handle, 458 440 ops->index_get(cur), ops->size_get(cur), old_lnkcnt); 459 441 goto out; 460 442 } 461 462 443 if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) || 463 444 (lflag & L_LINK)) { … … 465 446 goto out; 466 447 } 467 468 448 if ((lflag & L_FILE) && (ops->is_directory(cur))) { 469 449 ipc_answer_0(rid, EISDIR); 470 450 goto out; 471 451 } 472 473 452 if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) { 474 453 ipc_answer_0(rid, ENOTDIR); 475 454 goto out; 476 455 } 477 456 478 457 out_with_answer: 479 480 458 if (rc == EOK) { 481 if (lflag & L_OPEN) 482 rc = ops->node_open(cur); 483 484 ipc_answer_5(rid, rc, fs_handle, dev_handle, 459 ipc_answer_5(rid, EOK, fs_handle, dev_handle, 485 460 ops->index_get(cur), ops->size_get(cur), 486 461 ops->lnkcnt_get(cur)); 487 } else 462 } else { 488 463 ipc_answer_0(rid, rc); 489 464 } 465 490 466 out: 491 492 467 if (par) 493 468 (void) ops->node_put(par); 494 495 469 if (cur) 496 470 (void) ops->node_put(cur); 497 498 471 if (tmp) 499 472 (void) ops->node_put(tmp); … … 505 478 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 506 479 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 507 508 480 fs_node_t *fn; 509 int rc = ops->node_get(&fn, dev_handle, index); 481 int rc; 482 483 rc = ops->node_get(&fn, dev_handle, index); 510 484 on_error(rc, answer_and_return(rid, rc)); 511 485 512 486 ipc_callid_t callid; 513 487 size_t size; 514 if ((!async_data_read_receive(&callid, &size)) || 515 (size != sizeof(struct stat))) { 516 ops->node_put(fn); 488 if (!async_data_read_receive(&callid, &size) || 489 size != sizeof(struct stat)) { 517 490 ipc_answer_0(callid, EINVAL); 518 491 ipc_answer_0(rid, EINVAL); 519 492 return; 520 493 } 521 494 522 495 struct stat stat; 523 496 memset(&stat, 0, sizeof(struct stat)); … … 526 499 stat.dev_handle = dev_handle; 527 500 stat.index = index; 528 stat.lnkcnt = ops->lnkcnt_get(fn); 501 stat.lnkcnt = ops->lnkcnt_get(fn); 529 502 stat.is_file = ops->is_file(fn); 530 stat.is_directory = ops->is_directory(fn);531 503 stat.size = ops->size_get(fn); 532 stat.device = ops->device_get(fn); 533 534 ops->node_put(fn); 535 504 536 505 async_data_read_finalize(callid, &stat, sizeof(struct stat)); 537 506 ipc_answer_0(rid, EOK); … … 540 509 /** Open VFS triplet. 541 510 * 542 * @param ops libfs operations structure with function pointers to543 * file system implementation544 * @param rid Request ID of the VFS_OUT_OPEN_NODE request.545 * @param request VFS_OUT_OPEN_NODE request data itself.511 * @param ops libfs operations structure with function pointers to 512 * file system implementation 513 * @param rid Request ID of the VFS_OUT_OPEN_NODE request. 514 * @param request VFS_OUT_OPEN_NODE request data itself. 546 515 * 547 516 */ … … 562 531 } 563 532 564 rc = ops->node_open(fn); 565 ipc_answer_3(rid, rc, ops->size_get(fn), ops->lnkcnt_get(fn), 533 ipc_answer_3(rid, EOK, ops->size_get(fn), ops->lnkcnt_get(fn), 566 534 (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0)); 567 535
Note:
See TracChangeset
for help on using the changeset viewer.