Changes in / [e095644:fea0ce6] in mainline
- Location:
- uspace
- Files:
-
- 4 deleted
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/Makefile
re095644 rfea0ce6 48 48 cmds/modules/mv/mv.c \ 49 49 cmds/modules/mount/mount.c \ 50 cmds/modules/unmount/unmount.c \51 50 cmds/modules/kcon/kcon.c \ 52 51 cmds/builtins/exit/exit.c \ -
uspace/app/bdsh/cmds/modules/module_aliases.h
re095644 rfea0ce6 14 14 char *mod_aliases[] = { 15 15 "ren", "mv", 16 "umount", "unmount",17 16 NULL, NULL 18 17 }; -
uspace/app/bdsh/cmds/modules/modules.h
re095644 rfea0ce6 31 31 #include "mv/entry.h" 32 32 #include "mount/entry.h" 33 #include "unmount/entry.h"34 33 #include "kcon/entry.h" 35 34 … … 52 51 #include "mv/mv_def.h" 53 52 #include "mount/mount_def.h" 54 #include "unmount/unmount_def.h"55 53 #include "kcon/kcon_def.h" 56 54 -
uspace/lib/libc/generic/adt/hash_table.c
re095644 rfea0ce6 193 193 } 194 194 195 /** Apply fucntion to all items in hash table.196 *197 * @param h Hash table.198 * @param f Function to be applied.199 * @param arg Argument to be passed to the function.200 */201 void202 hash_table_apply(hash_table_t *h, void (*f)(link_t *, void *), void *arg)203 {204 hash_index_t bucket;205 link_t *cur;206 207 for (bucket = 0; bucket < h->entries; bucket++) {208 for (cur = h->entry[bucket].next; cur != &h->entry[bucket];209 cur = cur->next) {210 f(cur, arg);211 }212 }213 }214 215 195 /** @} 216 196 */ -
uspace/lib/libc/generic/vfs/vfs.c
re095644 rfea0ce6 197 197 } 198 198 199 int unmount(const char *mp)200 {201 ipcarg_t rc;202 ipcarg_t rc_orig;203 aid_t req;204 size_t mpa_size;205 char *mpa;206 207 mpa = absolutize(mp, &mpa_size);208 if (!mpa)209 return ENOMEM;210 211 futex_down(&vfs_phone_futex);212 async_serialize_start();213 vfs_connect();214 215 req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);216 rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);217 if (rc != EOK) {218 async_wait_for(req, &rc_orig);219 async_serialize_end();220 futex_up(&vfs_phone_futex);221 free(mpa);222 if (rc_orig == EOK)223 return (int) rc;224 else225 return (int) rc_orig;226 }227 228 229 async_wait_for(req, &rc);230 async_serialize_end();231 futex_up(&vfs_phone_futex);232 free(mpa);233 234 return (int) rc;235 }236 237 199 static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag) 238 200 { -
uspace/lib/libc/include/adt/hash_table.h
re095644 rfea0ce6 88 88 extern void hash_table_remove(hash_table_t *, unsigned long [], hash_count_t); 89 89 extern void hash_table_destroy(hash_table_t *); 90 extern void hash_table_apply(hash_table_t *, void (*)(link_t *, void *),91 void *);92 90 93 91 #endif -
uspace/lib/libc/include/ipc/vfs.h
re095644 rfea0ce6 86 86 VFS_OUT_MOUNTED, 87 87 VFS_OUT_UNMOUNT, 88 VFS_OUT_UNMOUNTED,89 88 VFS_OUT_SYNC, 90 89 VFS_OUT_STAT, … … 141 140 142 141 /** 143 * L_OPEN is used to indicate that the lookup operation is a part of VFS_ IN_OPEN142 * L_OPEN is used to indicate that the lookup operation is a part of VFS_OPEN 144 143 * call from the client. This means that the server might allocate some 145 144 * resources for the opened file. This flag cannot be passed directly by the … … 148 147 #define L_OPEN 64 149 148 150 /**151 * L_NOCROSS_LAST_MP is used exclusively during the VFS_IN_UNMOUNT operation. It152 * tells the lookup routine not to cross the last mount point in the lookup153 * path.154 */155 #define L_NOCROSS_LAST_MP 128156 157 149 #endif 158 150 -
uspace/lib/libc/include/vfs/vfs.h
re095644 rfea0ce6 55 55 extern int mount(const char *, const char *, const char *, const char *, 56 56 unsigned int); 57 extern int unmount(const char *);58 57 59 58 extern void __stdio_init(int filc, fdi_node_t *filv[]); -
uspace/lib/libfs/libfs.c
re095644 rfea0ce6 304 304 on_error(rc, goto out_with_answer); 305 305 306 /* 307 * If the matching component is a mount point, there are two 308 * legitimate semantics of the lookup operation. The first is 309 * the commonly used one in which the lookup crosses each mount 310 * point into the mounted file system. The second semantics is 311 * used mostly during unmount() and differs from the first one 312 * only in that the last mount point in the looked up path, 313 * which is also its last component, is not crossed. 314 */ 315 316 if ((tmp) && (tmp->mp_data.mp_active) && 317 (!(lflag & L_NOCROSS_LAST_MP) || (next <= last))) { 306 if ((tmp) && (tmp->mp_data.mp_active)) { 318 307 if (next > last) 319 308 next = last = first; -
uspace/srv/vfs/vfs.c
re095644 rfea0ce6 86 86 case VFS_IN_MOUNT: 87 87 vfs_mount(callid, &call); 88 break;89 case VFS_IN_UNMOUNT:90 vfs_unmount(callid, &call);91 88 break; 92 89 case VFS_IN_OPEN: -
uspace/srv/vfs/vfs.h
re095644 rfea0ce6 181 181 extern vfs_node_t *vfs_node_get(vfs_lookup_res_t *); 182 182 extern void vfs_node_put(vfs_node_t *); 183 extern void vfs_node_forget(vfs_node_t *);184 extern unsigned vfs_nodes_refcount_sum_get(fs_handle_t, dev_handle_t);185 186 183 187 184 #define MAX_OPEN_FILES 128 … … 201 198 extern void vfs_register(ipc_callid_t, ipc_call_t *); 202 199 extern void vfs_mount(ipc_callid_t, ipc_call_t *); 203 extern void vfs_unmount(ipc_callid_t, ipc_call_t *);204 200 extern void vfs_open(ipc_callid_t, ipc_call_t *); 205 201 extern void vfs_open_node(ipc_callid_t, ipc_call_t *); -
uspace/srv/vfs/vfs_node.c
re095644 rfea0ce6 137 137 if (free_vfs_node) 138 138 free(node); 139 }140 141 /** Forget node.142 *143 * This function will remove the node from the node hash table and deallocate144 * its memory, regardless of the node's reference count.145 *146 * @param node Node to be forgotten.147 */148 void vfs_node_forget(vfs_node_t *node)149 {150 fibril_mutex_lock(&nodes_mutex);151 unsigned long key[] = {152 [KEY_FS_HANDLE] = node->fs_handle,153 [KEY_DEV_HANDLE] = node->dev_handle,154 [KEY_INDEX] = node->index155 };156 hash_table_remove(&nodes, key, 3);157 fibril_mutex_unlock(&nodes_mutex);158 free(node);159 139 } 160 140 … … 251 231 } 252 232 253 struct refcnt_data {254 /** Sum of all reference counts for this file system instance. */255 unsigned refcnt;256 fs_handle_t fs_handle;257 dev_handle_t dev_handle;258 };259 260 static void refcnt_visitor(link_t *item, void *arg)261 {262 vfs_node_t *node = hash_table_get_instance(item, vfs_node_t, nh_link);263 struct refcnt_data *rd = (void *) arg;264 265 if ((node->fs_handle == rd->fs_handle) &&266 (node->dev_handle == rd->dev_handle))267 rd->refcnt += node->refcnt;268 }269 270 unsigned271 vfs_nodes_refcount_sum_get(fs_handle_t fs_handle, dev_handle_t dev_handle)272 {273 struct refcnt_data rd = {274 .refcnt = 0,275 .fs_handle = fs_handle,276 .dev_handle = dev_handle277 };278 279 fibril_mutex_lock(&nodes_mutex);280 hash_table_apply(&nodes, refcnt_visitor, &rd);281 fibril_mutex_unlock(&nodes_mutex);282 283 return rd.refcnt;284 }285 286 233 /** 287 234 * @} -
uspace/srv/vfs/vfs_ops.c
re095644 rfea0ce6 429 429 } 430 430 431 void vfs_unmount(ipc_callid_t rid, ipc_call_t *request)432 {433 int rc;434 char *mp;435 vfs_lookup_res_t mp_res;436 vfs_lookup_res_t mr_res;437 vfs_node_t *mp_node;438 vfs_node_t *mr_node;439 int phone;440 441 /*442 * Receive the mount point path.443 */444 rc = async_data_string_receive(&mp, MAX_PATH_LEN);445 if (rc != EOK)446 ipc_answer_0(rid, rc);447 448 /*449 * Taking the namespace lock will do two things for us. First, it will450 * prevent races with other lookup operations. Second, it will stop new451 * references to already existing VFS nodes and creation of new VFS452 * nodes. This is because new references are added as a result of some453 * lookup operation or at least of some operation which is protected by454 * the namespace lock.455 */456 fibril_rwlock_write_lock(&namespace_rwlock);457 458 /*459 * Lookup the mounted root and instantiate it.460 */461 rc = vfs_lookup_internal(mp, L_NONE, &mr_res, NULL);462 if (rc != EOK) {463 fibril_rwlock_write_unlock(&namespace_rwlock);464 free(mp);465 ipc_answer_0(rid, rc);466 return;467 }468 mr_node = vfs_node_get(&mr_res);469 if (!mr_node) {470 fibril_rwlock_write_unlock(&namespace_rwlock);471 free(mp);472 ipc_answer_0(rid, ENOMEM);473 return;474 }475 476 /*477 * Count the total number of references for the mounted file system. We478 * are expecting at least two. One which we got above and one which we479 * got when the file system was mounted. If we find more, it means that480 * the file system cannot be gracefully unmounted at the moment because481 * someone is working with it.482 */483 if (vfs_nodes_refcount_sum_get(mr_node->fs_handle,484 mr_node->dev_handle) != 2) {485 fibril_rwlock_write_unlock(&namespace_rwlock);486 vfs_node_put(mr_node);487 free(mp);488 ipc_answer_0(rid, EBUSY);489 return;490 }491 492 if (str_cmp(mp, "/") == 0) {493 494 /*495 * Unmounting the root file system.496 *497 * In this case, there is no mount point node and we send498 * VFS_OUT_UNMOUNTED directly to the mounted file system.499 */500 501 free(mp);502 phone = vfs_grab_phone(mr_node->fs_handle);503 rc = async_req_1_0(phone, VFS_OUT_UNMOUNTED,504 mr_node->dev_handle);505 vfs_release_phone(phone);506 if (rc != EOK) {507 fibril_rwlock_write_unlock(&namespace_rwlock);508 vfs_node_put(mr_node);509 ipc_answer_0(rid, rc);510 return;511 }512 rootfs.fs_handle = 0;513 rootfs.dev_handle = 0;514 } else {515 516 /*517 * Unmounting a non-root file system.518 *519 * We have a regular mount point node representing the parent520 * file system, so we delegate the operation to it.521 */522 523 /*524 * The L_NOCROSS_LAST_MP flag is essential if we really want to525 * lookup the mount point and not the mounted root.526 */527 rc = vfs_lookup_internal(mp, L_NOCROSS_LAST_MP, &mp_res, NULL);528 free(mp);529 if (rc != EOK) {530 fibril_rwlock_write_unlock(&namespace_rwlock);531 vfs_node_put(mr_node);532 ipc_answer_0(rid, rc);533 return;534 }535 vfs_node_t *mp_node = vfs_node_get(&mp_res);536 if (!mp_node) {537 fibril_rwlock_write_unlock(&namespace_rwlock);538 vfs_node_put(mr_node);539 ipc_answer_0(rid, ENOMEM);540 return;541 }542 543 phone = vfs_grab_phone(mp_node->fs_handle);544 rc = async_req_2_0(phone, VFS_OUT_UNMOUNT, mp_node->fs_handle,545 mp_node->dev_handle);546 vfs_release_phone(phone);547 if (rc != EOK) {548 fibril_rwlock_write_unlock(&namespace_rwlock);549 vfs_node_put(mp_node);550 vfs_node_put(mr_node);551 ipc_answer_0(rid, rc);552 return;553 }554 555 /* Drop the reference we got above. */556 vfs_node_put(mp_node);557 /* Drop the reference from when the file system was mounted. */558 vfs_node_put(mp_node);559 }560 561 562 /*563 * All went well, the mounted file system was successfully unmounted.564 * The only thing left is to forget the unmounted root VFS node.565 */566 vfs_node_forget(mr_node);567 568 fibril_rwlock_write_unlock(&namespace_rwlock);569 ipc_answer_0(rid, EOK);570 }571 572 431 void vfs_open(ipc_callid_t rid, ipc_call_t *request) 573 432 { … … 595 454 /* 596 455 * Make sure that we are called with exactly one of L_FILE and 597 * L_DIRECTORY. Make sure that the user does not pass L_OPEN or 598 * L_NOCROSS_LAST_MP. 456 * L_DIRECTORY. Make sure that the user does not pass L_OPEN. 599 457 */ 600 458 if (((lflag & (L_FILE | L_DIRECTORY)) == 0) || 601 459 ((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) || 602 ( lflag & L_OPEN) || (lflag & L_NOCROSS_LAST_MP)) {460 ((lflag & L_OPEN) != 0)) { 603 461 ipc_answer_0(rid, EINVAL); 604 462 return;
Note:
See TracChangeset
for help on using the changeset viewer.