Changes in uspace/srv/fs/fat/fat_ops.c [9f64c1e:4f30222] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_ops.c
r9f64c1e r4f30222 785 785 case FAT_DENTRY_SKIP: 786 786 case FAT_DENTRY_FREE: 787 case FAT_DENTRY_VOLLABEL:788 787 continue; 789 788 case FAT_DENTRY_LAST: … … 910 909 }; 911 910 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 915 static int fat_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info) 914 916 { 915 917 fat_bs_t *bs; … … 937 939 938 940 /* 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); 940 942 if (rc != EOK) { 941 943 block_fini(service_id); … … 945 947 /* Do some simple sanity checks on the file system. */ 946 948 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 1030 950 (void) block_cache_fini(service_id); 1031 951 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; 1076 954 } 1077 955 … … 1081 959 { 1082 960 enum cache_mode cmode = CACHE_MODE_WB; 961 fat_bs_t *bs; 1083 962 fat_instance_t *instance; 1084 fat_idx_t *ridxp;1085 fs_node_t *rfn;1086 963 int rc; 1087 964 … … 1101 978 } 1102 979 1103 rc = fat_fs_open(service_id, cmode, &rfn, &ridxp); 980 /* initialize libblock */ 981 rc = block_init(service_id, BS_SIZE); 1104 982 if (rc != EOK) { 1105 983 free(instance); … … 1107 985 } 1108 986 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); 1110 1085 1111 1086 rc = fs_instance_create(service_id, instance); 1112 1087 if (rc != EOK) { 1113 1088 fibril_mutex_unlock(&ridxp->lock); 1114 fat_fs_close(service_id, rfn);1115 1089 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; 1118 1102 1119 1103 fibril_mutex_unlock(&ridxp->lock); 1120 1104 1121 1105 *index = ridxp->index; 1122 *size = FAT_NODE(rfn)->size;1106 *size = rootp->size; 1123 1107 1124 1108 return EOK; … … 1190 1174 */ 1191 1175 (void) fat_node_put(fn); 1176 (void) fat_node_put(fn); 1192 1177 1193 1178 /* … … 1197 1182 */ 1198 1183 (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); 1200 1187 1201 1188 void *data;
Note:
See TracChangeset
for help on using the changeset viewer.