Changes in uspace/srv/fs/exfat/exfat_ops.c [4f30222:18902ca6] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/exfat/exfat_ops.c
r4f30222 r18902ca6 595 595 int exfat_node_put(fs_node_t *fn) 596 596 { 597 if (fn == NULL) 598 return EOK; 599 597 600 exfat_node_t *nodep = EXFAT_NODE(fn); 598 601 bool destroy = false; … … 932 935 int exfat_free_block_count(service_id_t service_id, uint64_t *count) 933 936 { 934 fs_node_t *node ;937 fs_node_t *node = NULL; 935 938 exfat_node_t *bmap_node; 936 939 exfat_bs_t *bs; … … 945 948 946 949 bs = block_bb_get(service_id); 947 node = NULL;948 950 rc = exfat_bitmap_get(&node, service_id); 949 951 if (rc != EOK) … … 1013 1015 }; 1014 1016 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 1015 1231 1016 1232 /* … … 1054 1270 { 1055 1271 int rc; 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; 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; 1079 1281 } 1080 1282 … … 1084 1286 { 1085 1287 int rc; 1086 exfat_node_t *rootp = NULL, *bitmapp = NULL, *uctablep = NULL;1087 1288 enum cache_mode cmode; 1088 exfat_bs_t *bs; 1289 exfat_idx_t *ridxp; 1290 fs_node_t *rfn; 1089 1291 1090 1292 /* Check for option enabling write through. */ … … 1094 1296 cmode = CACHE_MODE_WB; 1095 1297 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 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 1262 1305 return EOK; 1263 1306 } … … 1265 1308 static int exfat_unmounted(service_id_t service_id) 1266 1309 { 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 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); 1301 1318 return EOK; 1302 1319 } … … 1363 1380 return ENOTSUP; 1364 1381 } 1365 1382 1366 1383 aoff64_t spos = pos; 1367 1384 char name[EXFAT_FILENAME_LEN + 1];
Note:
See TracChangeset
for help on using the changeset viewer.