Ignore:
File:
1 edited

Legend:

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

    r9f64c1e r4f30222  
    785785                        case FAT_DENTRY_SKIP:
    786786                        case FAT_DENTRY_FREE:
    787                         case FAT_DENTRY_VOLLABEL:
    788787                                continue;
    789788                        case FAT_DENTRY_LAST:
     
    910909};
    911910
    912 static int fat_fs_open(service_id_t service_id, enum cache_mode cmode,
    913     fs_node_t **rrfn, fat_idx_t **rridxp)
     911/*
     912 * FAT VFS_OUT operations.
     913 */
     914
     915static int fat_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
    914916{
    915917        fat_bs_t *bs;
     
    937939
    938940        /* Initialize the block cache */
    939         rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
     941        rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, CACHE_MODE_WB);
    940942        if (rc != EOK) {
    941943                block_fini(service_id);
     
    945947        /* Do some simple sanity checks on the file system. */
    946948        rc = fat_sanity_check(bs, service_id);
    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 
    1026 static void fat_fs_close(service_id_t service_id, fs_node_t *rfn)
    1027 {
    1028         free(rfn->data);
    1029         free(rfn);
     949
    1030950        (void) block_cache_fini(service_id);
    1031951        block_fini(service_id);
    1032         fat_idx_fini_by_service_id(service_id);
    1033 }
    1034 
    1035 /*
    1036  * FAT VFS_OUT operations.
    1037  */
    1038 
    1039 static 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;
     952
     953        return rc;
    1076954}
    1077955
     
    1081959{
    1082960        enum cache_mode cmode = CACHE_MODE_WB;
     961        fat_bs_t *bs;
    1083962        fat_instance_t *instance;
    1084         fat_idx_t *ridxp;
    1085         fs_node_t *rfn;
    1086963        int rc;
    1087964
     
    1101978        }
    1102979
    1103         rc = fat_fs_open(service_id, cmode, &rfn, &ridxp);
     980        /* initialize libblock */
     981        rc = block_init(service_id, BS_SIZE);
    1104982        if (rc != EOK) {
    1105983                free(instance);
     
    1107985        }
    1108986
    1109         fibril_mutex_lock(&ridxp->lock);
     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);
    11101085
    11111086        rc = fs_instance_create(service_id, instance);
    11121087        if (rc != EOK) {
    11131088                fibril_mutex_unlock(&ridxp->lock);
    1114                 fat_fs_close(service_id, rfn);
    11151089                free(instance);
    1116                 return rc;
    1117         }
     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;
    11181102
    11191103        fibril_mutex_unlock(&ridxp->lock);
    11201104
    11211105        *index = ridxp->index;
    1122         *size = FAT_NODE(rfn)->size;
     1106        *size = rootp->size;
    11231107
    11241108        return EOK;
     
    11901174         */
    11911175        (void) fat_node_put(fn);
     1176        (void) fat_node_put(fn);
    11921177
    11931178        /*
     
    11971182         */
    11981183        (void) fat_node_fini_by_service_id(service_id);
    1199         fat_fs_close(service_id, fn);
     1184        fat_idx_fini_by_service_id(service_id);
     1185        (void) block_cache_fini(service_id);
     1186        block_fini(service_id);
    12001187
    12011188        void *data;
Note: See TracChangeset for help on using the changeset viewer.