Changeset 5cde90f in mainline for uspace/srv


Ignore:
Timestamp:
2010-02-19T17:16:46Z (16 years ago)
Author:
Pavel Rimsky <pavel@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
617652f
Parents:
b86d436 (diff), f41aa81 (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:

Synchronizing with head (which has just been synchronized with this branch).

Location:
uspace/srv
Files:
15 added
45 edited
7 moved

Legend:

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

    rb86d436 r5cde90f  
    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");
     
    499500
    500501        d = &disk[disk_id];
    501         bc.h = 0;       /* Silence warning. */
     502       
     503        /* Silence warning. */
     504        memset(&bc, 0, sizeof(bc));
    502505
    503506        /* Compute block coordinates. */
     
    573576
    574577        d = &disk[disk_id];
    575         bc.h = 0;       /* Silence warning. */
     578       
     579        /* Silence warning. */
     580        memset(&bc, 0, sizeof(bc));
    576581
    577582        /* Compute block coordinates. */
  • uspace/srv/bd/file_bd/file_bd.c

    rb86d436 r5cde90f  
    4848#include <devmap.h>
    4949#include <sys/types.h>
     50#include <sys/typefmt.h>
    5051#include <errno.h>
    5152#include <bool.h>
     
    5657
    5758static const size_t block_size = 512;
    58 static bn_t num_blocks;
     59static aoff64_t num_blocks;
    5960static FILE *img;
    6061
     
    207208        int rc;
    208209
     210        /* Check whether access is within device address bounds. */
     211        if (ba + cnt > num_blocks) {
     212                printf(NAME ": Accessed blocks %" PRIuOFF64 "-%" PRIuOFF64 ", while "
     213                    "max block number is %" PRIuOFF64 ".\n", ba, ba + cnt - 1,
     214                    num_blocks - 1);
     215                return ELIMIT;
     216        }
     217
    209218        fibril_mutex_lock(&dev_lock);
    210219
     
    237246        int rc;
    238247
     248        /* Check whether access is within device address bounds. */
     249        if (ba + cnt > num_blocks) {
     250                printf(NAME ": Accessed blocks %" PRIuOFF64 "-%" PRIuOFF64 ", while "
     251                    "max block number is %" PRIuOFF64 ".\n", ba, ba + cnt - 1,
     252                    num_blocks - 1);
     253                return ELIMIT;
     254        }
     255
    239256        fibril_mutex_lock(&dev_lock);
    240257
  • uspace/srv/bd/part/mbr_part/mbr_part.c

    rb86d436 r5cde90f  
    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>
     
    9597        bool present;
    9698        /** Address of first block */
    97         bn_t start_addr;
     99        aoff64_t start_addr;
    98100        /** Number of blocks */
    99         bn_t length;
     101        aoff64_t length;
    100102        /** Device representing the partition (outbound device) */
    101103        dev_handle_t dev;
     
    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: %" PRIuOFF64 " 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

    rb86d436 r5cde90f  
    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);
     
    145145       
    146146        fibril_mutex_unlock(&clip_mtx);
    147         ipc_answer_2(rid, EOK, (ipcarg_t) size, (ipcarg_t) clip_tag);
     147        ipc_answer_2(rid, EOK, (ipcarg_t) size, (ipcarg_t) tag);
    148148}
    149149
  • uspace/srv/devmap/devmap.c

    rb86d436 r5cde90f  
    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

    rb86d436 r5cde90f  
    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

    rb86d436 r5cde90f  
    3737
    3838#include <ipc/ipc.h>
     39#include <macros.h>
    3940#include <bool.h>
    4041#include <errno.h>
     
    337338}
    338339
    339 static size_t devfs_size_get(fs_node_t *fn)
     340static aoff64_t devfs_size_get(fs_node_t *fn)
    340341{
    341342        return 0;
     
    419420       
    420421        /* Accept the mount options */
    421         ipcarg_t retval = async_data_string_receive(&opts, 0);
     422        ipcarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,
     423            0, NULL);
    422424        if (retval != EOK) {
    423425                ipc_answer_0(rid, retval);
     
    434436}
    435437
     438void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
     439{
     440        ipc_answer_0(rid, ENOTSUP);
     441}
     442
     443void devfs_unmount(ipc_callid_t rid, ipc_call_t *request)
     444{
     445        libfs_unmount(&devfs_libfs_ops, rid, request);
     446}
     447
    436448void devfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    437449{
     
    452464{
    453465        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    454         off_t pos = (off_t) IPC_GET_ARG3(*request);
     466        aoff64_t pos =
     467            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    455468       
    456469        if (index == 0) {
     
    586599{
    587600        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    588         off_t pos = (off_t) IPC_GET_ARG3(*request);
    589        
    590601        if (index == 0) {
    591602                ipc_answer_0(rid, ENOTSUP);
  • uspace/srv/fs/devfs/devfs_ops.h

    rb86d436 r5cde90f  
    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

    rb86d436 r5cde90f  
    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

    rb86d436 r5cde90f  
    8989                        uint16_t        signature;
    9090                } __attribute__ ((packed));
    91                 struct fat32 {
     91                struct {
    9292                        /* FAT32 only */
    9393                        /** Sectors per FAT. */
     
    119119                        /** Signature. */
    120120                        uint16_t        signature;
    121                 } __attribute__ ((packed));
    122         }; 
     121                } fat32 __attribute__ ((packed));
     122        };
    123123} __attribute__ ((packed)) fat_bs_t;
    124124
     
    194194        /** FAT in-core node free list link. */
    195195        link_t                  ffn_link;
    196         size_t                  size;
     196        aoff64_t                size;
    197197        unsigned                lnkcnt;
    198198        unsigned                refcnt;
     
    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_dentry.c

    rb86d436 r5cde90f  
    8282bool fat_dentry_name_verify(const char *name)
    8383{
    84         unsigned i, dot;
     84        unsigned int i;
     85        unsigned int dot = 0;
    8586        bool dot_found = false;
    8687       
  • uspace/srv/fs/fat/fat_fat.c

    rb86d436 r5cde90f  
    9393
    9494        while (clst < FAT_CLST_LAST1 && clusters < max_clusters) {
    95                 bn_t fsec;      /* sector offset relative to FAT1 */
     95                aoff64_t fsec;  /* sector offset relative to FAT1 */
    9696                unsigned fidx;  /* FAT1 entry index */
    9797
     
    135135int
    136136_fat_block_get(block_t **block, fat_bs_t *bs, dev_handle_t dev_handle,
    137     fat_cluster_t firstc, bn_t bn, int flags)
     137    fat_cluster_t firstc, aoff64_t bn, int flags)
    138138{
    139139        unsigned bps;
     
    148148        int rc;
    149149
     150        /*
     151         * This function can only operate on non-zero length files.
     152         */
     153        if (firstc == FAT_CLST_RES0)
     154                return ELIMIT;
     155
    150156        bps = uint16_t_le2host(bs->bps);
    151157        rscnt = uint16_t_le2host(bs->rscnt);
     
    190196 * @return              EOK on success or a negative error code.
    191197 */
    192 int fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, off_t pos)
     198int fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, aoff64_t pos)
    193199{
    194200        uint16_t bps;
    195201        unsigned spc;
    196202        block_t *b;
    197         off_t o, boundary;
     203        aoff64_t o, boundary;
    198204        int rc;
    199205
     
    361367        uint16_t rscnt;
    362368        uint16_t sf;
    363         uint16_t ts;
     369        uint32_t ts;
    364370        unsigned rde;
    365371        unsigned rds;
     
    379385        sf = uint16_t_le2host(bs->sec_per_fat);
    380386        rde = uint16_t_le2host(bs->root_ent_max);
    381         ts = uint16_t_le2host(bs->totsec16);
     387        ts = (uint32_t) uint16_t_le2host(bs->totsec16);
     388        if (ts == 0)
     389                ts = uint32_t_le2host(bs->totsec32);
    382390
    383391        rds = (sizeof(fat_dentry_t) * rde) / bps;
     
    608616}
    609617
     618/** Perform basic sanity checks on the file system.
     619 *
     620 * Verify if values of boot sector fields are sane. Also verify media
     621 * descriptor. This is used to rule out cases when a device obviously
     622 * does not contain a fat file system.
     623 */
     624int fat_sanity_check(fat_bs_t *bs, dev_handle_t dev_handle)
     625{
     626        fat_cluster_t e0, e1;
     627        unsigned fat_no;
     628        int rc;
     629
     630        /* Check number of FATs. */
     631        if (bs->fatcnt == 0)
     632                return ENOTSUP;
     633
     634        /* Check total number of sectors. */
     635
     636        if (bs->totsec16 == 0 && bs->totsec32 == 0)
     637                return ENOTSUP;
     638
     639        if (bs->totsec16 != 0 && bs->totsec32 != 0 &&
     640            bs->totsec16 != bs->totsec32)
     641                return ENOTSUP;
     642
     643        /* Check media descriptor. Must be between 0xf0 and 0xff. */
     644        if ((bs->mdesc & 0xf0) != 0xf0)
     645                return ENOTSUP;
     646
     647        /* Check number of sectors per FAT. */
     648        if (bs->sec_per_fat == 0)
     649                return ENOTSUP;
     650
     651        /*
     652         * Check that the root directory entries take up whole blocks.
     653         * This check is rather strict, but it allows us to treat the root
     654         * directory and non-root directories uniformly in some places.
     655         * It can be removed provided that functions such as fat_read() are
     656         * sanitized to support file systems with this property.
     657         */
     658        if ((uint16_t_le2host(bs->root_ent_max) * sizeof(fat_dentry_t)) %
     659            uint16_t_le2host(bs->bps) != 0)
     660                return ENOTSUP;
     661
     662        /* Check signature of each FAT. */
     663
     664        for (fat_no = 0; fat_no < bs->fatcnt; fat_no++) {
     665                rc = fat_get_cluster(bs, dev_handle, fat_no, 0, &e0);
     666                if (rc != EOK)
     667                        return EIO;
     668
     669                rc = fat_get_cluster(bs, dev_handle, fat_no, 1, &e1);
     670                if (rc != EOK)
     671                        return EIO;
     672
     673                /* Check that first byte of FAT contains the media descriptor. */
     674                if ((e0 & 0xff) != bs->mdesc)
     675                        return ENOTSUP;
     676
     677                /*
     678                 * Check that remaining bits of the first two entries are
     679                 * set to one.
     680                 */
     681                if ((e0 >> 8) != 0xff || e1 != 0xffff)
     682                        return ENOTSUP;
     683        }
     684
     685        return EOK;
     686}
     687
    610688/**
    611689 * @}
  • uspace/srv/fs/fat/fat_fat.h

    rb86d436 r5cde90f  
    6969
    7070extern int _fat_block_get(block_t **, struct fat_bs *, dev_handle_t,
    71     fat_cluster_t, bn_t, int);
    72  
     71    fat_cluster_t, aoff64_t, int);
     72
    7373extern int fat_append_clusters(struct fat_bs *, struct fat_node *,
    7474    fat_cluster_t);
     
    8585    fat_cluster_t, fat_cluster_t);
    8686extern int fat_fill_gap(struct fat_bs *, struct fat_node *, fat_cluster_t,
    87     off_t);
     87    aoff64_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

    rb86d436 r5cde90f  
    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

    rb86d436 r5cde90f  
    4545#include <ipc/services.h>
    4646#include <ipc/devmap.h>
     47#include <macros.h>
    4748#include <async.h>
    4849#include <errno.h>
     
    7980static int fat_has_children(bool *, fs_node_t *);
    8081static fs_index_t fat_index_get(fs_node_t *);
    81 static size_t fat_size_get(fs_node_t *);
     82static aoff64_t fat_size_get(fs_node_t *);
    8283static unsigned fat_lnkcnt_get(fs_node_t *);
    8384static char fat_plb_get_char(unsigned);
     
    137138        rc = block_put(b);
    138139        return rc;
     140}
     141
     142static int fat_node_fini_by_dev_handle(dev_handle_t dev_handle)
     143{
     144        link_t *lnk;
     145        fat_node_t *nodep;
     146        int rc;
     147
     148        /*
     149         * We are called from fat_unmounted() and assume that there are already
     150         * no nodes belonging to this instance with non-zero refcount. Therefore
     151         * it is sufficient to clean up only the FAT free node list.
     152         */
     153
     154restart:
     155        fibril_mutex_lock(&ffn_mutex);
     156        for (lnk = ffn_head.next; lnk != &ffn_head; lnk = lnk->next) {
     157                nodep = list_get_instance(lnk, fat_node_t, ffn_link);
     158                if (!fibril_mutex_trylock(&nodep->lock)) {
     159                        fibril_mutex_unlock(&ffn_mutex);
     160                        goto restart;
     161                }
     162                if (!fibril_mutex_trylock(&nodep->idx->lock)) {
     163                        fibril_mutex_unlock(&nodep->lock);
     164                        fibril_mutex_unlock(&ffn_mutex);
     165                        goto restart;
     166                }
     167                if (nodep->idx->dev_handle != dev_handle) {
     168                        fibril_mutex_unlock(&nodep->idx->lock);
     169                        fibril_mutex_unlock(&nodep->lock);
     170                        continue;
     171                }
     172
     173                list_remove(&nodep->ffn_link);
     174                fibril_mutex_unlock(&ffn_mutex);
     175
     176                /*
     177                 * We can unlock the node and its index structure because we are
     178                 * the last player on this playground and VFS is preventing new
     179                 * players from entering.
     180                 */
     181                fibril_mutex_unlock(&nodep->idx->lock);
     182                fibril_mutex_unlock(&nodep->lock);
     183
     184                if (nodep->dirty) {
     185                        rc = fat_node_sync(nodep);
     186                        if (rc != EOK)
     187                                return rc;
     188                }
     189                nodep->idx->nodep = NULL;
     190                free(nodep->bp);
     191                free(nodep);
     192
     193                /* Need to restart because we changed the ffn_head list. */
     194                goto restart;
     195        }
     196        fibril_mutex_unlock(&ffn_mutex);
     197
     198        return EOK;
    139199}
    140200
     
    290350
    291351        *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 
    362352        return EOK;
    363353}
     
    733723        fibril_mutex_lock(&childp->idx->lock);
    734724       
    735         /*
    736          * If possible, create the Sub-directory Identifier Entry and the
    737          * Sub-directory Parent Pointer Entry (i.e. "." and ".."). These entries
    738          * are not mandatory according to Standard ECMA-107 and HelenOS VFS does
    739          * not use them anyway, so this is rather a sign of our good will.
    740          */
    741         rc = fat_block_get(&b, bs, childp, 0, BLOCK_FLAGS_NONE);
    742         if (rc != EOK) {
     725        if (childp->type == FAT_DIRECTORY) {
    743726                /*
    744                  * Rather than returning an error, simply skip the creation of
    745                  * these two entries.
     727                 * If possible, create the Sub-directory Identifier Entry and
     728                 * the Sub-directory Parent Pointer Entry (i.e. "." and "..").
     729                 * These entries are not mandatory according to Standard
     730                 * ECMA-107 and HelenOS VFS does not use them anyway, so this is
     731                 * rather a sign of our good will.
    746732                 */
    747                 goto skip_dots;
    748         }
    749         d = (fat_dentry_t *)b->data;
    750         if (fat_classify_dentry(d) == FAT_DENTRY_LAST ||
    751             str_cmp(d->name, FAT_NAME_DOT) == 0) {
    752                 memset(d, 0, sizeof(fat_dentry_t));
    753                 str_cpy(d->name, 8, FAT_NAME_DOT);
    754                 str_cpy(d->ext, 3, FAT_EXT_PAD);
    755                 d->attr = FAT_ATTR_SUBDIR;
    756                 d->firstc = host2uint16_t_le(childp->firstc);
    757                 /* TODO: initialize also the date/time members. */
    758         }
    759         d++;
    760         if (fat_classify_dentry(d) == FAT_DENTRY_LAST ||
    761             str_cmp(d->name, FAT_NAME_DOT_DOT) == 0) {
    762                 memset(d, 0, sizeof(fat_dentry_t));
    763                 str_cpy(d->name, 8, FAT_NAME_DOT_DOT);
    764                 str_cpy(d->ext, 3, FAT_EXT_PAD);
    765                 d->attr = FAT_ATTR_SUBDIR;
    766                 d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
    767                     host2uint16_t_le(FAT_CLST_RES0) :
    768                     host2uint16_t_le(parentp->firstc);
    769                 /* TODO: initialize also the date/time members. */
    770         }
    771         b->dirty = true;                /* need to sync block */
    772         /*
    773          * Ignore the return value as we would have fallen through on error
    774          * anyway.
    775          */
    776         (void) block_put(b);
     733                rc = fat_block_get(&b, bs, childp, 0, BLOCK_FLAGS_NONE);
     734                if (rc != EOK) {
     735                        /*
     736                         * Rather than returning an error, simply skip the
     737                         * creation of these two entries.
     738                         */
     739                        goto skip_dots;
     740                }
     741                d = (fat_dentry_t *) b->data;
     742                if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
     743                    (str_cmp((char *) d->name, FAT_NAME_DOT)) == 0) {
     744                        memset(d, 0, sizeof(fat_dentry_t));
     745                        str_cpy((char *) d->name, 8, FAT_NAME_DOT);
     746                        str_cpy((char *) d->ext, 3, FAT_EXT_PAD);
     747                        d->attr = FAT_ATTR_SUBDIR;
     748                        d->firstc = host2uint16_t_le(childp->firstc);
     749                        /* TODO: initialize also the date/time members. */
     750                }
     751                d++;
     752                if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
     753                    (str_cmp((char *) d->name, FAT_NAME_DOT_DOT) == 0)) {
     754                        memset(d, 0, sizeof(fat_dentry_t));
     755                        str_cpy((char *) d->name, 8, FAT_NAME_DOT_DOT);
     756                        str_cpy((char *) d->ext, 3, FAT_EXT_PAD);
     757                        d->attr = FAT_ATTR_SUBDIR;
     758                        d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
     759                            host2uint16_t_le(FAT_CLST_RES0) :
     760                            host2uint16_t_le(parentp->firstc);
     761                        /* TODO: initialize also the date/time members. */
     762                }
     763                b->dirty = true;                /* need to sync block */
     764                /*
     765                 * Ignore the return value as we would have fallen through on error
     766                 * anyway.
     767                 */
     768                (void) block_put(b);
     769        }
    777770skip_dots:
    778771
     
    923916}
    924917
    925 size_t fat_size_get(fs_node_t *fn)
     918aoff64_t fat_size_get(fs_node_t *fn)
    926919{
    927920        return FAT_NODE(fn)->size;
     
    985978        uint16_t bps;
    986979        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';
     980       
     981        /* Accept the mount options */
     982        char *opts;
     983        int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
     984       
     985        if (rc != EOK) {
     986                ipc_answer_0(rid, rc);
     987                return;
     988        }
    1010989
    1011990        /* Check for option enabling write through. */
     
    1015994                cmode = CACHE_MODE_WB;
    1016995
     996        free(opts);
     997
    1017998        /* initialize libblock */
    1018999        rc = block_init(dev_handle, BS_SIZE);
     
    10541035        rc = fat_sanity_check(bs, dev_handle);
    10551036        if (rc != EOK) {
     1037                (void) block_cache_fini(dev_handle);
    10561038                block_fini(dev_handle);
    10571039                ipc_answer_0(rid, rc);
     
    10611043        rc = fat_idx_init_by_dev_handle(dev_handle);
    10621044        if (rc != EOK) {
     1045                (void) block_cache_fini(dev_handle);
    10631046                block_fini(dev_handle);
    10641047                ipc_answer_0(rid, rc);
     
    10691052        fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
    10701053        if (!rfn) {
     1054                (void) block_cache_fini(dev_handle);
    10711055                block_fini(dev_handle);
    10721056                fat_idx_fini_by_dev_handle(dev_handle);
     
    10781062        if (!rootp) {
    10791063                free(rfn);
     1064                (void) block_cache_fini(dev_handle);
    10801065                block_fini(dev_handle);
    10811066                fat_idx_fini_by_dev_handle(dev_handle);
     
    10891074                free(rfn);
    10901075                free(rootp);
     1076                (void) block_cache_fini(dev_handle);
    10911077                block_fini(dev_handle);
    10921078                fat_idx_fini_by_dev_handle(dev_handle);
     
    11171103}
    11181104
     1105void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)
     1106{
     1107        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     1108        fs_node_t *fn;
     1109        fat_node_t *nodep;
     1110        int rc;
     1111
     1112        rc = fat_root_get(&fn, dev_handle);
     1113        if (rc != EOK) {
     1114                ipc_answer_0(rid, rc);
     1115                return;
     1116        }
     1117        nodep = FAT_NODE(fn);
     1118
     1119        /*
     1120         * We expect exactly two references on the root node. One for the
     1121         * fat_root_get() above and one created in fat_mounted().
     1122         */
     1123        if (nodep->refcnt != 2) {
     1124                (void) fat_node_put(fn);
     1125                ipc_answer_0(rid, EBUSY);
     1126                return;
     1127        }
     1128       
     1129        /*
     1130         * Put the root node and force it to the FAT free node list.
     1131         */
     1132        (void) fat_node_put(fn);
     1133        (void) fat_node_put(fn);
     1134
     1135        /*
     1136         * Perform cleanup of the node structures, index structures and
     1137         * associated data. Write back this file system's dirty blocks and
     1138         * stop using libblock for this instance.
     1139         */
     1140        (void) fat_node_fini_by_dev_handle(dev_handle);
     1141        fat_idx_fini_by_dev_handle(dev_handle);
     1142        (void) block_cache_fini(dev_handle);
     1143        block_fini(dev_handle);
     1144
     1145        ipc_answer_0(rid, EOK);
     1146}
     1147
     1148void fat_unmount(ipc_callid_t rid, ipc_call_t *request)
     1149{
     1150        libfs_unmount(&fat_libfs_ops, rid, request);
     1151}
     1152
    11191153void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
    11201154{
     
    11241158void fat_read(ipc_callid_t rid, ipc_call_t *request)
    11251159{
    1126         dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    1127         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    1128         off_t pos = (off_t)IPC_GET_ARG3(*request);
     1160        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     1161        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     1162        aoff64_t pos =
     1163            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    11291164        fs_node_t *fn;
    11301165        fat_node_t *nodep;
     
    11901225        } else {
    11911226                unsigned bnum;
    1192                 off_t spos = pos;
     1227                aoff64_t spos = pos;
    11931228                char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
    11941229                fat_dentry_t *d;
     
    12061241                bnum = (pos * sizeof(fat_dentry_t)) / bps;
    12071242                while (bnum < nodep->size / bps) {
    1208                         off_t o;
     1243                        aoff64_t o;
    12091244
    12101245                        rc = fat_block_get(&b, bs, nodep, bnum,
     
    12621297void fat_write(ipc_callid_t rid, ipc_call_t *request)
    12631298{
    1264         dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    1265         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    1266         off_t pos = (off_t)IPC_GET_ARG3(*request);
     1299        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     1300        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     1301        aoff64_t pos =
     1302            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    12671303        fs_node_t *fn;
    12681304        fat_node_t *nodep;
     
    12731309        unsigned spc;
    12741310        unsigned bpc;           /* bytes per cluster */
    1275         off_t boundary;
     1311        aoff64_t boundary;
    12761312        int flags = BLOCK_FLAGS_NONE;
    12771313        int rc;
     
    14191455void fat_truncate(ipc_callid_t rid, ipc_call_t *request)
    14201456{
    1421         dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    1422         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    1423         size_t size = (off_t)IPC_GET_ARG3(*request);
     1457        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     1458        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     1459        aoff64_t size =
     1460            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    14241461        fs_node_t *fn;
    14251462        fat_node_t *nodep;
  • uspace/srv/fs/tmpfs/tmpfs.c

    rb86d436 r5cde90f  
    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

    rb86d436 r5cde90f  
    2929/** @addtogroup fs
    3030 * @{
    31  */ 
     31 */
    3232
    3333#ifndef TMPFS_TMPFS_H_
     
    4040#include <bool.h>
    4141#include <adt/hash_table.h>
    42 
    43 #ifndef dprintf
    44 #define dprintf(...)    printf(__VA_ARGS__)
    45 #endif
    4642
    4743#define TMPFS_NODE(node)        ((node) ? (tmpfs_node_t *)(node)->data : NULL)
     
    8379extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *);
    8480extern void tmpfs_mount(ipc_callid_t, ipc_call_t *);
     81extern void tmpfs_unmounted(ipc_callid_t, ipc_call_t *);
     82extern void tmpfs_unmount(ipc_callid_t, ipc_call_t *);
    8583extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);
    8684extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
  • uspace/srv/fs/tmpfs/tmpfs_dump.c

    rb86d436 r5cde90f  
    5555
    5656static bool
    57 tmpfs_restore_recursion(dev_handle_t dev, off_t *bufpos, size_t *buflen,
    58     off_t *pos, fs_node_t *pfn)
     57tmpfs_restore_recursion(dev_handle_t dev, size_t *bufpos, size_t *buflen,
     58    aoff64_t *pos, fs_node_t *pfn)
    5959{
    6060        struct rdentry entry;
     
    171171                return false;
    172172       
    173         off_t bufpos = 0;
     173        size_t bufpos = 0;
    174174        size_t buflen = 0;
    175         off_t pos = 0;
     175        aoff64_t pos = 0;
    176176       
    177177        char tag[6];
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    rb86d436 r5cde90f  
    2929/** @addtogroup fs
    3030 * @{
    31  */ 
     31 */
    3232
    3333/**
     
    4040#include "../../vfs/vfs.h"
    4141#include <ipc/ipc.h>
     42#include <macros.h>
     43#include <limits.h>
    4244#include <async.h>
    4345#include <errno.h>
     
    9395}
    9496
    95 static size_t tmpfs_size_get(fs_node_t *fn)
     97static aoff64_t tmpfs_size_get(fs_node_t *fn)
    9698{
    9799        return TMPFS_NODE(fn)->size;
     
    147149hash_table_t nodes;
    148150
    149 #define NODES_KEY_INDEX 0
    150 #define NODES_KEY_DEV   1
     151#define NODES_KEY_DEV   0       
     152#define NODES_KEY_INDEX 1
    151153
    152154/* Implementation of hash table interface for the nodes hash table. */
     
    160162        tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
    161163            nh_link);
    162         return (nodep->index == key[NODES_KEY_INDEX] &&
    163             nodep->dev_handle == key[NODES_KEY_DEV]);
     164       
     165        switch (keys) {
     166        case 1:
     167                return (nodep->dev_handle == key[NODES_KEY_DEV]);
     168        case 2:
     169                return ((nodep->dev_handle == key[NODES_KEY_DEV]) &&
     170                    (nodep->index == key[NODES_KEY_INDEX]));
     171        default:
     172                assert((keys == 1) || (keys == 2));
     173        }
     174
     175        return 0;
    164176}
    165177
    166178static void nodes_remove_callback(link_t *item)
    167179{
     180        tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
     181            nh_link);
     182
     183        while (!list_empty(&nodep->cs_head)) {
     184                tmpfs_dentry_t *dentryp = list_get_instance(nodep->cs_head.next,
     185                    tmpfs_dentry_t, link);
     186
     187                assert(nodep->type == TMPFS_DIRECTORY);
     188                list_remove(&dentryp->link);
     189                free(dentryp);
     190        }
     191
     192        if (nodep->data) {
     193                assert(nodep->type == TMPFS_FILE);
     194                free(nodep->data);
     195        }
     196        free(nodep->bp);
     197        free(nodep);
    168198}
    169199
     
    215245}
    216246
     247static void tmpfs_instance_done(dev_handle_t dev_handle)
     248{
     249        unsigned long key[] = {
     250                [NODES_KEY_DEV] = dev_handle
     251        };
     252        /*
     253         * Here we are making use of one special feature of our hash table
     254         * implementation, which allows to remove more items based on a partial
     255         * key match. In the following, we are going to remove all nodes
     256         * matching our device handle. The nodes_remove_callback() function will
     257         * take care of resource deallocation.
     258         */
     259        hash_table_remove(&nodes, key, 1);
     260}
     261
    217262int tmpfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
    218263{
     
    237282{
    238283        unsigned long key[] = {
    239                 [NODES_KEY_INDEX] = index,
    240                 [NODES_KEY_DEV] = dev_handle
     284                [NODES_KEY_DEV] = dev_handle,
     285                [NODES_KEY_INDEX] = index
    241286        };
    242287        link_t *lnk = hash_table_find(&nodes, key);
     
    296341        /* Insert the new node into the nodes hash table. */
    297342        unsigned long key[] = {
    298                 [NODES_KEY_INDEX] = nodep->index,
    299                 [NODES_KEY_DEV] = nodep->dev_handle
     343                [NODES_KEY_DEV] = nodep->dev_handle,
     344                [NODES_KEY_INDEX] = nodep->index
    300345        };
    301346        hash_table_insert(&nodes, key, &nodep->nh_link);
     
    312357
    313358        unsigned long key[] = {
    314                 [NODES_KEY_INDEX] = nodep->index,
    315                 [NODES_KEY_DEV] = nodep->dev_handle
     359                [NODES_KEY_DEV] = nodep->dev_handle,
     360                [NODES_KEY_INDEX] = nodep->index
    316361        };
    317362        hash_table_remove(&nodes, key, 2);
    318363
    319         if (nodep->type == TMPFS_FILE)
    320                 free(nodep->data);
    321         free(nodep->bp);
    322         free(nodep);
     364        /*
     365         * The nodes_remove_callback() function takes care of the actual
     366         * resource deallocation.
     367         */
    323368        return EOK;
    324369}
     
    398443{
    399444        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     445        fs_node_t *rootfn;
    400446        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);
     447       
     448        /* Accept the mount options. */
     449        char *opts;
     450        rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
     451        if (rc != EOK) {
     452                ipc_answer_0(rid, rc);
     453                return;
     454        }
     455
     456        /* Check if this device is not already mounted. */
     457        rc = tmpfs_root_get(&rootfn, dev_handle);
     458        if ((rc == EOK) && (rootfn)) {
     459                (void) tmpfs_node_put(rootfn);
    419460                free(opts);
    420                 return;
    421         }
    422         opts[size] = '\0';
     461                ipc_answer_0(rid, EEXIST);
     462                return;
     463        }
    423464
    424465        /* Initialize TMPFS instance. */
    425466        if (!tmpfs_instance_init(dev_handle)) {
     467                free(opts);
    426468                ipc_answer_0(rid, ENOMEM);
    427469                return;
    428470        }
    429471
    430         fs_node_t *rootfn;
    431472        rc = tmpfs_root_get(&rootfn, dev_handle);
    432473        assert(rc == EOK);
     
    442483                    rootp->lnkcnt);
    443484        }
     485        free(opts);
    444486}
    445487
     
    449491}
    450492
     493void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
     494{
     495        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     496
     497        tmpfs_instance_done(dev_handle);
     498        ipc_answer_0(rid, EOK);
     499}
     500
     501void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request)
     502{
     503        libfs_unmount(&tmpfs_libfs_ops, rid, request);
     504}
     505
    451506void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    452507{
     
    456511void tmpfs_read(ipc_callid_t rid, ipc_call_t *request)
    457512{
    458         dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    459         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    460         off_t pos = (off_t)IPC_GET_ARG3(*request);
    461 
     513        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     514        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     515        aoff64_t pos =
     516            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     517       
    462518        /*
    463519         * Lookup the respective TMPFS node.
     
    465521        link_t *hlp;
    466522        unsigned long key[] = {
    467                 [NODES_KEY_INDEX] = index,
    468523                [NODES_KEY_DEV] = dev_handle,
     524                [NODES_KEY_INDEX] = index
    469525        };
    470526        hlp = hash_table_find(&nodes, key);
     
    475531        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    476532            nh_link);
    477 
     533       
    478534        /*
    479535         * Receive the read request.
     
    482538        size_t size;
    483539        if (!async_data_read_receive(&callid, &size)) {
    484                 ipc_answer_0(callid, EINVAL);   
     540                ipc_answer_0(callid, EINVAL);
    485541                ipc_answer_0(rid, EINVAL);
    486542                return;
     
    489545        size_t bytes;
    490546        if (nodep->type == TMPFS_FILE) {
    491                 bytes = max(0, min(nodep->size - pos, size));
     547                bytes = min(nodep->size - pos, size);
    492548                (void) async_data_read_finalize(callid, nodep->data + pos,
    493549                    bytes);
     
    495551                tmpfs_dentry_t *dentryp;
    496552                link_t *lnk;
    497                 int i;
     553                aoff64_t i;
    498554               
    499555                assert(nodep->type == TMPFS_DIRECTORY);
     
    505561                 */
    506562                for (i = 0, lnk = nodep->cs_head.next;
    507                     i < pos && lnk != &nodep->cs_head;
     563                    (i < pos) && (lnk != &nodep->cs_head);
    508564                    i++, lnk = lnk->next)
    509565                        ;
     
    530586void tmpfs_write(ipc_callid_t rid, ipc_call_t *request)
    531587{
    532         dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    533         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    534         off_t pos = (off_t)IPC_GET_ARG3(*request);
    535 
     588        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     589        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     590        aoff64_t pos =
     591            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     592       
    536593        /*
    537594         * Lookup the respective TMPFS node.
     
    539596        link_t *hlp;
    540597        unsigned long key[] = {
    541                 [NODES_KEY_INDEX] = index,
    542                 [NODES_KEY_DEV] = dev_handle
     598                [NODES_KEY_DEV] = dev_handle,
     599                [NODES_KEY_INDEX] = index
    543600        };
    544601        hlp = hash_table_find(&nodes, key);
     
    594651void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request)
    595652{
     653        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     654        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     655        aoff64_t size =
     656            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     657       
     658        /*
     659         * Lookup the respective TMPFS node.
     660         */
     661        unsigned long key[] = {
     662                [NODES_KEY_DEV] = dev_handle,
     663                [NODES_KEY_INDEX] = index
     664        };
     665        link_t *hlp = hash_table_find(&nodes, key);
     666        if (!hlp) {
     667                ipc_answer_0(rid, ENOENT);
     668                return;
     669        }
     670        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
     671            nh_link);
     672       
     673        if (size == nodep->size) {
     674                ipc_answer_0(rid, EOK);
     675                return;
     676        }
     677       
     678        if (size > SIZE_MAX) {
     679                ipc_answer_0(rid, ENOMEM);
     680                return;
     681        }
     682       
     683        void *newdata = realloc(nodep->data, size);
     684        if (!newdata) {
     685                ipc_answer_0(rid, ENOMEM);
     686                return;
     687        }
     688       
     689        if (size > nodep->size) {
     690                size_t delta = size - nodep->size;
     691                memset(newdata + nodep->size, 0, delta);
     692        }
     693       
     694        nodep->size = size;
     695        nodep->data = newdata;
     696        ipc_answer_0(rid, EOK);
     697}
     698
     699void tmpfs_close(ipc_callid_t rid, ipc_call_t *request)
     700{
     701        ipc_answer_0(rid, EOK);
     702}
     703
     704void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request)
     705{
    596706        dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    597707        fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    598         size_t size = (off_t)IPC_GET_ARG3(*request);
    599 
    600         /*
    601          * Lookup the respective TMPFS node.
    602          */
     708        int rc;
     709
    603710        link_t *hlp;
    604711        unsigned long key[] = {
    605                 [NODES_KEY_INDEX] = index,
    606                 [NODES_KEY_DEV] = dev_handle
     712                [NODES_KEY_DEV] = dev_handle,
     713                [NODES_KEY_INDEX] = index
    607714        };
    608715        hlp = hash_table_find(&nodes, key);
     
    613720        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    614721            nh_link);
    615 
    616         if (size == nodep->size) {
    617                 ipc_answer_0(rid, EOK);
    618                 return;
    619         }
    620 
    621         void *newdata = realloc(nodep->data, size);
    622         if (!newdata) {
    623                 ipc_answer_0(rid, ENOMEM);
    624                 return;
    625         }
    626         if (size > nodep->size) {
    627                 size_t delta = size - nodep->size;
    628                 memset(newdata + nodep->size, 0, delta);
    629         }
    630         nodep->size = size;
    631         nodep->data = newdata;
    632         ipc_answer_0(rid, EOK);
    633 }
    634 
    635 void tmpfs_close(ipc_callid_t rid, ipc_call_t *request)
    636 {
    637         ipc_answer_0(rid, EOK);
    638 }
    639 
    640 void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request)
    641 {
    642         dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
    643         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    644         int rc;
    645 
    646         link_t *hlp;
    647         unsigned long key[] = {
    648                 [NODES_KEY_INDEX] = index,
    649                 [NODES_KEY_DEV] = dev_handle
    650         };
    651         hlp = hash_table_find(&nodes, key);
    652         if (!hlp) {
    653                 ipc_answer_0(rid, ENOENT);
    654                 return;
    655         }
    656         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    657             nh_link);
    658722        rc = tmpfs_destroy_node(FS_NODE(nodep));
    659723        ipc_answer_0(rid, rc);
  • uspace/srv/hid/char_mouse/Makefile

    rb86d436 r5cde90f  
    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

    rb86d436 r5cde90f  
    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

    rb86d436 r5cde90f  
    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

    rb86d436 r5cde90f  
    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

    rb86d436 r5cde90f  
    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

    rb86d436 r5cde90f  
    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/console/gcons.c

    rb86d436 r5cde90f  
    448448       
    449449        int pm = make_pixmap(_binary_gfx_anim_1_ppm_start,
    450             (int) &_binary_gfx_anim_1_ppm_size);
     450            (size_t) &_binary_gfx_anim_1_ppm_size);
    451451        async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
    452452       
    453453        pm = make_pixmap(_binary_gfx_anim_2_ppm_start,
    454             (int) &_binary_gfx_anim_2_ppm_size);
     454            (size_t) &_binary_gfx_anim_2_ppm_size);
    455455        async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
    456456       
    457457        pm = make_pixmap(_binary_gfx_anim_3_ppm_start,
    458             (int) &_binary_gfx_anim_3_ppm_size);
     458            (size_t) &_binary_gfx_anim_3_ppm_size);
    459459        async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
    460460       
    461461        pm = make_pixmap(_binary_gfx_anim_4_ppm_start,
    462             (int) &_binary_gfx_anim_4_ppm_size);
     462            (size_t) &_binary_gfx_anim_4_ppm_size);
    463463        async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
    464464       
  • uspace/srv/hid/fb/serial_console.c

    rb86d436 r5cde90f  
    5757void serial_putchar(wchar_t ch);
    5858
    59 static int scr_width;
    60 static int scr_height;
     59static unsigned int scr_width;
     60static unsigned int scr_height;
    6161static bool color = true;       /** True if producing color output. */
    6262static bool utf8 = false;       /** True if producing UTF8 output. */
     
    108108void serial_putchar(wchar_t ch)
    109109{
    110         uint8_t buf[STR_BOUNDS(1)];
     110        char buf[STR_BOUNDS(1)];
    111111        size_t offs;
    112112        size_t i;
     
    294294}
    295295
    296 int lastcol = 0;
    297 int lastrow = 0;
     296unsigned int lastcol = 0;
     297unsigned int lastrow = 0;
    298298
    299299/**
     
    309309
    310310        wchar_t c;
    311         int col, row, w, h;
     311        unsigned int col;
     312        unsigned int row;
     313        unsigned int w;
     314        unsigned int h;
    312315        int i;
    313316
     
    358361                                break;
    359362                        }
    360                         if (col + w > scr_width || row + h > scr_height) {
     363                        if ((col + w > scr_width) || (row + h > scr_height)) {
    361364                                retval = EINVAL;
    362365                                break;
     
    424427                case FB_SCROLL:
    425428                        i = IPC_GET_ARG1(call);
    426                         if ((i > scr_height) || (i < -scr_height)) {
     429                        if ((i > (int) scr_height) || (i < -((int) scr_height))) {
    427430                                retval = EINVAL;
    428431                                break;
  • uspace/srv/hid/kbd/Makefile.build

    rb86d436 r5cde90f  
    125125ifeq ($(UARCH),ppc32)
    126126        SOURCES += \
    127                 port/dummy.c \
    128                 ctl/stty.c
     127                port/adb.c \
     128                ctl/apple.c
    129129endif
    130130
    131131ifeq ($(UARCH),sparc64)
    132         ifeq ($(PROCESSOR),sun4u)
     132        ifeq ($(PROCESSOR),sun4v)
     133                SOURCES += \
     134                        port/niagara.c \
     135                        ctl/stty.c
     136        else
    133137                ifeq ($(MACHINE),serengeti)
    134138                        SOURCES += \
     
    143147                        ctl/sun.c
    144148                endif
    145         endif
    146         ifeq ($(PROCESSOR),sun4v)
    147                 SOURCES += \
    148                         port/niagara.c \
    149                         ctl/stty.c
    150149        endif
    151150endif
  • uspace/srv/hid/kbd/port/msim.c

    rb86d436 r5cde90f  
    6464{
    6565        async_set_interrupt_received(msim_irq_handler);
    66         msim_cmds[0].addr = sysinfo_value("kbd.address.virtual");
     66        msim_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual");
    6767        ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
    6868            0, &msim_kbd);
  • uspace/srv/hid/kbd/port/niagara.c

    rb86d436 r5cde90f  
    7171
    7272static volatile bool polling_disabled = false;
    73 static void *niagara_thread_impl(void *arg);
     73static void niagara_thread_impl(void *arg);
    7474
    7575/**
     
    136136 * Thread to poll SGCN for keypresses.
    137137 */
    138 static void *niagara_thread_impl(void *arg)
     138static void niagara_thread_impl(void *arg)
    139139{
    140140        (void) arg;
     
    145145                usleep(POLL_INTERVAL);
    146146        }
    147         return 0;
    148147}
    149148/** @}
  • uspace/srv/hid/kbd/port/ns16550.c

    rb86d436 r5cde90f  
    107107}
    108108
    109 void ns16550_port_yield(void)
    110 {
    111 }
    112 
    113 void ns16550_port_reclaim(void)
    114 {
    115 }
    116 
    117109static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call)
    118110{
  • uspace/srv/hid/kbd/port/sgcn.c

    rb86d436 r5cde90f  
    9292
    9393/* polling thread */
    94 static void *sgcn_thread_impl(void *arg);
     94static void sgcn_thread_impl(void *arg);
    9595
    9696static volatile bool polling_disabled = false;
     
    167167 * Thread to poll SGCN for keypresses.
    168168 */
    169 static void *sgcn_thread_impl(void *arg)
     169static void sgcn_thread_impl(void *arg)
    170170{
    171171        (void) arg;
  • uspace/srv/hid/kbd/port/ski.c

    rb86d436 r5cde90f  
    4949#define POLL_INTERVAL           10000
    5050
    51 static void *ski_thread_impl(void *arg);
     51static void ski_thread_impl(void *arg);
    5252static int32_t ski_getchar(void);
    5353
     
    8484
    8585/** Thread to poll Ski for keypresses. */
    86 static void *ski_thread_impl(void *arg)
     86static void ski_thread_impl(void *arg)
    8787{
    8888        int32_t c;
  • uspace/srv/hid/kbd/port/z8530.c

    rb86d436 r5cde90f  
    9696}
    9797
    98 void z8530_port_yield(void)
    99 {
    100 }
    101 
    102 void z8530_port_reclaim(void)
    103 {
    104 }
    105 
    10698static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call)
    10799{
  • uspace/srv/loader/arch/amd64/Makefile.inc

    rb86d436 r5cde90f  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__64_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/amd64.s
  • uspace/srv/loader/arch/arm32/Makefile.inc

    rb86d436 r5cde90f  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__32_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/arm32.s
  • uspace/srv/loader/arch/ia32/Makefile.inc

    rb86d436 r5cde90f  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__32_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/ia32.s
  • uspace/srv/loader/arch/ia64/Makefile.inc

    rb86d436 r5cde90f  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__64_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/ia64.s
    3130AFLAGS += -xexplicit
  • uspace/srv/loader/arch/mips32/Makefile.inc

    rb86d436 r5cde90f  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__32_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/mips32.s
  • uspace/srv/loader/arch/ppc32/Makefile.inc

    rb86d436 r5cde90f  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__32_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/ppc32.s
  • uspace/srv/loader/arch/sparc64/Makefile.inc

    rb86d436 r5cde90f  
    2727#
    2828
    29 EXTRA_CFLAGS = -D__64_BITS__
    3029ARCH_SOURCES := arch/$(UARCH)/sparc64.s
  • uspace/srv/loader/elf_load.c

    rb86d436 r5cde90f  
    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

    rb86d436 r5cde90f  
    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 **) calloc(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/vfs/vfs.c

    rb86d436 r5cde90f  
    7373                ipc_callid_t callid = async_get_call(&call);
    7474               
    75                 fs_handle_t fs_handle;
    76                 int phone;
    77                
    7875                switch (IPC_GET_METHOD(call)) {
    7976                case IPC_M_PHONE_HUNGUP:
     
    8683                case VFS_IN_MOUNT:
    8784                        vfs_mount(callid, &call);
     85                        break;
     86                case VFS_IN_UNMOUNT:
     87                        vfs_unmount(callid, &call);
    8888                        break;
    8989                case VFS_IN_OPEN:
     
    134134        }
    135135       
    136         /* TODO: cleanup after the client */
     136        vfs_files_done();
    137137}
    138138
  • uspace/srv/vfs/vfs.h

    rb86d436 r5cde90f  
    4242#include <ipc/vfs.h>
    4343
    44 // FIXME: according to CONFIG_DEBUG
    45 // #define dprintf(...)  printf(__VA_ARGS__)
    46 
    47 #define dprintf(...)
     44#ifndef dprintf
     45        #define dprintf(...)
     46#endif
    4847
    4948/**
     
    9392        vfs_triplet_t triplet;
    9493        vfs_node_type_t type;
    95         size_t size;
    96         unsigned lnkcnt;
     94        aoff64_t size;
     95        unsigned int lnkcnt;
    9796} vfs_lookup_res_t;
    9897
     
    117116        vfs_node_type_t type;   /**< Partial info about the node type. */
    118117
    119         size_t size;            /**< Cached size if the node is a file. */
     118        aoff64_t size;          /**< Cached size if the node is a file. */
    120119
    121120        /**
     
    141140        bool append;
    142141
    143         /** Current position in the file. */
    144         off_t pos;
     142        /** Current absolute position in the file. */
     143        aoff64_t pos;
    145144} vfs_file_t;
    146145
     
    177176    vfs_pair_t *, ...);
    178177extern int vfs_open_node_internal(vfs_lookup_res_t *);
     178extern int vfs_close_internal(vfs_file_t *);
    179179
    180180extern bool vfs_nodes_init(void);
    181181extern vfs_node_t *vfs_node_get(vfs_lookup_res_t *);
    182182extern void vfs_node_put(vfs_node_t *);
     183extern void vfs_node_forget(vfs_node_t *);
     184extern unsigned vfs_nodes_refcount_sum_get(fs_handle_t, dev_handle_t);
     185
    183186
    184187#define MAX_OPEN_FILES  128
    185188
    186189extern bool vfs_files_init(void);
     190extern void vfs_files_done(void);
    187191extern vfs_file_t *vfs_file_get(int);
    188192extern int vfs_fd_assign(vfs_file_t *file, int fd);
     
    198202extern void vfs_register(ipc_callid_t, ipc_call_t *);
    199203extern void vfs_mount(ipc_callid_t, ipc_call_t *);
     204extern void vfs_unmount(ipc_callid_t, ipc_call_t *);
    200205extern void vfs_open(ipc_callid_t, ipc_call_t *);
    201206extern void vfs_open_node(ipc_callid_t, ipc_call_t *);
     
    208213extern void vfs_truncate(ipc_callid_t, ipc_call_t *);
    209214extern void vfs_fstat(ipc_callid_t, ipc_call_t *);
    210 extern void vfs_fstat(ipc_callid_t, ipc_call_t *);
    211215extern void vfs_stat(ipc_callid_t, ipc_call_t *);
    212216extern void vfs_mkdir(ipc_callid_t, ipc_call_t *);
  • uspace/srv/vfs/vfs_file.c

    rb86d436 r5cde90f  
    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_lookup.c

    rb86d436 r5cde90f  
    3838#include "vfs.h"
    3939#include <ipc/ipc.h>
     40#include <macros.h>
    4041#include <async.h>
    4142#include <errno.h>
     
    99100        entry.len = len;
    100101
    101         off_t first;    /* the first free index */
    102         off_t last;     /* the last free index */
     102        size_t first;   /* the first free index */
     103        size_t last;    /* the last free index */
    103104
    104105        if (list_empty(&plb_head)) {
     
    177178        memset(plb, 0, cnt2);
    178179        fibril_mutex_unlock(&plb_mutex);
    179 
    180         if ((rc == EOK) && (result)) {
    181                 result->triplet.fs_handle = (fs_handle_t) IPC_GET_ARG1(answer);
    182                 result->triplet.dev_handle = (dev_handle_t) IPC_GET_ARG2(answer);
    183                 result->triplet.index = (fs_index_t) IPC_GET_ARG3(answer);
    184                 result->size = (size_t) IPC_GET_ARG4(answer);
    185                 result->lnkcnt = (unsigned) IPC_GET_ARG5(answer);
    186                 if (lflag & L_FILE)
    187                         result->type = VFS_NODE_FILE;
    188                 else if (lflag & L_DIRECTORY)
    189                         result->type = VFS_NODE_DIRECTORY;
    190                 else
    191                         result->type = VFS_NODE_UNKNOWN;
    192         }
    193 
    194         return rc;
     180       
     181        if (((int) rc < EOK) || (!result))
     182                return (int) rc;
     183       
     184        result->triplet.fs_handle = (fs_handle_t) rc;
     185        result->triplet.dev_handle = (dev_handle_t) IPC_GET_ARG1(answer);
     186        result->triplet.index = (fs_index_t) IPC_GET_ARG2(answer);
     187        result->size =
     188            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(answer), IPC_GET_ARG4(answer));
     189        result->lnkcnt = (unsigned int) IPC_GET_ARG5(answer);
     190       
     191        if (lflag & L_FILE)
     192                result->type = VFS_NODE_FILE;
     193        else if (lflag & L_DIRECTORY)
     194                result->type = VFS_NODE_DIRECTORY;
     195        else
     196                result->type = VFS_NODE_UNKNOWN;
     197       
     198        return EOK;
    195199}
    196200
     
    214218       
    215219        if (rc == EOK) {
    216                 result->size = (size_t) IPC_GET_ARG1(answer);
    217                 result->lnkcnt = (unsigned) IPC_GET_ARG2(answer);
    218                 if (IPC_GET_ARG3(answer) & L_FILE)
     220                result->size =
     221                    MERGE_LOUP32(IPC_GET_ARG1(answer), IPC_GET_ARG2(answer));
     222                result->lnkcnt = (unsigned int) IPC_GET_ARG3(answer);
     223                if (IPC_GET_ARG4(answer) & L_FILE)
    219224                        result->type = VFS_NODE_FILE;
    220                 else if (IPC_GET_ARG3(answer) & L_DIRECTORY)
     225                else if (IPC_GET_ARG4(answer) & L_DIRECTORY)
    221226                        result->type = VFS_NODE_DIRECTORY;
    222227                else
  • uspace/srv/vfs/vfs_node.c

    rb86d436 r5cde90f  
    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
     
    222242{
    223243        vfs_node_t *node = hash_table_get_instance(item, vfs_node_t, nh_link);
    224         return (node->fs_handle == key[KEY_FS_HANDLE]) &&
     244        return (node->fs_handle == (fs_handle_t) key[KEY_FS_HANDLE]) &&
    225245            (node->dev_handle == key[KEY_DEV_HANDLE]) &&
    226246            (node->index == key[KEY_INDEX]);
     
    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

    rb86d436 r5cde90f  
    3838#include "vfs.h"
    3939#include <ipc/ipc.h>
     40#include <macros.h>
     41#include <limits.h>
    4042#include <async.h>
    4143#include <errno.h>
     
    5355
    5456/* Forward declarations of static functions. */
    55 static int vfs_truncate_internal(fs_handle_t, dev_handle_t, fs_index_t, size_t);
     57static int vfs_truncate_internal(fs_handle_t, dev_handle_t, fs_index_t, aoff64_t);
    5658
    5759/**
     
    9294                }
    9395               
    94                 rc = vfs_lookup_internal(mp, L_DIRECTORY, &mp_res, NULL);
     96                rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
    9597                if (rc != EOK) {
    9698                        /* The lookup failed for some reason. */
     
    266268       
    267269        /* 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);
     270        char *mp;
     271        int rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
     272            0, NULL);
     273        if (rc != EOK) {
     274                ipc_answer_0(rid, rc);
     275                return;
     276        }
     277       
     278        /* Now we expect to receive the mount options. */
     279        char *opts;
     280        rc = async_data_write_accept((void **) &opts, true, 0, MAX_MNTOPTS_LEN,
     281            0, NULL);
     282        if (rc != EOK) {
    295283                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);
     284                ipc_answer_0(rid, rc);
     285                return;
     286        }
     287       
     288        /*
     289         * Now, we expect the client to send us data with the name of the file
     290         * system.
     291         */
     292        char *fs_name;
     293        rc = async_data_write_accept((void **) &fs_name, true, 0, FS_NAME_MAXLEN,
     294            0, NULL);
     295        if (rc != EOK) {
    329296                free(mp);
    330297                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 
     298                ipc_answer_0(rid, rc);
     299                return;
     300        }
     301       
    382302        /*
    383303         * Wait for IPC_M_PING so that we can return an error if we don't know
     
    385305         */
    386306        ipc_call_t data;
    387         callid = async_get_call(&data);
     307        ipc_callid_t callid = async_get_call(&data);
    388308        if (IPC_GET_METHOD(data) != IPC_M_PING) {
    389309                ipc_answer_0(callid, ENOTSUP);
     
    429349}
    430350
     351void vfs_unmount(ipc_callid_t rid, ipc_call_t *request)
     352{
     353        int rc;
     354        char *mp;
     355        vfs_lookup_res_t mp_res;
     356        vfs_lookup_res_t mr_res;
     357        vfs_node_t *mr_node;
     358        int phone;
     359
     360        /*
     361         * Receive the mount point path.
     362         */
     363        rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
     364            0, NULL);
     365        if (rc != EOK)
     366                ipc_answer_0(rid, rc);
     367
     368        /*
     369         * Taking the namespace lock will do two things for us. First, it will
     370         * prevent races with other lookup operations. Second, it will stop new
     371         * references to already existing VFS nodes and creation of new VFS
     372         * nodes. This is because new references are added as a result of some
     373         * lookup operation or at least of some operation which is protected by
     374         * the namespace lock.
     375         */
     376        fibril_rwlock_write_lock(&namespace_rwlock);
     377       
     378        /*
     379         * Lookup the mounted root and instantiate it.
     380         */
     381        rc = vfs_lookup_internal(mp, L_ROOT, &mr_res, NULL);
     382        if (rc != EOK) {
     383                fibril_rwlock_write_unlock(&namespace_rwlock);
     384                free(mp);
     385                ipc_answer_0(rid, rc);
     386                return;
     387        }
     388        mr_node = vfs_node_get(&mr_res);
     389        if (!mr_node) {
     390                fibril_rwlock_write_unlock(&namespace_rwlock);
     391                free(mp);
     392                ipc_answer_0(rid, ENOMEM);
     393                return;
     394        }
     395
     396        /*
     397         * Count the total number of references for the mounted file system. We
     398         * are expecting at least two. One which we got above and one which we
     399         * got when the file system was mounted. If we find more, it means that
     400         * the file system cannot be gracefully unmounted at the moment because
     401         * someone is working with it.
     402         */
     403        if (vfs_nodes_refcount_sum_get(mr_node->fs_handle,
     404            mr_node->dev_handle) != 2) {
     405                fibril_rwlock_write_unlock(&namespace_rwlock);
     406                vfs_node_put(mr_node);
     407                free(mp);
     408                ipc_answer_0(rid, EBUSY);
     409                return;
     410        }
     411
     412        if (str_cmp(mp, "/") == 0) {
     413
     414                /*
     415                 * Unmounting the root file system.
     416                 *
     417                 * In this case, there is no mount point node and we send
     418                 * VFS_OUT_UNMOUNTED directly to the mounted file system.
     419                 */
     420
     421                free(mp);
     422                phone = vfs_grab_phone(mr_node->fs_handle);
     423                rc = async_req_1_0(phone, VFS_OUT_UNMOUNTED,
     424                    mr_node->dev_handle);
     425                vfs_release_phone(phone);
     426                if (rc != EOK) {
     427                        fibril_rwlock_write_unlock(&namespace_rwlock);
     428                        vfs_node_put(mr_node);
     429                        ipc_answer_0(rid, rc);
     430                        return;
     431                }
     432                rootfs.fs_handle = 0;
     433                rootfs.dev_handle = 0;
     434        } else {
     435
     436                /*
     437                 * Unmounting a non-root file system.
     438                 *
     439                 * We have a regular mount point node representing the parent
     440                 * file system, so we delegate the operation to it.
     441                 */
     442
     443                rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
     444                free(mp);
     445                if (rc != EOK) {
     446                        fibril_rwlock_write_unlock(&namespace_rwlock);
     447                        vfs_node_put(mr_node);
     448                        ipc_answer_0(rid, rc);
     449                        return;
     450                }
     451                vfs_node_t *mp_node = vfs_node_get(&mp_res);
     452                if (!mp_node) {
     453                        fibril_rwlock_write_unlock(&namespace_rwlock);
     454                        vfs_node_put(mr_node);
     455                        ipc_answer_0(rid, ENOMEM);
     456                        return;
     457                }
     458
     459                phone = vfs_grab_phone(mp_node->fs_handle);
     460                rc = async_req_2_0(phone, VFS_OUT_UNMOUNT, mp_node->dev_handle,
     461                    mp_node->index);
     462                vfs_release_phone(phone);
     463                if (rc != EOK) {
     464                        fibril_rwlock_write_unlock(&namespace_rwlock);
     465                        vfs_node_put(mp_node);
     466                        vfs_node_put(mr_node);
     467                        ipc_answer_0(rid, rc);
     468                        return;
     469                }
     470
     471                /* Drop the reference we got above. */
     472                vfs_node_put(mp_node);
     473                /* Drop the reference from when the file system was mounted. */
     474                vfs_node_put(mp_node);
     475        }
     476
     477
     478        /*
     479         * All went well, the mounted file system was successfully unmounted.
     480         * The only thing left is to forget the unmounted root VFS node.
     481         */
     482        vfs_node_forget(mr_node);
     483
     484        fibril_rwlock_write_unlock(&namespace_rwlock);
     485        ipc_answer_0(rid, EOK);
     486}
     487
    431488void vfs_open(ipc_callid_t rid, ipc_call_t *request)
    432489{
     
    447504        int oflag = IPC_GET_ARG2(*request);
    448505        int mode = IPC_GET_ARG3(*request);
    449         size_t len;
    450506
    451507        /* Ignore mode for now. */
     
    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);
     
    859887{
    860888        int fd = (int) IPC_GET_ARG1(*request);
    861         off_t off = (off_t) IPC_GET_ARG2(*request);
    862         int whence = (int) IPC_GET_ARG3(*request);
    863 
    864 
     889        off64_t off =
     890            (off64_t) MERGE_LOUP32(IPC_GET_ARG2(*request), IPC_GET_ARG3(*request));
     891        int whence = (int) IPC_GET_ARG4(*request);
     892       
    865893        /* Lookup the file structure corresponding to the file descriptor. */
    866894        vfs_file_t *file = vfs_file_get(fd);
     
    869897                return;
    870898        }
    871 
    872         off_t newpos;
     899       
    873900        fibril_mutex_lock(&file->lock);
    874         if (whence == SEEK_SET) {
    875                 file->pos = off;
    876                 fibril_mutex_unlock(&file->lock);
    877                 ipc_answer_1(rid, EOK, off);
    878                 return;
    879         }
    880         if (whence == SEEK_CUR) {
    881                 if (file->pos + off < file->pos) {
     901       
     902        off64_t newoff;
     903        switch (whence) {
     904                case SEEK_SET:
     905                        if (off >= 0) {
     906                                file->pos = (aoff64_t) off;
     907                                fibril_mutex_unlock(&file->lock);
     908                                ipc_answer_1(rid, EOK, off);
     909                                return;
     910                        }
     911                        break;
     912                case SEEK_CUR:
     913                        if ((off >= 0) && (file->pos + off < file->pos)) {
     914                                fibril_mutex_unlock(&file->lock);
     915                                ipc_answer_0(rid, EOVERFLOW);
     916                                return;
     917                        }
     918                       
     919                        if ((off < 0) && (file->pos < (aoff64_t) -off)) {
     920                                fibril_mutex_unlock(&file->lock);
     921                                ipc_answer_0(rid, EOVERFLOW);
     922                                return;
     923                        }
     924                       
     925                        file->pos += off;
     926                        newoff = (file->pos > OFF64_MAX) ? OFF64_MAX : file->pos;
     927                       
    882928                        fibril_mutex_unlock(&file->lock);
    883                         ipc_answer_0(rid, EOVERFLOW);
     929                        ipc_answer_2(rid, EOK, LOWER32(newoff), UPPER32(newoff));
    884930                        return;
    885                 }
    886                 file->pos += off;
    887                 newpos = file->pos;
    888                 fibril_mutex_unlock(&file->lock);
    889                 ipc_answer_1(rid, EOK, newpos);
    890                 return;
    891         }
    892         if (whence == SEEK_END) {
    893                 fibril_rwlock_read_lock(&file->node->contents_rwlock);
    894                 size_t size = file->node->size;
    895                 fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    896                 if (size + off < size) {
     931                case SEEK_END:
     932                        fibril_rwlock_read_lock(&file->node->contents_rwlock);
     933                        aoff64_t size = file->node->size;
     934                       
     935                        if ((off >= 0) && (size + off < size)) {
     936                                fibril_rwlock_read_unlock(&file->node->contents_rwlock);
     937                                fibril_mutex_unlock(&file->lock);
     938                                ipc_answer_0(rid, EOVERFLOW);
     939                                return;
     940                        }
     941                       
     942                        if ((off < 0) && (size < (aoff64_t) -off)) {
     943                                fibril_rwlock_read_unlock(&file->node->contents_rwlock);
     944                                fibril_mutex_unlock(&file->lock);
     945                                ipc_answer_0(rid, EOVERFLOW);
     946                                return;
     947                        }
     948                       
     949                        file->pos = size + off;
     950                        newoff = (file->pos > OFF64_MAX) ? OFF64_MAX : file->pos;
     951                       
     952                        fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    897953                        fibril_mutex_unlock(&file->lock);
    898                         ipc_answer_0(rid, EOVERFLOW);
     954                        ipc_answer_2(rid, EOK, LOWER32(newoff), UPPER32(newoff));
    899955                        return;
    900                 }
    901                 newpos = size + off;
    902                 file->pos = newpos;
    903                 fibril_mutex_unlock(&file->lock);
    904                 ipc_answer_1(rid, EOK, newpos);
    905                 return;
    906         }
     956        }
     957       
    907958        fibril_mutex_unlock(&file->lock);
    908959        ipc_answer_0(rid, EINVAL);
    909960}
    910961
    911 int
    912 vfs_truncate_internal(fs_handle_t fs_handle, dev_handle_t dev_handle,
    913     fs_index_t index, size_t size)
     962int vfs_truncate_internal(fs_handle_t fs_handle, dev_handle_t dev_handle,
     963    fs_index_t index, aoff64_t size)
    914964{
    915965        ipcarg_t rc;
     
    917967       
    918968        fs_phone = vfs_grab_phone(fs_handle);
    919         rc = async_req_3_0(fs_phone, VFS_OUT_TRUNCATE, (ipcarg_t)dev_handle,
    920             (ipcarg_t)index, (ipcarg_t)size);
     969        rc = async_req_4_0(fs_phone, VFS_OUT_TRUNCATE, (ipcarg_t) dev_handle,
     970            (ipcarg_t) index, LOWER32(size), UPPER32(size));
    921971        vfs_release_phone(fs_phone);
    922972        return (int)rc;
     
    926976{
    927977        int fd = IPC_GET_ARG1(*request);
    928         size_t size = IPC_GET_ARG2(*request);
     978        aoff64_t size =
     979            (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(*request), IPC_GET_ARG3(*request));
    929980        int rc;
    930981
     
    9821033void vfs_stat(ipc_callid_t rid, ipc_call_t *request)
    9831034{
    984         size_t len;
     1035        char *path;
     1036        int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
     1037        if (rc != EOK) {
     1038                ipc_answer_0(rid, rc);
     1039                return;
     1040        }
     1041       
    9851042        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 
    10061043        if (!async_data_read_receive(&callid, NULL)) {
    10071044                free(path);
     
    10491086{
    10501087        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 
     1088       
     1089        char *path;
     1090        int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
     1091        if (rc != EOK) {
     1092                ipc_answer_0(rid, rc);
     1093                return;
     1094        }
     1095       
    10741096        /* Ignore mode for now. */
    10751097        (void) mode;
     
    10861108{
    10871109        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';
     1110       
     1111        char *path;
     1112        int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
     1113        if (rc != EOK) {
     1114                ipc_answer_0(rid, rc);
     1115                return;
     1116        }
    11101117       
    11111118        fibril_rwlock_write_lock(&namespace_rwlock);
     
    11361143void vfs_rename(ipc_callid_t rid, ipc_call_t *request)
    11371144{
    1138         size_t olen, nlen;
    1139         ipc_callid_t callid;
    1140         int rc;
    1141 
    11421145        /* 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);
     1146        char *old;
     1147        int rc = async_data_write_accept((void **) &old, true, 0, 0, 0, NULL);
     1148        if (rc != EOK) {
     1149                ipc_answer_0(rid, rc);
     1150                return;
     1151        }
     1152       
     1153        /* Retrieve the new path. */
     1154        char *new;
     1155        rc = async_data_write_accept((void **) &new, true, 0, 0, 0, NULL);
     1156        if (rc != EOK) {
    11561157                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 
     1158                ipc_answer_0(rid, rc);
     1159                return;
     1160        }
     1161       
     1162        size_t olen;
     1163        size_t nlen;
    11831164        char *oldc = canonify(old, &olen);
    11841165        char *newc = canonify(new, &nlen);
    1185         if (!oldc || !newc) {
     1166       
     1167        if ((!oldc) || (!newc)) {
    11861168                ipc_answer_0(rid, EINVAL);
    11871169                free(old);
     
    11891171                return;
    11901172        }
     1173       
    11911174        oldc[olen] = '\0';
    11921175        newc[nlen] = '\0';
     1176       
    11931177        if ((!str_lcmp(newc, oldc, str_length(oldc))) &&
    11941178            ((newc[str_length(oldc)] == '/') ||
     
    12111195        vfs_lookup_res_t new_par_lr;
    12121196        fibril_rwlock_write_lock(&namespace_rwlock);
     1197       
    12131198        /* Lookup the node belonging to the old file name. */
    12141199        rc = vfs_lookup_internal(oldc, L_NONE, &old_lr, NULL);
     
    12201205                return;
    12211206        }
     1207       
    12221208        vfs_node_t *old_node = vfs_node_get(&old_lr);
    12231209        if (!old_node) {
     
    12281214                return;
    12291215        }
     1216       
    12301217        /* Determine the path to the parent of the node with the new name. */
    12311218        char *parentc = str_dup(newc);
     
    12371224                return;
    12381225        }
     1226       
    12391227        char *lastsl = str_rchr(parentc + 1, '/');
    12401228        if (lastsl)
     
    12421230        else
    12431231                parentc[1] = '\0';
     1232       
    12441233        /* Lookup parent of the new file name. */
    12451234        rc = vfs_lookup_internal(parentc, L_NONE, &new_par_lr, NULL);
     
    12521241                return;
    12531242        }
     1243       
    12541244        /* Check whether linking to the same file system instance. */
    12551245        if ((old_node->fs_handle != new_par_lr.triplet.fs_handle) ||
     
    12611251                return;
    12621252        }
     1253       
    12631254        /* Destroy the old link for the new name. */
    12641255        vfs_node_t *new_node = NULL;
    12651256        rc = vfs_lookup_internal(newc, L_UNLINK, &new_lr, NULL);
     1257       
    12661258        switch (rc) {
    12671259        case ENOENT:
     
    12881280                return;
    12891281        }
     1282       
    12901283        /* Create the new link for the new name. */
    12911284        rc = vfs_lookup_internal(newc, L_LINK, NULL, NULL, old_node->index);
     
    12991292                return;
    13001293        }
     1294       
    13011295        fibril_mutex_lock(&nodes_mutex);
    13021296        old_node->lnkcnt++;
    13031297        fibril_mutex_unlock(&nodes_mutex);
     1298       
    13041299        /* Destroy the link for the old name. */
    13051300        rc = vfs_lookup_internal(oldc, L_UNLINK, NULL, NULL);
     
    13141309                return;
    13151310        }
     1311       
    13161312        fibril_mutex_lock(&nodes_mutex);
    13171313        old_node->lnkcnt--;
     
    13191315        fibril_rwlock_write_unlock(&namespace_rwlock);
    13201316        vfs_node_put(old_node);
     1317       
    13211318        if (new_node)
    13221319                vfs_node_put(new_node);
     1320       
    13231321        free(old);
    13241322        free(new);
  • uspace/srv/vfs/vfs_register.c

    rb86d436 r5cde90f  
    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.