Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/exfat/exfat_ops.c

    r18902ca6 r4f30222  
    595595int exfat_node_put(fs_node_t *fn)
    596596{
    597         if (fn == NULL)
    598                 return EOK;
    599 
    600597        exfat_node_t *nodep = EXFAT_NODE(fn);
    601598        bool destroy = false;
     
    935932int exfat_free_block_count(service_id_t service_id, uint64_t *count)
    936933{
    937         fs_node_t *node = NULL;
     934        fs_node_t *node;
    938935        exfat_node_t *bmap_node;
    939936        exfat_bs_t *bs;
     
    948945
    949946        bs = block_bb_get(service_id);
     947        node = NULL;
    950948        rc = exfat_bitmap_get(&node, service_id);
    951949        if (rc != EOK)
     
    10151013};
    10161014
    1017 static int exfat_fs_open(service_id_t service_id, enum cache_mode cmode,
    1018     fs_node_t **rrfn, exfat_idx_t **rridxp, vfs_fs_probe_info_t *info)
    1019 {
    1020         int rc;
    1021         exfat_node_t *rootp = NULL, *bitmapp = NULL, *uctablep = NULL;
    1022         exfat_bs_t *bs;
    1023 
    1024         /* initialize libblock */
    1025         rc = block_init(service_id, BS_SIZE);
    1026         if (rc != EOK)
    1027                 return rc;
    1028 
    1029         /* prepare the boot block */
    1030         rc = block_bb_read(service_id, BS_BLOCK);
    1031         if (rc != EOK) {
    1032                 block_fini(service_id);
    1033                 return rc;
    1034         }
    1035 
    1036         /* get the buffer with the boot sector */
    1037         bs = block_bb_get(service_id);
    1038 
    1039         /* Do some simple sanity checks on the file system. */
    1040         rc = exfat_sanity_check(bs);
    1041         if (rc != EOK) {
    1042                 (void) block_cache_fini(service_id);
    1043                 block_fini(service_id);
    1044                 return rc;
    1045         }
    1046 
    1047         /* Initialize the block cache */
    1048         rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
    1049         if (rc != EOK) {
    1050                 block_fini(service_id);
    1051                 return rc;
    1052         }
    1053 
    1054         rc = exfat_idx_init_by_service_id(service_id);
    1055         if (rc != EOK) {
    1056                 (void) block_cache_fini(service_id);
    1057                 block_fini(service_id);
    1058                 return rc;
    1059         }
    1060 
    1061         /* Initialize the root node. */
    1062         rc = exfat_node_get_new_by_pos(&rootp, service_id, EXFAT_ROOT_PAR,
    1063             EXFAT_ROOT_POS);
    1064         if (rc!=EOK) {
    1065                 (void) block_cache_fini(service_id);
    1066                 block_fini(service_id);
    1067                 exfat_idx_fini_by_service_id(service_id);
    1068                 return ENOMEM;
    1069         }
    1070         assert(rootp->idx->index == EXFAT_ROOT_IDX);
    1071 
    1072         rootp->type = EXFAT_DIRECTORY;
    1073         rootp->firstc = ROOT_FC(bs);
    1074         rootp->fragmented = true;
    1075         rootp->refcnt = 1;
    1076         rootp->lnkcnt = 0;      /* FS root is not linked */
    1077 
    1078         uint32_t clusters;
    1079         rc = exfat_clusters_get(&clusters, bs, service_id, rootp->firstc);
    1080         if (rc != EOK) {
    1081                 free(rootp);
    1082                 (void) block_cache_fini(service_id);
    1083                 block_fini(service_id);
    1084                 exfat_idx_fini_by_service_id(service_id);
    1085                 return ENOTSUP;
    1086         }
    1087         rootp->size = BPS(bs) * SPC(bs) * clusters;
    1088         fibril_mutex_unlock(&rootp->idx->lock);
    1089 
    1090         /* Open root directory and looking for Bitmap and UC-Table */
    1091         exfat_directory_t di;
    1092         exfat_dentry_t *de;
    1093         rc = exfat_directory_open(rootp, &di);
    1094         if (rc != EOK) {
    1095                 free(rootp);
    1096                 (void) block_cache_fini(service_id);
    1097                 block_fini(service_id);
    1098                 exfat_idx_fini_by_service_id(service_id);
    1099                 return ENOTSUP;
    1100         }
    1101 
    1102         /* Initialize the bitmap node. */
    1103         rc = exfat_directory_find(&di, EXFAT_DENTRY_BITMAP, &de);
    1104         if (rc != EOK) {
    1105                 free(rootp);
    1106                 (void) block_cache_fini(service_id);
    1107                 block_fini(service_id);
    1108                 exfat_idx_fini_by_service_id(service_id);
    1109                 return ENOTSUP;
    1110         }
    1111 
    1112         rc = exfat_node_get_new_by_pos(&bitmapp, service_id, rootp->firstc,
    1113             di.pos);
    1114         if (rc != EOK) {
    1115                 free(rootp);
    1116                 (void) block_cache_fini(service_id);
    1117                 block_fini(service_id);
    1118                 exfat_idx_fini_by_service_id(service_id);
    1119                 return ENOMEM;
    1120         }
    1121         assert(bitmapp->idx->index == EXFAT_BITMAP_IDX);
    1122         fibril_mutex_unlock(&bitmapp->idx->lock);
    1123 
    1124         bitmapp->type = EXFAT_BITMAP;
    1125         bitmapp->firstc = uint32_t_le2host(de->bitmap.firstc);
    1126         bitmapp->fragmented = true;
    1127         bitmapp->idx->parent_fragmented = true;
    1128         bitmapp->refcnt = 1;
    1129         bitmapp->lnkcnt = 0;
    1130         bitmapp->size = uint64_t_le2host(de->bitmap.size);
    1131 
    1132         /* Initialize the uctable node. */
    1133         rc = exfat_directory_seek(&di, 0);
    1134         if (rc != EOK) {
    1135                 free(rootp);
    1136                 free(bitmapp);
    1137                 (void) block_cache_fini(service_id);
    1138                 block_fini(service_id);
    1139                 exfat_idx_fini_by_service_id(service_id);
    1140                 return ENOTSUP;
    1141         }
    1142 
    1143         rc = exfat_directory_find(&di, EXFAT_DENTRY_UCTABLE, &de);
    1144         if (rc != EOK) {
    1145                 free(rootp);
    1146                 free(bitmapp);
    1147                 (void) block_cache_fini(service_id);
    1148                 block_fini(service_id);
    1149                 exfat_idx_fini_by_service_id(service_id);
    1150                 return ENOTSUP;
    1151         }
    1152 
    1153         rc = exfat_node_get_new_by_pos(&uctablep, service_id, rootp->firstc,
    1154             di.pos);
    1155         if (rc != EOK) {
    1156                 free(rootp);
    1157                 free(bitmapp);
    1158                 (void) block_cache_fini(service_id);
    1159                 block_fini(service_id);
    1160                 exfat_idx_fini_by_service_id(service_id);
    1161                 return ENOMEM;
    1162         }
    1163         assert(uctablep->idx->index == EXFAT_UCTABLE_IDX);
    1164         fibril_mutex_unlock(&uctablep->idx->lock);
    1165 
    1166         uctablep->type = EXFAT_UCTABLE;
    1167         uctablep->firstc = uint32_t_le2host(de->uctable.firstc);
    1168         uctablep->fragmented = true;
    1169         uctablep->idx->parent_fragmented = true;
    1170         uctablep->refcnt = 1;
    1171         uctablep->lnkcnt = 0;
    1172         uctablep->size = uint64_t_le2host(de->uctable.size);
    1173 
    1174         if (info != NULL) {
    1175                 /* Read volume label. */
    1176                 rc = exfat_directory_read_vollabel(&di, info->label,
    1177                     FS_LABEL_MAXLEN + 1);
    1178                 if (rc != EOK) {
    1179                         free(rootp);
    1180                         free(bitmapp);
    1181                         free(uctablep);
    1182                         (void) block_cache_fini(service_id);
    1183                         block_fini(service_id);
    1184                         exfat_idx_fini_by_service_id(service_id);
    1185                     return ENOTSUP;
    1186                 }
    1187         }
    1188 
    1189         rc = exfat_directory_close(&di);
    1190         if (rc != EOK) {
    1191                 free(rootp);
    1192                 free(bitmapp);
    1193                 free(uctablep);
    1194                 (void) block_cache_fini(service_id);
    1195                 block_fini(service_id);
    1196                 exfat_idx_fini_by_service_id(service_id);
    1197                 return ENOMEM;
    1198         }
    1199 
    1200         /* exfat_fsinfo(bs, service_id); */
    1201 
    1202         *rrfn = FS_NODE(rootp);
    1203         *rridxp = rootp->idx;
    1204 
    1205         if (info != NULL) {
    1206 //              str_cpy(info->label, FS_LABEL_MAXLEN + 1, label);
    1207         }
    1208 
    1209         return EOK;
    1210 }
    1211 
    1212 static void exfat_fs_close(service_id_t service_id, fs_node_t *rfn)
    1213 {
    1214         /*
    1215          * Put the root node and force it to the FAT free node list.
    1216          */
    1217         (void) exfat_node_put(rfn);
    1218         (void) exfat_node_put(rfn);
    1219 
    1220         /*
    1221          * Perform cleanup of the node structures, index structures and
    1222          * associated data. Write back this file system's dirty blocks and
    1223          * stop using libblock for this instance.
    1224          */
    1225         (void) exfat_node_fini_by_service_id(service_id);
    1226         exfat_idx_fini_by_service_id(service_id);
    1227         (void) block_cache_fini(service_id);
    1228         block_fini(service_id);
    1229 }
    1230 
    12311015
    12321016/*
     
    12701054{
    12711055        int rc;
    1272         exfat_idx_t *ridxp;
    1273         fs_node_t *rfn;
    1274 
    1275         rc = exfat_fs_open(service_id, CACHE_MODE_WT, &rfn, &ridxp, info);
    1276         if (rc != EOK)
    1277                 return rc;
    1278 
    1279         exfat_fs_close(service_id, rfn);
    1280         return EOK;
     1056        exfat_bs_t *bs;
     1057
     1058        /* initialize libblock */
     1059        rc = block_init(service_id, BS_SIZE);
     1060        if (rc != EOK)
     1061                return rc;
     1062
     1063        /* prepare the boot block */
     1064        rc = block_bb_read(service_id, BS_BLOCK);
     1065        if (rc != EOK) {
     1066                block_fini(service_id);
     1067                return rc;
     1068        }
     1069
     1070        /* get the buffer with the boot sector */
     1071        bs = block_bb_get(service_id);
     1072
     1073        /* Do some simple sanity checks on the file system. */
     1074        rc = exfat_sanity_check(bs);
     1075
     1076        (void) block_cache_fini(service_id);
     1077        block_fini(service_id);
     1078        return rc;
    12811079}
    12821080
     
    12861084{
    12871085        int rc;
     1086        exfat_node_t *rootp = NULL, *bitmapp = NULL, *uctablep = NULL;
    12881087        enum cache_mode cmode;
    1289         exfat_idx_t *ridxp;
    1290         fs_node_t *rfn;
     1088        exfat_bs_t *bs;
    12911089
    12921090        /* Check for option enabling write through. */
     
    12961094                cmode = CACHE_MODE_WB;
    12971095
    1298         rc = exfat_fs_open(service_id, cmode, &rfn, &ridxp, NULL);
    1299         if (rc != EOK)
    1300                 return rc;
    1301 
    1302         *index = ridxp->index;
    1303         *size = EXFAT_NODE(rfn)->size;
    1304 
     1096        /* initialize libblock */
     1097        rc = block_init(service_id, BS_SIZE);
     1098        if (rc != EOK)
     1099                return rc;
     1100
     1101        /* prepare the boot block */
     1102        rc = block_bb_read(service_id, BS_BLOCK);
     1103        if (rc != EOK) {
     1104                block_fini(service_id);
     1105                return rc;
     1106        }
     1107
     1108        /* get the buffer with the boot sector */
     1109        bs = block_bb_get(service_id);
     1110
     1111        /* Do some simple sanity checks on the file system. */
     1112        rc = exfat_sanity_check(bs);
     1113        if (rc != EOK) {
     1114                (void) block_cache_fini(service_id);
     1115                block_fini(service_id);
     1116                return rc;
     1117        }
     1118
     1119        /* Initialize the block cache */
     1120        rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
     1121        if (rc != EOK) {
     1122                block_fini(service_id);
     1123                return rc;
     1124        }
     1125
     1126        rc = exfat_idx_init_by_service_id(service_id);
     1127        if (rc != EOK) {
     1128                (void) block_cache_fini(service_id);
     1129                block_fini(service_id);
     1130                return rc;
     1131        }
     1132
     1133        /* Initialize the root node. */
     1134        rc = exfat_node_get_new_by_pos(&rootp, service_id, EXFAT_ROOT_PAR,
     1135            EXFAT_ROOT_POS);
     1136        if (rc!=EOK) {
     1137                (void) block_cache_fini(service_id);
     1138                block_fini(service_id);
     1139                exfat_idx_fini_by_service_id(service_id);
     1140                return ENOMEM;
     1141        }
     1142        assert(rootp->idx->index == EXFAT_ROOT_IDX);
     1143
     1144        rootp->type = EXFAT_DIRECTORY;
     1145        rootp->firstc = ROOT_FC(bs);
     1146        rootp->fragmented = true;
     1147        rootp->refcnt = 1;
     1148        rootp->lnkcnt = 0;      /* FS root is not linked */
     1149
     1150        uint32_t clusters;
     1151        rc = exfat_clusters_get(&clusters, bs, service_id, rootp->firstc);
     1152        if (rc != EOK) {
     1153                free(rootp);
     1154                (void) block_cache_fini(service_id);
     1155                block_fini(service_id);
     1156                exfat_idx_fini_by_service_id(service_id);
     1157                return ENOTSUP;
     1158        }
     1159        rootp->size = BPS(bs) * SPC(bs) * clusters;
     1160        fibril_mutex_unlock(&rootp->idx->lock);
     1161
     1162        /* Open root directory and looking for Bitmap and UC-Table */
     1163        exfat_directory_t di;
     1164        exfat_dentry_t *de;
     1165        rc = exfat_directory_open(rootp, &di);
     1166        if (rc != EOK) {
     1167                free(rootp);
     1168                (void) block_cache_fini(service_id);
     1169                block_fini(service_id);
     1170                exfat_idx_fini_by_service_id(service_id);
     1171                return ENOTSUP;
     1172        }
     1173
     1174        /* Initialize the bitmap node. */
     1175        rc = exfat_directory_find(&di, EXFAT_DENTRY_BITMAP, &de);
     1176        if (rc != EOK) {
     1177                free(rootp);
     1178                (void) block_cache_fini(service_id);
     1179                block_fini(service_id);
     1180                exfat_idx_fini_by_service_id(service_id);
     1181                return ENOTSUP;
     1182        }
     1183
     1184        rc = exfat_node_get_new_by_pos(&bitmapp, service_id, rootp->firstc,
     1185            di.pos);
     1186        if (rc != EOK) {
     1187                free(rootp);
     1188                (void) block_cache_fini(service_id);
     1189                block_fini(service_id);
     1190                exfat_idx_fini_by_service_id(service_id);
     1191                return ENOMEM;
     1192        }
     1193        assert(bitmapp->idx->index == EXFAT_BITMAP_IDX);
     1194        fibril_mutex_unlock(&bitmapp->idx->lock);
     1195
     1196        bitmapp->type = EXFAT_BITMAP;
     1197        bitmapp->firstc = uint32_t_le2host(de->bitmap.firstc);
     1198        bitmapp->fragmented = true;
     1199        bitmapp->idx->parent_fragmented = true;
     1200        bitmapp->refcnt = 1;
     1201        bitmapp->lnkcnt = 0;
     1202        bitmapp->size = uint64_t_le2host(de->bitmap.size);
     1203
     1204        /* Initialize the uctable node. */
     1205        rc = exfat_directory_seek(&di, 0);
     1206        if (rc != EOK) {
     1207                free(rootp);
     1208                free(bitmapp);
     1209                (void) block_cache_fini(service_id);
     1210                block_fini(service_id);
     1211                exfat_idx_fini_by_service_id(service_id);
     1212                return ENOTSUP;
     1213        }
     1214
     1215        rc = exfat_directory_find(&di, EXFAT_DENTRY_UCTABLE, &de);
     1216        if (rc != EOK) {
     1217                free(rootp);
     1218                free(bitmapp);
     1219                (void) block_cache_fini(service_id);
     1220                block_fini(service_id);
     1221                exfat_idx_fini_by_service_id(service_id);
     1222                return ENOTSUP;
     1223        }
     1224
     1225        rc = exfat_node_get_new_by_pos(&uctablep, service_id, rootp->firstc,
     1226            di.pos);
     1227        if (rc != EOK) {
     1228                free(rootp);
     1229                free(bitmapp);
     1230                (void) block_cache_fini(service_id);
     1231                block_fini(service_id);
     1232                exfat_idx_fini_by_service_id(service_id);
     1233                return ENOMEM;
     1234        }
     1235        assert(uctablep->idx->index == EXFAT_UCTABLE_IDX);
     1236        fibril_mutex_unlock(&uctablep->idx->lock);
     1237
     1238        uctablep->type = EXFAT_UCTABLE;
     1239        uctablep->firstc = uint32_t_le2host(de->uctable.firstc);
     1240        uctablep->fragmented = true;
     1241        uctablep->idx->parent_fragmented = true;
     1242        uctablep->refcnt = 1;
     1243        uctablep->lnkcnt = 0;
     1244        uctablep->size = uint64_t_le2host(de->uctable.size);
     1245
     1246        rc = exfat_directory_close(&di);
     1247        if (rc != EOK) {
     1248                free(rootp);
     1249                free(bitmapp);
     1250                free(uctablep);
     1251                (void) block_cache_fini(service_id);
     1252                block_fini(service_id);
     1253                exfat_idx_fini_by_service_id(service_id);
     1254                return ENOMEM;
     1255        }
     1256
     1257        /* exfat_fsinfo(bs, service_id); */
     1258
     1259        *index = rootp->idx->index;
     1260        *size = rootp->size;
     1261       
    13051262        return EOK;
    13061263}
     
    13081265static int exfat_unmounted(service_id_t service_id)
    13091266{
    1310         fs_node_t *rfn;
    1311         int rc;
    1312 
    1313         rc = exfat_root_get(&rfn, service_id);
    1314         if (rc != EOK)
    1315                 return rc;
    1316 
    1317         exfat_fs_close(service_id, rfn);
     1267        fs_node_t *fn;
     1268        exfat_node_t *nodep;
     1269        int rc;
     1270
     1271        rc = exfat_root_get(&fn, service_id);
     1272        if (rc != EOK)
     1273                return rc;
     1274        nodep = EXFAT_NODE(fn);
     1275
     1276        /*
     1277         * We expect exactly two references on the root node. One for the
     1278         * fat_root_get() above and one created in fat_mounted().
     1279         */
     1280        if (nodep->refcnt != 2) {
     1281                (void) exfat_node_put(fn);
     1282                return EBUSY;
     1283        }
     1284
     1285        /*
     1286         * Put the root node and force it to the FAT free node list.
     1287         */
     1288        (void) exfat_node_put(fn);
     1289        (void) exfat_node_put(fn);
     1290
     1291        /*
     1292         * Perform cleanup of the node structures, index structures and
     1293         * associated data. Write back this file system's dirty blocks and
     1294         * stop using libblock for this instance.
     1295         */
     1296        (void) exfat_node_fini_by_service_id(service_id);
     1297        exfat_idx_fini_by_service_id(service_id);
     1298        (void) block_cache_fini(service_id);
     1299        block_fini(service_id);
     1300
    13181301        return EOK;
    13191302}
     
    13801363                        return ENOTSUP;
    13811364                }
    1382 
     1365                       
    13831366                aoff64_t spos = pos;
    13841367                char name[EXFAT_FILENAME_LEN + 1];
Note: See TracChangeset for help on using the changeset viewer.