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