Changeset a33f0a6 in mainline for uspace/srv/fs


Ignore:
Timestamp:
2011-08-03T17:34:57Z (14 years ago)
Author:
Oleg Romanenko <romanenko.oleg@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1940326
Parents:
52a79081 (diff), 3fab770 (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 from mainline

Location:
uspace/srv/fs
Files:
3 added
15 edited
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/devfs/Makefile

    r52a79081 ra33f0a6  
    3232EXTRA_CFLAGS += -I$(LIBFS_PREFIX)
    3333BINARY = devfs
     34STATIC_NEEDED = y
    3435
    3536SOURCES = \
  • uspace/srv/fs/devfs/devfs.c

    r52a79081 ra33f0a6  
    4141#include <stdio.h>
    4242#include <ipc/services.h>
    43 #include <ipc/ns.h>
     43#include <ns.h>
    4444#include <async.h>
    4545#include <errno.h>
     
    5757};
    5858
    59 fs_reg_t devfs_reg;
    60 
    61 static void devfs_connection(ipc_callid_t iid, ipc_call_t *icall)
    62 {
    63         if (iid)
    64                 async_answer_0(iid, EOK);
    65        
    66         while (true) {
    67                 ipc_call_t call;
    68                 ipc_callid_t callid = async_get_call(&call);
    69                
    70                 switch  (IPC_GET_IMETHOD(call)) {
    71                 case IPC_M_PHONE_HUNGUP:
    72                         return;
    73                 case VFS_OUT_MOUNTED:
    74                         devfs_mounted(callid, &call);
    75                         break;
    76                 case VFS_OUT_MOUNT:
    77                         devfs_mount(callid, &call);
    78                         break;
    79                 case VFS_OUT_UNMOUNTED:
    80                         devfs_unmounted(callid, &call);
    81                         break;
    82                 case VFS_OUT_UNMOUNT:
    83                         devfs_unmount(callid, &call);
    84                         break;
    85                 case VFS_OUT_LOOKUP:
    86                         devfs_lookup(callid, &call);
    87                         break;
    88                 case VFS_OUT_OPEN_NODE:
    89                         devfs_open_node(callid, &call);
    90                         break;
    91                 case VFS_OUT_STAT:
    92                         devfs_stat(callid, &call);
    93                         break;
    94                 case VFS_OUT_READ:
    95                         devfs_read(callid, &call);
    96                         break;
    97                 case VFS_OUT_WRITE:
    98                         devfs_write(callid, &call);
    99                         break;
    100                 case VFS_OUT_TRUNCATE:
    101                         devfs_truncate(callid, &call);
    102                         break;
    103                 case VFS_OUT_CLOSE:
    104                         devfs_close(callid, &call);
    105                         break;
    106                 case VFS_OUT_SYNC:
    107                         devfs_sync(callid, &call);
    108                         break;
    109                 case VFS_OUT_DESTROY:
    110                         devfs_destroy(callid, &call);
    111                         break;
    112                 default:
    113                         async_answer_0(callid, ENOTSUP);
    114                         break;
    115                 }
    116         }
    117 }
    118 
    11959int main(int argc, char *argv[])
    12060{
    121         printf(NAME ": HelenOS Device Filesystem\n");
     61        printf("%s: HelenOS Device Filesystem\n", NAME);
    12262       
    12363        if (!devfs_init()) {
    124                 printf(NAME ": failed to initialize devfs\n");
     64                printf("%s: failed to initialize devfs\n", NAME);
    12565                return -1;
    12666        }
    12767       
    128         int vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
    129         if (vfs_phone < EOK) {
    130                 printf(NAME ": Unable to connect to VFS\n");
     68        async_sess_t *vfs_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
     69            SERVICE_VFS, 0, 0);
     70        if (!vfs_sess) {
     71                printf("%s: Unable to connect to VFS\n", NAME);
    13172                return -1;
    13273        }
    13374       
    134         int rc = fs_register(vfs_phone, &devfs_reg, &devfs_vfs_info,
    135             devfs_connection);
     75        int rc = fs_register(vfs_sess, &devfs_vfs_info, &devfs_ops,
     76            &devfs_libfs_ops);
    13677        if (rc != EOK) {
    137                 printf(NAME ": Failed to register file system (%d)\n", rc);
     78                printf("%s: Failed to register file system (%d)\n", NAME, rc);
    13879                return rc;
    13980        }
    14081       
    141         printf(NAME ": Accepting connections\n");
     82        printf("%s: Accepting connections\n", NAME);
    14283        task_retval(0);
    14384        async_manager();
     
    15091 * @}
    15192 */
     93
  • uspace/srv/fs/devfs/devfs.h

    r52a79081 ra33f0a6  
    3636#include <libfs.h>
    3737
    38 extern fs_reg_t devfs_reg;
     38extern vfs_out_ops_t devfs_ops;
     39extern libfs_ops_t devfs_libfs_ops;
    3940
    4041#endif
  • uspace/srv/fs/devfs/devfs_ops.c

    r52a79081 ra33f0a6  
    5959typedef struct {
    6060        devmap_handle_t handle;
    61         int phone;              /**< When < 0, the structure is incomplete. */
     61        async_sess_t *sess;       /**< If NULL, the structure is incomplete. */
    6262        size_t refcount;
    6363        link_t link;
    64         fibril_condvar_t cv;    /**< Broadcast when completed. */
     64        fibril_condvar_t cv;      /**< Broadcast when completed. */
    6565} device_t;
    6666
     
    232232                };
    233233                link_t *lnk;
    234 
     234               
    235235                fibril_mutex_lock(&devices_mutex);
    236236restart:
     
    244244                       
    245245                        dev->handle = node->handle;
    246                         dev->phone = -1;        /* mark as incomplete */
     246                       
     247                        /* Mark as incomplete */
     248                        dev->sess = NULL;
    247249                        dev->refcount = 1;
    248250                        fibril_condvar_initialize(&dev->cv);
    249 
     251                       
    250252                        /*
    251253                         * Insert the incomplete device structure so that other
     
    254256                         */
    255257                        hash_table_insert(&devices, key, &dev->link);
    256 
     258                       
    257259                        /*
    258260                         * Drop the mutex to allow recursive devfs requests.
    259261                         */
    260262                        fibril_mutex_unlock(&devices_mutex);
    261 
    262                         int phone = devmap_device_connect(node->handle, 0);
    263 
     263                       
     264                        async_sess_t *sess = devmap_device_connect(EXCHANGE_SERIALIZE,
     265                            node->handle, 0);
     266                       
    264267                        fibril_mutex_lock(&devices_mutex);
    265 
     268                       
    266269                        /*
    267270                         * Notify possible waiters about this device structure
     
    269272                         */
    270273                        fibril_condvar_broadcast(&dev->cv);
    271 
    272                         if (phone < 0) {
     274                       
     275                        if (!sess) {
    273276                                /*
    274277                                 * Connecting failed, need to remove the
     
    277280                                hash_table_remove(&devices, key, DEVICES_KEYS);
    278281                                fibril_mutex_unlock(&devices_mutex);
    279 
     282                               
    280283                                return ENOENT;
    281284                        }
    282285                       
    283                         /* Set the correct phone. */
    284                         dev->phone = phone;
     286                        /* Set the correct session. */
     287                        dev->sess = sess;
    285288                } else {
    286289                        device_t *dev = hash_table_get_instance(lnk, device_t, link);
    287 
    288                         if (dev->phone < 0) {
     290                       
     291                        if (!dev->sess) {
    289292                                /*
    290293                                 * Wait until the device structure is completed
     
    398401       
    399402        return 1;
    400 }
    401 
    402 static char devfs_plb_get_char(unsigned pos)
    403 {
    404         return devfs_reg.plb_ro[pos % PLB_SIZE];
    405403}
    406404
     
    444442        .size_get = devfs_size_get,
    445443        .lnkcnt_get = devfs_lnkcnt_get,
    446         .plb_get_char = devfs_plb_get_char,
    447444        .is_directory = devfs_is_directory,
    448445        .is_file = devfs_is_file,
     
    459456}
    460457
    461 void devfs_mounted(ipc_callid_t rid, ipc_call_t *request)
    462 {
    463         char *opts;
    464        
    465         /* Accept the mount options */
    466         sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,
    467             0, NULL);
    468         if (retval != EOK) {
    469                 async_answer_0(rid, retval);
    470                 return;
    471         }
    472        
    473         free(opts);
    474         async_answer_3(rid, EOK, 0, 0, 0);
    475 }
    476 
    477 void devfs_mount(ipc_callid_t rid, ipc_call_t *request)
    478 {
    479         libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    480 }
    481 
    482 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
    483 {
    484         async_answer_0(rid, ENOTSUP);
    485 }
    486 
    487 void devfs_unmount(ipc_callid_t rid, ipc_call_t *request)
    488 {
    489         libfs_unmount(&devfs_libfs_ops, rid, request);
    490 }
    491 
    492 void devfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    493 {
    494         libfs_lookup(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    495 }
    496 
    497 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request)
    498 {
    499         libfs_open_node(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    500 }
    501 
    502 void devfs_stat(ipc_callid_t rid, ipc_call_t *request)
    503 {
    504         libfs_stat(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    505 }
    506 
    507 void devfs_read(ipc_callid_t rid, ipc_call_t *request)
    508 {
    509         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    510         aoff64_t pos =
    511             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    512        
     458static int devfs_mounted(devmap_handle_t devmap_handle, const char *opts,
     459    fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     460{
     461        *index = 0;
     462        *size = 0;
     463        *lnkcnt = 0;
     464        return EOK;
     465}
     466
     467static int devfs_unmounted(devmap_handle_t devmap_handle)
     468{
     469        return ENOTSUP;
     470}
     471
     472static int
     473devfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     474    size_t *rbytes)
     475{
    513476        if (index == 0) {
    514477                ipc_callid_t callid;
     
    516479                if (!async_data_read_receive(&callid, &size)) {
    517480                        async_answer_0(callid, EINVAL);
    518                         async_answer_0(rid, EINVAL);
    519                         return;
     481                        return EINVAL;
    520482                }
    521483               
     
    537499                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    538500                        free(desc);
    539                         async_answer_1(rid, EOK, 1);
    540                         return;
     501                        *rbytes = 1;
     502                        return EOK;
    541503                }
    542504               
     
    552514                                async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    553515                                free(desc);
    554                                 async_answer_1(rid, EOK, 1);
    555                                 return;
     516                                *rbytes = 1;
     517                                return EOK;
    556518                        }
    557519                       
     
    560522               
    561523                async_answer_0(callid, ENOENT);
    562                 async_answer_1(rid, ENOENT, 0);
    563                 return;
     524                return ENOENT;
    564525        }
    565526       
     
    572533                if (!async_data_read_receive(&callid, &size)) {
    573534                        async_answer_0(callid, EINVAL);
    574                         async_answer_0(rid, EINVAL);
    575                         return;
     535                        return EINVAL;
    576536                }
    577537               
     
    582542                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    583543                        free(desc);
    584                         async_answer_1(rid, EOK, 1);
    585                         return;
     544                        *rbytes = 1;
     545                        return EOK;
    586546                }
    587547               
    588548                free(desc);
    589549                async_answer_0(callid, ENOENT);
    590                 async_answer_1(rid, ENOENT, 0);
    591                 return;
     550                return ENOENT;
    592551        }
    593552       
     
    603562                if (lnk == NULL) {
    604563                        fibril_mutex_unlock(&devices_mutex);
    605                         async_answer_0(rid, ENOENT);
    606                         return;
     564                        return ENOENT;
    607565                }
    608566               
    609567                device_t *dev = hash_table_get_instance(lnk, device_t, link);
    610                 assert(dev->phone >= 0);
     568                assert(dev->sess);
    611569               
    612570                ipc_callid_t callid;
     
    614572                        fibril_mutex_unlock(&devices_mutex);
    615573                        async_answer_0(callid, EINVAL);
    616                         async_answer_0(rid, EINVAL);
    617                         return;
     574                        return EINVAL;
    618575                }
    619576               
    620577                /* Make a request at the driver */
     578                async_exch_t *exch = async_exchange_begin(dev->sess);
     579               
    621580                ipc_call_t answer;
    622                 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request),
    623                     IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    624                     IPC_GET_ARG3(*request), &answer);
     581                aid_t msg = async_send_4(exch, VFS_OUT_READ, devmap_handle,
     582                    index, LOWER32(pos), UPPER32(pos), &answer);
    625583               
    626584                /* Forward the IPC_M_DATA_READ request to the driver */
    627                 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     585                async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     586               
     587                async_exchange_end(exch);
     588               
    628589                fibril_mutex_unlock(&devices_mutex);
    629590               
     
    631592                sysarg_t rc;
    632593                async_wait_for(msg, &rc);
    633                 size_t bytes = IPC_GET_ARG1(answer);
    634                
    635                 /* Driver reply is the final result of the whole operation */
    636                 async_answer_1(rid, rc, bytes);
    637                 return;
    638         }
    639        
    640         async_answer_0(rid, ENOENT);
    641 }
    642 
    643 void devfs_write(ipc_callid_t rid, ipc_call_t *request)
    644 {
    645         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    646         if (index == 0) {
    647                 async_answer_0(rid, ENOTSUP);
    648                 return;
    649         }
     594               
     595                *rbytes = IPC_GET_ARG1(answer);
     596                return rc;
     597        }
     598       
     599        return ENOENT;
     600}
     601
     602static int
     603devfs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     604    size_t *wbytes, aoff64_t *nsize)
     605{
     606        if (index == 0)
     607                return ENOTSUP;
    650608       
    651609        devmap_handle_type_t type = devmap_handle_probe(index);
     
    653611        if (type == DEV_HANDLE_NAMESPACE) {
    654612                /* Namespace directory */
    655                 async_answer_0(rid, ENOTSUP);
    656                 return;
     613                return ENOTSUP;
    657614        }
    658615       
     
    667624                if (lnk == NULL) {
    668625                        fibril_mutex_unlock(&devices_mutex);
    669                         async_answer_0(rid, ENOENT);
    670                         return;
     626                        return ENOENT;
    671627                }
    672628               
    673629                device_t *dev = hash_table_get_instance(lnk, device_t, link);
    674                 assert(dev->phone >= 0);
     630                assert(dev->sess);
    675631               
    676632                ipc_callid_t callid;
     
    678634                        fibril_mutex_unlock(&devices_mutex);
    679635                        async_answer_0(callid, EINVAL);
    680                         async_answer_0(rid, EINVAL);
    681                         return;
     636                        return EINVAL;
    682637                }
    683638               
    684639                /* Make a request at the driver */
     640                async_exch_t *exch = async_exchange_begin(dev->sess);
     641               
    685642                ipc_call_t answer;
    686                 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request),
    687                     IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    688                     IPC_GET_ARG3(*request), &answer);
     643                aid_t msg = async_send_4(exch, VFS_OUT_WRITE, devmap_handle,
     644                    index, LOWER32(pos), UPPER32(pos), &answer);
    689645               
    690646                /* Forward the IPC_M_DATA_WRITE request to the driver */
    691                 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     647                async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     648               
     649                async_exchange_end(exch);
    692650               
    693651                fibril_mutex_unlock(&devices_mutex);
     
    696654                sysarg_t rc;
    697655                async_wait_for(msg, &rc);
    698                 size_t bytes = IPC_GET_ARG1(answer);
    699                
    700                 /* Driver reply is the final result of the whole operation */
    701                 async_answer_1(rid, rc, bytes);
    702                 return;
    703         }
    704        
    705         async_answer_0(rid, ENOENT);
    706 }
    707 
    708 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request)
    709 {
    710         async_answer_0(rid, ENOTSUP);
    711 }
    712 
    713 void devfs_close(ipc_callid_t rid, ipc_call_t *request)
    714 {
    715         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    716        
    717         if (index == 0) {
    718                 async_answer_0(rid, EOK);
    719                 return;
    720         }
     656               
     657                *wbytes = IPC_GET_ARG1(answer);
     658                *nsize = 0;
     659                return rc;
     660        }
     661       
     662        return ENOENT;
     663}
     664
     665static int
     666devfs_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size)
     667{
     668        return ENOTSUP;
     669}
     670
     671static int devfs_close(devmap_handle_t devmap_handle, fs_index_t index)
     672{
     673        if (index == 0)
     674                return EOK;
    721675       
    722676        devmap_handle_type_t type = devmap_handle_probe(index);
     
    724678        if (type == DEV_HANDLE_NAMESPACE) {
    725679                /* Namespace directory */
    726                 async_answer_0(rid, EOK);
    727                 return;
     680                return EOK;
    728681        }
    729682       
     
    737690                if (lnk == NULL) {
    738691                        fibril_mutex_unlock(&devices_mutex);
    739                         async_answer_0(rid, ENOENT);
    740                         return;
     692                        return ENOENT;
    741693                }
    742694               
    743695                device_t *dev = hash_table_get_instance(lnk, device_t, link);
    744                 assert(dev->phone >= 0);
     696                assert(dev->sess);
    745697                dev->refcount--;
    746698               
    747699                if (dev->refcount == 0) {
    748                         async_hangup(dev->phone);
     700                        async_hangup(dev->sess);
    749701                        hash_table_remove(&devices, key, DEVICES_KEYS);
    750702                }
     
    752704                fibril_mutex_unlock(&devices_mutex);
    753705               
    754                 async_answer_0(rid, EOK);
    755                 return;
    756         }
    757        
    758         async_answer_0(rid, ENOENT);
    759 }
    760 
    761 void devfs_sync(ipc_callid_t rid, ipc_call_t *request)
    762 {
    763         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    764        
    765         if (index == 0) {
    766                 async_answer_0(rid, EOK);
    767                 return;
    768         }
     706                return EOK;
     707        }
     708       
     709        return ENOENT;
     710}
     711
     712static int devfs_sync(devmap_handle_t devmap_handle, fs_index_t index)
     713{
     714        if (index == 0)
     715                return EOK;
    769716       
    770717        devmap_handle_type_t type = devmap_handle_probe(index);
     
    772719        if (type == DEV_HANDLE_NAMESPACE) {
    773720                /* Namespace directory */
    774                 async_answer_0(rid, EOK);
    775                 return;
     721                return EOK;
    776722        }
    777723       
     
    785731                if (lnk == NULL) {
    786732                        fibril_mutex_unlock(&devices_mutex);
    787                         async_answer_0(rid, ENOENT);
    788                         return;
     733                        return ENOENT;
    789734                }
    790735               
    791736                device_t *dev = hash_table_get_instance(lnk, device_t, link);
    792                 assert(dev->phone >= 0);
     737                assert(dev->sess);
    793738               
    794739                /* Make a request at the driver */
     740                async_exch_t *exch = async_exchange_begin(dev->sess);
     741               
    795742                ipc_call_t answer;
    796                 aid_t msg = async_send_2(dev->phone, IPC_GET_IMETHOD(*request),
    797                     IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer);
     743                aid_t msg = async_send_2(exch, VFS_OUT_SYNC, devmap_handle,
     744                    index, &answer);
     745               
     746                async_exchange_end(exch);
    798747               
    799748                fibril_mutex_unlock(&devices_mutex);
     
    803752                async_wait_for(msg, &rc);
    804753               
    805                 /* Driver reply is the final result of the whole operation */
    806                 async_answer_0(rid, rc);
    807                 return;
    808         }
    809        
    810         async_answer_0(rid, ENOENT);
    811 }
    812 
    813 void devfs_destroy(ipc_callid_t rid, ipc_call_t *request)
    814 {
    815         async_answer_0(rid, ENOTSUP);
    816 }
     754                return rc;
     755        }
     756       
     757        return  ENOENT;
     758}
     759
     760static int devfs_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     761{
     762        return ENOTSUP;
     763}
     764
     765vfs_out_ops_t devfs_ops = {
     766        .mounted = devfs_mounted,
     767        .unmounted = devfs_unmounted,
     768        .read = devfs_read,
     769        .write = devfs_write,
     770        .truncate = devfs_truncate,
     771        .close = devfs_close,
     772        .destroy = devfs_destroy,
     773        .sync = devfs_sync,
     774};
    817775
    818776/**
  • uspace/srv/fs/devfs/devfs_ops.h

    r52a79081 ra33f0a6  
    3434#define DEVFS_DEVFS_OPS_H_
    3535
    36 #include <ipc/common.h>
    3736#include <bool.h>
    3837
    3938extern bool devfs_init(void);
    40 
    41 extern void devfs_mounted(ipc_callid_t, ipc_call_t *);
    42 extern void devfs_mount(ipc_callid_t, ipc_call_t *);
    43 extern void devfs_unmounted(ipc_callid_t, ipc_call_t *);
    44 extern void devfs_unmount(ipc_callid_t, ipc_call_t *);
    45 extern void devfs_lookup(ipc_callid_t, ipc_call_t *);
    46 extern void devfs_open_node(ipc_callid_t, ipc_call_t *);
    47 extern void devfs_stat(ipc_callid_t, ipc_call_t *);
    48 extern void devfs_sync(ipc_callid_t, ipc_call_t *);
    49 extern void devfs_read(ipc_callid_t, ipc_call_t *);
    50 extern void devfs_write(ipc_callid_t, ipc_call_t *);
    51 extern void devfs_truncate(ipc_callid_t, ipc_call_t *);
    52 extern void devfs_close(ipc_callid_t, ipc_call_t *);
    53 extern void devfs_destroy(ipc_callid_t, ipc_call_t *);
    5439
    5540#endif
  • uspace/srv/fs/ext2fs/ext2fs.h

    r52a79081 ra33f0a6  
    11/*
    2  * Copyright (c) 2009 Jiri Svoboda
     2 * Copyright (c) 2011 Martin Sucha
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup kbdgen generic
    30  * @brief       HelenOS generic uspace keyboard handler.
    31  * @ingroup  kbd
     29/** @addtogroup fs
    3230 * @{
    3331 */
    34 /** @file
    35  */
    3632
    37 #ifndef KBD_PORT_H_
    38 #define KBD_PORT_H_
     33#ifndef EXT2FS_EXT2FS_H_
     34#define EXT2FS_EXT2FS_H_
    3935
     36#include <libext2.h>
     37#include <libfs.h>
    4038#include <sys/types.h>
    4139
    42 extern int kbd_port_init(void);
    43 extern void kbd_port_yield(void);
    44 extern void kbd_port_reclaim(void);
    45 extern void kbd_port_write(uint8_t);
     40#define min(a, b)               ((a) < (b) ? (a) : (b))
     41
     42extern vfs_out_ops_t ext2fs_ops;
     43extern libfs_ops_t ext2fs_libfs_ops;
     44
     45extern int ext2fs_global_init(void);
     46extern int ext2fs_global_fini(void);
    4647
    4748#endif
     
    4950/**
    5051 * @}
    51  */
    52 
     52 */
  • uspace/srv/fs/fat/Makefile

    r52a79081 ra33f0a6  
    3232EXTRA_CFLAGS += -I$(LIBBLOCK_PREFIX) -I$(LIBFS_PREFIX)
    3333BINARY = fat
     34STATIC_NEEDED = y
    3435
    3536SOURCES = \
  • uspace/srv/fs/fat/fat.c

    r52a79081 ra33f0a6  
    4040#include "fat.h"
    4141#include <ipc/services.h>
    42 #include <ipc/ns.h>
     42#include <ns.h>
    4343#include <async.h>
    4444#include <errno.h>
     
    5757};
    5858
    59 fs_reg_t fat_reg;
    60 
    61 /**
    62  * This connection fibril processes VFS requests from VFS.
    63  *
    64  * In order to support simultaneous VFS requests, our design is as follows.
    65  * The connection fibril accepts VFS requests from VFS. If there is only one
    66  * instance of the fibril, VFS will need to serialize all VFS requests it sends
    67  * to FAT. To overcome this bottleneck, VFS can send FAT the IPC_M_CONNECT_ME_TO
    68  * call. In that case, a new connection fibril will be created, which in turn
    69  * will accept the call. Thus, a new phone will be opened for VFS.
    70  *
    71  * There are few issues with this arrangement. First, VFS can run out of
    72  * available phones. In that case, VFS can close some other phones or use one
    73  * phone for more serialized requests. Similarily, FAT can refuse to duplicate
    74  * the connection. VFS should then just make use of already existing phones and
    75  * route its requests through them. To avoid paying the fibril creation price
    76  * upon each request, FAT might want to keep the connections open after the
    77  * request has been completed.
    78  */
    79 static void fat_connection(ipc_callid_t iid, ipc_call_t *icall)
    80 {
    81         if (iid) {
    82                 /*
    83                  * This only happens for connections opened by
    84                  * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
    85                  * created by IPC_M_CONNECT_TO_ME.
    86                  */
    87                 async_answer_0(iid, EOK);
    88         }
    89        
    90         dprintf(NAME ": connection opened\n");
    91         while (1) {
    92                 ipc_callid_t callid;
    93                 ipc_call_t call;
    94        
    95                 callid = async_get_call(&call);
    96                 switch  (IPC_GET_IMETHOD(call)) {
    97                 case IPC_M_PHONE_HUNGUP:
    98                         return;
    99                 case VFS_OUT_MOUNTED:
    100                         fat_mounted(callid, &call);
    101                         break;
    102                 case VFS_OUT_MOUNT:
    103                         fat_mount(callid, &call);
    104                         break;
    105                 case VFS_OUT_UNMOUNTED:
    106                         fat_unmounted(callid, &call);
    107                         break;
    108                 case VFS_OUT_UNMOUNT:
    109                         fat_unmount(callid, &call);
    110                         break;
    111                 case VFS_OUT_LOOKUP:
    112                         fat_lookup(callid, &call);
    113                         break;
    114                 case VFS_OUT_READ:
    115                         fat_read(callid, &call);
    116                         break;
    117                 case VFS_OUT_WRITE:
    118                         fat_write(callid, &call);
    119                         break;
    120                 case VFS_OUT_TRUNCATE:
    121                         fat_truncate(callid, &call);
    122                         break;
    123                 case VFS_OUT_STAT:
    124                         fat_stat(callid, &call);
    125                         break;
    126                 case VFS_OUT_CLOSE:
    127                         fat_close(callid, &call);
    128                         break;
    129                 case VFS_OUT_DESTROY:
    130                         fat_destroy(callid, &call);
    131                         break;
    132                 case VFS_OUT_OPEN_NODE:
    133                         fat_open_node(callid, &call);
    134                         break;
    135                 case VFS_OUT_SYNC:
    136                         fat_sync(callid, &call);
    137                         break;
    138                 default:
    139                         async_answer_0(callid, ENOTSUP);
    140                         break;
    141                 }
    142         }
    143 }
    144 
    14559int main(int argc, char **argv)
    14660{
    147         int vfs_phone;
    148         int rc;
    149 
    15061        printf(NAME ": HelenOS FAT file system server\n");
    151 
    152         rc = fat_idx_init();
     62       
     63        int rc = fat_idx_init();
    15364        if (rc != EOK)
    15465                goto err;
    155 
    156         vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
    157         if (vfs_phone < EOK) {
     66       
     67        async_sess_t *vfs_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
     68            SERVICE_VFS, 0, 0);
     69        if (!vfs_sess) {
    15870                printf(NAME ": failed to connect to VFS\n");
    15971                return -1;
    16072        }
    16173       
    162         rc = fs_register(vfs_phone, &fat_reg, &fat_vfs_info, fat_connection);
     74        rc = fs_register(vfs_sess, &fat_vfs_info, &fat_ops, &fat_libfs_ops);
    16375        if (rc != EOK) {
    16476                fat_idx_fini();
     
    16981        task_retval(0);
    17082        async_manager();
    171         /* not reached */
     83       
     84        /* Not reached */
    17285        return 0;
    173 
     86       
    17487err:
    17588        printf(NAME ": Failed to register file system (%d)\n", rc);
     
    17992/**
    18093 * @}
    181  */ 
     94 */
  • uspace/srv/fs/fat/fat.h

    r52a79081 ra33f0a6  
    227227} fat_node_t;
    228228
    229 extern fs_reg_t fat_reg;
    230 
    231 extern void fat_mounted(ipc_callid_t, ipc_call_t *);
    232 extern void fat_mount(ipc_callid_t, ipc_call_t *);
    233 extern void fat_unmounted(ipc_callid_t, ipc_call_t *);
    234 extern void fat_unmount(ipc_callid_t, ipc_call_t *);
    235 extern void fat_lookup(ipc_callid_t, ipc_call_t *);
    236 extern void fat_read(ipc_callid_t, ipc_call_t *);
    237 extern void fat_write(ipc_callid_t, ipc_call_t *);
    238 extern void fat_truncate(ipc_callid_t, ipc_call_t *);
    239 extern void fat_stat(ipc_callid_t, ipc_call_t *);
    240 extern void fat_close(ipc_callid_t, ipc_call_t *);
    241 extern void fat_destroy(ipc_callid_t, ipc_call_t *);
    242 extern void fat_open_node(ipc_callid_t, ipc_call_t *);
    243 extern void fat_stat(ipc_callid_t, ipc_call_t *);
    244 extern void fat_sync(ipc_callid_t, ipc_call_t *);
     229extern vfs_out_ops_t fat_ops;
     230extern libfs_ops_t fat_libfs_ops;
    245231
    246232extern int fat_idx_get_new(fat_idx_t **, devmap_handle_t);
  • uspace/srv/fs/fat/fat_idx.c

    r52a79081 ra33f0a6  
    5959typedef struct {
    6060        link_t          link;
    61         devmap_handle_t devmap_handle;
     61        devmap_handle_t devmap_handle;
    6262
    6363        /** Next unassigned index. */
    64         fs_index_t      next;
     64        fs_index_t next;
    6565        /** Number of remaining unassigned indices. */
    66         uint64_t        remaining;
     66        uint64_t remaining;
    6767
    6868        /** Sorted list of intervals of freed indices. */
    69         link_t          freed_head;
     69        list_t freed_list;
    7070} unused_t;
    7171
     
    7474
    7575/** List of unused structures. */
    76 static LIST_INITIALIZE(unused_head);
     76static LIST_INITIALIZE(unused_list);
    7777
    7878static void unused_initialize(unused_t *u, devmap_handle_t devmap_handle)
     
    8282        u->next = 0;
    8383        u->remaining = ((uint64_t)((fs_index_t)-1)) + 1;
    84         list_initialize(&u->freed_head);
     84        list_initialize(&u->freed_list);
    8585}
    8686
     
    8888{
    8989        unused_t *u;
    90         link_t *l;
    9190
    9291        if (lock)
    9392                fibril_mutex_lock(&unused_lock);
    94         for (l = unused_head.next; l != &unused_head; l = l->next) {
     93
     94        list_foreach(unused_list, l) {
    9595                u = list_get_instance(l, unused_t, link);
    9696                if (u->devmap_handle == devmap_handle)
    9797                        return u;
    9898        }
     99       
    99100        if (lock)
    100101                fibril_mutex_unlock(&unused_lock);
     
    249250                return false;   
    250251
    251         if (list_empty(&u->freed_head)) {
     252        if (list_empty(&u->freed_list)) {
    252253                if (u->remaining) {
    253254                        /*
     
    262263        } else {
    263264                /* There are some freed indices which we can reuse. */
    264                 freed_t *f = list_get_instance(u->freed_head.next, freed_t,
    265                     link);
     265                freed_t *f = list_get_instance(list_first(&u->freed_list),
     266                    freed_t, link);
    266267                *index = f->first;
    267268                if (f->first++ == f->last) {
     
    320321                link_t *lnk;
    321322                freed_t *n;
    322                 for (lnk = u->freed_head.next; lnk != &u->freed_head;
     323                for (lnk = u->freed_list.head.next; lnk != &u->freed_list.head;
    323324                    lnk = lnk->next) {
    324325                        freed_t *f = list_get_instance(lnk, freed_t, link);
    325326                        if (f->first == index + 1) {
    326327                                f->first--;
    327                                 if (lnk->prev != &u->freed_head)
     328                                if (lnk->prev != &u->freed_list.head)
    328329                                        try_coalesce_intervals(lnk->prev, lnk,
    329330                                            lnk);
     
    333334                        if (f->last == index - 1) {
    334335                                f->last++;
    335                                 if (lnk->next != &u->freed_head)
     336                                if (lnk->next != &u->freed_list.head)
    336337                                        try_coalesce_intervals(lnk, lnk->next,
    337338                                            lnk);
     
    359360                n->first = index;
    360361                n->last = index;
    361                 list_append(&n->link, &u->freed_head);
     362                list_append(&n->link, &u->freed_list);
    362363        }
    363364        fibril_mutex_unlock(&unused_lock);
     
    558559        fibril_mutex_lock(&unused_lock);
    559560        if (!unused_find(devmap_handle, false)) {
    560                 list_append(&u->link, &unused_head);
     561                list_append(&u->link, &unused_list);
    561562        } else {
    562563                free(u);
     
    594595        fibril_mutex_unlock(&unused_lock);
    595596
    596         while (!list_empty(&u->freed_head)) {
     597        while (!list_empty(&u->freed_list)) {
    597598                freed_t *f;
    598                 f = list_get_instance(u->freed_head.next, freed_t, link);
     599                f = list_get_instance(list_first(&u->freed_list), freed_t, link);
    599600                list_remove(&f->link);
    600601                free(f);
  • uspace/srv/fs/fat/fat_ops.c

    r52a79081 ra33f0a6  
    7070
    7171/** List of cached free FAT nodes. */
    72 static LIST_INITIALIZE(ffn_head);
     72static LIST_INITIALIZE(ffn_list);
    7373
    7474/*
     
    8888static aoff64_t fat_size_get(fs_node_t *);
    8989static unsigned fat_lnkcnt_get(fs_node_t *);
    90 static char fat_plb_get_char(unsigned);
    9190static bool fat_is_directory(fs_node_t *);
    9291static bool fat_is_file(fs_node_t *node);
     
    150149static int fat_node_fini_by_devmap_handle(devmap_handle_t devmap_handle)
    151150{
    152         link_t *lnk;
    153151        fat_node_t *nodep;
    154152        int rc;
     
    162160restart:
    163161        fibril_mutex_lock(&ffn_mutex);
    164         for (lnk = ffn_head.next; lnk != &ffn_head; lnk = lnk->next) {
     162        list_foreach(ffn_list, lnk) {
    165163                nodep = list_get_instance(lnk, fat_node_t, ffn_link);
    166164                if (!fibril_mutex_trylock(&nodep->lock)) {
     
    199197                free(nodep);
    200198
    201                 /* Need to restart because we changed the ffn_head list. */
     199                /* Need to restart because we changed ffn_list. */
    202200                goto restart;
    203201        }
     
    214212
    215213        fibril_mutex_lock(&ffn_mutex);
    216         if (!list_empty(&ffn_head)) {
     214        if (!list_empty(&ffn_list)) {
    217215                /* Try to use a cached free node structure. */
    218216                fat_idx_t *idxp_tmp;
    219                 nodep = list_get_instance(ffn_head.next, fat_node_t, ffn_link);
     217                nodep = list_get_instance(list_first(&ffn_list), fat_node_t,
     218                    ffn_link);
    220219                if (!fibril_mutex_trylock(&nodep->lock))
    221220                        goto skip_cache;
     
    464463                if (nodep->idx) {
    465464                        fibril_mutex_lock(&ffn_mutex);
    466                         list_append(&nodep->ffn_link, &ffn_head);
     465                        list_append(&nodep->ffn_link, &ffn_list);
    467466                        fibril_mutex_unlock(&ffn_mutex);
    468467                } else {
     
    823822}
    824823
    825 char fat_plb_get_char(unsigned pos)
    826 {
    827         return fat_reg.plb_ro[pos % PLB_SIZE];
    828 }
    829 
    830824bool fat_is_directory(fs_node_t *fn)
    831825{
     
    858852        .size_get = fat_size_get,
    859853        .lnkcnt_get = fat_lnkcnt_get,
    860         .plb_get_char = fat_plb_get_char,
    861854        .is_directory = fat_is_directory,
    862855        .is_file = fat_is_file,
     
    865858
    866859/*
    867  * VFS operations.
     860 * FAT VFS_OUT operations.
    868861 */
    869862
    870 void fat_mounted(ipc_callid_t rid, ipc_call_t *request)
    871 {
    872         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     863static int
     864fat_mounted(devmap_handle_t devmap_handle, const char *opts, fs_index_t *index,
     865    aoff64_t *size, unsigned *linkcnt)
     866{
    873867        enum cache_mode cmode;
    874868        fat_bs_t *bs;
    875 
    876         /* Accept the mount options */
    877         char *opts;
    878         int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
    879 
    880         if (rc != EOK) {
    881                 async_answer_0(rid, rc);
    882                 return;
    883         }
     869        int rc;
    884870
    885871        /* Check for option enabling write through. */
     
    889875                cmode = CACHE_MODE_WB;
    890876
    891         free(opts);
    892 
    893877        /* initialize libblock */
    894         rc = block_init(devmap_handle, BS_SIZE);
    895         if (rc != EOK) {
    896                 async_answer_0(rid, rc);
    897                 return;
    898         }
     878        rc = block_init(EXCHANGE_SERIALIZE, devmap_handle, BS_SIZE);
     879        if (rc != EOK)
     880                return rc;
    899881
    900882        /* prepare the boot block */
     
    902884        if (rc != EOK) {
    903885                block_fini(devmap_handle);
    904                 async_answer_0(rid, rc);
    905                 return;
     886                return rc;
    906887        }
    907888
     
    911892        if (BPS(bs) != BS_SIZE) {
    912893                block_fini(devmap_handle);
    913                 async_answer_0(rid, ENOTSUP);
    914                 return;
     894                return ENOTSUP;
    915895        }
    916896
     
    919899        if (rc != EOK) {
    920900                block_fini(devmap_handle);
    921                 async_answer_0(rid, rc);
    922                 return;
     901                return rc;
    923902        }
    924903
     
    928907                (void) block_cache_fini(devmap_handle);
    929908                block_fini(devmap_handle);
    930                 async_answer_0(rid, rc);
    931                 return;
     909                return rc;
    932910        }
    933911
     
    936914                (void) block_cache_fini(devmap_handle);
    937915                block_fini(devmap_handle);
    938                 async_answer_0(rid, rc);
    939                 return;
     916                return rc;
    940917        }
    941918
     
    946923                block_fini(devmap_handle);
    947924                fat_idx_fini_by_devmap_handle(devmap_handle);
    948                 async_answer_0(rid, ENOMEM);
    949                 return;
     925                return ENOMEM;
    950926        }
    951927
     
    957933                block_fini(devmap_handle);
    958934                fat_idx_fini_by_devmap_handle(devmap_handle);
    959                 async_answer_0(rid, ENOMEM);
    960                 return;
     935                return ENOMEM;
    961936        }
    962937        fat_node_initialize(rootp);
     
    969944                block_fini(devmap_handle);
    970945                fat_idx_fini_by_devmap_handle(devmap_handle);
    971                 async_answer_0(rid, ENOMEM);
    972                 return;
     946                return ENOMEM;
    973947        }
    974948        assert(ridxp->index == 0);
     
    1004978        fibril_mutex_unlock(&ridxp->lock);
    1005979
    1006         async_answer_3(rid, EOK, ridxp->index, rootp->size, rootp->lnkcnt);
    1007 }
    1008 
    1009 void fat_mount(ipc_callid_t rid, ipc_call_t *request)
    1010 {
    1011         libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1012 }
    1013 
    1014 void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)
    1015 {
    1016         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     980        *index = ridxp->index;
     981        *size = rootp->size;
     982        *linkcnt = rootp->lnkcnt;
     983
     984        return EOK;
     985}
     986
     987static int fat_unmounted(devmap_handle_t devmap_handle)
     988{
    1017989        fs_node_t *fn;
    1018990        fat_node_t *nodep;
     
    1020992
    1021993        rc = fat_root_get(&fn, devmap_handle);
    1022         if (rc != EOK) {
    1023                 async_answer_0(rid, rc);
    1024                 return;
    1025         }
     994        if (rc != EOK)
     995                return rc;
    1026996        nodep = FAT_NODE(fn);
    1027997
     
    10321002        if (nodep->refcnt != 2) {
    10331003                (void) fat_node_put(fn);
    1034                 async_answer_0(rid, EBUSY);
    1035                 return;
     1004                return EBUSY;
    10361005        }
    10371006
     
    10521021        block_fini(devmap_handle);
    10531022
    1054         async_answer_0(rid, EOK);
    1055 }
    1056 
    1057 void fat_unmount(ipc_callid_t rid, ipc_call_t *request)
    1058 {
    1059         libfs_unmount(&fat_libfs_ops, rid, request);
    1060 }
    1061 
    1062 void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
    1063 {
    1064         libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1065 }
    1066 
    1067 void fat_read(ipc_callid_t rid, ipc_call_t *request)
    1068 {
    1069         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1070         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1071         aoff64_t pos =
    1072             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     1023        return EOK;
     1024}
     1025
     1026static int
     1027fat_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     1028    size_t *rbytes)
     1029{
    10731030        fs_node_t *fn;
    10741031        fat_node_t *nodep;
     
    10791036
    10801037        rc = fat_node_get(&fn, devmap_handle, index);
    1081         if (rc != EOK) {
    1082                 async_answer_0(rid, rc);
    1083                 return;
    1084         }
    1085         if (!fn) {
    1086                 async_answer_0(rid, ENOENT);
    1087                 return;
    1088         }
     1038        if (rc != EOK)
     1039                return rc;
     1040        if (!fn)
     1041                return ENOENT;
    10891042        nodep = FAT_NODE(fn);
    10901043
     
    10941047                fat_node_put(fn);
    10951048                async_answer_0(callid, EINVAL);
    1096                 async_answer_0(rid, EINVAL);
    1097                 return;
     1049                return EINVAL;
    10981050        }
    10991051
     
    11181070                                fat_node_put(fn);
    11191071                                async_answer_0(callid, rc);
    1120                                 async_answer_0(rid, rc);
    1121                                 return;
     1072                                return rc;
    11221073                        }
    11231074                        (void) async_data_read_finalize(callid,
     
    11261077                        if (rc != EOK) {
    11271078                                fat_node_put(fn);
    1128                                 async_answer_0(rid, rc);
    1129                                 return;
     1079                                return rc;
    11301080                        }
    11311081                }
     
    11551105                (void) fat_node_put(fn);
    11561106                async_answer_0(callid, rc);
    1157                 async_answer_0(rid, rc);
    1158                 return;
     1107                return rc;
    11591108
    11601109miss:
     
    11641113                rc = fat_node_put(fn);
    11651114                async_answer_0(callid, rc != EOK ? rc : ENOENT);
    1166                 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0);
    1167                 return;
     1115                *rbytes = 0;
     1116                return rc != EOK ? rc : ENOENT;
    11681117
    11691118hit:
     
    11771126
    11781127        rc = fat_node_put(fn);
    1179         async_answer_1(rid, rc, (sysarg_t)bytes);
    1180 }
    1181 
    1182 void fat_write(ipc_callid_t rid, ipc_call_t *request)
    1183 {
    1184         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1185         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1186         aoff64_t pos =
    1187             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     1128        *rbytes = bytes;
     1129        return rc;
     1130}
     1131
     1132static int
     1133fat_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     1134    size_t *wbytes, aoff64_t *nsize)
     1135{
    11881136        fs_node_t *fn;
    11891137        fat_node_t *nodep;
    11901138        fat_bs_t *bs;
    1191         size_t bytes, size;
     1139        size_t bytes;
    11921140        block_t *b;
    11931141        aoff64_t boundary;
     
    11961144
    11971145        rc = fat_node_get(&fn, devmap_handle, index);
    1198         if (rc != EOK) {
    1199                 async_answer_0(rid, rc);
    1200                 return;
    1201         }
    1202         if (!fn) {
    1203                 async_answer_0(rid, ENOENT);
    1204                 return;
    1205         }
     1146        if (rc != EOK)
     1147                return rc;
     1148        if (!fn)
     1149                return ENOENT;
    12061150        nodep = FAT_NODE(fn);
    12071151
     
    12111155                (void) fat_node_put(fn);
    12121156                async_answer_0(callid, EINVAL);
    1213                 async_answer_0(rid, EINVAL);
    1214                 return;
     1157                return EINVAL;
    12151158        }
    12161159
     
    12401183                        (void) fat_node_put(fn);
    12411184                        async_answer_0(callid, rc);
    1242                         async_answer_0(rid, rc);
    1243                         return;
     1185                        return rc;
    12441186                }
    12451187                rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags);
     
    12471189                        (void) fat_node_put(fn);
    12481190                        async_answer_0(callid, rc);
    1249                         async_answer_0(rid, rc);
    1250                         return;
     1191                        return rc;
    12511192                }
    12521193                (void) async_data_write_finalize(callid,
     
    12561197                if (rc != EOK) {
    12571198                        (void) fat_node_put(fn);
    1258                         async_answer_0(rid, rc);
    1259                         return;
     1199                        return rc;
    12601200                }
    12611201                if (pos + bytes > nodep->size) {
     
    12631203                        nodep->dirty = true;    /* need to sync node */
    12641204                }
    1265                 size = nodep->size;
     1205                *wbytes = bytes;
     1206                *nsize = nodep->size;
    12661207                rc = fat_node_put(fn);
    1267                 async_answer_2(rid, rc, bytes, nodep->size);
    1268                 return;
     1208                return rc;
    12691209        } else {
    12701210                /*
     
    12821222                        (void) fat_node_put(fn);
    12831223                        async_answer_0(callid, rc);
    1284                         async_answer_0(rid, rc);
    1285                         return;
     1224                        return rc;
    12861225                }
    12871226                /* zero fill any gaps */
     
    12911230                        (void) fat_node_put(fn);
    12921231                        async_answer_0(callid, rc);
    1293                         async_answer_0(rid, rc);
    1294                         return;
     1232                        return rc;
    12951233                }
    12961234                rc = _fat_block_get(&b, bs, devmap_handle, lcl, NULL,
     
    13001238                        (void) fat_node_put(fn);
    13011239                        async_answer_0(callid, rc);
    1302                         async_answer_0(rid, rc);
    1303                         return;
     1240                        return rc;
    13041241                }
    13051242                (void) async_data_write_finalize(callid,
     
    13101247                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    13111248                        (void) fat_node_put(fn);
    1312                         async_answer_0(rid, rc);
    1313                         return;
     1249                        return rc;
    13141250                }
    13151251                /*
     
    13211257                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    13221258                        (void) fat_node_put(fn);
    1323                         async_answer_0(rid, rc);
    1324                         return;
    1325                 }
    1326                 nodep->size = size = pos + bytes;
     1259                        return rc;
     1260                }
     1261                *nsize = nodep->size = pos + bytes;
     1262                rc = fat_node_put(fn);
    13271263                nodep->dirty = true;            /* need to sync node */
    1328                 rc = fat_node_put(fn);
    1329                 async_answer_2(rid, rc, bytes, size);
    1330                 return;
    1331         }
    1332 }
    1333 
    1334 void fat_truncate(ipc_callid_t rid, ipc_call_t *request)
    1335 {
    1336         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1337         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1338         aoff64_t size =
    1339             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     1264                *wbytes = bytes;
     1265                return rc;
     1266        }
     1267}
     1268
     1269static int
     1270fat_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size)
     1271{
    13401272        fs_node_t *fn;
    13411273        fat_node_t *nodep;
     
    13441276
    13451277        rc = fat_node_get(&fn, devmap_handle, index);
    1346         if (rc != EOK) {
    1347                 async_answer_0(rid, rc);
    1348                 return;
    1349         }
    1350         if (!fn) {
    1351                 async_answer_0(rid, ENOENT);
    1352                 return;
    1353         }
     1278        if (rc != EOK)
     1279                return rc;
     1280        if (!fn)
     1281                return ENOENT;
    13541282        nodep = FAT_NODE(fn);
    13551283
     
    13951323out:
    13961324        fat_node_put(fn);
    1397         async_answer_0(rid, rc);
    1398         return;
    1399 }
    1400 
    1401 void fat_close(ipc_callid_t rid, ipc_call_t *request)
    1402 {
    1403         async_answer_0(rid, EOK);
    1404 }
    1405 
    1406 void fat_destroy(ipc_callid_t rid, ipc_call_t *request)
    1407 {
    1408         devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
    1409         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
     1325        return rc;
     1326}
     1327
     1328static int fat_close(devmap_handle_t devmap_handle, fs_index_t index)
     1329{
     1330        return EOK;
     1331}
     1332
     1333static int fat_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     1334{
    14101335        fs_node_t *fn;
    14111336        fat_node_t *nodep;
     
    14131338
    14141339        rc = fat_node_get(&fn, devmap_handle, index);
    1415         if (rc != EOK) {
    1416                 async_answer_0(rid, rc);
    1417                 return;
    1418         }
    1419         if (!fn) {
    1420                 async_answer_0(rid, ENOENT);
    1421                 return;
    1422         }
     1340        if (rc != EOK)
     1341                return rc;
     1342        if (!fn)
     1343                return ENOENT;
    14231344
    14241345        nodep = FAT_NODE(fn);
     
    14301351
    14311352        rc = fat_destroy_node(fn);
    1432         async_answer_0(rid, rc);
    1433 }
    1434 
    1435 void fat_open_node(ipc_callid_t rid, ipc_call_t *request)
    1436 {
    1437         libfs_open_node(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1438 }
    1439 
    1440 void fat_stat(ipc_callid_t rid, ipc_call_t *request)
    1441 {
    1442         libfs_stat(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1443 }
    1444 
    1445 void fat_sync(ipc_callid_t rid, ipc_call_t *request)
    1446 {
    1447         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1448         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1449 
     1353        return rc;
     1354}
     1355
     1356static int fat_sync(devmap_handle_t devmap_handle, fs_index_t index)
     1357{
    14501358        fs_node_t *fn;
    14511359        int rc = fat_node_get(&fn, devmap_handle, index);
    1452         if (rc != EOK) {
    1453                 async_answer_0(rid, rc);
    1454                 return;
    1455         }
    1456         if (!fn) {
    1457                 async_answer_0(rid, ENOENT);
    1458                 return;
    1459         }
     1360        if (rc != EOK)
     1361                return rc;
     1362        if (!fn)
     1363                return ENOENT;
    14601364
    14611365        fat_node_t *nodep = FAT_NODE(fn);
     
    14651369
    14661370        fat_node_put(fn);
    1467         async_answer_0(rid, rc);
    1468 }
     1371        return rc;
     1372}
     1373
     1374vfs_out_ops_t fat_ops = {
     1375        .mounted = fat_mounted,
     1376        .unmounted = fat_unmounted,
     1377        .read = fat_read,
     1378        .write = fat_write,
     1379        .truncate = fat_truncate,
     1380        .close = fat_close,
     1381        .destroy = fat_destroy,
     1382        .sync = fat_sync,
     1383};
    14691384
    14701385/**
  • uspace/srv/fs/tmpfs/Makefile

    r52a79081 ra33f0a6  
    3232EXTRA_CFLAGS += -I$(LIBBLOCK_PREFIX) -I$(LIBFS_PREFIX)
    3333BINARY = tmpfs
     34STATIC_NEEDED = y
    3435
    3536SOURCES = \
  • uspace/srv/fs/tmpfs/tmpfs.c

    r52a79081 ra33f0a6  
    3030/** @addtogroup fs
    3131 * @{
    32  */ 
     32 */
    3333
    3434/**
     
    4343#include "tmpfs.h"
    4444#include <ipc/services.h>
    45 #include <ipc/ns.h>
     45#include <ns.h>
    4646#include <async.h>
    4747#include <errno.h>
     
    6161};
    6262
    63 fs_reg_t tmpfs_reg;
    64 
    65 /**
    66  * This connection fibril processes VFS requests from VFS.
    67  *
    68  * In order to support simultaneous VFS requests, our design is as follows.
    69  * The connection fibril accepts VFS requests from VFS. If there is only one
    70  * instance of the fibril, VFS will need to serialize all VFS requests it sends
    71  * to FAT. To overcome this bottleneck, VFS can send TMPFS the
    72  * IPC_M_CONNECT_ME_TO call. In that case, a new connection fibril will be
    73  * created, which in turn will accept the call. Thus, a new phone will be
    74  * opened for VFS.
    75  *
    76  * There are few issues with this arrangement. First, VFS can run out of
    77  * available phones. In that case, VFS can close some other phones or use one
    78  * phone for more serialized requests. Similarily, TMPFS can refuse to duplicate
    79  * the connection. VFS should then just make use of already existing phones and
    80  * route its requests through them. To avoid paying the fibril creation price
    81  * upon each request, TMPFS might want to keep the connections open after the
    82  * request has been completed.
    83  */
    84 static void tmpfs_connection(ipc_callid_t iid, ipc_call_t *icall)
    85 {
    86         if (iid) {
    87                 /*
    88                  * This only happens for connections opened by
    89                  * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
    90                  * created by IPC_M_CONNECT_TO_ME.
    91                  */
    92                 async_answer_0(iid, EOK);
    93         }
    94        
    95         dprintf(NAME ": connection opened\n");
    96         while (1) {
    97                 ipc_callid_t callid;
    98                 ipc_call_t call;
    99        
    100                 callid = async_get_call(&call);
    101                 switch  (IPC_GET_IMETHOD(call)) {
    102                 case IPC_M_PHONE_HUNGUP:
    103                         return;
    104                 case VFS_OUT_MOUNTED:
    105                         tmpfs_mounted(callid, &call);
    106                         break;
    107                 case VFS_OUT_MOUNT:
    108                         tmpfs_mount(callid, &call);
    109                         break;
    110                 case VFS_OUT_UNMOUNTED:
    111                         tmpfs_unmounted(callid, &call);
    112                         break;
    113                 case VFS_OUT_UNMOUNT:
    114                         tmpfs_unmount(callid, &call);
    115                         break;
    116                 case VFS_OUT_LOOKUP:
    117                         tmpfs_lookup(callid, &call);
    118                         break;
    119                 case VFS_OUT_READ:
    120                         tmpfs_read(callid, &call);
    121                         break;
    122                 case VFS_OUT_WRITE:
    123                         tmpfs_write(callid, &call);
    124                         break;
    125                 case VFS_OUT_TRUNCATE:
    126                         tmpfs_truncate(callid, &call);
    127                         break;
    128                 case VFS_OUT_CLOSE:
    129                         tmpfs_close(callid, &call);
    130                         break;
    131                 case VFS_OUT_DESTROY:
    132                         tmpfs_destroy(callid, &call);
    133                         break;
    134                 case VFS_OUT_OPEN_NODE:
    135                         tmpfs_open_node(callid, &call);
    136                         break;
    137                 case VFS_OUT_STAT:
    138                         tmpfs_stat(callid, &call);
    139                         break;
    140                 case VFS_OUT_SYNC:
    141                         tmpfs_sync(callid, &call);
    142                         break;
    143                 default:
    144                         async_answer_0(callid, ENOTSUP);
    145                         break;
    146                 }
    147         }
    148 }
    149 
    15063int main(int argc, char **argv)
    15164{
    15265        printf(NAME ": HelenOS TMPFS file system server\n");
    153 
     66       
    15467        if (!tmpfs_init()) {
    15568                printf(NAME ": failed to initialize TMPFS\n");
    15669                return -1;
    15770        }
    158 
    159         int vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
    160         if (vfs_phone < EOK) {
     71       
     72        async_sess_t *vfs_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
     73            SERVICE_VFS, 0, 0);
     74        if (!vfs_sess) {
    16175                printf(NAME ": Unable to connect to VFS\n");
    16276                return -1;
    16377        }
    164 
    165         int rc = fs_register(vfs_phone, &tmpfs_reg, &tmpfs_vfs_info,
    166             tmpfs_connection);
     78       
     79        int rc = fs_register(vfs_sess, &tmpfs_vfs_info, &tmpfs_ops,
     80            &tmpfs_libfs_ops);
    16781        if (rc != EOK) {
    16882                printf(NAME ": Failed to register file system (%d)\n", rc);
    16983                return rc;
    17084        }
    171 
     85       
    17286        printf(NAME ": Accepting connections\n");
    17387        task_retval(0);
    17488        async_manager();
    175         /* not reached */
     89       
     90        /* Not reached */
    17691        return 0;
    17792}
     
    17994/**
    18095 * @}
    181  */ 
     96 */
  • uspace/srv/fs/tmpfs/tmpfs.h

    r52a79081 ra33f0a6  
    6767        size_t size;            /**< File size if type is TMPFS_FILE. */
    6868        void *data;             /**< File content's if type is TMPFS_FILE. */
    69         link_t cs_head;         /**< Head of child's siblings list. */
     69        list_t cs_list;         /**< Child's siblings list. */
    7070} tmpfs_node_t;
    7171
    72 extern fs_reg_t tmpfs_reg;
    73 
     72extern vfs_out_ops_t tmpfs_ops;
    7473extern libfs_ops_t tmpfs_libfs_ops;
    7574
    7675extern bool tmpfs_init(void);
    77 
    78 extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *);
    79 extern void tmpfs_mount(ipc_callid_t, ipc_call_t *);
    80 extern void tmpfs_unmounted(ipc_callid_t, ipc_call_t *);
    81 extern void tmpfs_unmount(ipc_callid_t, ipc_call_t *);
    82 extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);
    83 extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
    84 extern void tmpfs_write(ipc_callid_t, ipc_call_t *);
    85 extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *);
    86 extern void tmpfs_stat(ipc_callid_t, ipc_call_t *);
    87 extern void tmpfs_close(ipc_callid_t, ipc_call_t *);
    88 extern void tmpfs_destroy(ipc_callid_t, ipc_call_t *);
    89 extern void tmpfs_open_node(ipc_callid_t, ipc_call_t *);
    90 extern void tmpfs_sync(ipc_callid_t, ipc_call_t *);
    91 
    9276extern bool tmpfs_restore(devmap_handle_t);
    9377
  • uspace/srv/fs/tmpfs/tmpfs_dump.c

    r52a79081 ra33f0a6  
    167167        int rc;
    168168
    169         rc = block_init(dev, TMPFS_COMM_SIZE);
     169        rc = block_init(EXCHANGE_SERIALIZE, dev, TMPFS_COMM_SIZE);
    170170        if (rc != EOK)
    171171                return false;
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r52a79081 ra33f0a6  
    8585static int tmpfs_has_children(bool *has_children, fs_node_t *fn)
    8686{
    87         *has_children = !list_empty(&TMPFS_NODE(fn)->cs_head);
     87        *has_children = !list_empty(&TMPFS_NODE(fn)->cs_list);
    8888        return EOK;
    8989}
     
    102102{
    103103        return TMPFS_NODE(fn)->lnkcnt;
    104 }
    105 
    106 static char tmpfs_plb_get_char(unsigned pos)
    107 {
    108         return tmpfs_reg.plb_ro[pos % PLB_SIZE];
    109104}
    110105
     
    139134        .size_get = tmpfs_size_get,
    140135        .lnkcnt_get = tmpfs_lnkcnt_get,
    141         .plb_get_char = tmpfs_plb_get_char,
    142136        .is_directory = tmpfs_is_directory,
    143137        .is_file = tmpfs_is_file,
     
    180174            nh_link);
    181175
    182         while (!list_empty(&nodep->cs_head)) {
    183                 tmpfs_dentry_t *dentryp = list_get_instance(nodep->cs_head.next,
    184                     tmpfs_dentry_t, link);
     176        while (!list_empty(&nodep->cs_list)) {
     177                tmpfs_dentry_t *dentryp = list_get_instance(
     178                    list_first(&nodep->cs_list), tmpfs_dentry_t, link);
    185179
    186180                assert(nodep->type == TMPFS_DIRECTORY);
     
    214208        nodep->data = NULL;
    215209        link_initialize(&nodep->nh_link);
    216         list_initialize(&nodep->cs_head);
     210        list_initialize(&nodep->cs_list);
    217211}
    218212
     
    262256{
    263257        tmpfs_node_t *parentp = TMPFS_NODE(pfn);
    264         link_t *lnk;
    265 
    266         for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head;
    267             lnk = lnk->next) {
     258
     259        list_foreach(parentp->cs_list, lnk) {
    268260                tmpfs_dentry_t *dentryp;
    269261                dentryp = list_get_instance(lnk, tmpfs_dentry_t, link);
     
    353345       
    354346        assert(!nodep->lnkcnt);
    355         assert(list_empty(&nodep->cs_head));
     347        assert(list_empty(&nodep->cs_list));
    356348
    357349        unsigned long key[] = {
     
    373365        tmpfs_node_t *childp = TMPFS_NODE(cfn);
    374366        tmpfs_dentry_t *dentryp;
    375         link_t *lnk;
    376367
    377368        assert(parentp->type == TMPFS_DIRECTORY);
    378369
    379370        /* Check for duplicit entries. */
    380         for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head;
    381             lnk = lnk->next) {
     371        list_foreach(parentp->cs_list, lnk) {
    382372                dentryp = list_get_instance(lnk, tmpfs_dentry_t, link);
    383373                if (!str_cmp(dentryp->name, nm))
     
    401391        dentryp->node = childp;
    402392        childp->lnkcnt++;
    403         list_append(&dentryp->link, &parentp->cs_head);
     393        list_append(&dentryp->link, &parentp->cs_list);
    404394
    405395        return EOK;
     
    411401        tmpfs_node_t *childp = NULL;
    412402        tmpfs_dentry_t *dentryp;
    413         link_t *lnk;
    414403
    415404        if (!parentp)
    416405                return EBUSY;
    417406       
    418         for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head;
    419             lnk = lnk->next) {
     407        list_foreach(parentp->cs_list, lnk) {
    420408                dentryp = list_get_instance(lnk, tmpfs_dentry_t, link);
    421409                if (!str_cmp(dentryp->name, nm)) {
     
    423411                        assert(FS_NODE(childp) == cfn);
    424412                        break;
    425                 }       
     413                }
    426414        }
    427415
     
    429417                return ENOENT;
    430418               
    431         if ((childp->lnkcnt == 1) && !list_empty(&childp->cs_head))
     419        if ((childp->lnkcnt == 1) && !list_empty(&childp->cs_list))
    432420                return ENOTEMPTY;
    433421
     
    439427}
    440428
    441 void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request)
    442 {
    443         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     429/*
     430 * Implementation of the VFS_OUT interface.
     431 */
     432
     433static int
     434tmpfs_mounted(devmap_handle_t devmap_handle, const char *opts,
     435    fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     436{
    444437        fs_node_t *rootfn;
    445438        int rc;
    446439       
    447         /* Accept the mount options. */
    448         char *opts;
    449         rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
    450         if (rc != EOK) {
    451                 async_answer_0(rid, rc);
    452                 return;
    453         }
    454 
    455440        /* Check if this device is not already mounted. */
    456441        rc = tmpfs_root_get(&rootfn, devmap_handle);
    457442        if ((rc == EOK) && (rootfn)) {
    458443                (void) tmpfs_node_put(rootfn);
    459                 free(opts);
    460                 async_answer_0(rid, EEXIST);
    461                 return;
     444                return EEXIST;
    462445        }
    463446
    464447        /* Initialize TMPFS instance. */
    465         if (!tmpfs_instance_init(devmap_handle)) {
    466                 free(opts);
    467                 async_answer_0(rid, ENOMEM);
    468                 return;
    469         }
     448        if (!tmpfs_instance_init(devmap_handle))
     449                return ENOMEM;
    470450
    471451        rc = tmpfs_root_get(&rootfn, devmap_handle);
     
    473453        tmpfs_node_t *rootp = TMPFS_NODE(rootfn);
    474454        if (str_cmp(opts, "restore") == 0) {
    475                 if (tmpfs_restore(devmap_handle))
    476                         async_answer_3(rid, EOK, rootp->index, rootp->size,
    477                             rootp->lnkcnt);
    478                 else
    479                         async_answer_0(rid, ELIMIT);
    480         } else {
    481                 async_answer_3(rid, EOK, rootp->index, rootp->size,
    482                     rootp->lnkcnt);
    483         }
    484         free(opts);
    485 }
    486 
    487 void tmpfs_mount(ipc_callid_t rid, ipc_call_t *request)
    488 {
    489         libfs_mount(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
    490 }
    491 
    492 void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
    493 {
    494         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    495 
     455                if (!tmpfs_restore(devmap_handle))
     456                        return ELIMIT;
     457        }
     458
     459        *index = rootp->index;
     460        *size = rootp->size;
     461        *lnkcnt = rootp->lnkcnt;
     462
     463        return EOK;
     464}
     465
     466static int tmpfs_unmounted(devmap_handle_t devmap_handle)
     467{
    496468        tmpfs_instance_done(devmap_handle);
    497         async_answer_0(rid, EOK);
    498 }
    499 
    500 void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request)
    501 {
    502         libfs_unmount(&tmpfs_libfs_ops, rid, request);
    503 }
    504 
    505 void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    506 {
    507         libfs_lookup(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
    508 }
    509 
    510 void tmpfs_read(ipc_callid_t rid, ipc_call_t *request)
    511 {
    512         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    513         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    514         aoff64_t pos =
    515             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    516        
     469        return EOK;
     470}
     471
     472static int tmpfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     473    size_t *rbytes)
     474{
    517475        /*
    518476         * Lookup the respective TMPFS node.
     
    524482        };
    525483        hlp = hash_table_find(&nodes, key);
    526         if (!hlp) {
    527                 async_answer_0(rid, ENOENT);
    528                 return;
    529         }
     484        if (!hlp)
     485                return ENOENT;
    530486        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    531487            nh_link);
     
    538494        if (!async_data_read_receive(&callid, &size)) {
    539495                async_answer_0(callid, EINVAL);
    540                 async_answer_0(rid, EINVAL);
    541                 return;
     496                return EINVAL;
    542497        }
    543498
     
    550505                tmpfs_dentry_t *dentryp;
    551506                link_t *lnk;
    552                 aoff64_t i;
    553507               
    554508                assert(nodep->type == TMPFS_DIRECTORY);
     
    559513                 * hash table.
    560514                 */
    561                 for (i = 0, lnk = nodep->cs_head.next;
    562                     (i < pos) && (lnk != &nodep->cs_head);
    563                     i++, lnk = lnk->next)
    564                         ;
    565 
    566                 if (lnk == &nodep->cs_head) {
     515                lnk = list_nth(&nodep->cs_list, pos);
     516               
     517                if (lnk == NULL) {
    567518                        async_answer_0(callid, ENOENT);
    568                         async_answer_1(rid, ENOENT, 0);
    569                         return;
     519                        return ENOENT;
    570520                }
    571521
     
    577527        }
    578528
    579         /*
    580          * Answer the VFS_READ call.
    581          */
    582         async_answer_1(rid, EOK, bytes);
    583 }
    584 
    585 void tmpfs_write(ipc_callid_t rid, ipc_call_t *request)
    586 {
    587         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    588         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    589         aoff64_t pos =
    590             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    591        
     529        *rbytes = bytes;
     530        return EOK;
     531}
     532
     533static int
     534tmpfs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     535    size_t *wbytes, aoff64_t *nsize)
     536{
    592537        /*
    593538         * Lookup the respective TMPFS node.
     
    599544        };
    600545        hlp = hash_table_find(&nodes, key);
    601         if (!hlp) {
    602                 async_answer_0(rid, ENOENT);
    603                 return;
    604         }
     546        if (!hlp)
     547                return ENOENT;
    605548        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    606549            nh_link);
     
    613556        if (!async_data_write_receive(&callid, &size)) {
    614557                async_answer_0(callid, EINVAL);
    615                 async_answer_0(rid, EINVAL);
    616                 return;
     558                return EINVAL;
    617559        }
    618560
     
    622564        if (pos + size <= nodep->size) {
    623565                /* The file size is not changing. */
    624                 (void) async_data_write_finalize(callid, nodep->data + pos, size);
    625                 async_answer_2(rid, EOK, size, nodep->size);
    626                 return;
     566                (void) async_data_write_finalize(callid, nodep->data + pos,
     567                    size);
     568                goto out;
    627569        }
    628570        size_t delta = (pos + size) - nodep->size;
     
    637579        if (!newdata) {
    638580                async_answer_0(callid, ENOMEM);
    639                 async_answer_2(rid, EOK, 0, nodep->size);
    640                 return;
     581                size = 0;
     582                goto out;
    641583        }
    642584        /* Clear any newly allocated memory in order to emulate gaps. */
     
    645587        nodep->data = newdata;
    646588        (void) async_data_write_finalize(callid, nodep->data + pos, size);
    647         async_answer_2(rid, EOK, size, nodep->size);
    648 }
    649 
    650 void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request)
    651 {
    652         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    653         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    654         aoff64_t size =
    655             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    656        
     589
     590out:
     591        *wbytes = size;
     592        *nsize = nodep->size;
     593        return EOK;
     594}
     595
     596static int tmpfs_truncate(devmap_handle_t devmap_handle, fs_index_t index,
     597    aoff64_t size)
     598{
    657599        /*
    658600         * Lookup the respective TMPFS node.
     
    663605        };
    664606        link_t *hlp = hash_table_find(&nodes, key);
    665         if (!hlp) {
    666                 async_answer_0(rid, ENOENT);
    667                 return;
    668         }
    669         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    670             nh_link);
    671        
    672         if (size == nodep->size) {
    673                 async_answer_0(rid, EOK);
    674                 return;
    675         }
    676        
    677         if (size > SIZE_MAX) {
    678                 async_answer_0(rid, ENOMEM);
    679                 return;
    680         }
     607        if (!hlp)
     608                return ENOENT;
     609        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, nh_link);
     610       
     611        if (size == nodep->size)
     612                return EOK;
     613       
     614        if (size > SIZE_MAX)
     615                return ENOMEM;
    681616       
    682617        void *newdata = realloc(nodep->data, size);
    683         if (!newdata) {
    684                 async_answer_0(rid, ENOMEM);
    685                 return;
    686         }
     618        if (!newdata)
     619                return ENOMEM;
    687620       
    688621        if (size > nodep->size) {
     
    693626        nodep->size = size;
    694627        nodep->data = newdata;
    695         async_answer_0(rid, EOK);
    696 }
    697 
    698 void tmpfs_close(ipc_callid_t rid, ipc_call_t *request)
    699 {
    700         async_answer_0(rid, EOK);
    701 }
    702 
    703 void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request)
    704 {
    705         devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
    706         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    707         int rc;
    708 
     628        return EOK;
     629}
     630
     631static int tmpfs_close(devmap_handle_t devmap_handle, fs_index_t index)
     632{
     633        return EOK;
     634}
     635
     636static int tmpfs_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     637{
    709638        link_t *hlp;
    710639        unsigned long key[] = {
     
    713642        };
    714643        hlp = hash_table_find(&nodes, key);
    715         if (!hlp) {
    716                 async_answer_0(rid, ENOENT);
    717                 return;
    718         }
     644        if (!hlp)
     645                return ENOENT;
    719646        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    720647            nh_link);
    721         rc = tmpfs_destroy_node(FS_NODE(nodep));
    722         async_answer_0(rid, rc);
    723 }
    724 
    725 void tmpfs_open_node(ipc_callid_t rid, ipc_call_t *request)
    726 {
    727         libfs_open_node(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
    728 }
    729 
    730 void tmpfs_stat(ipc_callid_t rid, ipc_call_t *request)
    731 {
    732         libfs_stat(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
    733 }
    734 
    735 void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request)
     648        return tmpfs_destroy_node(FS_NODE(nodep));
     649}
     650
     651static int tmpfs_sync(devmap_handle_t devmap_handle, fs_index_t index)
    736652{
    737653        /*
     
    739655         * thus the sync operation is a no-op.
    740656         */
    741         async_answer_0(rid, EOK);
    742 }
     657        return EOK;
     658}
     659
     660vfs_out_ops_t tmpfs_ops = {
     661        .mounted = tmpfs_mounted,
     662        .unmounted = tmpfs_unmounted,
     663        .read = tmpfs_read,
     664        .write = tmpfs_write,
     665        .truncate = tmpfs_truncate,
     666        .close = tmpfs_close,
     667        .destroy = tmpfs_destroy,
     668        .sync = tmpfs_sync,
     669};
    743670
    744671/**
    745672 * @}
    746673 */
     674
Note: See TracChangeset for help on using the changeset viewer.