Ignore:
File:
1 edited

Legend:

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

    r4f30222 r9f64c1e  
    785785                        case FAT_DENTRY_SKIP:
    786786                        case FAT_DENTRY_FREE:
     787                        case FAT_DENTRY_VOLLABEL:
    787788                                continue;
    788789                        case FAT_DENTRY_LAST:
     
    909910};
    910911
    911 /*
    912  * FAT VFS_OUT operations.
    913  */
    914 
    915 static int fat_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
     912static int fat_fs_open(service_id_t service_id, enum cache_mode cmode,
     913    fs_node_t **rrfn, fat_idx_t **rridxp)
    916914{
    917915        fat_bs_t *bs;
     
    939937
    940938        /* Initialize the block cache */
    941         rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, CACHE_MODE_WB);
     939        rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
    942940        if (rc != EOK) {
    943941                block_fini(service_id);
     
    947945        /* Do some simple sanity checks on the file system. */
    948946        rc = fat_sanity_check(bs, service_id);
    949 
     947        if (rc != EOK) {
     948                (void) block_cache_fini(service_id);
     949                block_fini(service_id);
     950                return rc;
     951        }
     952
     953        rc = fat_idx_init_by_service_id(service_id);
     954        if (rc != EOK) {
     955                (void) block_cache_fini(service_id);
     956                block_fini(service_id);
     957                return rc;
     958        }
     959
     960        /* Initialize the root node. */
     961        fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
     962        if (!rfn) {
     963                (void) block_cache_fini(service_id);
     964                block_fini(service_id);
     965                fat_idx_fini_by_service_id(service_id);
     966                return ENOMEM;
     967        }
     968
     969        fs_node_initialize(rfn);
     970        fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
     971        if (!rootp) {
     972                free(rfn);
     973                (void) block_cache_fini(service_id);
     974                block_fini(service_id);
     975                fat_idx_fini_by_service_id(service_id);
     976                return ENOMEM;
     977        }
     978        fat_node_initialize(rootp);
     979
     980        fat_idx_t *ridxp = fat_idx_get_by_pos(service_id, FAT_CLST_ROOTPAR, 0);
     981        if (!ridxp) {
     982                free(rfn);
     983                free(rootp);
     984                (void) block_cache_fini(service_id);
     985                block_fini(service_id);
     986                fat_idx_fini_by_service_id(service_id);
     987                return ENOMEM;
     988        }
     989        assert(ridxp->index == 0);
     990        /* ridxp->lock held */
     991
     992        rootp->type = FAT_DIRECTORY;
     993        rootp->firstc = FAT_ROOT_CLST(bs);
     994        rootp->refcnt = 1;
     995        rootp->lnkcnt = 0;      /* FS root is not linked */
     996
     997        if (FAT_IS_FAT32(bs)) {
     998                uint32_t clusters;
     999                rc = fat_clusters_get(&clusters, bs, service_id, rootp->firstc);
     1000                if (rc != EOK) {
     1001                        fibril_mutex_unlock(&ridxp->lock);
     1002                        free(rfn);
     1003                        free(rootp);
     1004                        (void) block_cache_fini(service_id);
     1005                        block_fini(service_id);
     1006                        fat_idx_fini_by_service_id(service_id);
     1007                        return ENOTSUP;
     1008                }
     1009                rootp->size = BPS(bs) * SPC(bs) * clusters;
     1010        } else
     1011                rootp->size = RDE(bs) * sizeof(fat_dentry_t);
     1012
     1013        rootp->idx = ridxp;
     1014        ridxp->nodep = rootp;
     1015        rootp->bp = rfn;
     1016        rfn->data = rootp;
     1017
     1018        fibril_mutex_unlock(&ridxp->lock);
     1019
     1020        *rrfn = rfn;
     1021        *rridxp = ridxp;
     1022
     1023        return EOK;
     1024}
     1025
     1026static void fat_fs_close(service_id_t service_id, fs_node_t *rfn)
     1027{
     1028        free(rfn->data);
     1029        free(rfn);
    9501030        (void) block_cache_fini(service_id);
    9511031        block_fini(service_id);
    952 
    953         return rc;
     1032        fat_idx_fini_by_service_id(service_id);
     1033}
     1034
     1035/*
     1036 * FAT VFS_OUT operations.
     1037 */
     1038
     1039static int fat_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
     1040{
     1041        fat_idx_t *ridxp;
     1042        fs_node_t *rfn;
     1043        fat_node_t *nodep;
     1044        fat_directory_t di;
     1045        char label[FAT_VOLLABEL_LEN + 1];
     1046        int rc;
     1047
     1048        rc = fat_fs_open(service_id, CACHE_MODE_WT, &rfn, &ridxp);
     1049        if (rc != EOK)
     1050                return rc;
     1051
     1052        nodep = FAT_NODE(rfn);
     1053
     1054        rc = fat_directory_open(nodep, &di);
     1055        if (rc != EOK) {
     1056                fat_fs_close(service_id, rfn);
     1057                return rc;
     1058        }
     1059
     1060        rc = fat_directory_vollabel_get(&di, label);
     1061        if (rc != EOK) {
     1062                if (rc != ENOENT) {
     1063                        fat_fs_close(service_id, rfn);
     1064                        return rc;
     1065                }
     1066
     1067                label[0] = '\0';
     1068        }
     1069
     1070        str_cpy(info->label, FS_LABEL_MAXLEN + 1, label);
     1071
     1072        fat_directory_close(&di);
     1073        fat_fs_close(service_id, rfn);
     1074
     1075        return EOK;
    9541076}
    9551077
     
    9591081{
    9601082        enum cache_mode cmode = CACHE_MODE_WB;
    961         fat_bs_t *bs;
    9621083        fat_instance_t *instance;
     1084        fat_idx_t *ridxp;
     1085        fs_node_t *rfn;
    9631086        int rc;
    9641087
     
    9781101        }
    9791102
    980         /* initialize libblock */
    981         rc = block_init(service_id, BS_SIZE);
     1103        rc = fat_fs_open(service_id, cmode, &rfn, &ridxp);
    9821104        if (rc != EOK) {
    9831105                free(instance);
     
    9851107        }
    9861108
    987         /* prepare the boot block */
    988         rc = block_bb_read(service_id, BS_BLOCK);
    989         if (rc != EOK) {
    990                 free(instance);
    991                 block_fini(service_id);
    992                 return rc;
    993         }
    994 
    995         /* get the buffer with the boot sector */
    996         bs = block_bb_get(service_id);
    997        
    998         if (BPS(bs) != BS_SIZE) {
    999                 free(instance);
    1000                 block_fini(service_id);
    1001                 return ENOTSUP;
    1002         }
    1003 
    1004         /* Initialize the block cache */
    1005         rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
    1006         if (rc != EOK) {
    1007                 free(instance);
    1008                 block_fini(service_id);
    1009                 return rc;
    1010         }
    1011 
    1012         /* Do some simple sanity checks on the file system. */
    1013         rc = fat_sanity_check(bs, service_id);
    1014         if (rc != EOK) {
    1015                 free(instance);
    1016                 (void) block_cache_fini(service_id);
    1017                 block_fini(service_id);
    1018                 return rc;
    1019         }
    1020 
    1021         rc = fat_idx_init_by_service_id(service_id);
    1022         if (rc != EOK) {
    1023                 free(instance);
    1024                 (void) block_cache_fini(service_id);
    1025                 block_fini(service_id);
    1026                 return rc;
    1027         }
    1028 
    1029         /* Initialize the root node. */
    1030         fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
    1031         if (!rfn) {
    1032                 free(instance);
    1033                 (void) block_cache_fini(service_id);
    1034                 block_fini(service_id);
    1035                 fat_idx_fini_by_service_id(service_id);
    1036                 return ENOMEM;
    1037         }
    1038 
    1039         fs_node_initialize(rfn);
    1040         fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
    1041         if (!rootp) {
    1042                 free(instance);
    1043                 free(rfn);
    1044                 (void) block_cache_fini(service_id);
    1045                 block_fini(service_id);
    1046                 fat_idx_fini_by_service_id(service_id);
    1047                 return ENOMEM;
    1048         }
    1049         fat_node_initialize(rootp);
    1050 
    1051         fat_idx_t *ridxp = fat_idx_get_by_pos(service_id, FAT_CLST_ROOTPAR, 0);
    1052         if (!ridxp) {
    1053                 free(instance);
    1054                 free(rfn);
    1055                 free(rootp);
    1056                 (void) block_cache_fini(service_id);
    1057                 block_fini(service_id);
    1058                 fat_idx_fini_by_service_id(service_id);
    1059                 return ENOMEM;
    1060         }
    1061         assert(ridxp->index == 0);
    1062         /* ridxp->lock held */
    1063 
    1064         rootp->type = FAT_DIRECTORY;
    1065         rootp->firstc = FAT_ROOT_CLST(bs);
    1066         rootp->refcnt = 1;
    1067         rootp->lnkcnt = 0;      /* FS root is not linked */
    1068 
    1069         if (FAT_IS_FAT32(bs)) {
    1070                 uint32_t clusters;
    1071                 rc = fat_clusters_get(&clusters, bs, service_id, rootp->firstc);
    1072                 if (rc != EOK) {
    1073                         fibril_mutex_unlock(&ridxp->lock);
    1074                         free(instance);
    1075                         free(rfn);
    1076                         free(rootp);
    1077                         (void) block_cache_fini(service_id);
    1078                         block_fini(service_id);
    1079                         fat_idx_fini_by_service_id(service_id);
    1080                         return ENOTSUP;
    1081                 }
    1082                 rootp->size = BPS(bs) * SPC(bs) * clusters;
    1083         } else
    1084                 rootp->size = RDE(bs) * sizeof(fat_dentry_t);
     1109        fibril_mutex_lock(&ridxp->lock);
    10851110
    10861111        rc = fs_instance_create(service_id, instance);
    10871112        if (rc != EOK) {
    10881113                fibril_mutex_unlock(&ridxp->lock);
     1114                fat_fs_close(service_id, rfn);
    10891115                free(instance);
    1090                 free(rfn);
    1091                 free(rootp);
    1092                 (void) block_cache_fini(service_id);
    1093                 block_fini(service_id);
    1094                 fat_idx_fini_by_service_id(service_id);
    1095                 return rc;
    1096         }
    1097 
    1098         rootp->idx = ridxp;
    1099         ridxp->nodep = rootp;
    1100         rootp->bp = rfn;
    1101         rfn->data = rootp;
     1116                return rc;
     1117        }
    11021118
    11031119        fibril_mutex_unlock(&ridxp->lock);
    11041120
    11051121        *index = ridxp->index;
    1106         *size = rootp->size;
     1122        *size = FAT_NODE(rfn)->size;
    11071123
    11081124        return EOK;
     
    11741190         */
    11751191        (void) fat_node_put(fn);
    1176         (void) fat_node_put(fn);
    11771192
    11781193        /*
     
    11821197         */
    11831198        (void) fat_node_fini_by_service_id(service_id);
    1184         fat_idx_fini_by_service_id(service_id);
    1185         (void) block_cache_fini(service_id);
    1186         block_fini(service_id);
     1199        fat_fs_close(service_id, fn);
    11871200
    11881201        void *data;
Note: See TracChangeset for help on using the changeset viewer.