Changes in / [e095644:fea0ce6] in mainline


Ignore:
Location:
uspace
Files:
4 deleted
13 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/Makefile

    re095644 rfea0ce6  
    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

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

    re095644 rfea0ce6  
    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

    re095644 rfea0ce6  
    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

    re095644 rfea0ce6  
    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

    re095644 rfea0ce6  
    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

    re095644 rfea0ce6  
    8686        VFS_OUT_MOUNTED,
    8787        VFS_OUT_UNMOUNT,
    88         VFS_OUT_UNMOUNTED,
    8988        VFS_OUT_SYNC,
    9089        VFS_OUT_STAT,
     
    141140
    142141/**
    143  * 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
    144143 * call from the client. This means that the server might allocate some
    145144 * resources for the opened file. This flag cannot be passed directly by the
     
    148147#define L_OPEN  64
    149148
    150 /**
    151  * L_NOCROSS_LAST_MP is used exclusively during the VFS_IN_UNMOUNT operation. It
    152  * tells the lookup routine not to cross the last mount point in the lookup
    153  * path.
    154  */
    155 #define L_NOCROSS_LAST_MP       128
    156 
    157149#endif
    158150
  • uspace/lib/libc/include/vfs/vfs.h

    re095644 rfea0ce6  
    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

    re095644 rfea0ce6  
    304304                on_error(rc, goto out_with_answer);
    305305               
    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)) {
    318307                        if (next > last)
    319308                                next = last = first;
  • uspace/srv/vfs/vfs.c

    re095644 rfea0ce6  
    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

    re095644 rfea0ce6  
    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

    re095644 rfea0ce6  
    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

    re095644 rfea0ce6  
    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_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. 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                 /*
    524                  * The L_NOCROSS_LAST_MP flag is essential if we really want to
    525                  * 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 
    572431void vfs_open(ipc_callid_t rid, ipc_call_t *request)
    573432{
     
    595454        /*
    596455         * 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.
    599457         */
    600458        if (((lflag & (L_FILE | L_DIRECTORY)) == 0) ||
    601459            ((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) ||
    602             (lflag & L_OPEN) || (lflag & L_NOCROSS_LAST_MP)) {
     460            ((lflag & L_OPEN) != 0)) {
    603461                ipc_answer_0(rid, EINVAL);
    604462                return;
Note: See TracChangeset for help on using the changeset viewer.