Changeset 19f24fd in mainline for uspace/srv


Ignore:
Timestamp:
2010-02-05T22:25:52Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
dafa2d04
Parents:
83349b03 (diff), d42976c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

Location:
uspace/srv
Files:
10 added
28 edited
7 moved

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/ata_bd/ata_bd.c

    r83349b03 r19f24fd  
    5959#include <devmap.h>
    6060#include <sys/types.h>
     61#include <inttypes.h>
    6162#include <errno.h>
    6263#include <bool.h>
     
    112113        printf(NAME ": ATA disk driver\n");
    113114
    114         printf("I/O address 0x%p/0x%p\n", ctl_physical, cmd_physical);
     115        printf("I/O address %p/%p\n", ctl_physical, cmd_physical);
    115116
    116117        if (ata_bd_init() != EOK)
     
    180181        }
    181182
    182         printf(" %llu blocks", d->blocks, d->blocks / (2 * 1024));
     183        printf(" %" PRIu64 " blocks", d->blocks, d->blocks / (2 * 1024));
    183184
    184185        mbytes = d->blocks / (2 * 1024);
    185186        if (mbytes > 0)
    186                 printf(" %llu MB.", mbytes);
     187                printf(" %" PRIu64 " MB.", mbytes);
    187188
    188189        printf("\n");
  • uspace/srv/bd/part/guid_part/guid_part.c

    r83349b03 r19f24fd  
    5454#include <devmap.h>
    5555#include <sys/types.h>
     56#include <sys/typefmt.h>
     57#include <inttypes.h>
    5658#include <libblock.h>
    5759#include <devmap.h>
     
    196198                size_mb = (part->length * block_size + 1024 * 1024 - 1)
    197199                    / (1024 * 1024);
    198                 printf(NAME ": Registered device %s: %llu blocks %llu MB.\n",
    199                     name, part->length, size_mb);
     200                printf(NAME ": Registered device %s: %" PRIu64 " blocks "
     201                    "%" PRIuBN " MB.\n", name, part->length, size_mb);
    200202
    201203                part->dev = dev;
  • uspace/srv/bd/part/mbr_part/mbr_part.c

    r83349b03 r19f24fd  
    6464#include <devmap.h>
    6565#include <sys/types.h>
     66#include <sys/typefmt.h>
     67#include <inttypes.h>
    6668#include <libblock.h>
    6769#include <devmap.h>
     
    247249                size_mb = (part->length * block_size + 1024 * 1024 - 1)
    248250                    / (1024 * 1024);
    249                 printf(NAME ": Registered device %s: %llu blocks %llu MB.\n",
    250                     name, part->length, size_mb);
     251                printf(NAME ": Registered device %s: %" PRIuBN " blocks "
     252                    "%" PRIu64 " MB.\n", name, part->length, size_mb);
    251253
    252254                part->dev = dev;
     
    274276        if (brb == NULL) {
    275277                printf(NAME ": Failed allocating memory.\n");
    276                 return ENOMEM; 
     278                return ENOMEM;
    277279        }
    278280
     
    289291        sgn = uint16_t_le2host(brb->signature);
    290292        if (sgn != BR_SIGNATURE) {
    291                 printf(NAME ": Invalid boot record signature 0x%04X.\n", sgn);
     293                printf(NAME ": Invalid boot record signature 0x%04" PRIX16
     294                    ".\n", sgn);
    292295                return EINVAL;
    293296        }
     
    333336                rc = block_read_direct(indev_handle, ba, 1, brb);
    334337                if (rc != EOK) {
    335                         printf(NAME ": Failed reading EBR block at %u.\n", ba);
     338                        printf(NAME ": Failed reading EBR block at %"
     339                            PRIu32 ".\n", ba);
    336340                        return rc;
    337341                }
     
    339343                sgn = uint16_t_le2host(brb->signature);
    340344                if (sgn != BR_SIGNATURE) {
    341                         printf(NAME ": Invalid boot record signature 0x%04X "
    342                             " in EBR at %u.\n", sgn, ba);
     345                        printf(NAME ": Invalid boot record signature 0x%04"
     346                            PRIX16 " in EBR at %" PRIu32 ".\n", sgn, ba);
    343347                        return EINVAL;
    344348                }
  • uspace/srv/clip/clip.c

    r83349b03 r19f24fd  
    6464                ipc_answer_0(rid, EOK);
    6565                break;
    66         case CLIPBOARD_TAG_BLOB:
    67                 rc = async_data_blob_receive(&data, 0, &size);
     66        case CLIPBOARD_TAG_DATA:
     67                rc = async_data_write_accept((void **) &data, false, 0, 0, 0, &size);
    6868                if (rc != EOK) {
    6969                        ipc_answer_0(rid, rc);
     
    7878                clip_data = data;
    7979                clip_size = size;
    80                 clip_tag = CLIPBOARD_TAG_BLOB;
     80                clip_tag = CLIPBOARD_TAG_DATA;
    8181               
    8282                fibril_mutex_unlock(&clip_mtx);
     
    9797        /* Check for clipboard data tag compatibility */
    9898        switch (IPC_GET_ARG1(*request)) {
    99         case CLIPBOARD_TAG_BLOB:
     99        case CLIPBOARD_TAG_DATA:
    100100                if (!async_data_read_receive(&callid, &size)) {
    101101                        ipc_answer_0(callid, EINVAL);
     
    104104                }
    105105               
    106                 if (clip_tag != CLIPBOARD_TAG_BLOB) {
    107                         /* So far we only understand BLOB */
     106                if (clip_tag != CLIPBOARD_TAG_DATA) {
     107                        /* So far we only understand binary data */
    108108                        ipc_answer_0(callid, EOVERFLOW);
    109109                        ipc_answer_0(rid, EOVERFLOW);
  • uspace/srv/devmap/devmap.c

    r83349b03 r19f24fd  
    396396         * Get driver name
    397397         */
    398         int rc = async_data_string_receive(&driver->name, DEVMAP_NAME_MAXLEN);
     398        int rc = async_data_write_accept((void **) &driver->name, true, 0,
     399            DEVMAP_NAME_MAXLEN, 0, NULL);
    399400        if (rc != EOK) {
    400401                free(driver);
     
    510511        /* Get fqdn */
    511512        char *fqdn;
    512         int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN);
     513        int rc = async_data_write_accept((void **) &fqdn, true, 0,
     514            DEVMAP_NAME_MAXLEN, 0, NULL);
    513515        if (rc != EOK) {
    514516                free(device);
     
    622624       
    623625        /* Get fqdn */
    624         int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN);
     626        int rc = async_data_write_accept((void **) &fqdn, true, 0,
     627            DEVMAP_NAME_MAXLEN, 0, NULL);
    625628        if (rc != EOK) {
    626629                ipc_answer_0(iid, rc);
     
    683686       
    684687        /* Get device name */
    685         int rc = async_data_string_receive(&name, DEVMAP_NAME_MAXLEN);
     688        int rc = async_data_write_accept((void **) &name, true, 0,
     689            DEVMAP_NAME_MAXLEN, 0, NULL);
    686690        if (rc != EOK) {
    687691                ipc_answer_0(iid, rc);
  • uspace/srv/fs/devfs/devfs.c

    r83349b03 r19f24fd  
    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;
    7783                case VFS_OUT_LOOKUP:
    7884                        devfs_lookup(callid, &call);
  • uspace/srv/fs/devfs/devfs_ops.c

    r83349b03 r19f24fd  
    419419       
    420420        /* Accept the mount options */
    421         ipcarg_t retval = async_data_string_receive(&opts, 0);
     421        ipcarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,
     422            0, NULL);
    422423        if (retval != EOK) {
    423424                ipc_answer_0(rid, retval);
     
    432433{
    433434        libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
     435}
     436
     437void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
     438{
     439        ipc_answer_0(rid, ENOTSUP);
     440}
     441
     442void devfs_unmount(ipc_callid_t rid, ipc_call_t *request)
     443{
     444        libfs_unmount(&devfs_libfs_ops, rid, request);
    434445}
    435446
  • uspace/srv/fs/devfs/devfs_ops.h

    r83349b03 r19f24fd  
    4141extern void devfs_mounted(ipc_callid_t, ipc_call_t *);
    4242extern void devfs_mount(ipc_callid_t, ipc_call_t *);
     43extern void devfs_unmounted(ipc_callid_t, ipc_call_t *);
     44extern void devfs_unmount(ipc_callid_t, ipc_call_t *);
    4345extern void devfs_lookup(ipc_callid_t, ipc_call_t *);
    4446extern void devfs_open_node(ipc_callid_t, ipc_call_t *);
  • uspace/srv/fs/fat/fat.c

    r83349b03 r19f24fd  
    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;
    102108                case VFS_OUT_LOOKUP:
    103109                        fat_lookup(callid, &call);
  • uspace/srv/fs/fat/fat.h

    r83349b03 r19f24fd  
    204204extern void fat_mounted(ipc_callid_t, ipc_call_t *);
    205205extern void fat_mount(ipc_callid_t, ipc_call_t *);
     206extern void fat_unmounted(ipc_callid_t, ipc_call_t *);
     207extern void fat_unmount(ipc_callid_t, ipc_call_t *);
    206208extern void fat_lookup(ipc_callid_t, ipc_call_t *);
    207209extern void fat_read(ipc_callid_t, ipc_call_t *);
  • uspace/srv/fs/fat/fat_fat.c

    r83349b03 r19f24fd  
    608608}
    609609
     610/** Perform basic sanity checks on the file system.
     611 *
     612 * Verify if values of boot sector fields are sane. Also verify media
     613 * descriptor. This is used to rule out cases when a device obviously
     614 * does not contain a fat file system.
     615 */
     616int fat_sanity_check(fat_bs_t *bs, dev_handle_t dev_handle)
     617{
     618        fat_cluster_t e0, e1;
     619        unsigned fat_no;
     620        int rc;
     621
     622        /* Check number of FATs. */
     623        if (bs->fatcnt == 0)
     624                return ENOTSUP;
     625
     626        /* Check total number of sectors. */
     627
     628        if (bs->totsec16 == 0 && bs->totsec32 == 0)
     629                return ENOTSUP;
     630
     631        if (bs->totsec16 != 0 && bs->totsec32 != 0 &&
     632            bs->totsec16 != bs->totsec32)
     633                return ENOTSUP;
     634
     635        /* Check media descriptor. Must be between 0xf0 and 0xff. */
     636        if ((bs->mdesc & 0xf0) != 0xf0)
     637                return ENOTSUP;
     638
     639        /* Check number of sectors per FAT. */
     640        if (bs->sec_per_fat == 0)
     641                return ENOTSUP;
     642
     643        /*
     644         * Check that the root directory entries take up whole blocks.
     645         * This check is rather strict, but it allows us to treat the root
     646         * directory and non-root directories uniformly in some places.
     647         * It can be removed provided that functions such as fat_read() are
     648         * sanitized to support file systems with this property.
     649         */
     650        if ((uint16_t_le2host(bs->root_ent_max) * sizeof(fat_dentry_t)) %
     651            uint16_t_le2host(bs->bps) != 0)
     652                return ENOTSUP;
     653
     654        /* Check signature of each FAT. */
     655
     656        for (fat_no = 0; fat_no < bs->fatcnt; fat_no++) {
     657                rc = fat_get_cluster(bs, dev_handle, fat_no, 0, &e0);
     658                if (rc != EOK)
     659                        return EIO;
     660
     661                rc = fat_get_cluster(bs, dev_handle, fat_no, 1, &e1);
     662                if (rc != EOK)
     663                        return EIO;
     664
     665                /* Check that first byte of FAT contains the media descriptor. */
     666                if ((e0 & 0xff) != bs->mdesc)
     667                        return ENOTSUP;
     668
     669                /*
     670                 * Check that remaining bits of the first two entries are
     671                 * set to one.
     672                 */
     673                if ((e0 >> 8) != 0xff || e1 != 0xffff)
     674                        return ENOTSUP;
     675        }
     676
     677        return EOK;
     678}
     679
    610680/**
    611681 * @}
  • uspace/srv/fs/fat/fat_fat.h

    r83349b03 r19f24fd  
    8787    off_t);
    8888extern int fat_zero_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t);
     89extern int fat_sanity_check(struct fat_bs *, dev_handle_t);
    8990
    9091#endif
  • uspace/srv/fs/fat/fat_idx.c

    r83349b03 r19f24fd  
    149149{
    150150        dev_handle_t dev_handle = (dev_handle_t)key[UPH_DH_KEY];
    151         fat_cluster_t pfc = (fat_cluster_t)key[UPH_PFC_KEY];
    152         unsigned pdi = (unsigned)key[UPH_PDI_KEY];
     151        fat_cluster_t pfc;
     152        unsigned pdi;
    153153        fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uph_link);
    154154
    155         return (dev_handle == fidx->dev_handle) && (pfc == fidx->pfc) &&
    156             (pdi == fidx->pdi);
     155        switch (keys) {
     156        case 1:
     157                return (dev_handle == fidx->dev_handle);
     158        case 3:
     159                pfc = (fat_cluster_t) key[UPH_PFC_KEY];
     160                pdi = (unsigned) key[UPH_PDI_KEY];
     161                return (dev_handle == fidx->dev_handle) && (pfc == fidx->pfc) &&
     162                    (pdi == fidx->pdi);
     163        default:
     164                assert((keys == 1) || (keys == 3));
     165        }
     166
     167        return 0;
    157168}
    158169
     
    197208{
    198209        dev_handle_t dev_handle = (dev_handle_t)key[UIH_DH_KEY];
    199         fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY];
     210        fs_index_t index;
    200211        fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link);
    201212
    202         return (dev_handle == fidx->dev_handle) && (index == fidx->index);
     213        switch (keys) {
     214        case 1:
     215                return (dev_handle == fidx->dev_handle);
     216        case 2:
     217                index = (fs_index_t) key[UIH_INDEX_KEY];
     218                return (dev_handle == fidx->dev_handle) &&
     219                    (index == fidx->index);
     220        default:
     221                assert((keys == 1) || (keys == 2));
     222        }
     223
     224        return 0;
    203225}
    204226
    205227static void idx_remove_callback(link_t *item)
    206228{
    207         /* nothing to do */
     229        fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link);
     230
     231        free(fidx);
    208232}
    209233
     
    486510                [UIH_INDEX_KEY] = idx->index,
    487511        };
     512        dev_handle_t dev_handle = idx->dev_handle;
     513        fs_index_t index = idx->index;
    488514
    489515        assert(idx->pfc == FAT_CLST_RES0);
     
    498524        fibril_mutex_unlock(&used_lock);
    499525        /* Release the VFS index. */
    500         fat_index_free(idx->dev_handle, idx->index);
    501         /* Deallocate the structure. */
    502         free(idx);
     526        fat_index_free(dev_handle, index);
     527        /* The index structure itself is freed in idx_remove_callback(). */
    503528}
    504529
     
    531556        unused_initialize(u, dev_handle);
    532557        fibril_mutex_lock(&unused_lock);
    533         if (!unused_find(dev_handle, false))
     558        if (!unused_find(dev_handle, false)) {
    534559                list_append(&u->link, &unused_head);
    535         else
     560        } else {
     561                free(u);
    536562                rc = EEXIST;
     563        }
    537564        fibril_mutex_unlock(&unused_lock);
    538565        return rc;
     
    541568void fat_idx_fini_by_dev_handle(dev_handle_t dev_handle)
    542569{
    543         unused_t *u;
    544 
    545         u = unused_find(dev_handle, true);
     570        unsigned long ikey[] = {
     571                [UIH_DH_KEY] = dev_handle
     572        };
     573        unsigned long pkey[] = {
     574                [UPH_DH_KEY] = dev_handle
     575        };
     576
     577        /*
     578         * Remove this instance's index structure from up_hash and ui_hash.
     579         * Process up_hash first and ui_hash second because the index structure
     580         * is actually removed in idx_remove_callback().
     581         */
     582        fibril_mutex_lock(&used_lock);
     583        hash_table_remove(&up_hash, pkey, 1);
     584        hash_table_remove(&ui_hash, ikey, 1);
     585        fibril_mutex_unlock(&used_lock);
     586
     587        /*
     588         * Free the unused and freed structures for this instance.
     589         */
     590        unused_t *u = unused_find(dev_handle, true);
    546591        assert(u);
    547592        list_remove(&u->link);
  • uspace/srv/fs/fat/fat_ops.c

    r83349b03 r19f24fd  
    139139}
    140140
     141static int fat_node_fini_by_dev_handle(dev_handle_t dev_handle)
     142{
     143        link_t *lnk;
     144        fat_node_t *nodep;
     145        int rc;
     146
     147        /*
     148         * We are called from fat_unmounted() and assume that there are already
     149         * no nodes belonging to this instance with non-zero refcount. Therefore
     150         * it is sufficient to clean up only the FAT free node list.
     151         */
     152
     153restart:
     154        fibril_mutex_lock(&ffn_mutex);
     155        for (lnk = ffn_head.next; lnk != &ffn_head; lnk = lnk->next) {
     156                nodep = list_get_instance(lnk, fat_node_t, ffn_link);
     157                if (!fibril_mutex_trylock(&nodep->lock)) {
     158                        fibril_mutex_unlock(&ffn_mutex);
     159                        goto restart;
     160                }
     161                if (!fibril_mutex_trylock(&nodep->idx->lock)) {
     162                        fibril_mutex_unlock(&nodep->lock);
     163                        fibril_mutex_unlock(&ffn_mutex);
     164                        goto restart;
     165                }
     166                if (nodep->idx->dev_handle != dev_handle) {
     167                        fibril_mutex_unlock(&nodep->idx->lock);
     168                        fibril_mutex_unlock(&nodep->lock);
     169                        continue;
     170                }
     171
     172                list_remove(&nodep->ffn_link);
     173                fibril_mutex_unlock(&ffn_mutex);
     174
     175                /*
     176                 * We can unlock the node and its index structure because we are
     177                 * the last player on this playground and VFS is preventing new
     178                 * players from entering.
     179                 */
     180                fibril_mutex_unlock(&nodep->idx->lock);
     181                fibril_mutex_unlock(&nodep->lock);
     182
     183                if (nodep->dirty) {
     184                        rc = fat_node_sync(nodep);
     185                        if (rc != EOK)
     186                                return rc;
     187                }
     188                nodep->idx->nodep = NULL;
     189                free(nodep->bp);
     190                free(nodep);
     191
     192                /* Need to restart because we changed the ffn_head list. */
     193                goto restart;
     194        }
     195        fibril_mutex_unlock(&ffn_mutex);
     196
     197        return EOK;
     198}
     199
    141200static int fat_node_get_new(fat_node_t **nodepp)
    142201{
     
    290349
    291350        *nodepp = nodep;
    292         return EOK;
    293 }
    294 
    295 /** Perform basic sanity checks on the file system.
    296  *
    297  * Verify if values of boot sector fields are sane. Also verify media
    298  * descriptor. This is used to rule out cases when a device obviously
    299  * does not contain a fat file system.
    300  */
    301 static int fat_sanity_check(fat_bs_t *bs, dev_handle_t dev_handle)
    302 {
    303         fat_cluster_t e0, e1;
    304         unsigned fat_no;
    305         int rc;
    306 
    307         /* Check number of FATs. */
    308         if (bs->fatcnt == 0)
    309                 return ENOTSUP;
    310 
    311         /* Check total number of sectors. */
    312 
    313         if (bs->totsec16 == 0 && bs->totsec32 == 0)
    314                 return ENOTSUP;
    315 
    316         if (bs->totsec16 != 0 && bs->totsec32 != 0 &&
    317             bs->totsec16 != bs->totsec32)
    318                 return ENOTSUP;
    319 
    320         /* Check media descriptor. Must be between 0xf0 and 0xff. */
    321         if ((bs->mdesc & 0xf0) != 0xf0)
    322                 return ENOTSUP;
    323 
    324         /* Check number of sectors per FAT. */
    325         if (bs->sec_per_fat == 0)
    326                 return ENOTSUP;
    327 
    328         /*
    329          * Check that the root directory entries take up whole blocks.
    330          * This check is rather strict, but it allows us to treat the root
    331          * directory and non-root directories uniformly in some places.
    332          * It can be removed provided that functions such as fat_read() are
    333          * sanitized to support file systems with this property.
    334          */
    335         if ((uint16_t_le2host(bs->root_ent_max) * sizeof(fat_dentry_t)) %
    336             uint16_t_le2host(bs->bps) != 0)
    337                 return ENOTSUP;
    338 
    339         /* Check signature of each FAT. */
    340 
    341         for (fat_no = 0; fat_no < bs->fatcnt; fat_no++) {
    342                 rc = fat_get_cluster(bs, dev_handle, fat_no, 0, &e0);
    343                 if (rc != EOK)
    344                         return EIO;
    345 
    346                 rc = fat_get_cluster(bs, dev_handle, fat_no, 1, &e1);
    347                 if (rc != EOK)
    348                         return EIO;
    349 
    350                 /* Check that first byte of FAT contains the media descriptor. */
    351                 if ((e0 & 0xff) != bs->mdesc)
    352                         return ENOTSUP;
    353 
    354                 /*
    355                  * Check that remaining bits of the first two entries are
    356                  * set to one.
    357                  */
    358                 if ((e0 >> 8) != 0xff || e1 != 0xffff)
    359                         return ENOTSUP;
    360         }
    361 
    362351        return EOK;
    363352}
     
    985974        uint16_t bps;
    986975        uint16_t rde;
    987         int rc;
    988 
    989         /* accept the mount options */
    990         ipc_callid_t callid;
    991         size_t size;
    992         if (!async_data_write_receive(&callid, &size)) {
    993                 ipc_answer_0(callid, EINVAL);
    994                 ipc_answer_0(rid, EINVAL);
    995                 return;
    996         }
    997         char *opts = malloc(size + 1);
    998         if (!opts) {
    999                 ipc_answer_0(callid, ENOMEM);
    1000                 ipc_answer_0(rid, ENOMEM);
    1001                 return;
    1002         }
    1003         ipcarg_t retval = async_data_write_finalize(callid, opts, size);
    1004         if (retval != EOK) {
    1005                 ipc_answer_0(rid, retval);
    1006                 free(opts);
    1007                 return;
    1008         }
    1009         opts[size] = '\0';
     976       
     977        /* Accept the mount options */
     978        char *opts;
     979        int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
     980       
     981        if (rc != EOK) {
     982                ipc_answer_0(rid, rc);
     983                return;
     984        }
    1010985
    1011986        /* Check for option enabling write through. */
     
    1015990                cmode = CACHE_MODE_WB;
    1016991
     992        free(opts);
     993
    1017994        /* initialize libblock */
    1018995        rc = block_init(dev_handle, BS_SIZE);
     
    10541031        rc = fat_sanity_check(bs, dev_handle);
    10551032        if (rc != EOK) {
     1033                (void) block_cache_fini(dev_handle);
    10561034                block_fini(dev_handle);
    10571035                ipc_answer_0(rid, rc);
     
    10611039        rc = fat_idx_init_by_dev_handle(dev_handle);
    10621040        if (rc != EOK) {
     1041                (void) block_cache_fini(dev_handle);
    10631042                block_fini(dev_handle);
    10641043                ipc_answer_0(rid, rc);
     
    10691048        fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
    10701049        if (!rfn) {
     1050                (void) block_cache_fini(dev_handle);
    10711051                block_fini(dev_handle);
    10721052                fat_idx_fini_by_dev_handle(dev_handle);
     
    10781058        if (!rootp) {
    10791059                free(rfn);
     1060                (void) block_cache_fini(dev_handle);
    10801061                block_fini(dev_handle);
    10811062                fat_idx_fini_by_dev_handle(dev_handle);
     
    10891070                free(rfn);
    10901071                free(rootp);
     1072                (void) block_cache_fini(dev_handle);
    10911073                block_fini(dev_handle);
    10921074                fat_idx_fini_by_dev_handle(dev_handle);
     
    11151097{
    11161098        libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
     1099}
     1100
     1101void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)
     1102{
     1103        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     1104        fs_node_t *fn;
     1105        fat_node_t *nodep;
     1106        int rc;
     1107
     1108        rc = fat_root_get(&fn, dev_handle);
     1109        if (rc != EOK) {
     1110                ipc_answer_0(rid, rc);
     1111                return;
     1112        }
     1113        nodep = FAT_NODE(fn);
     1114
     1115        /*
     1116         * We expect exactly two references on the root node. One for the
     1117         * fat_root_get() above and one created in fat_mounted().
     1118         */
     1119        if (nodep->refcnt != 2) {
     1120                (void) fat_node_put(fn);
     1121                ipc_answer_0(rid, EBUSY);
     1122                return;
     1123        }
     1124       
     1125        /*
     1126         * Put the root node and force it to the FAT free node list.
     1127         */
     1128        (void) fat_node_put(fn);
     1129        (void) fat_node_put(fn);
     1130
     1131        /*
     1132         * Perform cleanup of the node structures, index structures and
     1133         * associated data. Write back this file system's dirty blocks and
     1134         * stop using libblock for this instance.
     1135         */
     1136        (void) fat_node_fini_by_dev_handle(dev_handle);
     1137        fat_idx_fini_by_dev_handle(dev_handle);
     1138        (void) block_cache_fini(dev_handle);
     1139        block_fini(dev_handle);
     1140
     1141        ipc_answer_0(rid, EOK);
     1142}
     1143
     1144void fat_unmount(ipc_callid_t rid, ipc_call_t *request)
     1145{
     1146        libfs_unmount(&fat_libfs_ops, rid, request);
    11171147}
    11181148
  • uspace/srv/fs/tmpfs/tmpfs.c

    r83349b03 r19f24fd  
    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;
    108114                case VFS_OUT_LOOKUP:
    109115                        tmpfs_lookup(callid, &call);
  • uspace/srv/fs/tmpfs/tmpfs.h

    r83349b03 r19f24fd  
    8383extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *);
    8484extern void tmpfs_mount(ipc_callid_t, ipc_call_t *);
     85extern void tmpfs_unmounted(ipc_callid_t, ipc_call_t *);
     86extern void tmpfs_unmount(ipc_callid_t, ipc_call_t *);
    8587extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);
    8688extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r83349b03 r19f24fd  
    147147hash_table_t nodes;
    148148
    149 #define NODES_KEY_INDEX 0
    150 #define NODES_KEY_DEV   1
     149#define NODES_KEY_DEV   0       
     150#define NODES_KEY_INDEX 1
    151151
    152152/* Implementation of hash table interface for the nodes hash table. */
     
    160160        tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
    161161            nh_link);
    162         return (nodep->index == key[NODES_KEY_INDEX] &&
    163             nodep->dev_handle == key[NODES_KEY_DEV]);
     162       
     163        switch (keys) {
     164        case 1:
     165                return (nodep->dev_handle == key[NODES_KEY_DEV]);
     166        case 2:
     167                return ((nodep->dev_handle == key[NODES_KEY_DEV]) &&
     168                    (nodep->index == key[NODES_KEY_INDEX]));
     169        default:
     170                assert((keys == 1) || (keys == 2));
     171        }
     172
     173        return 0;
    164174}
    165175
    166176static void nodes_remove_callback(link_t *item)
    167177{
     178        tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
     179            nh_link);
     180
     181        while (!list_empty(&nodep->cs_head)) {
     182                tmpfs_dentry_t *dentryp = list_get_instance(nodep->cs_head.next,
     183                    tmpfs_dentry_t, link);
     184
     185                assert(nodep->type == TMPFS_DIRECTORY);
     186                list_remove(&dentryp->link);
     187                free(dentryp);
     188        }
     189
     190        if (nodep->data) {
     191                assert(nodep->type == TMPFS_FILE);
     192                free(nodep->data);
     193        }
     194        free(nodep->bp);
     195        free(nodep);
    168196}
    169197
     
    215243}
    216244
     245static void tmpfs_instance_done(dev_handle_t dev_handle)
     246{
     247        unsigned long key[] = {
     248                [NODES_KEY_DEV] = dev_handle
     249        };
     250        /*
     251         * Here we are making use of one special feature of our hash table
     252         * implementation, which allows to remove more items based on a partial
     253         * key match. In the following, we are going to remove all nodes
     254         * matching our device handle. The nodes_remove_callback() function will
     255         * take care of resource deallocation.
     256         */
     257        hash_table_remove(&nodes, key, 1);
     258}
     259
    217260int tmpfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
    218261{
     
    237280{
    238281        unsigned long key[] = {
    239                 [NODES_KEY_INDEX] = index,
    240                 [NODES_KEY_DEV] = dev_handle
     282                [NODES_KEY_DEV] = dev_handle,
     283                [NODES_KEY_INDEX] = index
    241284        };
    242285        link_t *lnk = hash_table_find(&nodes, key);
     
    296339        /* Insert the new node into the nodes hash table. */
    297340        unsigned long key[] = {
    298                 [NODES_KEY_INDEX] = nodep->index,
    299                 [NODES_KEY_DEV] = nodep->dev_handle
     341                [NODES_KEY_DEV] = nodep->dev_handle,
     342                [NODES_KEY_INDEX] = nodep->index
    300343        };
    301344        hash_table_insert(&nodes, key, &nodep->nh_link);
     
    312355
    313356        unsigned long key[] = {
    314                 [NODES_KEY_INDEX] = nodep->index,
    315                 [NODES_KEY_DEV] = nodep->dev_handle
     357                [NODES_KEY_DEV] = nodep->dev_handle,
     358                [NODES_KEY_INDEX] = nodep->index
    316359        };
    317360        hash_table_remove(&nodes, key, 2);
    318361
    319         if (nodep->type == TMPFS_FILE)
    320                 free(nodep->data);
    321         free(nodep->bp);
    322         free(nodep);
     362        /*
     363         * The nodes_remove_callback() function takes care of the actual
     364         * resource deallocation.
     365         */
    323366        return EOK;
    324367}
     
    398441{
    399442        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     443        fs_node_t *rootfn;
    400444        int rc;
    401 
    402         /* accept the mount options */
    403         ipc_callid_t callid;
    404         size_t size;
    405         if (!async_data_write_receive(&callid, &size)) {
    406                 ipc_answer_0(callid, EINVAL);
    407                 ipc_answer_0(rid, EINVAL);
    408                 return;
    409         }
    410         char *opts = malloc(size + 1);
    411         if (!opts) {
    412                 ipc_answer_0(callid, ENOMEM);
    413                 ipc_answer_0(rid, ENOMEM);
    414                 return;
    415         }
    416         ipcarg_t retval = async_data_write_finalize(callid, opts, size);
    417         if (retval != EOK) {
    418                 ipc_answer_0(rid, retval);
     445       
     446        /* Accept the mount options. */
     447        char *opts;
     448        rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
     449        if (rc != EOK) {
     450                ipc_answer_0(rid, rc);
     451                return;
     452        }
     453
     454        /* Check if this device is not already mounted. */
     455        rc = tmpfs_root_get(&rootfn, dev_handle);
     456        if ((rc == EOK) && (rootfn)) {
     457                (void) tmpfs_node_put(rootfn);
    419458                free(opts);
    420                 return;
    421         }
    422         opts[size] = '\0';
     459                ipc_answer_0(rid, EEXIST);
     460                return;
     461        }
    423462
    424463        /* Initialize TMPFS instance. */
    425464        if (!tmpfs_instance_init(dev_handle)) {
     465                free(opts);
    426466                ipc_answer_0(rid, ENOMEM);
    427467                return;
    428468        }
    429469
    430         fs_node_t *rootfn;
    431470        rc = tmpfs_root_get(&rootfn, dev_handle);
    432471        assert(rc == EOK);
     
    442481                    rootp->lnkcnt);
    443482        }
     483        free(opts);
    444484}
    445485
     
    447487{
    448488        libfs_mount(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
     489}
     490
     491void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
     492{
     493        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     494
     495        tmpfs_instance_done(dev_handle);
     496        ipc_answer_0(rid, EOK);
     497}
     498
     499void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request)
     500{
     501        libfs_unmount(&tmpfs_libfs_ops, rid, request);
    449502}
    450503
     
    465518        link_t *hlp;
    466519        unsigned long key[] = {
    467                 [NODES_KEY_INDEX] = index,
    468520                [NODES_KEY_DEV] = dev_handle,
     521                [NODES_KEY_INDEX] = index
    469522        };
    470523        hlp = hash_table_find(&nodes, key);
     
    539592        link_t *hlp;
    540593        unsigned long key[] = {
    541                 [NODES_KEY_INDEX] = index,
    542                 [NODES_KEY_DEV] = dev_handle
     594                [NODES_KEY_DEV] = dev_handle,
     595                [NODES_KEY_INDEX] = index
    543596        };
    544597        hlp = hash_table_find(&nodes, key);
     
    603656        link_t *hlp;
    604657        unsigned long key[] = {
    605                 [NODES_KEY_INDEX] = index,
    606                 [NODES_KEY_DEV] = dev_handle
     658                [NODES_KEY_DEV] = dev_handle,
     659                [NODES_KEY_INDEX] = index
    607660        };
    608661        hlp = hash_table_find(&nodes, key);
     
    646699        link_t *hlp;
    647700        unsigned long key[] = {
    648                 [NODES_KEY_INDEX] = index,
    649                 [NODES_KEY_DEV] = dev_handle
     701                [NODES_KEY_DEV] = dev_handle,
     702                [NODES_KEY_INDEX] = index
    650703        };
    651704        hlp = hash_table_find(&nodes, key);
  • uspace/srv/hid/char_mouse/Makefile

    r83349b03 r19f24fd  
    3232EXTRA_CFLAGS = -Iinclude
    3333
    34 OUTPUT = c_mouse
     34OUTPUT = char_ms
    3535
    3636SOURCES = \
    3737        proto/ps2.c \
    38         c_mouse.c \
     38        char_mouse.c \
    3939        chardev.c
    4040
  • uspace/srv/hid/char_mouse/char_mouse.c

    r83349b03 r19f24fd  
    4747#include <devmap.h>
    4848
    49 #include <c_mouse.h>
     49#include <char_mouse.h>
    5050#include <mouse_port.h>
    5151#include <mouse_proto.h>
  • uspace/srv/hid/char_mouse/chardev.c

    r83349b03 r19f24fd  
    4141#include <errno.h>
    4242
    43 #include <c_mouse.h>
     43#include <char_mouse.h>
    4444#include <mouse_port.h>
    4545
  • uspace/srv/hid/char_mouse/include/char_mouse.h

    r83349b03 r19f24fd  
    3434 */
    3535
    36 #ifndef C_MOUSE_H_
    37 #define C_MOUSE_H_
     36#ifndef CHAR_MOUSE_H_
     37#define CHAR_MOUSE_H_
    3838
    3939extern void mouse_handle_byte(int);
  • uspace/srv/hid/char_mouse/proto/ps2.c

    r83349b03 r19f24fd  
    3737#include <stdio.h>
    3838#include <mouse_proto.h>
    39 #include <c_mouse.h>
     39#include <char_mouse.h>
    4040
    4141#define BUFSIZE 3
  • uspace/srv/hid/console/console.c

    r83349b03 r19f24fd  
    475475static void cons_write(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
    476476{
    477         ipc_callid_t callid;
     477        void *buf;
    478478        size_t size;
    479         if (!async_data_write_receive(&callid, &size)) {
    480                 ipc_answer_0(callid, EINVAL);
    481                 ipc_answer_0(rid, EINVAL);
     479        int rc = async_data_write_accept(&buf, false, 0, 0, 0, &size);
     480       
     481        if (rc != EOK) {
     482                ipc_answer_0(rid, rc);
    482483                return;
    483484        }
    484        
    485         char *buf = (char *) malloc(size);
    486         if (buf == NULL) {
    487                 ipc_answer_0(callid, ENOMEM);
    488                 ipc_answer_0(rid, ENOMEM);
    489                 return;
    490         }
    491        
    492         (void) async_data_write_finalize(callid, buf, size);
    493485       
    494486        async_serialize_start();
  • uspace/srv/hid/kbd/Makefile.build

    r83349b03 r19f24fd  
    125125ifeq ($(UARCH),ppc32)
    126126        SOURCES += \
    127                 port/dummy.c \
    128                 ctl/stty.c
     127                port/adb.c \
     128                ctl/apple.c
    129129endif
    130130
  • uspace/srv/loader/elf_load.c

    r83349b03 r19f24fd  
    342342        seg_ptr = (void *) seg_addr;
    343343
    344         DPRINTF("Load segment at addr 0x%x, size 0x%x\n", seg_addr,
    345                 entry->p_memsz);       
     344        DPRINTF("Load segment at addr %p, size 0x%x\n", seg_addr,
     345                entry->p_memsz);
    346346
    347347        if (entry->p_align > 1) {
     
    370370        mem_sz = entry->p_memsz + (entry->p_vaddr - base);
    371371
    372         DPRINTF("Map to seg_addr=0x%x-0x%x.\n", seg_addr,
     372        DPRINTF("Map to seg_addr=%p-%p.\n", seg_addr,
    373373        entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE));
    374374
     
    384384        }
    385385
    386         DPRINTF("as_area_create(0x%lx, 0x%x, %d) -> 0x%lx\n",
     386        DPRINTF("as_area_create(%p, 0x%x, %d) -> 0x%lx\n",
    387387                base + bias, mem_sz, flags, (uintptr_t)a);
    388388
     
    461461                elf->info->dynamic =
    462462                    (void *)((uint8_t *)entry->sh_addr + elf->bias);
    463                 DPRINTF("Dynamic section found at 0x%x.\n",
     463                DPRINTF("Dynamic section found at %p.\n",
    464464                        (uintptr_t)elf->info->dynamic);
    465465                break;
  • uspace/srv/loader/main.c

    r83349b03 r19f24fd  
    125125static void ldr_set_cwd(ipc_callid_t rid, ipc_call_t *request)
    126126{
    127         ipc_callid_t callid;
    128         size_t len;
    129        
    130         if (!async_data_write_receive(&callid, &len)) {
    131                 ipc_answer_0(callid, EINVAL);
    132                 ipc_answer_0(rid, EINVAL);
    133                 return;
    134         }
    135        
    136         cwd = malloc(len + 1);
    137         if (!cwd) {
    138                 ipc_answer_0(callid, ENOMEM);
    139                 ipc_answer_0(rid, ENOMEM);
    140                 return;
    141         }
    142        
    143         async_data_write_finalize(callid, cwd, len);
    144         cwd[len] = '\0';
    145        
    146         ipc_answer_0(rid, EOK);
     127        char *buf;
     128        int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL);
     129       
     130        if (rc == EOK) {
     131                if (cwd != NULL)
     132                        free(cwd);
     133               
     134                cwd = buf;
     135        }
     136       
     137        ipc_answer_0(rid, rc);
    147138}
    148139
     
    154145static void ldr_set_pathname(ipc_callid_t rid, ipc_call_t *request)
    155146{
    156         ipc_callid_t callid;
    157         size_t len;
    158         char *name_buf;
    159        
    160         if (!async_data_write_receive(&callid, &len)) {
    161                 ipc_answer_0(callid, EINVAL);
    162                 ipc_answer_0(rid, EINVAL);
    163                 return;
    164         }
    165        
    166         name_buf = malloc(len + 1);
    167         if (!name_buf) {
    168                 ipc_answer_0(callid, ENOMEM);
    169                 ipc_answer_0(rid, ENOMEM);
    170                 return;
    171         }
    172        
    173         async_data_write_finalize(callid, name_buf, len);
    174         ipc_answer_0(rid, EOK);
    175        
    176         if (pathname != NULL) {
    177                 free(pathname);
    178                 pathname = NULL;
    179         }
    180        
    181         name_buf[len] = '\0';
    182         pathname = name_buf;
     147        char *buf;
     148        int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL);
     149       
     150        if (rc == EOK) {
     151                if (pathname != NULL)
     152                        free(pathname);
     153               
     154                pathname = buf;
     155        }
     156       
     157        ipc_answer_0(rid, rc);
    183158}
    184159
     
    190165static void ldr_set_args(ipc_callid_t rid, ipc_call_t *request)
    191166{
    192         ipc_callid_t callid;
    193         size_t buf_size, arg_size;
    194         char *p;
    195         int n;
    196        
    197         if (!async_data_write_receive(&callid, &buf_size)) {
    198                 ipc_answer_0(callid, EINVAL);
    199                 ipc_answer_0(rid, EINVAL);
    200                 return;
    201         }
    202        
    203         if (arg_buf != NULL) {
    204                 free(arg_buf);
    205                 arg_buf = NULL;
    206         }
    207        
    208         if (argv != NULL) {
    209                 free(argv);
    210                 argv = NULL;
    211         }
    212        
    213         arg_buf = malloc(buf_size + 1);
    214         if (!arg_buf) {
    215                 ipc_answer_0(callid, ENOMEM);
    216                 ipc_answer_0(rid, ENOMEM);
    217                 return;
    218         }
    219        
    220         async_data_write_finalize(callid, arg_buf, buf_size);
    221        
    222         arg_buf[buf_size] = '\0';
    223        
    224         /*
    225          * Count number of arguments
    226          */
    227         p = arg_buf;
    228         n = 0;
    229         while (p < arg_buf + buf_size) {
    230                 arg_size = str_size(p);
    231                 p = p + arg_size + 1;
    232                 ++n;
    233         }
    234        
    235         /* Allocate argv */
    236         argv = malloc((n + 1) * sizeof(char *));
    237        
    238         if (argv == NULL) {
    239                 free(arg_buf);
    240                 ipc_answer_0(rid, ENOMEM);
    241                 return;
    242         }
    243 
    244         /*
    245          * Fill argv with argument pointers
    246          */
    247         p = arg_buf;
    248         n = 0;
    249         while (p < arg_buf + buf_size) {
    250                 argv[n] = p;
    251                
    252                 arg_size = str_size(p);
    253                 p = p + arg_size + 1;
    254                 ++n;
    255         }
    256        
    257         argc = n;
    258         argv[n] = NULL;
    259 
    260         ipc_answer_0(rid, EOK);
     167        char *buf;
     168        size_t buf_size;
     169        int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, &buf_size);
     170       
     171        if (rc == EOK) {
     172                /*
     173                 * Count number of arguments
     174                 */
     175                char *cur = buf;
     176                int count = 0;
     177               
     178                while (cur < buf + buf_size) {
     179                        size_t arg_size = str_size(cur);
     180                        cur += arg_size + 1;
     181                        count++;
     182                }
     183               
     184                /*
     185                 * Allocate new argv
     186                 */
     187                char **_argv = (char **) malloc((count + 1) * sizeof(char *));
     188                if (_argv == NULL) {
     189                        free(buf);
     190                        ipc_answer_0(rid, ENOMEM);
     191                        return;
     192                }
     193               
     194                /*
     195                 * Fill the new argv with argument pointers
     196                 */
     197                cur = buf;
     198                count = 0;
     199                while (cur < buf + buf_size) {
     200                        _argv[count] = cur;
     201                       
     202                        size_t arg_size = str_size(cur);
     203                        cur += arg_size + 1;
     204                        count++;
     205                }
     206                _argv[count] = NULL;
     207               
     208                /*
     209                 * Copy temporary data to global variables
     210                 */
     211                if (arg_buf != NULL)
     212                        free(arg_buf);
     213               
     214                if (argv != NULL)
     215                        free(argv);
     216               
     217                argc = count;
     218                arg_buf = buf;
     219                argv = _argv;
     220        }
     221       
     222        ipc_answer_0(rid, rc);
    261223}
    262224
     
    268230static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
    269231{
    270         ipc_callid_t callid;
     232        fdi_node_t *buf;
    271233        size_t buf_size;
    272         if (!async_data_write_receive(&callid, &buf_size)) {
    273                 ipc_answer_0(callid, EINVAL);
    274                 ipc_answer_0(rid, EINVAL);
    275                 return;
    276         }
    277        
    278         if ((buf_size % sizeof(fdi_node_t)) != 0) {
    279                 ipc_answer_0(callid, EINVAL);
    280                 ipc_answer_0(rid, EINVAL);
    281                 return;
    282         }
    283        
    284         if (fil_buf != NULL) {
    285                 free(fil_buf);
    286                 fil_buf = NULL;
    287         }
    288        
    289         if (filv != NULL) {
    290                 free(filv);
    291                 filv = NULL;
    292         }
    293        
    294         fil_buf = malloc(buf_size);
    295         if (!fil_buf) {
    296                 ipc_answer_0(callid, ENOMEM);
    297                 ipc_answer_0(rid, ENOMEM);
    298                 return;
    299         }
    300        
    301         async_data_write_finalize(callid, fil_buf, buf_size);
    302        
    303         int count = buf_size / sizeof(fdi_node_t);
    304        
    305         /* Allocate filvv */
    306         filv = malloc((count + 1) * sizeof(fdi_node_t *));
    307        
    308         if (filv == NULL) {
    309                 free(fil_buf);
    310                 ipc_answer_0(rid, ENOMEM);
    311                 return;
    312         }
    313        
    314         /*
    315          * Fill filv with argument pointers
    316          */
    317         int i;
    318         for (i = 0; i < count; i++)
    319                 filv[i] = &fil_buf[i];
    320        
    321         filc = count;
    322         filv[count] = NULL;
     234        int rc = async_data_write_accept((void **) &buf, false, 0, 0,
     235            sizeof(fdi_node_t), &buf_size);
     236       
     237        if (rc == EOK) {
     238                int count = buf_size / sizeof(fdi_node_t);
     239               
     240                /*
     241                 * Allocate new filv
     242                 */
     243                fdi_node_t **_filv = (fdi_node_t *) malloc((count + 1) * sizeof(fdi_node_t *));
     244                if (_filv == NULL) {
     245                        free(buf);
     246                        ipc_answer_0(rid, ENOMEM);
     247                        return;
     248                }
     249               
     250                /*
     251                 * Fill the new filv with argument pointers
     252                 */
     253                int i;
     254                for (i = 0; i < count; i++)
     255                        _filv[i] = &buf[i];
     256               
     257                _filv[count] = NULL;
     258               
     259                /*
     260                 * Copy temporary data to global variables
     261                 */
     262                if (fil_buf != NULL)
     263                        free(fil_buf);
     264               
     265                if (filv != NULL)
     266                        free(filv);
     267               
     268                filc = count;
     269                fil_buf = buf;
     270                filv = _filv;
     271        }
    323272       
    324273        ipc_answer_0(rid, EOK);
     
    392341                /* Dynamically linked program */
    393342                DPRINTF("Run ELF interpreter.\n");
    394                 DPRINTF("Entry point: 0x%lx\n", interp_info.entry);
     343                DPRINTF("Entry point: %p\n", interp_info.entry);
    395344               
    396345                ipc_answer_0(rid, EOK);
  • uspace/srv/taskmon/taskmon.c

    r83349b03 r19f24fd  
    3939#include <async.h>
    4040#include <ipc/services.h>
     41#include <sys/typefmt.h>
    4142#include <task.h>
    4243#include <event.h>
     
    6061        thread = IPC_GET_ARG3(*call);
    6162
    62         if (asprintf(&s_taskid, "%lld", taskid) < 0) {
     63        if (asprintf(&s_taskid, "%" PRIuTASKID, taskid) < 0) {
    6364                printf("Memory allocation failed.\n");
    6465                return;
    6566        }
    6667
    67         if (asprintf(&dump_fname, "/scratch/d%lld.txt", taskid) < 0) {
     68        if (asprintf(&dump_fname, "/scratch/d" PRIuTASKID ".txt", taskid) < 0) {
    6869                printf("Memory allocation failed.\n");
    6970                return;
    7071        }
    7172
    72         printf(NAME ": Task %lld fault in thread 0x%lx.\n", taskid, thread);
     73        printf(NAME ": Task %" PRIuTASKID " fault in thread %p.\n", taskid, thread);
    7374
    7475#ifdef CONFIG_VERBOSE_DUMPS
  • uspace/srv/vfs/vfs.c

    r83349b03 r19f24fd  
    8787                        vfs_mount(callid, &call);
    8888                        break;
     89                case VFS_IN_UNMOUNT:
     90                        vfs_unmount(callid, &call);
     91                        break;
    8992                case VFS_IN_OPEN:
    9093                        vfs_open(callid, &call);
     
    134137        }
    135138       
    136         /* TODO: cleanup after the client */
     139        vfs_files_done();
    137140}
    138141
  • uspace/srv/vfs/vfs.h

    r83349b03 r19f24fd  
    177177    vfs_pair_t *, ...);
    178178extern int vfs_open_node_internal(vfs_lookup_res_t *);
     179extern int vfs_close_internal(vfs_file_t *);
    179180
    180181extern bool vfs_nodes_init(void);
    181182extern vfs_node_t *vfs_node_get(vfs_lookup_res_t *);
    182183extern void vfs_node_put(vfs_node_t *);
     184extern void vfs_node_forget(vfs_node_t *);
     185extern unsigned vfs_nodes_refcount_sum_get(fs_handle_t, dev_handle_t);
     186
    183187
    184188#define MAX_OPEN_FILES  128
    185189
    186190extern bool vfs_files_init(void);
     191extern void vfs_files_done(void);
    187192extern vfs_file_t *vfs_file_get(int);
    188193extern int vfs_fd_assign(vfs_file_t *file, int fd);
     
    198203extern void vfs_register(ipc_callid_t, ipc_call_t *);
    199204extern void vfs_mount(ipc_callid_t, ipc_call_t *);
     205extern void vfs_unmount(ipc_callid_t, ipc_call_t *);
    200206extern void vfs_open(ipc_callid_t, ipc_call_t *);
    201207extern void vfs_open_node(ipc_callid_t, ipc_call_t *);
  • uspace/srv/vfs/vfs_file.c

    r83349b03 r19f24fd  
    7272        }
    7373        return true;
     74}
     75
     76/** Cleanup the table of open files. */
     77void vfs_files_done(void)
     78{
     79        int i;
     80
     81        if (!files)
     82                return;
     83
     84        for (i = 0; i < MAX_OPEN_FILES; i++) {
     85                if (files[i]) {
     86                        (void) vfs_close_internal(files[i]);
     87                        (void) vfs_fd_free(i);
     88                }
     89        }
     90       
     91        free(files);
    7492}
    7593
  • uspace/srv/vfs/vfs_node.c

    r83349b03 r19f24fd  
    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 */
     148void 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);
    139159}
    140160
     
    231251}
    232252
     253struct 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
     260static 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
     270unsigned
     271vfs_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
    233286/**
    234287 * @}
  • uspace/srv/vfs/vfs_ops.c

    r83349b03 r19f24fd  
    9292                }
    9393               
    94                 rc = vfs_lookup_internal(mp, L_DIRECTORY, &mp_res, NULL);
     94                rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
    9595                if (rc != EOK) {
    9696                        /* The lookup failed for some reason. */
     
    266266       
    267267        /* We want the client to send us the mount point. */
    268         ipc_callid_t callid;
    269         size_t size;
    270         if (!async_data_write_receive(&callid, &size)) {
    271                 ipc_answer_0(callid, EINVAL);
    272                 ipc_answer_0(rid, EINVAL);
    273                 return;
    274         }
    275        
    276         /* Check whether size is reasonable wrt. the mount point. */
    277         if ((size < 1) || (size > MAX_PATH_LEN)) {
    278                 ipc_answer_0(callid, EINVAL);
    279                 ipc_answer_0(rid, EINVAL);
    280                 return;
    281         }
    282        
    283         /* Allocate buffer for the mount point data being received. */
    284         char *mp = malloc(size + 1);
    285         if (!mp) {
    286                 ipc_answer_0(callid, ENOMEM);
    287                 ipc_answer_0(rid, ENOMEM);
    288                 return;
    289         }
    290        
    291         /* Deliver the mount point. */
    292         ipcarg_t retval = async_data_write_finalize(callid, mp, size);
    293         if (retval != EOK) {
    294                 ipc_answer_0(rid, retval);
     268        char *mp;
     269        int rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
     270            0, NULL);
     271        if (rc != EOK) {
     272                ipc_answer_0(rid, rc);
     273                return;
     274        }
     275       
     276        /* Now we expect to receive the mount options. */
     277        char *opts;
     278        rc = async_data_write_accept((void **) &opts, true, 0, MAX_MNTOPTS_LEN,
     279            0, NULL);
     280        if (rc != EOK) {
    295281                free(mp);
    296                 return;
    297         }
    298         mp[size] = '\0';
    299        
    300         /* Now we expect to receive the mount options. */
    301         if (!async_data_write_receive(&callid, &size)) {
    302                 ipc_answer_0(callid, EINVAL);
    303                 ipc_answer_0(rid, EINVAL);
    304                 free(mp);
    305                 return;
    306         }
    307 
    308         /* Check the offered options size. */
    309         if (size > MAX_MNTOPTS_LEN) {
    310                 ipc_answer_0(callid, EINVAL);
    311                 ipc_answer_0(rid, EINVAL);
    312                 free(mp);
    313                 return;
    314         }
    315 
    316         /* Allocate buffer for the mount options. */
    317         char *opts = (char *) malloc(size + 1);
    318         if (!opts) {
    319                 ipc_answer_0(callid, ENOMEM);
    320                 ipc_answer_0(rid, ENOMEM);
    321                 free(mp);
    322                 return;
    323         }
    324 
    325         /* Deliver the mount options. */
    326         retval = async_data_write_finalize(callid, opts, size);
    327         if (retval != EOK) {
    328                 ipc_answer_0(rid, retval);
     282                ipc_answer_0(rid, rc);
     283                return;
     284        }
     285       
     286        /*
     287         * Now, we expect the client to send us data with the name of the file
     288         * system.
     289         */
     290        char *fs_name;
     291        rc = async_data_write_accept((void **) &fs_name, true, 0, FS_NAME_MAXLEN,
     292            0, NULL);
     293        if (rc != EOK) {
    329294                free(mp);
    330295                free(opts);
    331                 return;
    332         }
    333         opts[size] = '\0';
    334        
    335         /*
    336          * Now, we expect the client to send us data with the name of the file
    337          * system.
    338          */
    339         if (!async_data_write_receive(&callid, &size)) {
    340                 ipc_answer_0(callid, EINVAL);
    341                 ipc_answer_0(rid, EINVAL);
    342                 free(mp);
    343                 free(opts);
    344                 return;
    345         }
    346        
    347         /*
    348          * Don't receive more than is necessary for storing a full file system
    349          * name.
    350          */
    351         if ((size < 1) || (size > FS_NAME_MAXLEN)) {
    352                 ipc_answer_0(callid, EINVAL);
    353                 ipc_answer_0(rid, EINVAL);
    354                 free(mp);
    355                 free(opts);
    356                 return;
    357         }
    358        
    359         /*
    360          * Allocate buffer for file system name.
    361          */
    362         char *fs_name = (char *) malloc(size + 1);
    363         if (fs_name == NULL) {
    364                 ipc_answer_0(callid, ENOMEM);
    365                 ipc_answer_0(rid, ENOMEM);
    366                 free(mp);
    367                 free(opts);
    368                 return;
    369         }
    370        
    371         /* Deliver the file system name. */
    372         retval = async_data_write_finalize(callid, fs_name, size);
    373         if (retval != EOK) {
    374                 ipc_answer_0(rid, retval);
    375                 free(mp);
    376                 free(opts);
    377                 free(fs_name);
    378                 return;
    379         }
    380         fs_name[size] = '\0';
    381 
     296                ipc_answer_0(rid, rc);
     297                return;
     298        }
     299       
    382300        /*
    383301         * Wait for IPC_M_PING so that we can return an error if we don't know
     
    385303         */
    386304        ipc_call_t data;
    387         callid = async_get_call(&data);
     305        ipc_callid_t callid = async_get_call(&data);
    388306        if (IPC_GET_METHOD(data) != IPC_M_PING) {
    389307                ipc_answer_0(callid, ENOTSUP);
     
    429347}
    430348
     349void vfs_unmount(ipc_callid_t rid, ipc_call_t *request)
     350{
     351        int rc;
     352        char *mp;
     353        vfs_lookup_res_t mp_res;
     354        vfs_lookup_res_t mr_res;
     355        vfs_node_t *mp_node;
     356        vfs_node_t *mr_node;
     357        int phone;
     358
     359        /*
     360         * Receive the mount point path.
     361         */
     362        rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
     363            0, NULL);
     364        if (rc != EOK)
     365                ipc_answer_0(rid, rc);
     366
     367        /*
     368         * Taking the namespace lock will do two things for us. First, it will
     369         * prevent races with other lookup operations. Second, it will stop new
     370         * references to already existing VFS nodes and creation of new VFS
     371         * nodes. This is because new references are added as a result of some
     372         * lookup operation or at least of some operation which is protected by
     373         * the namespace lock.
     374         */
     375        fibril_rwlock_write_lock(&namespace_rwlock);
     376       
     377        /*
     378         * Lookup the mounted root and instantiate it.
     379         */
     380        rc = vfs_lookup_internal(mp, L_ROOT, &mr_res, NULL);
     381        if (rc != EOK) {
     382                fibril_rwlock_write_unlock(&namespace_rwlock);
     383                free(mp);
     384                ipc_answer_0(rid, rc);
     385                return;
     386        }
     387        mr_node = vfs_node_get(&mr_res);
     388        if (!mr_node) {
     389                fibril_rwlock_write_unlock(&namespace_rwlock);
     390                free(mp);
     391                ipc_answer_0(rid, ENOMEM);
     392                return;
     393        }
     394
     395        /*
     396         * Count the total number of references for the mounted file system. We
     397         * are expecting at least two. One which we got above and one which we
     398         * got when the file system was mounted. If we find more, it means that
     399         * the file system cannot be gracefully unmounted at the moment because
     400         * someone is working with it.
     401         */
     402        if (vfs_nodes_refcount_sum_get(mr_node->fs_handle,
     403            mr_node->dev_handle) != 2) {
     404                fibril_rwlock_write_unlock(&namespace_rwlock);
     405                vfs_node_put(mr_node);
     406                free(mp);
     407                ipc_answer_0(rid, EBUSY);
     408                return;
     409        }
     410
     411        if (str_cmp(mp, "/") == 0) {
     412
     413                /*
     414                 * Unmounting the root file system.
     415                 *
     416                 * In this case, there is no mount point node and we send
     417                 * VFS_OUT_UNMOUNTED directly to the mounted file system.
     418                 */
     419
     420                free(mp);
     421                phone = vfs_grab_phone(mr_node->fs_handle);
     422                rc = async_req_1_0(phone, VFS_OUT_UNMOUNTED,
     423                    mr_node->dev_handle);
     424                vfs_release_phone(phone);
     425                if (rc != EOK) {
     426                        fibril_rwlock_write_unlock(&namespace_rwlock);
     427                        vfs_node_put(mr_node);
     428                        ipc_answer_0(rid, rc);
     429                        return;
     430                }
     431                rootfs.fs_handle = 0;
     432                rootfs.dev_handle = 0;
     433        } else {
     434
     435                /*
     436                 * Unmounting a non-root file system.
     437                 *
     438                 * We have a regular mount point node representing the parent
     439                 * file system, so we delegate the operation to it.
     440                 */
     441
     442                rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
     443                free(mp);
     444                if (rc != EOK) {
     445                        fibril_rwlock_write_unlock(&namespace_rwlock);
     446                        vfs_node_put(mr_node);
     447                        ipc_answer_0(rid, rc);
     448                        return;
     449                }
     450                vfs_node_t *mp_node = vfs_node_get(&mp_res);
     451                if (!mp_node) {
     452                        fibril_rwlock_write_unlock(&namespace_rwlock);
     453                        vfs_node_put(mr_node);
     454                        ipc_answer_0(rid, ENOMEM);
     455                        return;
     456                }
     457
     458                phone = vfs_grab_phone(mp_node->fs_handle);
     459                rc = async_req_2_0(phone, VFS_OUT_UNMOUNT, mp_node->dev_handle,
     460                    mp_node->index);
     461                vfs_release_phone(phone);
     462                if (rc != EOK) {
     463                        fibril_rwlock_write_unlock(&namespace_rwlock);
     464                        vfs_node_put(mp_node);
     465                        vfs_node_put(mr_node);
     466                        ipc_answer_0(rid, rc);
     467                        return;
     468                }
     469
     470                /* Drop the reference we got above. */
     471                vfs_node_put(mp_node);
     472                /* Drop the reference from when the file system was mounted. */
     473                vfs_node_put(mp_node);
     474        }
     475
     476
     477        /*
     478         * All went well, the mounted file system was successfully unmounted.
     479         * The only thing left is to forget the unmounted root VFS node.
     480         */
     481        vfs_node_forget(mr_node);
     482
     483        fibril_rwlock_write_unlock(&namespace_rwlock);
     484        ipc_answer_0(rid, EOK);
     485}
     486
    431487void vfs_open(ipc_callid_t rid, ipc_call_t *request)
    432488{
     
    454510        /*
    455511         * Make sure that we are called with exactly one of L_FILE and
    456          * L_DIRECTORY. Make sure that the user does not pass L_OPEN.
     512         * L_DIRECTORY. Make sure that the user does not pass L_OPEN,
     513         * L_ROOT or L_MP.
    457514         */
    458515        if (((lflag & (L_FILE | L_DIRECTORY)) == 0) ||
    459516            ((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) ||
    460             ((lflag & L_OPEN) != 0)) {
     517            (lflag & (L_OPEN | L_ROOT | L_MP))) {
    461518                ipc_answer_0(rid, EINVAL);
    462519                return;
     
    468525                lflag |= L_EXCLUSIVE;
    469526       
    470         ipc_callid_t callid;
    471         if (!async_data_write_receive(&callid, &len)) {
    472                 ipc_answer_0(callid, EINVAL);
    473                 ipc_answer_0(rid, EINVAL);
    474                 return;
    475         }
    476        
    477         char *path = malloc(len + 1);
    478         if (!path) {
    479                 ipc_answer_0(callid, ENOMEM);
    480                 ipc_answer_0(rid, ENOMEM);
    481                 return;
    482         }
    483        
    484         int rc;
    485         if ((rc = async_data_write_finalize(callid, path, len))) {
    486                 ipc_answer_0(rid, rc);
    487                 free(path);
    488                 return;
    489         }
    490         path[len] = '\0';
     527        char *path;
     528        int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
     529        if (rc != EOK) {
     530                ipc_answer_0(rid, rc);
     531                return;
     532        }
    491533       
    492534        /*
     
    679721}
    680722
    681 static int vfs_close_internal(vfs_file_t *file)
     723int vfs_close_internal(vfs_file_t *file)
    682724{
    683725        /*
     
    756798       
    757799        /*
    758          * Now we need to receive a call with client's
    759          * IPC_M_DATA_READ/IPC_M_DATA_WRITE request.
    760          */
    761         ipc_callid_t callid;
    762         int res;
    763         if (read)
    764                 res = async_data_read_receive(&callid, NULL);
    765         else
    766                 res = async_data_write_receive(&callid, NULL);
    767         if (!res) {
    768                 ipc_answer_0(callid, EINVAL);
    769                 ipc_answer_0(rid, EINVAL);
    770                 return;
    771         }
    772        
    773         /*
    774800         * Lock the open file structure so that no other thread can manipulate
    775801         * the same open file at a time.
     
    795821        }
    796822       
    797         int fs_phone = vfs_grab_phone(file->node->fs_handle);   
    798        
    799         /* Make a VFS_READ/VFS_WRITE request at the destination FS server. */
    800         aid_t msg;
    801         ipc_call_t answer;
    802         if (!read && file->append)
    803                 file->pos = file->node->size;
    804         msg = async_send_3(fs_phone, read ? VFS_OUT_READ : VFS_OUT_WRITE,
    805             file->node->dev_handle, file->node->index, file->pos, &answer);
    806        
    807         /*
    808          * Forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the
     823        int fs_phone = vfs_grab_phone(file->node->fs_handle);
     824       
     825        /*
     826         * Make a VFS_READ/VFS_WRITE request at the destination FS server
     827         * and forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the
    809828         * destination FS server. The call will be routed as if sent by
    810829         * ourselves. Note that call arguments are immutable in this case so we
    811830         * don't have to bother.
    812831         */
    813         ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    814 
    815         /* Wait for reply from the FS server. */
    816832        ipcarg_t rc;
    817         async_wait_for(msg, &rc);
     833        ipc_call_t answer;
     834        if (read) {
     835                if (file->append)
     836                        file->pos = file->node->size;
     837               
     838                rc = async_data_read_forward_3_1(fs_phone, VFS_OUT_READ,
     839                    file->node->dev_handle, file->node->index, file->pos,
     840                    &answer);
     841        } else {
     842                rc = async_data_write_forward_3_1(fs_phone, VFS_OUT_WRITE,
     843                    file->node->dev_handle, file->node->index, file->pos,
     844                    &answer);
     845        }
    818846       
    819847        vfs_release_phone(fs_phone);
    820848       
    821849        size_t bytes = IPC_GET_ARG1(answer);
    822 
     850       
    823851        if (file->node->type == VFS_NODE_DIRECTORY)
    824852                fibril_rwlock_read_unlock(&namespace_rwlock);
     
    9821010void vfs_stat(ipc_callid_t rid, ipc_call_t *request)
    9831011{
    984         size_t len;
     1012        char *path;
     1013        int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
     1014        if (rc != EOK) {
     1015                ipc_answer_0(rid, rc);
     1016                return;
     1017        }
     1018       
    9851019        ipc_callid_t callid;
    986 
    987         if (!async_data_write_receive(&callid, &len)) {
    988                 ipc_answer_0(callid, EINVAL);
    989                 ipc_answer_0(rid, EINVAL);
    990                 return;
    991         }
    992         char *path = malloc(len + 1);
    993         if (!path) {
    994                 ipc_answer_0(callid, ENOMEM);
    995                 ipc_answer_0(rid, ENOMEM);
    996                 return;
    997         }
    998         int rc;
    999         if ((rc = async_data_write_finalize(callid, path, len))) {
    1000                 ipc_answer_0(rid, rc);
    1001                 free(path);
    1002                 return;
    1003         }
    1004         path[len] = '\0';
    1005 
    10061020        if (!async_data_read_receive(&callid, NULL)) {
    10071021                free(path);
     
    10491063{
    10501064        int mode = IPC_GET_ARG1(*request);
    1051 
    1052         size_t len;
    1053         ipc_callid_t callid;
    1054 
    1055         if (!async_data_write_receive(&callid, &len)) {
    1056                 ipc_answer_0(callid, EINVAL);
    1057                 ipc_answer_0(rid, EINVAL);
    1058                 return;
    1059         }
    1060         char *path = malloc(len + 1);
    1061         if (!path) {
    1062                 ipc_answer_0(callid, ENOMEM);
    1063                 ipc_answer_0(rid, ENOMEM);
    1064                 return;
    1065         }
    1066         int rc;
    1067         if ((rc = async_data_write_finalize(callid, path, len))) {
    1068                 ipc_answer_0(rid, rc);
    1069                 free(path);
    1070                 return;
    1071         }
    1072         path[len] = '\0';
    1073 
     1065       
     1066        char *path;
     1067        int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
     1068        if (rc != EOK) {
     1069                ipc_answer_0(rid, rc);
     1070                return;
     1071        }
     1072       
    10741073        /* Ignore mode for now. */
    10751074        (void) mode;
     
    10861085{
    10871086        int lflag = IPC_GET_ARG1(*request);
    1088 
    1089         size_t len;
    1090         ipc_callid_t callid;
    1091 
    1092         if (!async_data_write_receive(&callid, &len)) {
    1093                 ipc_answer_0(callid, EINVAL);
    1094                 ipc_answer_0(rid, EINVAL);
    1095                 return;
    1096         }
    1097         char *path = malloc(len + 1);
    1098         if (!path) {
    1099                 ipc_answer_0(callid, ENOMEM);
    1100                 ipc_answer_0(rid, ENOMEM);
    1101                 return;
    1102         }
    1103         int rc;
    1104         if ((rc = async_data_write_finalize(callid, path, len))) {
    1105                 ipc_answer_0(rid, rc);
    1106                 free(path);
    1107                 return;
    1108         }
    1109         path[len] = '\0';
     1087       
     1088        char *path;
     1089        int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
     1090        if (rc != EOK) {
     1091                ipc_answer_0(rid, rc);
     1092                return;
     1093        }
    11101094       
    11111095        fibril_rwlock_write_lock(&namespace_rwlock);
     
    11361120void vfs_rename(ipc_callid_t rid, ipc_call_t *request)
    11371121{
    1138         size_t olen, nlen;
    1139         ipc_callid_t callid;
    1140         int rc;
    1141 
    11421122        /* Retrieve the old path. */
    1143         if (!async_data_write_receive(&callid, &olen)) {
    1144                 ipc_answer_0(callid, EINVAL);
    1145                 ipc_answer_0(rid, EINVAL);
    1146                 return;
    1147         }
    1148         char *old = malloc(olen + 1);
    1149         if (!old) {
    1150                 ipc_answer_0(callid, ENOMEM);
    1151                 ipc_answer_0(rid, ENOMEM);
    1152                 return;
    1153         }
    1154         if ((rc = async_data_write_finalize(callid, old, olen))) {
    1155                 ipc_answer_0(rid, rc);
     1123        char *old;
     1124        int rc = async_data_write_accept((void **) &old, true, 0, 0, 0, NULL);
     1125        if (rc != EOK) {
     1126                ipc_answer_0(rid, rc);
     1127                return;
     1128        }
     1129       
     1130        /* Retrieve the new path. */
     1131        char *new;
     1132        rc = async_data_write_accept((void **) &new, true, 0, 0, 0, NULL);
     1133        if (rc != EOK) {
    11561134                free(old);
    1157                 return;
    1158         }
    1159         old[olen] = '\0';
    1160        
    1161         /* Retrieve the new path. */
    1162         if (!async_data_write_receive(&callid, &nlen)) {
    1163                 ipc_answer_0(callid, EINVAL);
    1164                 ipc_answer_0(rid, EINVAL);
    1165                 free(old);
    1166                 return;
    1167         }
    1168         char *new = malloc(nlen + 1);
    1169         if (!new) {
    1170                 ipc_answer_0(callid, ENOMEM);
    1171                 ipc_answer_0(rid, ENOMEM);
    1172                 free(old);
    1173                 return;
    1174         }
    1175         if ((rc = async_data_write_finalize(callid, new, nlen))) {
    1176                 ipc_answer_0(rid, rc);
    1177                 free(old);
    1178                 free(new);
    1179                 return;
    1180         }
    1181         new[nlen] = '\0';
    1182 
     1135                ipc_answer_0(rid, rc);
     1136                return;
     1137        }
     1138       
     1139        size_t olen;
     1140        size_t nlen;
    11831141        char *oldc = canonify(old, &olen);
    11841142        char *newc = canonify(new, &nlen);
    1185         if (!oldc || !newc) {
     1143       
     1144        if ((!oldc) || (!newc)) {
    11861145                ipc_answer_0(rid, EINVAL);
    11871146                free(old);
     
    11891148                return;
    11901149        }
     1150       
    11911151        oldc[olen] = '\0';
    11921152        newc[nlen] = '\0';
     1153       
    11931154        if ((!str_lcmp(newc, oldc, str_length(oldc))) &&
    11941155            ((newc[str_length(oldc)] == '/') ||
     
    12111172        vfs_lookup_res_t new_par_lr;
    12121173        fibril_rwlock_write_lock(&namespace_rwlock);
     1174       
    12131175        /* Lookup the node belonging to the old file name. */
    12141176        rc = vfs_lookup_internal(oldc, L_NONE, &old_lr, NULL);
     
    12201182                return;
    12211183        }
     1184       
    12221185        vfs_node_t *old_node = vfs_node_get(&old_lr);
    12231186        if (!old_node) {
     
    12281191                return;
    12291192        }
     1193       
    12301194        /* Determine the path to the parent of the node with the new name. */
    12311195        char *parentc = str_dup(newc);
     
    12371201                return;
    12381202        }
     1203       
    12391204        char *lastsl = str_rchr(parentc + 1, '/');
    12401205        if (lastsl)
     
    12421207        else
    12431208                parentc[1] = '\0';
     1209       
    12441210        /* Lookup parent of the new file name. */
    12451211        rc = vfs_lookup_internal(parentc, L_NONE, &new_par_lr, NULL);
     
    12521218                return;
    12531219        }
     1220       
    12541221        /* Check whether linking to the same file system instance. */
    12551222        if ((old_node->fs_handle != new_par_lr.triplet.fs_handle) ||
     
    12611228                return;
    12621229        }
     1230       
    12631231        /* Destroy the old link for the new name. */
    12641232        vfs_node_t *new_node = NULL;
    12651233        rc = vfs_lookup_internal(newc, L_UNLINK, &new_lr, NULL);
     1234       
    12661235        switch (rc) {
    12671236        case ENOENT:
     
    12881257                return;
    12891258        }
     1259       
    12901260        /* Create the new link for the new name. */
    12911261        rc = vfs_lookup_internal(newc, L_LINK, NULL, NULL, old_node->index);
     
    12991269                return;
    13001270        }
     1271       
    13011272        fibril_mutex_lock(&nodes_mutex);
    13021273        old_node->lnkcnt++;
    13031274        fibril_mutex_unlock(&nodes_mutex);
     1275       
    13041276        /* Destroy the link for the old name. */
    13051277        rc = vfs_lookup_internal(oldc, L_UNLINK, NULL, NULL);
     
    13141286                return;
    13151287        }
     1288       
    13161289        fibril_mutex_lock(&nodes_mutex);
    13171290        old_node->lnkcnt--;
     
    13191292        fibril_rwlock_write_unlock(&namespace_rwlock);
    13201293        vfs_node_put(old_node);
     1294       
    13211295        if (new_node)
    13221296                vfs_node_put(new_node);
     1297       
    13231298        free(old);
    13241299        free(new);
  • uspace/srv/vfs/vfs_register.c

    r83349b03 r19f24fd  
    110110void vfs_register(ipc_callid_t rid, ipc_call_t *request)
    111111{
    112         ipc_callid_t callid;
    113         ipc_call_t call;
    114         int rc;
    115         size_t size;
    116 
    117112        dprintf("Processing VFS_REGISTER request received from %p.\n",
    118113            request->in_phone_hash);
    119 
    120         /*
    121          * The first call has to be IPC_M_DATA_SEND in which we receive the
    122          * VFS info structure from the client FS.
    123          */
    124         if (!async_data_write_receive(&callid, &size)) {
    125                 /*
    126                  * The client doesn't obey the same protocol as we do.
    127                  */
    128                 dprintf("Receiving of VFS info failed.\n");
    129                 ipc_answer_0(callid, EINVAL);
    130                 ipc_answer_0(rid, EINVAL);
    131                 return;
    132         }
    133        
    134         dprintf("VFS info received, size = %d\n", size);
    135        
    136         /*
    137          * We know the size of the VFS info structure. See if the client
    138          * understands this easy concept too.
    139          */
    140         if (size != sizeof(vfs_info_t)) {
    141                 /*
    142                  * The client is sending us something, which cannot be
    143                  * the info structure.
    144                  */
    145                 dprintf("Received VFS info has bad size.\n");
    146                 ipc_answer_0(callid, EINVAL);
    147                 ipc_answer_0(rid, EINVAL);
    148                 return;
    149         }
    150 
    151         /*
    152          * Allocate and initialize a buffer for the fs_info structure.
    153          */
    154         fs_info_t *fs_info;
    155         fs_info = (fs_info_t *) malloc(sizeof(fs_info_t));
    156         if (!fs_info) {
    157                 dprintf("Could not allocate memory for FS info.\n");
    158                 ipc_answer_0(callid, ENOMEM);
    159                 ipc_answer_0(rid, ENOMEM);
    160                 return;
    161         }
    162         link_initialize(&fs_info->fs_link);
    163         fibril_mutex_initialize(&fs_info->phone_lock);
    164                
    165         rc = async_data_write_finalize(callid, &fs_info->vfs_info, size);
     114       
     115        vfs_info_t *vfs_info;
     116        int rc = async_data_write_accept((void **) &vfs_info, false,
     117            sizeof(vfs_info_t), sizeof(vfs_info_t), 0, NULL);
     118       
    166119        if (rc != EOK) {
    167120                dprintf("Failed to deliver the VFS info into our AS, rc=%d.\n",
    168121                    rc);
    169                 free(fs_info);
    170                 ipc_answer_0(callid, rc);
    171122                ipc_answer_0(rid, rc);
    172123                return;
    173124        }
    174 
     125       
     126        /*
     127         * Allocate and initialize a buffer for the fs_info structure.
     128         */
     129        fs_info_t *fs_info = (fs_info_t *) malloc(sizeof(fs_info_t));
     130        if (!fs_info) {
     131                dprintf("Could not allocate memory for FS info.\n");
     132                ipc_answer_0(rid, ENOMEM);
     133                return;
     134        }
     135       
     136        link_initialize(&fs_info->fs_link);
     137        fibril_mutex_initialize(&fs_info->phone_lock);
     138        fs_info->vfs_info = *vfs_info;
     139        free(vfs_info);
     140       
    175141        dprintf("VFS info delivered.\n");
    176                
     142       
    177143        if (!vfs_info_sane(&fs_info->vfs_info)) {
    178144                free(fs_info);
    179                 ipc_answer_0(callid, EINVAL);
    180145                ipc_answer_0(rid, EINVAL);
    181146                return;
    182147        }
    183                
     148       
    184149        fibril_mutex_lock(&fs_head_lock);
    185 
     150       
    186151        /*
    187152         * Check for duplicit registrations.
     
    194159                fibril_mutex_unlock(&fs_head_lock);
    195160                free(fs_info);
    196                 ipc_answer_0(callid, EEXISTS);
    197161                ipc_answer_0(rid, EEXISTS);
    198162                return;
    199163        }
    200 
     164       
    201165        /*
    202166         * Add fs_info to the list of registered FS's.
     
    210174         * which to forward VFS requests to it.
    211175         */
    212         callid = async_get_call(&call);
     176        ipc_call_t call;
     177        ipc_callid_t callid = async_get_call(&call);
    213178        if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) {
    214179                dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call));
     
    222187        fs_info->phone = IPC_GET_ARG5(call);
    223188        ipc_answer_0(callid, EOK);
    224 
     189       
    225190        dprintf("Callback connection to FS created.\n");
    226 
     191       
    227192        /*
    228193         * The client will want us to send him the address space area with PLB.
    229194         */
    230 
     195       
     196        size_t size;
    231197        if (!async_share_in_receive(&callid, &size)) {
    232198                dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call));
     
    253219                return;
    254220        }
    255 
     221       
    256222        /*
    257223         * Commit to read-only sharing the PLB with the client.
     
    259225        (void) async_share_in_finalize(callid, plb,
    260226            AS_AREA_READ | AS_AREA_CACHEABLE);
    261 
     227       
    262228        dprintf("Sharing PLB.\n");
    263 
     229       
    264230        /*
    265231         * That was it. The FS has been registered.
Note: See TracChangeset for help on using the changeset viewer.