Ignore:
File:
1 edited

Legend:

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

    r5ca5eaa7 refcebe1  
    5555#include <sys/mman.h>
    5656#include <align.h>
     57#include <malloc.h>
    5758
    5859#define FAT_NODE(node)  ((node) ? (fat_node_t *) (node)->data : NULL)
     
    6667
    6768/** List of cached free FAT nodes. */
    68 static LIST_INITIALIZE(ffn_head);
     69static LIST_INITIALIZE(ffn_list);
    6970
    7071/*
     
    8485static aoff64_t fat_size_get(fs_node_t *);
    8586static unsigned fat_lnkcnt_get(fs_node_t *);
    86 static char fat_plb_get_char(unsigned);
    8787static bool fat_is_directory(fs_node_t *);
    8888static bool fat_is_file(fs_node_t *node);
     
    146146static int fat_node_fini_by_devmap_handle(devmap_handle_t devmap_handle)
    147147{
    148         link_t *lnk;
    149148        fat_node_t *nodep;
    150149        int rc;
     
    158157restart:
    159158        fibril_mutex_lock(&ffn_mutex);
    160         for (lnk = ffn_head.next; lnk != &ffn_head; lnk = lnk->next) {
     159        list_foreach(ffn_list, lnk) {
    161160                nodep = list_get_instance(lnk, fat_node_t, ffn_link);
    162161                if (!fibril_mutex_trylock(&nodep->lock)) {
     
    195194                free(nodep);
    196195
    197                 /* Need to restart because we changed the ffn_head list. */
     196                /* Need to restart because we changed ffn_list. */
    198197                goto restart;
    199198        }
     
    210209
    211210        fibril_mutex_lock(&ffn_mutex);
    212         if (!list_empty(&ffn_head)) {
     211        if (!list_empty(&ffn_list)) {
    213212                /* Try to use a cached free node structure. */
    214213                fat_idx_t *idxp_tmp;
    215                 nodep = list_get_instance(ffn_head.next, fat_node_t, ffn_link);
     214                nodep = list_get_instance(list_first(&ffn_list), fat_node_t,
     215                    ffn_link);
    216216                if (!fibril_mutex_trylock(&nodep->lock))
    217217                        goto skip_cache;
     
    472472                if (nodep->idx) {
    473473                        fibril_mutex_lock(&ffn_mutex);
    474                         list_append(&nodep->ffn_link, &ffn_head);
     474                        list_append(&nodep->ffn_link, &ffn_list);
    475475                        fibril_mutex_unlock(&ffn_mutex);
    476476                } else {
     
    722722                    (str_cmp((char *) d->name, FAT_NAME_DOT)) == 0) {
    723723                        memset(d, 0, sizeof(fat_dentry_t));
    724                         str_cpy((char *) d->name, 8, FAT_NAME_DOT);
    725                         str_cpy((char *) d->ext, 3, FAT_EXT_PAD);
     724                        memcpy(d->name, FAT_NAME_DOT, FAT_NAME_LEN);
     725                        memcpy(d->ext, FAT_EXT_PAD, FAT_EXT_LEN);
    726726                        d->attr = FAT_ATTR_SUBDIR;
    727727                        d->firstc = host2uint16_t_le(childp->firstc);
     
    732732                    (str_cmp((char *) d->name, FAT_NAME_DOT_DOT) == 0)) {
    733733                        memset(d, 0, sizeof(fat_dentry_t));
    734                         str_cpy((char *) d->name, 8, FAT_NAME_DOT_DOT);
    735                         str_cpy((char *) d->ext, 3, FAT_EXT_PAD);
     734                        memcpy(d->name, FAT_NAME_DOT_DOT, FAT_NAME_LEN);
     735                        memcpy(d->ext, FAT_EXT_PAD, FAT_EXT_LEN);
    736736                        d->attr = FAT_ATTR_SUBDIR;
    737737                        d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
     
    900900}
    901901
    902 char fat_plb_get_char(unsigned pos)
    903 {
    904         return fat_reg.plb_ro[pos % PLB_SIZE];
    905 }
    906 
    907902bool fat_is_directory(fs_node_t *fn)
    908903{
     
    935930        .size_get = fat_size_get,
    936931        .lnkcnt_get = fat_lnkcnt_get,
    937         .plb_get_char = fat_plb_get_char,
    938932        .is_directory = fat_is_directory,
    939933        .is_file = fat_is_file,
     
    942936
    943937/*
    944  * VFS operations.
     938 * FAT VFS_OUT operations.
    945939 */
    946940
    947 void fat_mounted(ipc_callid_t rid, ipc_call_t *request)
    948 {
    949         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     941static int
     942fat_mounted(devmap_handle_t devmap_handle, const char *opts, fs_index_t *index,
     943    aoff64_t *size, unsigned *linkcnt)
     944{
    950945        enum cache_mode cmode;
    951946        fat_bs_t *bs;
    952        
    953         /* Accept the mount options */
    954         char *opts;
    955         int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
    956        
    957         if (rc != EOK) {
    958                 async_answer_0(rid, rc);
    959                 return;
    960         }
    961 
     947        int rc;
     948       
    962949        /* Check for option enabling write through. */
    963950        if (str_cmp(opts, "wtcache") == 0)
     
    966953                cmode = CACHE_MODE_WB;
    967954
    968         free(opts);
    969 
    970955        /* initialize libblock */
    971         rc = block_init(devmap_handle, BS_SIZE);
    972         if (rc != EOK) {
    973                 async_answer_0(rid, rc);
    974                 return;
    975         }
     956        rc = block_init(EXCHANGE_SERIALIZE, devmap_handle, BS_SIZE);
     957        if (rc != EOK)
     958                return rc;
    976959
    977960        /* prepare the boot block */
     
    979962        if (rc != EOK) {
    980963                block_fini(devmap_handle);
    981                 async_answer_0(rid, rc);
    982                 return;
     964                return rc;
    983965        }
    984966
     
    988970        if (BPS(bs) != BS_SIZE) {
    989971                block_fini(devmap_handle);
    990                 async_answer_0(rid, ENOTSUP);
    991                 return;
     972                return ENOTSUP;
    992973        }
    993974
     
    996977        if (rc != EOK) {
    997978                block_fini(devmap_handle);
    998                 async_answer_0(rid, rc);
    999                 return;
     979                return rc;
    1000980        }
    1001981
     
    1005985                (void) block_cache_fini(devmap_handle);
    1006986                block_fini(devmap_handle);
    1007                 async_answer_0(rid, rc);
    1008                 return;
     987                return rc;
    1009988        }
    1010989
     
    1013992                (void) block_cache_fini(devmap_handle);
    1014993                block_fini(devmap_handle);
    1015                 async_answer_0(rid, rc);
    1016                 return;
     994                return rc;
    1017995        }
    1018996
     
    10231001                block_fini(devmap_handle);
    10241002                fat_idx_fini_by_devmap_handle(devmap_handle);
    1025                 async_answer_0(rid, ENOMEM);
    1026                 return;
     1003                return ENOMEM;
    10271004        }
    10281005        fs_node_initialize(rfn);
     
    10331010                block_fini(devmap_handle);
    10341011                fat_idx_fini_by_devmap_handle(devmap_handle);
    1035                 async_answer_0(rid, ENOMEM);
    1036                 return;
     1012                return ENOMEM;
    10371013        }
    10381014        fat_node_initialize(rootp);
     
    10451021                block_fini(devmap_handle);
    10461022                fat_idx_fini_by_devmap_handle(devmap_handle);
    1047                 async_answer_0(rid, ENOMEM);
    1048                 return;
     1023                return ENOMEM;
    10491024        }
    10501025        assert(ridxp->index == 0);
     
    10631038        fibril_mutex_unlock(&ridxp->lock);
    10641039
    1065         async_answer_3(rid, EOK, ridxp->index, rootp->size, rootp->lnkcnt);
    1066 }
    1067 
    1068 void fat_mount(ipc_callid_t rid, ipc_call_t *request)
    1069 {
    1070         libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1071 }
    1072 
    1073 void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)
    1074 {
    1075         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     1040        *index = ridxp->index;
     1041        *size = rootp->size;
     1042        *linkcnt = rootp->lnkcnt;
     1043
     1044        return EOK;
     1045}
     1046
     1047static int fat_unmounted(devmap_handle_t devmap_handle)
     1048{
    10761049        fs_node_t *fn;
    10771050        fat_node_t *nodep;
     
    10791052
    10801053        rc = fat_root_get(&fn, devmap_handle);
    1081         if (rc != EOK) {
    1082                 async_answer_0(rid, rc);
    1083                 return;
    1084         }
     1054        if (rc != EOK)
     1055                return rc;
    10851056        nodep = FAT_NODE(fn);
    10861057
     
    10911062        if (nodep->refcnt != 2) {
    10921063                (void) fat_node_put(fn);
    1093                 async_answer_0(rid, EBUSY);
    1094                 return;
     1064                return EBUSY;
    10951065        }
    10961066       
     
    11111081        block_fini(devmap_handle);
    11121082
    1113         async_answer_0(rid, EOK);
    1114 }
    1115 
    1116 void fat_unmount(ipc_callid_t rid, ipc_call_t *request)
    1117 {
    1118         libfs_unmount(&fat_libfs_ops, rid, request);
    1119 }
    1120 
    1121 void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
    1122 {
    1123         libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1124 }
    1125 
    1126 void fat_read(ipc_callid_t rid, ipc_call_t *request)
    1127 {
    1128         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1129         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1130         aoff64_t pos =
    1131             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     1083        return EOK;
     1084}
     1085
     1086static int
     1087fat_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     1088    size_t *rbytes)
     1089{
    11321090        fs_node_t *fn;
    11331091        fat_node_t *nodep;
     
    11381096
    11391097        rc = fat_node_get(&fn, devmap_handle, index);
    1140         if (rc != EOK) {
    1141                 async_answer_0(rid, rc);
    1142                 return;
    1143         }
    1144         if (!fn) {
    1145                 async_answer_0(rid, ENOENT);
    1146                 return;
    1147         }
     1098        if (rc != EOK)
     1099                return rc;
     1100        if (!fn)
     1101                return ENOENT;
    11481102        nodep = FAT_NODE(fn);
    11491103
     
    11531107                fat_node_put(fn);
    11541108                async_answer_0(callid, EINVAL);
    1155                 async_answer_0(rid, EINVAL);
    1156                 return;
     1109                return EINVAL;
    11571110        }
    11581111
     
    11771130                                fat_node_put(fn);
    11781131                                async_answer_0(callid, rc);
    1179                                 async_answer_0(rid, rc);
    1180                                 return;
     1132                                return rc;
    11811133                        }
    11821134                        (void) async_data_read_finalize(callid,
     
    11851137                        if (rc != EOK) {
    11861138                                fat_node_put(fn);
    1187                                 async_answer_0(rid, rc);
    1188                                 return;
     1139                                return rc;
    11891140                        }
    11901141                }
     
    12431194                rc = fat_node_put(fn);
    12441195                async_answer_0(callid, rc != EOK ? rc : ENOENT);
    1245                 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0);
    1246                 return;
     1196                *rbytes = 0;
     1197                return rc != EOK ? rc : ENOENT;
    12471198
    12481199err:
    12491200                (void) fat_node_put(fn);
    12501201                async_answer_0(callid, rc);
    1251                 async_answer_0(rid, rc);
    1252                 return;
     1202                return rc;
    12531203
    12541204hit:
     
    12581208
    12591209        rc = fat_node_put(fn);
    1260         async_answer_1(rid, rc, (sysarg_t)bytes);
    1261 }
    1262 
    1263 void fat_write(ipc_callid_t rid, ipc_call_t *request)
    1264 {
    1265         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1266         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1267         aoff64_t pos =
    1268             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     1210        *rbytes = bytes;
     1211        return rc;
     1212}
     1213
     1214static int
     1215fat_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     1216    size_t *wbytes, aoff64_t *nsize)
     1217{
    12691218        fs_node_t *fn;
    12701219        fat_node_t *nodep;
    12711220        fat_bs_t *bs;
    1272         size_t bytes, size;
     1221        size_t bytes;
    12731222        block_t *b;
    12741223        aoff64_t boundary;
     
    12771226       
    12781227        rc = fat_node_get(&fn, devmap_handle, index);
    1279         if (rc != EOK) {
    1280                 async_answer_0(rid, rc);
    1281                 return;
    1282         }
    1283         if (!fn) {
    1284                 async_answer_0(rid, ENOENT);
    1285                 return;
    1286         }
     1228        if (rc != EOK)
     1229                return rc;
     1230        if (!fn)
     1231                return ENOENT;
    12871232        nodep = FAT_NODE(fn);
    12881233       
     
    12921237                (void) fat_node_put(fn);
    12931238                async_answer_0(callid, EINVAL);
    1294                 async_answer_0(rid, EINVAL);
    1295                 return;
     1239                return EINVAL;
    12961240        }
    12971241
     
    13211265                        (void) fat_node_put(fn);
    13221266                        async_answer_0(callid, rc);
    1323                         async_answer_0(rid, rc);
    1324                         return;
     1267                        return rc;
    13251268                }
    13261269                rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags);
     
    13281271                        (void) fat_node_put(fn);
    13291272                        async_answer_0(callid, rc);
    1330                         async_answer_0(rid, rc);
    1331                         return;
     1273                        return rc;
    13321274                }
    13331275                (void) async_data_write_finalize(callid,
     
    13371279                if (rc != EOK) {
    13381280                        (void) fat_node_put(fn);
    1339                         async_answer_0(rid, rc);
    1340                         return;
     1281                        return rc;
    13411282                }
    13421283                if (pos + bytes > nodep->size) {
     
    13441285                        nodep->dirty = true;    /* need to sync node */
    13451286                }
    1346                 size = nodep->size;
     1287                *wbytes = bytes;
     1288                *nsize = nodep->size;
    13471289                rc = fat_node_put(fn);
    1348                 async_answer_2(rid, rc, bytes, nodep->size);
    1349                 return;
     1290                return rc;
    13501291        } else {
    13511292                /*
     
    13631304                        (void) fat_node_put(fn);
    13641305                        async_answer_0(callid, rc);
    1365                         async_answer_0(rid, rc);
    1366                         return;
     1306                        return rc;
    13671307                }
    13681308                /* zero fill any gaps */
     
    13721312                        (void) fat_node_put(fn);
    13731313                        async_answer_0(callid, rc);
    1374                         async_answer_0(rid, rc);
    1375                         return;
     1314                        return rc;
    13761315                }
    13771316                rc = _fat_block_get(&b, bs, devmap_handle, lcl, NULL,
     
    13811320                        (void) fat_node_put(fn);
    13821321                        async_answer_0(callid, rc);
    1383                         async_answer_0(rid, rc);
    1384                         return;
     1322                        return rc;
    13851323                }
    13861324                (void) async_data_write_finalize(callid,
     
    13911329                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    13921330                        (void) fat_node_put(fn);
    1393                         async_answer_0(rid, rc);
    1394                         return;
     1331                        return rc;
    13951332                }
    13961333                /*
     
    14021339                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    14031340                        (void) fat_node_put(fn);
    1404                         async_answer_0(rid, rc);
    1405                         return;
    1406                 }
    1407                 nodep->size = size = pos + bytes;
     1341                        return rc;
     1342                }
     1343                *nsize = nodep->size = pos + bytes;
     1344                rc = fat_node_put(fn);
    14081345                nodep->dirty = true;            /* need to sync node */
    1409                 rc = fat_node_put(fn);
    1410                 async_answer_2(rid, rc, bytes, size);
    1411                 return;
    1412         }
    1413 }
    1414 
    1415 void fat_truncate(ipc_callid_t rid, ipc_call_t *request)
    1416 {
    1417         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1418         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1419         aoff64_t size =
    1420             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     1346                *wbytes = bytes;
     1347                return rc;
     1348        }
     1349}
     1350
     1351static int
     1352fat_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size)
     1353{
    14211354        fs_node_t *fn;
    14221355        fat_node_t *nodep;
     
    14251358
    14261359        rc = fat_node_get(&fn, devmap_handle, index);
    1427         if (rc != EOK) {
    1428                 async_answer_0(rid, rc);
    1429                 return;
    1430         }
    1431         if (!fn) {
    1432                 async_answer_0(rid, ENOENT);
    1433                 return;
    1434         }
     1360        if (rc != EOK)
     1361                return rc;
     1362        if (!fn)
     1363                return ENOENT;
    14351364        nodep = FAT_NODE(fn);
    14361365
     
    14761405out:
    14771406        fat_node_put(fn);
    1478         async_answer_0(rid, rc);
    1479         return;
    1480 }
    1481 
    1482 void fat_close(ipc_callid_t rid, ipc_call_t *request)
    1483 {
    1484         async_answer_0(rid, EOK);
    1485 }
    1486 
    1487 void fat_destroy(ipc_callid_t rid, ipc_call_t *request)
    1488 {
    1489         devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
    1490         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
     1407        return rc;
     1408}
     1409
     1410static int fat_close(devmap_handle_t devmap_handle, fs_index_t index)
     1411{
     1412        return EOK;
     1413}
     1414
     1415static int fat_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     1416{
    14911417        fs_node_t *fn;
    14921418        fat_node_t *nodep;
     
    14941420
    14951421        rc = fat_node_get(&fn, devmap_handle, index);
    1496         if (rc != EOK) {
    1497                 async_answer_0(rid, rc);
    1498                 return;
    1499         }
    1500         if (!fn) {
    1501                 async_answer_0(rid, ENOENT);
    1502                 return;
    1503         }
     1422        if (rc != EOK)
     1423                return rc;
     1424        if (!fn)
     1425                return ENOENT;
    15041426
    15051427        nodep = FAT_NODE(fn);
     
    15111433
    15121434        rc = fat_destroy_node(fn);
    1513         async_answer_0(rid, rc);
    1514 }
    1515 
    1516 void fat_open_node(ipc_callid_t rid, ipc_call_t *request)
    1517 {
    1518         libfs_open_node(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1519 }
    1520 
    1521 void fat_stat(ipc_callid_t rid, ipc_call_t *request)
    1522 {
    1523         libfs_stat(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1524 }
    1525 
    1526 void fat_sync(ipc_callid_t rid, ipc_call_t *request)
    1527 {
    1528         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1529         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1530        
     1435        return rc;
     1436}
     1437
     1438static int fat_sync(devmap_handle_t devmap_handle, fs_index_t index)
     1439{
    15311440        fs_node_t *fn;
    15321441        int rc = fat_node_get(&fn, devmap_handle, index);
    1533         if (rc != EOK) {
    1534                 async_answer_0(rid, rc);
    1535                 return;
    1536         }
    1537         if (!fn) {
    1538                 async_answer_0(rid, ENOENT);
    1539                 return;
    1540         }
     1442        if (rc != EOK)
     1443                return rc;
     1444        if (!fn)
     1445                return ENOENT;
    15411446       
    15421447        fat_node_t *nodep = FAT_NODE(fn);
     
    15461451       
    15471452        fat_node_put(fn);
    1548         async_answer_0(rid, rc);
    1549 }
     1453        return rc;
     1454}
     1455
     1456vfs_out_ops_t fat_ops = {
     1457        .mounted = fat_mounted,
     1458        .unmounted = fat_unmounted,
     1459        .read = fat_read,
     1460        .write = fat_write,
     1461        .truncate = fat_truncate,
     1462        .close = fat_close,
     1463        .destroy = fat_destroy,
     1464        .sync = fat_sync,
     1465};
    15501466
    15511467/**
Note: See TracChangeset for help on using the changeset viewer.