Changes in / [2314381:3698e44] in mainline
- Files:
-
- 40 deleted
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
HelenOS.config
r2314381 r3698e44 31 31 32 32 % Platform 33 @ "abs32le" abstract 32-bit little endian34 33 @ "amd64" AMD64/Intel EM64T (PC) 35 34 @ "arm32" ARM 32-bit … … 92 91 93 92 % Kernel architecture 94 @ "abs32le"95 ! [PLATFORM=abs32le] KARCH (choice)96 97 % Kernel architecture98 93 @ "amd64" 99 94 ! [PLATFORM=amd64] KARCH (choice) … … 135 130 136 131 % User space architecture 137 @ "abs32le"138 ! [PLATFORM=abs32le] UARCH (choice)139 140 % User space architecture141 132 @ "amd64" 142 133 ! [PLATFORM=amd64] UARCH (choice) … … 176 167 177 168 ## Mapping between platform and boot architecture 178 179 % Boot architecture180 @ "abs32le"181 ! [PLATFORM=abs32le] BARCH (choice)182 169 183 170 % Boot architecture … … 256 243 ! [PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] COMPILER (choice) 257 244 258 % Compiler259 @ "gcc_native" GNU C Compiler (native)260 @ "clang" Clang261 ! [PLATFORM=abs32le] COMPILER (choice)262 263 245 264 246 ## Kernel configuration … … 277 259 278 260 % Hierarchical page tables support 279 ! [PLATFORM= abs32le|PLATFORM=ia32|PLATFORM=amd64|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] CONFIG_PAGE_PT (y)261 ! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] CONFIG_PAGE_PT (y) 280 262 281 263 % Page hash table support -
Makefile
r2314381 r3698e44 59 59 60 60 distclean: clean 61 rm -f $(CSCOPE).out Makefile.config config.h config.defs tools/*.pyc tools/checkers/*.pyc61 rm -f $(CSCOPE).out Makefile.config config.h config.defs tools/*.pyc 62 62 63 63 clean: -
uspace/app/bdsh/Makefile
r2314381 r3698e44 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
r2314381 r3698e44 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
r2314381 r3698e44 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
r2314381 r3698e44 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
r2314381 r3698e44 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
r2314381 r3698e44 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
r2314381 r3698e44 86 86 VFS_OUT_MOUNTED, 87 87 VFS_OUT_UNMOUNT, 88 VFS_OUT_UNMOUNTED,89 88 VFS_OUT_SYNC, 90 89 VFS_OUT_STAT, … … 101 100 * No lookup flags used. 102 101 */ 103 #define L_NONE 102 #define L_NONE 0 104 103 105 104 /** … … 108 107 * with L_DIRECTORY. 109 108 */ 110 #define L_FILE 109 #define L_FILE 1 111 110 112 111 /** 113 * Lookup wil lsucceed only if the object is a directory. If L_CREATE is112 * Lookup wil succeed only if the object is a directory. If L_CREATE is 114 113 * specified, an empty directory will be created. This flag is mutually 115 114 * exclusive with L_FILE. 116 115 */ 117 #define L_DIRECTORY 2 118 119 /** 120 * Lookup will succeed only if the object is a root directory. The flag is 121 * mutually exclusive with L_FILE and L_MP. 122 */ 123 #define L_ROOT 4 124 125 /** 126 * Lookup will succeed only if the object is a mount point. The flag is mutually 127 * exclusive with L_FILE and L_ROOT. 128 */ 129 #define L_MP 8 130 116 #define L_DIRECTORY 2 131 117 132 118 /** … … 134 120 * object already exists. L_EXCLUSIVE is implied when L_DIRECTORY is used. 135 121 */ 136 #define L_EXCLUSIVE 16122 #define L_EXCLUSIVE 4 137 123 138 124 /** 139 125 * L_CREATE is used for creating both regular files and directories. 140 126 */ 141 #define L_CREATE 32127 #define L_CREATE 8 142 128 143 129 /** 144 130 * L_LINK is used for linking to an already existing nodes. 145 131 */ 146 #define L_LINK 64132 #define L_LINK 16 147 133 148 134 /** … … 151 137 * VFS_UNLINK. 152 138 */ 153 #define L_UNLINK 128139 #define L_UNLINK 32 154 140 155 141 /** 156 * 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 157 143 * call from the client. This means that the server might allocate some 158 144 * resources for the opened file. This flag cannot be passed directly by the 159 145 * client. 160 146 */ 161 #define L_OPEN 256147 #define L_OPEN 64 162 148 163 149 #endif -
uspace/lib/libc/include/vfs/vfs.h
r2314381 r3698e44 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
r2314381 r3698e44 224 224 ipc_answer_3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer), 225 225 IPC_GET_ARG3(answer)); 226 }227 228 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)229 {230 dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);231 fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);232 fs_node_t *fn;233 int res;234 235 res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);236 if ((res != EOK) || (!fn)) {237 ipc_answer_0(rid, combine_rc(res, ENOENT));238 return;239 }240 241 /*242 * We are clearly expecting to find the mount point active.243 */244 if (!fn->mp_data.mp_active) {245 (void) ops->node_put(fn);246 ipc_answer_0(rid, EINVAL);247 return;248 }249 250 /*251 * Tell the mounted file system to unmount.252 */253 res = async_req_1_0(fn->mp_data.phone, VFS_OUT_UNMOUNTED,254 fn->mp_data.dev_handle);255 256 /*257 * If everything went well, perform the clean-up on our side.258 */259 if (res == EOK) {260 ipc_hangup(fn->mp_data.phone);261 fn->mp_data.mp_active = false;262 fn->mp_data.fs_handle = 0;263 fn->mp_data.dev_handle = 0;264 fn->mp_data.phone = 0;265 /* Drop the reference created in libfs_mount(). */266 (void) ops->node_put(fn);267 }268 269 (void) ops->node_put(fn);270 ipc_answer_0(rid, res);271 226 } 272 227 … … 349 304 on_error(rc, goto out_with_answer); 350 305 351 /* 352 * If the matching component is a mount point, there are two 353 * legitimate semantics of the lookup operation. The first is 354 * the commonly used one in which the lookup crosses each mount 355 * point into the mounted file system. The second semantics is 356 * used mostly during unmount() and differs from the first one 357 * only in that the last mount point in the looked up path, 358 * which is also its last component, is not crossed. 359 */ 360 361 if ((tmp) && (tmp->mp_data.mp_active) && 362 (!(lflag & L_MP) || (next <= last))) { 306 if ((tmp) && (tmp->mp_data.mp_active)) { 363 307 if (next > last) 364 308 next = last = first; … … 531 475 goto out; 532 476 } 533 534 if ((lflag & L_ROOT) && par) {535 ipc_answer_0(rid, EINVAL);536 goto out;537 }538 477 539 478 out_with_answer: -
uspace/lib/libfs/libfs.h
r2314381 r3698e44 95 95 96 96 extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); 97 extern void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);98 97 extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); 99 98 extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); -
uspace/srv/fs/devfs/devfs.c
r2314381 r3698e44 75 75 devfs_mount(callid, &call); 76 76 break; 77 case VFS_OUT_UNMOUNTED:78 devfs_unmounted(callid, &call);79 break;80 case VFS_OUT_UNMOUNT:81 devfs_unmount(callid, &call);82 break;83 77 case VFS_OUT_LOOKUP: 84 78 devfs_lookup(callid, &call); -
uspace/srv/fs/devfs/devfs_ops.c
r2314381 r3698e44 434 434 } 435 435 436 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request)437 {438 ipc_answer_0(rid, ENOTSUP);439 }440 441 void devfs_unmount(ipc_callid_t rid, ipc_call_t *request)442 {443 libfs_unmount(&devfs_libfs_ops, rid, request);444 }445 446 436 void devfs_lookup(ipc_callid_t rid, ipc_call_t *request) 447 437 { -
uspace/srv/fs/devfs/devfs_ops.h
r2314381 r3698e44 41 41 extern void devfs_mounted(ipc_callid_t, ipc_call_t *); 42 42 extern void devfs_mount(ipc_callid_t, ipc_call_t *); 43 extern void devfs_unmounted(ipc_callid_t, ipc_call_t *);44 extern void devfs_unmount(ipc_callid_t, ipc_call_t *);45 43 extern void devfs_lookup(ipc_callid_t, ipc_call_t *); 46 44 extern void devfs_open_node(ipc_callid_t, ipc_call_t *); -
uspace/srv/fs/fat/fat.c
r2314381 r3698e44 100 100 fat_mount(callid, &call); 101 101 break; 102 case VFS_OUT_UNMOUNTED:103 fat_unmounted(callid, &call);104 break;105 case VFS_OUT_UNMOUNT:106 fat_unmount(callid, &call);107 break;108 102 case VFS_OUT_LOOKUP: 109 103 fat_lookup(callid, &call); -
uspace/srv/fs/fat/fat.h
r2314381 r3698e44 204 204 extern void fat_mounted(ipc_callid_t, ipc_call_t *); 205 205 extern void fat_mount(ipc_callid_t, ipc_call_t *); 206 extern void fat_unmounted(ipc_callid_t, ipc_call_t *);207 extern void fat_unmount(ipc_callid_t, ipc_call_t *);208 206 extern void fat_lookup(ipc_callid_t, ipc_call_t *); 209 207 extern void fat_read(ipc_callid_t, ipc_call_t *); -
uspace/srv/fs/fat/fat_ops.c
r2314381 r3698e44 1117 1117 } 1118 1118 1119 void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)1120 {1121 ipc_answer_0(rid, ENOTSUP);1122 }1123 1124 void fat_unmount(ipc_callid_t rid, ipc_call_t *request)1125 {1126 libfs_unmount(&fat_libfs_ops, rid, request);1127 }1128 1129 1119 void fat_lookup(ipc_callid_t rid, ipc_call_t *request) 1130 1120 { -
uspace/srv/fs/tmpfs/tmpfs.c
r2314381 r3698e44 106 106 tmpfs_mount(callid, &call); 107 107 break; 108 case VFS_OUT_UNMOUNTED:109 tmpfs_unmounted(callid, &call);110 break;111 case VFS_OUT_UNMOUNT:112 tmpfs_unmount(callid, &call);113 break;114 108 case VFS_OUT_LOOKUP: 115 109 tmpfs_lookup(callid, &call); -
uspace/srv/fs/tmpfs/tmpfs.h
r2314381 r3698e44 83 83 extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *); 84 84 extern void tmpfs_mount(ipc_callid_t, ipc_call_t *); 85 extern void tmpfs_unmounted(ipc_callid_t, ipc_call_t *);86 extern void tmpfs_unmount(ipc_callid_t, ipc_call_t *);87 85 extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *); 88 86 extern void tmpfs_read(ipc_callid_t, ipc_call_t *); -
uspace/srv/fs/tmpfs/tmpfs_ops.c
r2314381 r3698e44 147 147 hash_table_t nodes; 148 148 149 #define NODES_KEY_ DEV 0150 #define NODES_KEY_ INDEX1149 #define NODES_KEY_INDEX 0 150 #define NODES_KEY_DEV 1 151 151 152 152 /* Implementation of hash table interface for the nodes hash table. */ … … 166 166 static void nodes_remove_callback(link_t *item) 167 167 { 168 tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,169 nh_link);170 171 while (!list_empty(&nodep->cs_head)) {172 tmpfs_dentry_t *dentryp = list_get_instance(nodep->cs_head.next,173 tmpfs_dentry_t, link);174 175 assert(nodep->type == TMPFS_DIRECTORY);176 list_remove(&dentryp->link);177 free(dentryp);178 }179 180 if (nodep->data) {181 assert(nodep->type == TMPFS_FILE);182 free(nodep->data);183 }184 free(nodep->bp);185 free(nodep);186 168 } 187 169 … … 233 215 } 234 216 235 static void tmpfs_instance_done(dev_handle_t dev_handle)236 {237 unsigned long key[] = {238 [NODES_KEY_DEV] = dev_handle239 };240 /*241 * Here we are making use of one special feature of our hash table242 * implementation, which allows to remove more items based on a partial243 * key match. In the following, we are going to remove all nodes244 * matching our device handle. The nodes_remove_callback() function will245 * take care of resource deallocation.246 */247 hash_table_remove(&nodes, key, 1);248 }249 250 217 int tmpfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component) 251 218 { … … 270 237 { 271 238 unsigned long key[] = { 272 [NODES_KEY_ DEV] = dev_handle,273 [NODES_KEY_ INDEX] = index239 [NODES_KEY_INDEX] = index, 240 [NODES_KEY_DEV] = dev_handle 274 241 }; 275 242 link_t *lnk = hash_table_find(&nodes, key); … … 329 296 /* Insert the new node into the nodes hash table. */ 330 297 unsigned long key[] = { 331 [NODES_KEY_ DEV] = nodep->dev_handle,332 [NODES_KEY_ INDEX] = nodep->index298 [NODES_KEY_INDEX] = nodep->index, 299 [NODES_KEY_DEV] = nodep->dev_handle 333 300 }; 334 301 hash_table_insert(&nodes, key, &nodep->nh_link); … … 345 312 346 313 unsigned long key[] = { 347 [NODES_KEY_ DEV] = nodep->dev_handle,348 [NODES_KEY_ INDEX] = nodep->index314 [NODES_KEY_INDEX] = nodep->index, 315 [NODES_KEY_DEV] = nodep->dev_handle 349 316 }; 350 317 hash_table_remove(&nodes, key, 2); 351 318 352 /*353 * The nodes_remove_callback() function takes care of the actual354 * resource deallocation.355 */319 if (nodep->type == TMPFS_FILE) 320 free(nodep->data); 321 free(nodep->bp); 322 free(nodep); 356 323 return EOK; 357 324 } … … 457 424 /* Initialize TMPFS instance. */ 458 425 if (!tmpfs_instance_init(dev_handle)) { 459 free(opts);460 426 ipc_answer_0(rid, ENOMEM); 461 427 return; … … 476 442 rootp->lnkcnt); 477 443 } 478 free(opts);479 444 } 480 445 … … 482 447 { 483 448 libfs_mount(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 484 }485 486 void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request)487 {488 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);489 490 tmpfs_instance_done(dev_handle);491 ipc_answer_0(rid, EOK);492 }493 494 void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request)495 {496 libfs_unmount(&tmpfs_libfs_ops, rid, request);497 449 } 498 450 … … 513 465 link_t *hlp; 514 466 unsigned long key[] = { 467 [NODES_KEY_INDEX] = index, 515 468 [NODES_KEY_DEV] = dev_handle, 516 [NODES_KEY_INDEX] = index517 469 }; 518 470 hlp = hash_table_find(&nodes, key); … … 587 539 link_t *hlp; 588 540 unsigned long key[] = { 589 [NODES_KEY_ DEV] = dev_handle,590 [NODES_KEY_ INDEX] = index541 [NODES_KEY_INDEX] = index, 542 [NODES_KEY_DEV] = dev_handle 591 543 }; 592 544 hlp = hash_table_find(&nodes, key); … … 651 603 link_t *hlp; 652 604 unsigned long key[] = { 653 [NODES_KEY_ DEV] = dev_handle,654 [NODES_KEY_ INDEX] = index605 [NODES_KEY_INDEX] = index, 606 [NODES_KEY_DEV] = dev_handle 655 607 }; 656 608 hlp = hash_table_find(&nodes, key); … … 694 646 link_t *hlp; 695 647 unsigned long key[] = { 696 [NODES_KEY_ DEV] = dev_handle,697 [NODES_KEY_ INDEX] = index648 [NODES_KEY_INDEX] = index, 649 [NODES_KEY_DEV] = dev_handle 698 650 }; 699 651 hlp = hash_table_find(&nodes, key); -
uspace/srv/vfs/vfs.c
r2314381 r3698e44 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
r2314381 r3698e44 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
r2314381 r3698e44 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
r2314381 r3698e44 92 92 } 93 93 94 rc = vfs_lookup_internal(mp, L_ MP, &mp_res, NULL);94 rc = vfs_lookup_internal(mp, L_DIRECTORY, &mp_res, NULL); 95 95 if (rc != EOK) { 96 96 /* The lookup failed for some reason. */ … … 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_ROOT, &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 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);524 free(mp);525 if (rc != EOK) {526 fibril_rwlock_write_unlock(&namespace_rwlock);527 vfs_node_put(mr_node);528 ipc_answer_0(rid, rc);529 return;530 }531 vfs_node_t *mp_node = vfs_node_get(&mp_res);532 if (!mp_node) {533 fibril_rwlock_write_unlock(&namespace_rwlock);534 vfs_node_put(mr_node);535 ipc_answer_0(rid, ENOMEM);536 return;537 }538 539 phone = vfs_grab_phone(mp_node->fs_handle);540 rc = async_req_2_0(phone, VFS_OUT_UNMOUNT, mp_node->dev_handle,541 mp_node->index);542 vfs_release_phone(phone);543 if (rc != EOK) {544 fibril_rwlock_write_unlock(&namespace_rwlock);545 vfs_node_put(mp_node);546 vfs_node_put(mr_node);547 ipc_answer_0(rid, rc);548 return;549 }550 551 /* Drop the reference we got above. */552 vfs_node_put(mp_node);553 /* Drop the reference from when the file system was mounted. */554 vfs_node_put(mp_node);555 }556 557 558 /*559 * All went well, the mounted file system was successfully unmounted.560 * The only thing left is to forget the unmounted root VFS node.561 */562 vfs_node_forget(mr_node);563 564 fibril_rwlock_write_unlock(&namespace_rwlock);565 ipc_answer_0(rid, EOK);566 }567 568 431 void vfs_open(ipc_callid_t rid, ipc_call_t *request) 569 432 { … … 591 454 /* 592 455 * Make sure that we are called with exactly one of L_FILE and 593 * L_DIRECTORY. Make sure that the user does not pass L_OPEN, 594 * L_ROOT or L_MP. 456 * L_DIRECTORY. Make sure that the user does not pass L_OPEN. 595 457 */ 596 458 if (((lflag & (L_FILE | L_DIRECTORY)) == 0) || 597 459 ((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) || 598 ( lflag & (L_OPEN | L_ROOT | L_MP))) {460 ((lflag & L_OPEN) != 0)) { 599 461 ipc_answer_0(rid, EINVAL); 600 462 return;
Note:
See TracChangeset
for help on using the changeset viewer.