Changeset 39b0a51 in mainline
- Timestamp:
- 2017-06-28T16:05:37Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ee50130
- Parents:
- 30eab78
- Location:
- uspace/srv/fs/fat
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_dentry.c
r30eab78 r39b0a51 180 180 } 181 181 182 void fat_dentry_vollabel_get(const fat_dentry_t *d, char *buf) 183 { 184 unsigned int i; 185 186 for (i = 0; i < FAT_NAME_LEN; i++) { 187 if (d->name[i] == FAT_PAD) 188 break; 189 190 if (d->name[i] == FAT_DENTRY_E5_ESC) 191 *buf++ = 0xe5; 192 else 193 *buf++ = d->name[i]; 194 } 195 196 for (i = 0; i < FAT_EXT_LEN; i++) { 197 if (d->ext[i] == FAT_PAD) { 198 *buf = '\0'; 199 return; 200 } 201 202 if (d->ext[i] == FAT_DENTRY_E5_ESC) 203 *buf++ = 0xe5; 204 else 205 *buf++ = d->ext[i]; 206 } 207 208 *buf = '\0'; 209 } 210 182 211 fat_dentry_clsf_t fat_classify_dentry(const fat_dentry_t *d) 183 212 { … … 191 220 if (d->attr & FAT_ATTR_VOLLABEL) { 192 221 /* volume label entry */ 193 return FAT_DENTRY_ SKIP;222 return FAT_DENTRY_VOLLABEL; 194 223 } 195 224 if (d->name[0] == FAT_DENTRY_ERASED) { -
uspace/srv/fs/fat/fat_dentry.h
r30eab78 r39b0a51 45 45 #define FAT_NAME_LEN 8 46 46 #define FAT_EXT_LEN 3 47 #define FAT_VOLLABEL_LEN 11 47 48 48 49 #define FAT_NAME_DOT ". " … … 98 99 FAT_DENTRY_FREE, 99 100 FAT_DENTRY_VALID, 100 FAT_DENTRY_LFN 101 FAT_DENTRY_LFN, 102 FAT_DENTRY_VOLLABEL 101 103 } fat_dentry_clsf_t; 102 104 … … 138 140 extern void fat_dentry_name_get(const fat_dentry_t *, char *); 139 141 extern void fat_dentry_name_set(fat_dentry_t *, const char *); 142 extern void fat_dentry_vollabel_get(const fat_dentry_t *, char *); 140 143 extern fat_dentry_clsf_t fat_classify_dentry(const fat_dentry_t *); 141 144 extern uint8_t fat_dentry_chksum(uint8_t *); -
uspace/srv/fs/fat/fat_directory.c
r30eab78 r39b0a51 223 223 *de = d; 224 224 return EOK; 225 default:226 225 case FAT_DENTRY_SKIP: 227 226 case FAT_DENTRY_FREE: 227 case FAT_DENTRY_VOLLABEL: 228 default: 228 229 long_entry_count = 0; 229 230 long_entry = false; … … 252 253 while (!flag && fat_directory_prev(di) == EOK) { 253 254 if (fat_directory_get(di, &d) == EOK && 254 fat_classify_dentry(d) == FAT_DENTRY_LFN && 255 fat_classify_dentry(d) == FAT_DENTRY_LFN && 255 256 checksum == FAT_LFN_CHKSUM(d)) { 256 257 if (FAT_IS_LFN(d)) … … 473 474 case FAT_DENTRY_LFN: 474 475 case FAT_DENTRY_SKIP: 476 case FAT_DENTRY_VOLLABEL: 475 477 default: 476 478 found = 0; … … 523 525 case FAT_DENTRY_LFN: 524 526 case FAT_DENTRY_SKIP: 527 case FAT_DENTRY_VOLLABEL: 525 528 case FAT_DENTRY_FREE: 526 529 break; 527 530 } 528 } while (fat_directory_next(di) == EOK); 531 } while (fat_directory_next(di) == EOK); 529 532 530 533 return false; 534 } 535 536 /** Find volume label entry in a directory. 537 * 538 * @return EOK on success, ENOENT if not found, EIO on I/O error 539 */ 540 int fat_directory_vollabel_get(fat_directory_t *di, char *label) 541 { 542 fat_dentry_t *d; 543 int rc; 544 545 fat_directory_seek(di, 0); 546 do { 547 rc = fat_directory_get(di, &d); 548 if (rc != EOK) 549 return EIO; 550 551 switch (fat_classify_dentry(d)) { 552 case FAT_DENTRY_VOLLABEL: 553 fat_dentry_vollabel_get(d, label); 554 return EOK; 555 default: 556 break; 557 } 558 } while (fat_directory_next(di) == EOK); 559 560 /* Not found */ 561 return ENOENT; 531 562 } 532 563 -
uspace/srv/fs/fat/fat_directory.h
r30eab78 r39b0a51 72 72 const char *); 73 73 extern int fat_directory_expand(fat_directory_t *); 74 extern int fat_directory_vollabel_get(fat_directory_t *, char *); 74 75 75 76 #endif -
uspace/srv/fs/fat/fat_ops.c
r30eab78 r39b0a51 785 785 case FAT_DENTRY_SKIP: 786 786 case FAT_DENTRY_FREE: 787 case FAT_DENTRY_VOLLABEL: 787 788 continue; 788 789 case FAT_DENTRY_LAST: … … 909 910 }; 910 911 911 /* 912 * FAT VFS_OUT operations. 913 */ 914 915 static int fat_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info) 912 static int fat_fs_open(service_id_t service_id, enum cache_mode cmode, 913 fs_node_t **rrfn, fat_idx_t **rridxp) 916 914 { 917 915 fat_bs_t *bs; … … 939 937 940 938 /* 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); 942 940 if (rc != EOK) { 943 941 block_fini(service_id); … … 947 945 /* Do some simple sanity checks on the file system. */ 948 946 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 1026 static void fat_fs_close(service_id_t service_id, fs_node_t *rfn) 1027 { 1028 free(rfn->data); 1029 free(rfn); 950 1030 (void) block_cache_fini(service_id); 951 1031 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 1039 static int fat_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info) 1040 { 1041 fat_bs_t *bs; 1042 fat_idx_t *ridxp; 1043 fs_node_t *rfn; 1044 fat_node_t *nodep; 1045 fat_directory_t di; 1046 char label[FAT_VOLLABEL_LEN + 1]; 1047 int i; 1048 int rc; 1049 1050 rc = fat_fs_open(service_id, CACHE_MODE_WT, &rfn, &ridxp); 1051 if (rc != EOK) 1052 return rc; 1053 1054 nodep = FAT_NODE(rfn); 1055 1056 rc = fat_directory_open(nodep, &di); 1057 if (rc != EOK) 1058 return rc; 1059 1060 rc = fat_directory_vollabel_get(&di, label); 1061 if (rc != EOK) { 1062 /* No label in root directory. Read label from the BS */ 1063 bs = block_bb_get(service_id); 1064 i = FAT_VOLLABEL_LEN; 1065 while (i > 0 && bs->label[i - 1] == FAT_PAD) 1066 --i; 1067 1068 /* XXX Deal with non-ASCII characters */ 1069 memcpy(label, bs->label, i); 1070 label[i] = '\0'; 1071 } 1072 1073 str_cpy(info->label, FS_LABEL_MAXLEN + 1, label); 1074 1075 fat_directory_close(&di); 1076 fat_fs_close(service_id, rfn); 1077 1078 return EOK; 954 1079 } 955 1080 … … 959 1084 { 960 1085 enum cache_mode cmode = CACHE_MODE_WB; 961 fat_bs_t *bs;962 1086 fat_instance_t *instance; 1087 fat_idx_t *ridxp; 1088 fs_node_t *rfn; 963 1089 int rc; 964 1090 … … 978 1104 } 979 1105 980 /* initialize libblock */ 981 rc = block_init(service_id, BS_SIZE); 1106 rc = fat_fs_open(service_id, cmode, &rfn, &ridxp); 982 1107 if (rc != EOK) { 983 1108 free(instance); … … 985 1110 } 986 1111 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); 1112 fibril_mutex_lock(&ridxp->lock); 1085 1113 1086 1114 rc = fs_instance_create(service_id, instance); 1087 1115 if (rc != EOK) { 1088 1116 fibril_mutex_unlock(&ridxp->lock); 1117 fat_fs_close(service_id, rfn); 1089 1118 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; 1119 return rc; 1120 } 1102 1121 1103 1122 fibril_mutex_unlock(&ridxp->lock); 1104 1123 1105 1124 *index = ridxp->index; 1106 *size = rootp->size;1125 *size = FAT_NODE(rfn)->size; 1107 1126 1108 1127 return EOK; … … 1174 1193 */ 1175 1194 (void) fat_node_put(fn); 1176 (void) fat_node_put(fn);1177 1195 1178 1196 /* … … 1182 1200 */ 1183 1201 (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); 1202 fat_fs_close(service_id, fn); 1187 1203 1188 1204 void *data;
Note:
See TracChangeset
for help on using the changeset viewer.