Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/fat/fat_ops.c

    r472c09d rdfddfcd  
    5252#include <adt/list.h>
    5353#include <assert.h>
    54 #include <fibril_synch.h>
     54#include <fibril_sync.h>
    5555#include <sys/mman.h>
    5656#include <align.h>
     
    7171static int fat_match(fs_node_t **, fs_node_t *, const char *);
    7272static int fat_node_get(fs_node_t **, dev_handle_t, fs_index_t);
    73 static int fat_node_open(fs_node_t *);
    7473static int fat_node_put(fs_node_t *);
    7574static int fat_create_node(fs_node_t **, dev_handle_t, int);
     
    8483static bool fat_is_directory(fs_node_t *);
    8584static bool fat_is_file(fs_node_t *node);
    86 static dev_handle_t fat_device_get(fs_node_t *node);
    8785
    8886/*
     
    137135        rc = block_put(b);
    138136        return rc;
    139 }
    140 
    141 static int fat_node_fini_by_dev_handle(dev_handle_t dev_handle)
    142 {
    143         link_t *lnk;
    144         fat_node_t *nodep;
    145         int rc;
    146 
    147         /*
    148          * We are called from fat_unmounted() and assume that there are already
    149          * no nodes belonging to this instance with non-zero refcount. Therefore
    150          * it is sufficient to clean up only the FAT free node list.
    151          */
    152 
    153 restart:
    154         fibril_mutex_lock(&ffn_mutex);
    155         for (lnk = ffn_head.next; lnk != &ffn_head; lnk = lnk->next) {
    156                 nodep = list_get_instance(lnk, fat_node_t, ffn_link);
    157                 if (!fibril_mutex_trylock(&nodep->lock)) {
    158                         fibril_mutex_unlock(&ffn_mutex);
    159                         goto restart;
    160                 }
    161                 if (!fibril_mutex_trylock(&nodep->idx->lock)) {
    162                         fibril_mutex_unlock(&nodep->lock);
    163                         fibril_mutex_unlock(&ffn_mutex);
    164                         goto restart;
    165                 }
    166                 if (nodep->idx->dev_handle != dev_handle) {
    167                         fibril_mutex_unlock(&nodep->idx->lock);
    168                         fibril_mutex_unlock(&nodep->lock);
    169                         continue;
    170                 }
    171 
    172                 list_remove(&nodep->ffn_link);
    173                 fibril_mutex_unlock(&ffn_mutex);
    174 
    175                 /*
    176                  * We can unlock the node and its index structure because we are
    177                  * the last player on this playground and VFS is preventing new
    178                  * players from entering.
    179                  */
    180                 fibril_mutex_unlock(&nodep->idx->lock);
    181                 fibril_mutex_unlock(&nodep->lock);
    182 
    183                 if (nodep->dirty) {
    184                         rc = fat_node_sync(nodep);
    185                         if (rc != EOK)
    186                                 return rc;
    187                 }
    188                 nodep->idx->nodep = NULL;
    189                 free(nodep->bp);
    190                 free(nodep);
    191 
    192                 /* Need to restart because we changed the ffn_head list. */
    193                 goto restart;
    194         }
    195         fibril_mutex_unlock(&ffn_mutex);
    196 
    197         return EOK;
    198137}
    199138
     
    468407}
    469408
    470 int fat_node_open(fs_node_t *fn)
    471 {
    472         /*
    473          * Opening a file is stateless, nothing
    474          * to be done here.
    475          */
    476         return EOK;
    477 }
    478 
    479409int fat_node_put(fs_node_t *fn)
    480410{
     
    937867}
    938868
    939 dev_handle_t fat_device_get(fs_node_t *node)
    940 {
    941         return 0;
    942 }
    943 
    944869/** libfs operations */
    945870libfs_ops_t fat_libfs_ops = {
     
    947872        .match = fat_match,
    948873        .node_get = fat_node_get,
    949         .node_open = fat_node_open,
    950874        .node_put = fat_node_put,
    951875        .create = fat_create_node,
     
    957881        .size_get = fat_size_get,
    958882        .lnkcnt_get = fat_lnkcnt_get,
    959         .plb_get_char = fat_plb_get_char,
     883        .plb_get_char = fat_plb_get_char,
    960884        .is_directory = fat_is_directory,
    961         .is_file = fat_is_file,
    962         .device_get = fat_device_get
     885        .is_file = fat_is_file
    963886};
    964887
     
    974897        uint16_t bps;
    975898        uint16_t rde;
    976        
    977         /* Accept the mount options */
    978         char *opts;
    979         int rc = async_string_receive(&opts, 0, NULL);
    980        
    981         if (rc != EOK) {
    982                 ipc_answer_0(rid, rc);
    983                 return;
    984         }
     899        int rc;
     900
     901        /* accept the mount options */
     902        ipc_callid_t callid;
     903        size_t size;
     904        if (!async_data_write_receive(&callid, &size)) {
     905                ipc_answer_0(callid, EINVAL);
     906                ipc_answer_0(rid, EINVAL);
     907                return;
     908        }
     909        char *opts = malloc(size + 1);
     910        if (!opts) {
     911                ipc_answer_0(callid, ENOMEM);
     912                ipc_answer_0(rid, ENOMEM);
     913                return;
     914        }
     915        ipcarg_t retval = async_data_write_finalize(callid, opts, size);
     916        if (retval != EOK) {
     917                ipc_answer_0(rid, retval);
     918                free(opts);
     919                return;
     920        }
     921        opts[size] = '\0';
    985922
    986923        /* Check for option enabling write through. */
     
    990927                cmode = CACHE_MODE_WB;
    991928
    992         free(opts);
    993 
    994929        /* initialize libblock */
    995930        rc = block_init(dev_handle, BS_SIZE);
     
    1028963        }
    1029964
    1030         /* Do some simple sanity checks on the file system. */
    1031         rc = fat_sanity_check(bs, dev_handle);
    1032         if (rc != EOK) {
    1033                 (void) block_cache_fini(dev_handle);
    1034                 block_fini(dev_handle);
    1035                 ipc_answer_0(rid, rc);
    1036                 return;
    1037         }
    1038 
    1039965        rc = fat_idx_init_by_dev_handle(dev_handle);
    1040966        if (rc != EOK) {
    1041                 (void) block_cache_fini(dev_handle);
    1042967                block_fini(dev_handle);
    1043968                ipc_answer_0(rid, rc);
     
    1048973        fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
    1049974        if (!rfn) {
    1050                 (void) block_cache_fini(dev_handle);
    1051975                block_fini(dev_handle);
    1052976                fat_idx_fini_by_dev_handle(dev_handle);
     
    1058982        if (!rootp) {
    1059983                free(rfn);
    1060                 (void) block_cache_fini(dev_handle);
    1061984                block_fini(dev_handle);
    1062985                fat_idx_fini_by_dev_handle(dev_handle);
     
    1070993                free(rfn);
    1071994                free(rootp);
    1072                 (void) block_cache_fini(dev_handle);
    1073995                block_fini(dev_handle);
    1074996                fat_idx_fini_by_dev_handle(dev_handle);
     
    10971019{
    10981020        libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1099 }
    1100 
    1101 void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)
    1102 {
    1103         dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
    1104         fs_node_t *fn;
    1105         fat_node_t *nodep;
    1106         int rc;
    1107 
    1108         rc = fat_root_get(&fn, dev_handle);
    1109         if (rc != EOK) {
    1110                 ipc_answer_0(rid, rc);
    1111                 return;
    1112         }
    1113         nodep = FAT_NODE(fn);
    1114 
    1115         /*
    1116          * We expect exactly two references on the root node. One for the
    1117          * fat_root_get() above and one created in fat_mounted().
    1118          */
    1119         if (nodep->refcnt != 2) {
    1120                 (void) fat_node_put(fn);
    1121                 ipc_answer_0(rid, EBUSY);
    1122                 return;
    1123         }
    1124        
    1125         /*
    1126          * Put the root node and force it to the FAT free node list.
    1127          */
    1128         (void) fat_node_put(fn);
    1129         (void) fat_node_put(fn);
    1130 
    1131         /*
    1132          * Perform cleanup of the node structures, index structures and
    1133          * associated data. Write back this file system's dirty blocks and
    1134          * stop using libblock for this instance.
    1135          */
    1136         (void) fat_node_fini_by_dev_handle(dev_handle);
    1137         fat_idx_fini_by_dev_handle(dev_handle);
    1138         (void) block_cache_fini(dev_handle);
    1139         block_fini(dev_handle);
    1140 
    1141         ipc_answer_0(rid, EOK);
    1142 }
    1143 
    1144 void fat_unmount(ipc_callid_t rid, ipc_call_t *request)
    1145 {
    1146         libfs_unmount(&fat_libfs_ops, rid, request);
    11471021}
    11481022
Note: See TracChangeset for help on using the changeset viewer.