Changes in / [2314381:3698e44] in mainline


Ignore:
Files:
40 deleted
25 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    r2314381 r3698e44  
    3131
    3232% Platform
    33 @ "abs32le" abstract 32-bit little endian
    3433@ "amd64" AMD64/Intel EM64T (PC)
    3534@ "arm32" ARM 32-bit
     
    9291
    9392% Kernel architecture
    94 @ "abs32le"
    95 ! [PLATFORM=abs32le] KARCH (choice)
    96 
    97 % Kernel architecture
    9893@ "amd64"
    9994! [PLATFORM=amd64] KARCH (choice)
     
    135130
    136131% User space architecture
    137 @ "abs32le"
    138 ! [PLATFORM=abs32le] UARCH (choice)
    139 
    140 % User space architecture
    141132@ "amd64"
    142133! [PLATFORM=amd64] UARCH (choice)
     
    176167
    177168## Mapping between platform and boot architecture
    178 
    179 % Boot architecture
    180 @ "abs32le"
    181 ! [PLATFORM=abs32le] BARCH (choice)
    182169
    183170% Boot architecture
     
    256243! [PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] COMPILER (choice)
    257244
    258 % Compiler
    259 @ "gcc_native" GNU C Compiler (native)
    260 @ "clang" Clang
    261 ! [PLATFORM=abs32le] COMPILER (choice)
    262 
    263245
    264246## Kernel configuration
     
    277259
    278260% 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)
    280262
    281263% Page hash table support
  • Makefile

    r2314381 r3698e44  
    5959
    6060distclean: clean
    61         rm -f $(CSCOPE).out Makefile.config config.h config.defs tools/*.pyc tools/checkers/*.pyc
     61        rm -f $(CSCOPE).out Makefile.config config.h config.defs tools/*.pyc
    6262
    6363clean:
  • uspace/app/bdsh/Makefile

    r2314381 r3698e44  
    4848        cmds/modules/mv/mv.c \
    4949        cmds/modules/mount/mount.c \
    50         cmds/modules/unmount/unmount.c \
    5150        cmds/modules/kcon/kcon.c \
    5251        cmds/builtins/exit/exit.c \
  • uspace/app/bdsh/cmds/modules/module_aliases.h

    r2314381 r3698e44  
    1414char *mod_aliases[] = {
    1515        "ren", "mv",
    16         "umount", "unmount",
    1716        NULL, NULL
    1817};
  • uspace/app/bdsh/cmds/modules/modules.h

    r2314381 r3698e44  
    3131#include "mv/entry.h"
    3232#include "mount/entry.h"
    33 #include "unmount/entry.h"
    3433#include "kcon/entry.h"
    3534
     
    5251#include "mv/mv_def.h"
    5352#include "mount/mount_def.h"
    54 #include "unmount/unmount_def.h"
    5553#include "kcon/kcon_def.h"
    5654
  • uspace/lib/libc/generic/adt/hash_table.c

    r2314381 r3698e44  
    193193}
    194194
    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 void
    202 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 
    215195/** @}
    216196 */
  • uspace/lib/libc/generic/vfs/vfs.c

    r2314381 r3698e44  
    197197}
    198198
    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                 else
    225                         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 
    237199static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    238200{
  • uspace/lib/libc/include/adt/hash_table.h

    r2314381 r3698e44  
    8888extern void hash_table_remove(hash_table_t *, unsigned long [], hash_count_t);
    8989extern void hash_table_destroy(hash_table_t *);
    90 extern void hash_table_apply(hash_table_t *, void (*)(link_t *, void *),
    91     void *);
    9290
    9391#endif
  • uspace/lib/libc/include/ipc/vfs.h

    r2314381 r3698e44  
    8686        VFS_OUT_MOUNTED,
    8787        VFS_OUT_UNMOUNT,
    88         VFS_OUT_UNMOUNTED,
    8988        VFS_OUT_SYNC,
    9089        VFS_OUT_STAT,
     
    101100 * No lookup flags used.
    102101 */
    103 #define L_NONE                  0
     102#define L_NONE  0
    104103
    105104/**
     
    108107 * with L_DIRECTORY.
    109108 */
    110 #define L_FILE                  1
     109#define L_FILE  1
    111110
    112111/**
    113  * Lookup will succeed only if the object is a directory. If L_CREATE is
     112 * Lookup wil succeed only if the object is a directory. If L_CREATE is
    114113 * specified, an empty directory will be created. This flag is mutually
    115114 * exclusive with L_FILE.
    116115 */
    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
    131117
    132118/**
     
    134120 * object already exists. L_EXCLUSIVE is implied when L_DIRECTORY is used.
    135121 */
    136 #define L_EXCLUSIVE             16
     122#define L_EXCLUSIVE  4
    137123
    138124/**
    139125 * L_CREATE is used for creating both regular files and directories.
    140126 */
    141 #define L_CREATE                32
     127#define L_CREATE  8
    142128
    143129/**
    144130 * L_LINK is used for linking to an already existing nodes.
    145131 */
    146 #define L_LINK                  64
     132#define L_LINK  16
    147133
    148134/**
     
    151137 * VFS_UNLINK.
    152138 */
    153 #define L_UNLINK                128
     139#define L_UNLINK  32
    154140
    155141/**
    156  * L_OPEN is used to indicate that the lookup operation is a part of VFS_IN_OPEN
     142 * L_OPEN is used to indicate that the lookup operation is a part of VFS_OPEN
    157143 * call from the client. This means that the server might allocate some
    158144 * resources for the opened file. This flag cannot be passed directly by the
    159145 * client.
    160146 */
    161 #define L_OPEN                  256
     147#define L_OPEN  64
    162148
    163149#endif
  • uspace/lib/libc/include/vfs/vfs.h

    r2314381 r3698e44  
    5555extern int mount(const char *, const char *, const char *, const char *,
    5656    unsigned int);
    57 extern int unmount(const char *);
    5857
    5958extern void __stdio_init(int filc, fdi_node_t *filv[]);
  • uspace/lib/libfs/libfs.c

    r2314381 r3698e44  
    224224        ipc_answer_3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
    225225            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);
    271226}
    272227
     
    349304                on_error(rc, goto out_with_answer);
    350305               
    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)) {
    363307                        if (next > last)
    364308                                next = last = first;
     
    531475                goto out;
    532476        }
    533 
    534         if ((lflag & L_ROOT) && par) {
    535                 ipc_answer_0(rid, EINVAL);
    536                 goto out;
    537         }
    538477       
    539478out_with_answer:
  • uspace/lib/libfs/libfs.h

    r2314381 r3698e44  
    9595
    9696extern 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 *);
    9897extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    9998extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
  • uspace/srv/fs/devfs/devfs.c

    r2314381 r3698e44  
    7575                        devfs_mount(callid, &call);
    7676                        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;
    8377                case VFS_OUT_LOOKUP:
    8478                        devfs_lookup(callid, &call);
  • uspace/srv/fs/devfs/devfs_ops.c

    r2314381 r3698e44  
    434434}
    435435
    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 
    446436void devfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    447437{
  • uspace/srv/fs/devfs/devfs_ops.h

    r2314381 r3698e44  
    4141extern void devfs_mounted(ipc_callid_t, ipc_call_t *);
    4242extern 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 *);
    4543extern void devfs_lookup(ipc_callid_t, ipc_call_t *);
    4644extern void devfs_open_node(ipc_callid_t, ipc_call_t *);
  • uspace/srv/fs/fat/fat.c

    r2314381 r3698e44  
    100100                        fat_mount(callid, &call);
    101101                        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;
    108102                case VFS_OUT_LOOKUP:
    109103                        fat_lookup(callid, &call);
  • uspace/srv/fs/fat/fat.h

    r2314381 r3698e44  
    204204extern void fat_mounted(ipc_callid_t, ipc_call_t *);
    205205extern 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 *);
    208206extern void fat_lookup(ipc_callid_t, ipc_call_t *);
    209207extern void fat_read(ipc_callid_t, ipc_call_t *);
  • uspace/srv/fs/fat/fat_ops.c

    r2314381 r3698e44  
    11171117}
    11181118
    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 
    11291119void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
    11301120{
  • uspace/srv/fs/tmpfs/tmpfs.c

    r2314381 r3698e44  
    106106                        tmpfs_mount(callid, &call);
    107107                        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;
    114108                case VFS_OUT_LOOKUP:
    115109                        tmpfs_lookup(callid, &call);
  • uspace/srv/fs/tmpfs/tmpfs.h

    r2314381 r3698e44  
    8383extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *);
    8484extern 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 *);
    8785extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);
    8886extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r2314381 r3698e44  
    147147hash_table_t nodes;
    148148
    149 #define NODES_KEY_DEV   0       
    150 #define NODES_KEY_INDEX 1
     149#define NODES_KEY_INDEX 0
     150#define NODES_KEY_DEV   1
    151151
    152152/* Implementation of hash table interface for the nodes hash table. */
     
    166166static void nodes_remove_callback(link_t *item)
    167167{
    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);
    186168}
    187169
     
    233215}
    234216
    235 static void tmpfs_instance_done(dev_handle_t dev_handle)
    236 {
    237         unsigned long key[] = {
    238                 [NODES_KEY_DEV] = dev_handle
    239         };
    240         /*
    241          * Here we are making use of one special feature of our hash table
    242          * implementation, which allows to remove more items based on a partial
    243          * key match. In the following, we are going to remove all nodes
    244          * matching our device handle. The nodes_remove_callback() function will
    245          * take care of resource deallocation.
    246          */
    247         hash_table_remove(&nodes, key, 1);
    248 }
    249 
    250217int tmpfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
    251218{
     
    270237{
    271238        unsigned long key[] = {
    272                 [NODES_KEY_DEV] = dev_handle,
    273                 [NODES_KEY_INDEX] = index
     239                [NODES_KEY_INDEX] = index,
     240                [NODES_KEY_DEV] = dev_handle
    274241        };
    275242        link_t *lnk = hash_table_find(&nodes, key);
     
    329296        /* Insert the new node into the nodes hash table. */
    330297        unsigned long key[] = {
    331                 [NODES_KEY_DEV] = nodep->dev_handle,
    332                 [NODES_KEY_INDEX] = nodep->index
     298                [NODES_KEY_INDEX] = nodep->index,
     299                [NODES_KEY_DEV] = nodep->dev_handle
    333300        };
    334301        hash_table_insert(&nodes, key, &nodep->nh_link);
     
    345312
    346313        unsigned long key[] = {
    347                 [NODES_KEY_DEV] = nodep->dev_handle,
    348                 [NODES_KEY_INDEX] = nodep->index
     314                [NODES_KEY_INDEX] = nodep->index,
     315                [NODES_KEY_DEV] = nodep->dev_handle
    349316        };
    350317        hash_table_remove(&nodes, key, 2);
    351318
    352         /*
    353          * The nodes_remove_callback() function takes care of the actual
    354          * resource deallocation.
    355          */
     319        if (nodep->type == TMPFS_FILE)
     320                free(nodep->data);
     321        free(nodep->bp);
     322        free(nodep);
    356323        return EOK;
    357324}
     
    457424        /* Initialize TMPFS instance. */
    458425        if (!tmpfs_instance_init(dev_handle)) {
    459                 free(opts);
    460426                ipc_answer_0(rid, ENOMEM);
    461427                return;
     
    476442                    rootp->lnkcnt);
    477443        }
    478         free(opts);
    479444}
    480445
     
    482447{
    483448        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);
    497449}
    498450
     
    513465        link_t *hlp;
    514466        unsigned long key[] = {
     467                [NODES_KEY_INDEX] = index,
    515468                [NODES_KEY_DEV] = dev_handle,
    516                 [NODES_KEY_INDEX] = index
    517469        };
    518470        hlp = hash_table_find(&nodes, key);
     
    587539        link_t *hlp;
    588540        unsigned long key[] = {
    589                 [NODES_KEY_DEV] = dev_handle,
    590                 [NODES_KEY_INDEX] = index
     541                [NODES_KEY_INDEX] = index,
     542                [NODES_KEY_DEV] = dev_handle
    591543        };
    592544        hlp = hash_table_find(&nodes, key);
     
    651603        link_t *hlp;
    652604        unsigned long key[] = {
    653                 [NODES_KEY_DEV] = dev_handle,
    654                 [NODES_KEY_INDEX] = index
     605                [NODES_KEY_INDEX] = index,
     606                [NODES_KEY_DEV] = dev_handle
    655607        };
    656608        hlp = hash_table_find(&nodes, key);
     
    694646        link_t *hlp;
    695647        unsigned long key[] = {
    696                 [NODES_KEY_DEV] = dev_handle,
    697                 [NODES_KEY_INDEX] = index
     648                [NODES_KEY_INDEX] = index,
     649                [NODES_KEY_DEV] = dev_handle
    698650        };
    699651        hlp = hash_table_find(&nodes, key);
  • uspace/srv/vfs/vfs.c

    r2314381 r3698e44  
    8686                case VFS_IN_MOUNT:
    8787                        vfs_mount(callid, &call);
    88                         break;
    89                 case VFS_IN_UNMOUNT:
    90                         vfs_unmount(callid, &call);
    9188                        break;
    9289                case VFS_IN_OPEN:
  • uspace/srv/vfs/vfs.h

    r2314381 r3698e44  
    181181extern vfs_node_t *vfs_node_get(vfs_lookup_res_t *);
    182182extern 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 
    186183
    187184#define MAX_OPEN_FILES  128
     
    201198extern void vfs_register(ipc_callid_t, ipc_call_t *);
    202199extern void vfs_mount(ipc_callid_t, ipc_call_t *);
    203 extern void vfs_unmount(ipc_callid_t, ipc_call_t *);
    204200extern void vfs_open(ipc_callid_t, ipc_call_t *);
    205201extern void vfs_open_node(ipc_callid_t, ipc_call_t *);
  • uspace/srv/vfs/vfs_node.c

    r2314381 r3698e44  
    137137        if (free_vfs_node)
    138138                free(node);
    139 }
    140 
    141 /** Forget node.
    142  *
    143  * This function will remove the node from the node hash table and deallocate
    144  * 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->index
    155         };
    156         hash_table_remove(&nodes, key, 3);
    157         fibril_mutex_unlock(&nodes_mutex);
    158         free(node);
    159139}
    160140
     
    251231}
    252232
    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 unsigned
    271 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_handle
    277         };
    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 
    286233/**
    287234 * @}
  • uspace/srv/vfs/vfs_ops.c

    r2314381 r3698e44  
    9292                }
    9393               
    94                 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
     94                rc = vfs_lookup_internal(mp, L_DIRECTORY, &mp_res, NULL);
    9595                if (rc != EOK) {
    9696                        /* The lookup failed for some reason. */
     
    429429}
    430430
    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 will
    450          * prevent races with other lookup operations. Second, it will stop new
    451          * references to already existing VFS nodes and creation of new VFS
    452          * nodes. This is because new references are added as a result of some
    453          * lookup operation or at least of some operation which is protected by
    454          * 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. We
    478          * are expecting at least two. One which we got above and one which we
    479          * got when the file system was mounted. If we find more, it means that
    480          * the file system cannot be gracefully unmounted at the moment because
    481          * 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 send
    498                  * 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 parent
    520                  * 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 
    568431void vfs_open(ipc_callid_t rid, ipc_call_t *request)
    569432{
     
    591454        /*
    592455         * 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.
    595457         */
    596458        if (((lflag & (L_FILE | L_DIRECTORY)) == 0) ||
    597459            ((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) ||
    598             (lflag & (L_OPEN | L_ROOT | L_MP))) {
     460            ((lflag & L_OPEN) != 0)) {
    599461                ipc_answer_0(rid, EINVAL);
    600462                return;
Note: See TracChangeset for help on using the changeset viewer.