Changeset 19f24fd in mainline for uspace/lib


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

Merge mainline changes.

Location:
uspace/lib
Files:
11 added
16 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libblock/libblock.c

    r83349b03 r19f24fd  
    198198        assert(devcon);
    199199       
     200        if (devcon->cache)
     201                (void) block_cache_fini(dev_handle);
     202
    200203        devcon_remove(devcon);
    201204
    202205        if (devcon->bb_buf)
    203206                free(devcon->bb_buf);
    204 
    205         if (devcon->cache) {
    206                 hash_table_destroy(&devcon->cache->block_hash);
    207                 free(devcon->cache);
    208         }
    209207
    210208        munmap(devcon->comm_area, devcon->comm_size);
     
    302300
    303301        devcon->cache = cache;
     302        return EOK;
     303}
     304
     305int block_cache_fini(dev_handle_t dev_handle)
     306{
     307        devcon_t *devcon = devcon_search(dev_handle);
     308        cache_t *cache;
     309        int rc;
     310
     311        if (!devcon)
     312                return ENOENT;
     313        if (!devcon->cache)
     314                return EOK;
     315        cache = devcon->cache;
     316       
     317        /*
     318         * We are expecting to find all blocks for this device handle on the
     319         * free list, i.e. the block reference count should be zero. Do not
     320         * bother with the cache and block locks because we are single-threaded.
     321         */
     322        while (!list_empty(&cache->free_head)) {
     323                block_t *b = list_get_instance(cache->free_head.next,
     324                    block_t, free_link);
     325
     326                list_remove(&b->free_link);
     327                if (b->dirty) {
     328                        memcpy(devcon->comm_area, b->data, b->size);
     329                        rc = write_blocks(devcon, b->boff, 1);
     330                        if (rc != EOK)
     331                                return rc;
     332                }
     333
     334                long key = b->boff;
     335                hash_table_remove(&cache->block_hash, &key, 1);
     336               
     337                free(b->data);
     338                free(b);
     339        }
     340
     341        hash_table_destroy(&cache->block_hash);
     342        devcon->cache = NULL;
     343        free(cache);
     344
    304345        return EOK;
    305346}
  • uspace/lib/libblock/libblock.h

    r83349b03 r19f24fd  
    100100
    101101extern int block_cache_init(dev_handle_t, size_t, unsigned, enum cache_mode);
     102extern int block_cache_fini(dev_handle_t);
    102103
    103104extern int block_get(block_t **, dev_handle_t, bn_t, int);
  • uspace/lib/libc/arch/ia64/include/fibril.h

    r83349b03 r19f24fd  
    5252/* Stack is divided into two equal parts (for memory stack and register stack). */
    5353#define PSTHREAD_INITIAL_STACK_DIVISION 2 
    54 
    55 #ifdef context_set
    56 #undef context_set
    57 #endif
    5854
    5955#define context_set(c, _pc, stack, size, tls)                                                           \
  • uspace/lib/libc/arch/sparc64/include/fibril.h

    r83349b03 r19f24fd  
    4242#define SP_DELTA        (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
    4343
    44 #ifdef context_set
    45 #undef context_set
    46 #endif
    47 
    4844#define context_set(c, _pc, stack, size, ptls) \
    4945        do { \
  • uspace/lib/libc/generic/adt/hash_table.c

    r83349b03 r19f24fd  
    193193}
    194194
     195/** Apply fucntion to all items in hash table.
     196 *
     197 * @param h             Hash table.
     198 * @param f             Function to be applied.
     199 * @param arg           Argument to be passed to the function.
     200 */
     201void
     202hash_table_apply(hash_table_t *h, void (*f)(link_t *, void *), void *arg)
     203{
     204        hash_index_t bucket;
     205        link_t *cur;
     206
     207        for (bucket = 0; bucket < h->entries; bucket++) {
     208                for (cur = h->entry[bucket].next; cur != &h->entry[bucket];
     209                    cur = cur->next) {
     210                        f(cur, arg);
     211                }
     212        }
     213}
     214
    195215/** @}
    196216 */
  • uspace/lib/libc/generic/async.c

    r83349b03 r19f24fd  
    12871287}
    12881288
     1289/** Wrapper for forwarding any read request
     1290 *
     1291 *
     1292 */
     1293int async_data_read_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
     1294    ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr)
     1295{
     1296        ipc_callid_t callid;
     1297        if (!async_data_read_receive(&callid, NULL)) {
     1298                ipc_answer_0(callid, EINVAL);
     1299                return EINVAL;
     1300        }
     1301       
     1302        aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
     1303            dataptr);
     1304        if (msg == 0) {
     1305                ipc_answer_0(callid, EINVAL);
     1306                return EINVAL;
     1307        }
     1308       
     1309        int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
     1310            IPC_FF_ROUTE_FROM_ME);
     1311        if (retval != EOK) {
     1312                ipc_answer_0(callid, retval);
     1313                return retval;
     1314        }
     1315       
     1316        ipcarg_t rc;
     1317        async_wait_for(msg, &rc);
     1318       
     1319        return (int) rc;
     1320}
     1321
    12891322/** Wrapper for making IPC_M_DATA_WRITE calls using the async framework.
    12901323 *
    1291  * @param phoneid       Phone that will be used to contact the receiving side.
    1292  * @param src           Address of the beginning of the source buffer.
    1293  * @param size          Size of the source buffer.
    1294  *
    1295  * @return              Zero on success or a negative error code from errno.h.
     1324 * @param phoneid Phone that will be used to contact the receiving side.
     1325 * @param src     Address of the beginning of the source buffer.
     1326 * @param size    Size of the source buffer.
     1327 *
     1328 * @return Zero on success or a negative error code from errno.h.
     1329 *
    12961330 */
    12971331int async_data_write_start(int phoneid, const void *src, size_t size)
     
    13081342 * So far, this wrapper is to be used from within a connection fibril.
    13091343 *
    1310  * @param callid        Storage where the hash of the IPC_M_DATA_WRITE call will
    1311  *                      be stored.
    1312  * @param size          Storage where the suggested size will be stored. May be
    1313  *                      NULL
    1314  *
    1315  * @return              Non-zero on success, zero on failure.
     1344 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will
     1345 *               be stored.
     1346 * @param size   Storage where the suggested size will be stored. May be
     1347 *               NULL
     1348 *
     1349 * @return Non-zero on success, zero on failure.
     1350 *
    13161351 */
    13171352int async_data_write_receive(ipc_callid_t *callid, size_t *size)
     
    13201355       
    13211356        assert(callid);
    1322 
     1357       
    13231358        *callid = async_get_call(&data);
    13241359        if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE)
    13251360                return 0;
     1361       
    13261362        if (size)
    13271363                *size = (size_t) IPC_GET_ARG2(data);
     1364       
    13281365        return 1;
    13291366}
     
    13341371 * so that the user doesn't have to remember the meaning of each IPC argument.
    13351372 *
    1336  * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
    1337  * @param dst           Final destination address for the IPC_M_DATA_WRITE call.
    1338  * @param size          Final size for the IPC_M_DATA_WRITE call.
    1339  *
    1340  * @return              Zero on success or a value from @ref errno.h on failure.
     1373 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     1374 * @param dst    Final destination address for the IPC_M_DATA_WRITE call.
     1375 * @param size   Final size for the IPC_M_DATA_WRITE call.
     1376 *
     1377 * @return Zero on success or a value from @ref errno.h on failure.
     1378 *
    13411379 */
    13421380int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
     
    13451383}
    13461384
    1347 /** Wrapper for receiving blobs via the async_data_write_*
     1385/** Wrapper for receiving binary data or strings
    13481386 *
    13491387 * This wrapper only makes it more comfortable to use async_data_write_*
    1350  * functions to receive blobs.
    1351  *
    1352  * @param blob     Pointer to data pointer (which should be later disposed
    1353  *                 by free()). If the operation fails, the pointer is not
    1354  *                 touched.
    1355  * @param max_size Maximum size (in bytes) of the blob to receive. 0 means
    1356  *                 no limit.
    1357  * @param received If not NULL, the size of the received data is stored here.
     1388 * functions to receive binary data or strings.
     1389 *
     1390 * @param data       Pointer to data pointer (which should be later disposed
     1391 *                   by free()). If the operation fails, the pointer is not
     1392 *                   touched.
     1393 * @param nullterm   If true then the received data is always zero terminated.
     1394 *                   This also causes to allocate one extra byte beyond the
     1395 *                   raw transmitted data.
     1396 * @param min_size   Minimum size (in bytes) of the data to receive.
     1397 * @param max_size   Maximum size (in bytes) of the data to receive. 0 means
     1398 *                   no limit.
     1399 * @param granulariy If non-zero then the size of the received data has to
     1400 *                   be divisible by this value.
     1401 * @param received   If not NULL, the size of the received data is stored here.
    13581402 *
    13591403 * @return Zero on success or a value from @ref errno.h on failure.
    13601404 *
    13611405 */
    1362 int async_data_blob_receive(char **blob, const size_t max_size, size_t *received)
     1406int async_data_write_accept(void **data, const bool nullterm,
     1407    const size_t min_size, const size_t max_size, const size_t granularity,
     1408    size_t *received)
    13631409{
    13641410        ipc_callid_t callid;
     
    13691415        }
    13701416       
     1417        if (size < min_size) {
     1418                ipc_answer_0(callid, EINVAL);
     1419                return EINVAL;
     1420        }
     1421       
    13711422        if ((max_size > 0) && (size > max_size)) {
    13721423                ipc_answer_0(callid, EINVAL);
     
    13741425        }
    13751426       
    1376         char *data = (char *) malloc(size);
    1377         if (data == NULL) {
     1427        if ((granularity > 0) && ((size % granularity) != 0)) {
     1428                ipc_answer_0(callid, EINVAL);
     1429                return EINVAL;
     1430        }
     1431       
     1432        void *_data;
     1433       
     1434        if (nullterm)
     1435                _data = malloc(size + 1);
     1436        else
     1437                _data = malloc(size);
     1438       
     1439        if (_data == NULL) {
    13781440                ipc_answer_0(callid, ENOMEM);
    13791441                return ENOMEM;
    13801442        }
    13811443       
    1382         int rc = async_data_write_finalize(callid, data, size);
     1444        int rc = async_data_write_finalize(callid, _data, size);
    13831445        if (rc != EOK) {
    1384                 free(data);
     1446                free(_data);
    13851447                return rc;
    13861448        }
    13871449       
    1388         *blob = data;
     1450        if (nullterm)
     1451                ((char *) _data)[size] = 0;
     1452       
     1453        *data = _data;
    13891454        if (received != NULL)
    13901455                *received = size;
     
    13931458}
    13941459
    1395 /** Wrapper for receiving strings via the async_data_write_*
    1396  *
    1397  * This wrapper only makes it more comfortable to use async_data_write_*
    1398  * functions to receive strings.
    1399  *
    1400  * @param str      Pointer to string pointer (which should be later disposed
    1401  *                 by free()). If the operation fails, the pointer is not
    1402  *                 touched.
    1403  * @param max_size Maximum size (in bytes) of the string to receive. 0 means
    1404  *                 no limit.
    1405  *
    1406  * @return Zero on success or a value from @ref errno.h on failure.
    1407  *
    1408  */
    1409 int async_data_string_receive(char **str, const size_t max_size)
     1460/** Wrapper for voiding any data that is about to be received
     1461 *
     1462 * This wrapper can be used to void any pending data
     1463 *
     1464 * @param retval Error value from @ref errno.h to be returned to the caller.
     1465 *
     1466 */
     1467void async_data_write_void(const int retval)
    14101468{
    14111469        ipc_callid_t callid;
    1412         size_t size;
    1413         if (!async_data_write_receive(&callid, &size)) {
     1470        async_data_write_receive(&callid, NULL);
     1471        ipc_answer_0(callid, retval);
     1472}
     1473
     1474/** Wrapper for forwarding any data that is about to be received
     1475 *
     1476 *
     1477 */
     1478int async_data_write_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
     1479    ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr)
     1480{
     1481        ipc_callid_t callid;
     1482        if (!async_data_write_receive(&callid, NULL)) {
    14141483                ipc_answer_0(callid, EINVAL);
    14151484                return EINVAL;
    14161485        }
    14171486       
    1418         if ((max_size > 0) && (size > max_size)) {
     1487        aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
     1488            dataptr);
     1489        if (msg == 0) {
    14191490                ipc_answer_0(callid, EINVAL);
    14201491                return EINVAL;
    14211492        }
    14221493       
    1423         char *data = (char *) malloc(size + 1);
    1424         if (data == NULL) {
    1425                 ipc_answer_0(callid, ENOMEM);
    1426                 return ENOMEM;
    1427         }
    1428        
    1429         int rc = async_data_write_finalize(callid, data, size);
    1430         if (rc != EOK) {
    1431                 free(data);
    1432                 return rc;
    1433         }
    1434        
    1435         data[size] = 0;
    1436         *str = data;
    1437         return EOK;
     1494        int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
     1495            IPC_FF_ROUTE_FROM_ME);
     1496        if (retval != EOK) {
     1497                ipc_answer_0(callid, retval);
     1498                return retval;
     1499        }
     1500       
     1501        ipcarg_t rc;
     1502        async_wait_for(msg, &rc);
     1503       
     1504        return (int) rc;
    14381505}
    14391506
  • uspace/lib/libc/generic/clipboard.c

    r83349b03 r19f24fd  
    8484                clip_connect();
    8585               
    86                 aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_BLOB, NULL);
     86                aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA, NULL);
    8787                ipcarg_t rc = async_data_write_start(clip_phone, (void *) str, size);
    8888                if (rc != EOK) {
     
    139139                        *str = sbuf;
    140140                        return EOK;
    141                 case CLIPBOARD_TAG_BLOB:
     141                case CLIPBOARD_TAG_DATA:
    142142                        sbuf = malloc(size + 1);
    143143                        if (sbuf == NULL)
  • uspace/lib/libc/generic/vfs/vfs.c

    r83349b03 r19f24fd  
    120120    const char *opts, unsigned int flags)
    121121{
    122         int res;
     122        int null_id = -1;
     123        char null[DEVMAP_NAME_MAXLEN];
     124       
     125        if (str_cmp(fqdn, "") == 0) {
     126                /* No device specified, create a fresh
     127                   null/%d device instead */
     128                null_id = devmap_null_create();
     129               
     130                if (null_id == -1)
     131                        return ENOMEM;
     132               
     133                snprintf(null, DEVMAP_NAME_MAXLEN, "null/%d", null_id);
     134                fqdn = null;
     135        }
     136       
     137        dev_handle_t dev_handle;
     138        int res = devmap_device_get_handle(fqdn, &dev_handle, flags);
     139        if (res != EOK) {
     140                if (null_id != -1)
     141                        devmap_null_destroy(null_id);
     142               
     143                return res;
     144        }
     145       
     146        size_t mpa_size;
     147        char *mpa = absolutize(mp, &mpa_size);
     148        if (!mpa) {
     149                if (null_id != -1)
     150                        devmap_null_destroy(null_id);
     151               
     152                return ENOMEM;
     153        }
     154       
     155        futex_down(&vfs_phone_futex);
     156        async_serialize_start();
     157        vfs_connect();
     158       
     159        ipcarg_t rc_orig;
     160        aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);
     161        ipcarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
     162        if (rc != EOK) {
     163                async_wait_for(req, &rc_orig);
     164                async_serialize_end();
     165                futex_up(&vfs_phone_futex);
     166                free(mpa);
     167               
     168                if (null_id != -1)
     169                        devmap_null_destroy(null_id);
     170               
     171                if (rc_orig == EOK)
     172                        return (int) rc;
     173                else
     174                        return (int) rc_orig;
     175        }
     176       
     177        rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
     178        if (rc != EOK) {
     179                async_wait_for(req, &rc_orig);
     180                async_serialize_end();
     181                futex_up(&vfs_phone_futex);
     182                free(mpa);
     183               
     184                if (null_id != -1)
     185                        devmap_null_destroy(null_id);
     186               
     187                if (rc_orig == EOK)
     188                        return (int) rc;
     189                else
     190                        return (int) rc_orig;
     191        }
     192       
     193        rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
     194        if (rc != EOK) {
     195                async_wait_for(req, &rc_orig);
     196                async_serialize_end();
     197                futex_up(&vfs_phone_futex);
     198                free(mpa);
     199               
     200                if (null_id != -1)
     201                        devmap_null_destroy(null_id);
     202               
     203                if (rc_orig == EOK)
     204                        return (int) rc;
     205                else
     206                        return (int) rc_orig;
     207        }
     208       
     209        /* Ask VFS whether it likes fs_name. */
     210        rc = async_req_0_0(vfs_phone, IPC_M_PING);
     211        if (rc != EOK) {
     212                async_wait_for(req, &rc_orig);
     213                async_serialize_end();
     214                futex_up(&vfs_phone_futex);
     215                free(mpa);
     216               
     217                if (null_id != -1)
     218                        devmap_null_destroy(null_id);
     219               
     220                if (rc_orig == EOK)
     221                        return (int) rc;
     222                else
     223                        return (int) rc_orig;
     224        }
     225       
     226        async_wait_for(req, &rc);
     227        async_serialize_end();
     228        futex_up(&vfs_phone_futex);
     229        free(mpa);
     230       
     231        if ((rc != EOK) && (null_id != -1))
     232                devmap_null_destroy(null_id);
     233       
     234        return (int) rc;
     235}
     236
     237int unmount(const char *mp)
     238{
    123239        ipcarg_t rc;
    124240        ipcarg_t rc_orig;
    125241        aid_t req;
    126         dev_handle_t dev_handle;
    127        
    128         res = devmap_device_get_handle(fqdn, &dev_handle, flags);
    129         if (res != EOK)
    130                 return res;
    131        
    132242        size_t mpa_size;
    133         char *mpa = absolutize(mp, &mpa_size);
     243        char *mpa;
     244       
     245        mpa = absolutize(mp, &mpa_size);
    134246        if (!mpa)
    135247                return ENOMEM;
     
    139251        vfs_connect();
    140252       
    141         req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);
     253        req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
    142254        rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    143255        if (rc != EOK) {
     
    152264        }
    153265       
    154         rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    155         if (rc != EOK) {
    156                 async_wait_for(req, &rc_orig);
    157                 async_serialize_end();
    158                 futex_up(&vfs_phone_futex);
    159                 free(mpa);
    160                 if (rc_orig == EOK)
    161                         return (int) rc;
    162                 else
    163                         return (int) rc_orig;
    164         }
    165 
    166         rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    167         if (rc != EOK) {
    168                 async_wait_for(req, &rc_orig);
    169                 async_serialize_end();
    170                 futex_up(&vfs_phone_futex);
    171                 free(mpa);
    172                 if (rc_orig == EOK)
    173                         return (int) rc;
    174                 else
    175                         return (int) rc_orig;
    176         }
    177 
    178         /* Ask VFS whether it likes fs_name. */
    179         rc = async_req_0_0(vfs_phone, IPC_M_PING);
    180         if (rc != EOK) {
    181                 async_wait_for(req, &rc_orig);
    182                 async_serialize_end();
    183                 futex_up(&vfs_phone_futex);
    184                 free(mpa);
    185                 if (rc_orig == EOK)
    186                         return (int) rc;
    187                 else
    188                         return (int) rc_orig;
    189         }
    190        
     266
    191267        async_wait_for(req, &rc);
    192268        async_serialize_end();
  • uspace/lib/libc/include/adt/hash_table.h

    r83349b03 r19f24fd  
    8888extern void hash_table_remove(hash_table_t *, unsigned long [], hash_count_t);
    8989extern void hash_table_destroy(hash_table_t *);
     90extern void hash_table_apply(hash_table_t *, void (*)(link_t *, void *),
     91    void *);
    9092
    9193#endif
  • uspace/lib/libc/include/async.h

    r83349b03 r19f24fd  
    277277extern int async_share_out_receive(ipc_callid_t *, size_t *, int *);
    278278extern int async_share_out_finalize(ipc_callid_t, void *);
     279
     280/*
     281 * User-friendly wrappers for async_data_read_forward_fast().
     282 */
     283#define async_data_read_forward_0_0(phoneid, method, answer) \
     284        async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL)
     285#define async_data_read_forward_0_1(phoneid, method, answer) \
     286        async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer))
     287#define async_data_read_forward_1_0(phoneid, method, arg1, answer) \
     288        async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL)
     289#define async_data_read_forward_1_1(phoneid, method, arg1, answer) \
     290        async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, (answer))
     291#define async_data_read_forward_2_0(phoneid, method, arg1, arg2, answer) \
     292        async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL)
     293#define async_data_read_forward_2_1(phoneid, method, arg1, arg2, answer) \
     294        async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
     295            (answer))
     296#define async_data_read_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \
     297        async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
     298            NULL)
     299#define async_data_read_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \
     300        async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
     301            (answer))
     302#define async_data_read_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \
     303        async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
     304            (arg4), NULL)
     305#define async_data_read_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \
     306        async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
     307            (arg4), (answer))
     308
    279309extern int async_data_read_start(int, void *, size_t);
    280310extern int async_data_read_receive(ipc_callid_t *, size_t *);
    281311extern int async_data_read_finalize(ipc_callid_t, const void *, size_t);
     312
     313extern int async_data_read_forward_fast(int, ipcarg_t, ipcarg_t, ipcarg_t,
     314    ipcarg_t, ipcarg_t, ipc_call_t *);
     315
     316/*
     317 * User-friendly wrappers for async_data_write_forward_fast().
     318 */
     319#define async_data_write_forward_0_0(phoneid, method, answer) \
     320        async_data_write_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL)
     321#define async_data_write_forward_0_1(phoneid, method, answer) \
     322        async_data_write_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer))
     323#define async_data_write_forward_1_0(phoneid, method, arg1, answer) \
     324        async_data_write_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL)
     325#define async_data_write_forward_1_1(phoneid, method, arg1, answer) \
     326        async_data_write_forward_fast((phoneid), (method), (arg1), 0, 0, 0, \
     327            (answer))
     328#define async_data_write_forward_2_0(phoneid, method, arg1, arg2, answer) \
     329        async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
     330            NULL)
     331#define async_data_write_forward_2_1(phoneid, method, arg1, arg2, answer) \
     332        async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
     333            (answer))
     334#define async_data_write_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \
     335        async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
     336            0, NULL)
     337#define async_data_write_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \
     338        async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
     339            0, (answer))
     340#define async_data_write_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \
     341        async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
     342            (arg4), NULL)
     343#define async_data_write_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \
     344        async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
     345            (arg4), (answer))
     346
    282347extern int async_data_write_start(int, const void *, size_t);
    283348extern int async_data_write_receive(ipc_callid_t *, size_t *);
    284349extern int async_data_write_finalize(ipc_callid_t, void *, size_t);
    285350
    286 extern int async_data_blob_receive(char **, const size_t, size_t *);
    287 extern int async_data_string_receive(char **, const size_t);
     351extern int async_data_write_accept(void **, const bool, const size_t,
     352    const size_t, const size_t, size_t *);
     353extern void async_data_write_void(const int);
     354
     355extern int async_data_write_forward_fast(int, ipcarg_t, ipcarg_t, ipcarg_t,
     356    ipcarg_t, ipcarg_t, ipc_call_t *);
    288357
    289358#endif
  • uspace/lib/libc/include/fibril.h

    r83349b03 r19f24fd  
    4040#include <libarch/tls.h>
    4141
    42 #ifndef context_set
    43 #define context_set(c, _pc, stack, size, ptls) \
     42#define context_set_generic(c, _pc, stack, size, ptls) \
    4443        (c)->pc = (sysarg_t) (_pc); \
    4544        (c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
    4645        (c)->tls = (sysarg_t) (ptls);
    47 #endif /* context_set */
    4846
    49 #define FIBRIL_SERIALIZED       1
    50 #define FIBRIL_WRITER           2
     47#define FIBRIL_SERIALIZED  1
     48#define FIBRIL_WRITER      2
    5149
    5250typedef enum {
     
    5957typedef sysarg_t fid_t;
    6058
    61 struct fibril {
     59typedef struct fibril {
    6260        link_t link;
    6361        context_t ctx;
     
    7068        int retval;
    7169        int flags;
    72 };
    73 typedef struct fibril fibril_t;
     70} fibril_t;
    7471
    7572/** Fibril-local variable specifier */
    7673#define fibril_local __thread
    7774
    78 extern int context_save(context_t *c) __attribute__ ((returns_twice));
    79 extern void context_restore(context_t *c) __attribute__ ((noreturn));
     75extern int context_save(context_t *ctx) __attribute__((returns_twice));
     76extern void context_restore(context_t *ctx) __attribute__((noreturn));
    8077
    8178extern fid_t fibril_create(int (*func)(void *), void *arg);
     
    9087extern void fibril_dec_sercount(void);
    9188
    92 static inline int fibril_yield(void) {
     89static inline int fibril_yield(void)
     90{
    9391        return fibril_switch(FIBRIL_PREEMPT);
    9492}
  • uspace/lib/libc/include/ipc/clipboard.h

    r83349b03 r19f24fd  
    4646typedef enum {
    4747        CLIPBOARD_TAG_NONE,
    48         CLIPBOARD_TAG_BLOB
     48        CLIPBOARD_TAG_DATA
    4949} clipboard_tag_t;
    5050
  • uspace/lib/libc/include/ipc/vfs.h

    r83349b03 r19f24fd  
    8686        VFS_OUT_MOUNTED,
    8787        VFS_OUT_UNMOUNT,
     88        VFS_OUT_UNMOUNTED,
    8889        VFS_OUT_SYNC,
    8990        VFS_OUT_STAT,
     
    100101 * No lookup flags used.
    101102 */
    102 #define L_NONE  0
     103#define L_NONE                  0
    103104
    104105/**
     
    107108 * with L_DIRECTORY.
    108109 */
    109 #define L_FILE  1
     110#define L_FILE                  1
    110111
    111112/**
    112  * Lookup wil succeed only if the object is a directory. If L_CREATE is
     113 * Lookup will succeed only if the object is a directory. If L_CREATE is
    113114 * specified, an empty directory will be created. This flag is mutually
    114115 * exclusive with L_FILE.
    115116 */
    116 #define L_DIRECTORY  2
     117#define L_DIRECTORY             2
     118
     119/**
     120 * Lookup will succeed only if the object is a root directory. The flag is
     121 * mutually exclusive with L_FILE and L_MP.
     122 */
     123#define L_ROOT                  4
     124
     125/**
     126 * Lookup will succeed only if the object is a mount point. The flag is mutually
     127 * exclusive with L_FILE and L_ROOT.
     128 */
     129#define L_MP                    8
     130
    117131
    118132/**
     
    120134 * object already exists. L_EXCLUSIVE is implied when L_DIRECTORY is used.
    121135 */
    122 #define L_EXCLUSIVE  4
     136#define L_EXCLUSIVE             16
    123137
    124138/**
    125139 * L_CREATE is used for creating both regular files and directories.
    126140 */
    127 #define L_CREATE  8
     141#define L_CREATE                32
    128142
    129143/**
    130144 * L_LINK is used for linking to an already existing nodes.
    131145 */
    132 #define L_LINK  16
     146#define L_LINK                  64
    133147
    134148/**
     
    137151 * VFS_UNLINK.
    138152 */
    139 #define L_UNLINK  32
     153#define L_UNLINK                128
    140154
    141155/**
    142  * L_OPEN is used to indicate that the lookup operation is a part of VFS_OPEN
     156 * L_OPEN is used to indicate that the lookup operation is a part of VFS_IN_OPEN
    143157 * call from the client. This means that the server might allocate some
    144158 * resources for the opened file. This flag cannot be passed directly by the
    145159 * client.
    146160 */
    147 #define L_OPEN  64
     161#define L_OPEN                  256
    148162
    149163#endif
  • uspace/lib/libc/include/vfs/vfs.h

    r83349b03 r19f24fd  
    5555extern int mount(const char *, const char *, const char *, const char *,
    5656    unsigned int);
     57extern int unmount(const char *);
    5758
    5859extern void __stdio_init(int filc, fdi_node_t *filv[]);
  • uspace/lib/libfs/libfs.c

    r83349b03 r19f24fd  
    161161        /* Accept the phone */
    162162        callid = async_get_call(&call);
    163         int mountee_phone = (int)IPC_GET_ARG1(call);
     163        int mountee_phone = (int) IPC_GET_ARG1(call);
    164164        if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) ||
    165165            (mountee_phone < 0)) {
     
    172172        ipc_answer_0(callid, EOK);
    173173       
    174         res = async_data_write_receive(&callid, NULL);
    175         if (!res) {
    176                 ipc_hangup(mountee_phone);
    177                 ipc_answer_0(callid, EINVAL);
    178                 ipc_answer_0(rid, EINVAL);
    179                 return;
    180         }
    181        
    182174        fs_node_t *fn;
    183175        res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);
    184176        if ((res != EOK) || (!fn)) {
    185177                ipc_hangup(mountee_phone);
    186                 ipc_answer_0(callid, combine_rc(res, ENOENT));
     178                async_data_write_void(combine_rc(res, ENOENT));
    187179                ipc_answer_0(rid, combine_rc(res, ENOENT));
    188180                return;
     
    192184                ipc_hangup(mountee_phone);
    193185                (void) ops->node_put(fn);
    194                 ipc_answer_0(callid, EBUSY);
     186                async_data_write_void(EBUSY);
    195187                ipc_answer_0(rid, EBUSY);
    196188                return;
     
    201193                ipc_hangup(mountee_phone);
    202194                (void) ops->node_put(fn);
    203                 ipc_answer_0(callid, rc);
     195                async_data_write_void(rc);
    204196                ipc_answer_0(rid, rc);
    205197                return;
     
    207199       
    208200        ipc_call_t answer;
    209         aid_t msg = async_send_1(mountee_phone, VFS_OUT_MOUNTED, mr_dev_handle,
    210             &answer);
    211         ipc_forward_fast(callid, mountee_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    212         async_wait_for(msg, &rc);
     201        rc = async_data_write_forward_1_1(mountee_phone, VFS_OUT_MOUNTED,
     202            mr_dev_handle, &answer);
    213203       
    214204        if (rc == EOK) {
     
    224214        ipc_answer_3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
    225215            IPC_GET_ARG3(answer));
     216}
     217
     218void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)
     219{
     220        dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     221        fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
     222        fs_node_t *fn;
     223        int res;
     224
     225        res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);
     226        if ((res != EOK) || (!fn)) {
     227                ipc_answer_0(rid, combine_rc(res, ENOENT));
     228                return;
     229        }
     230
     231        /*
     232         * We are clearly expecting to find the mount point active.
     233         */
     234        if (!fn->mp_data.mp_active) {
     235                (void) ops->node_put(fn);
     236                ipc_answer_0(rid, EINVAL);
     237                return;
     238        }
     239
     240        /*
     241         * Tell the mounted file system to unmount.
     242         */
     243        res = async_req_1_0(fn->mp_data.phone, VFS_OUT_UNMOUNTED,
     244            fn->mp_data.dev_handle);
     245
     246        /*
     247         * If everything went well, perform the clean-up on our side.
     248         */
     249        if (res == EOK) {
     250                ipc_hangup(fn->mp_data.phone);
     251                fn->mp_data.mp_active = false;
     252                fn->mp_data.fs_handle = 0;
     253                fn->mp_data.dev_handle = 0;
     254                fn->mp_data.phone = 0;
     255                /* Drop the reference created in libfs_mount(). */
     256                (void) ops->node_put(fn);
     257        }
     258
     259        (void) ops->node_put(fn);
     260        ipc_answer_0(rid, res);
    226261}
    227262
     
    304339                on_error(rc, goto out_with_answer);
    305340               
    306                 if ((tmp) && (tmp->mp_data.mp_active)) {
     341                /*
     342                 * If the matching component is a mount point, there are two
     343                 * legitimate semantics of the lookup operation. The first is
     344                 * the commonly used one in which the lookup crosses each mount
     345                 * point into the mounted file system. The second semantics is
     346                 * used mostly during unmount() and differs from the first one
     347                 * only in that the last mount point in the looked up path,
     348                 * which is also its last component, is not crossed.
     349                 */
     350
     351                if ((tmp) && (tmp->mp_data.mp_active) &&
     352                    (!(lflag & L_MP) || (next <= last))) {
    307353                        if (next > last)
    308354                                next = last = first;
     
    475521                goto out;
    476522        }
     523
     524        if ((lflag & L_ROOT) && par) {
     525                ipc_answer_0(rid, EINVAL);
     526                goto out;
     527        }
    477528       
    478529out_with_answer:
  • uspace/lib/libfs/libfs.h

    r83349b03 r19f24fd  
    9595
    9696extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
     97extern void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
    9798extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    9899extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
Note: See TracChangeset for help on using the changeset viewer.