Changes in uspace/srv/fs/fat/fat_ops.c [4f30222:9f64c1e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_ops.c
r4f30222 r9f64c1e 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_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; 954 1076 } 955 1077 … … 959 1081 { 960 1082 enum cache_mode cmode = CACHE_MODE_WB; 961 fat_bs_t *bs;962 1083 fat_instance_t *instance; 1084 fat_idx_t *ridxp; 1085 fs_node_t *rfn; 963 1086 int rc; 964 1087 … … 978 1101 } 979 1102 980 /* initialize libblock */ 981 rc = block_init(service_id, BS_SIZE); 1103 rc = fat_fs_open(service_id, cmode, &rfn, &ridxp); 982 1104 if (rc != EOK) { 983 1105 free(instance); … … 985 1107 } 986 1108 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); 1109 fibril_mutex_lock(&ridxp->lock); 1085 1110 1086 1111 rc = fs_instance_create(service_id, instance); 1087 1112 if (rc != EOK) { 1088 1113 fibril_mutex_unlock(&ridxp->lock); 1114 fat_fs_close(service_id, rfn); 1089 1115 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; 1116 return rc; 1117 } 1102 1118 1103 1119 fibril_mutex_unlock(&ridxp->lock); 1104 1120 1105 1121 *index = ridxp->index; 1106 *size = rootp->size;1122 *size = FAT_NODE(rfn)->size; 1107 1123 1108 1124 return EOK; … … 1174 1190 */ 1175 1191 (void) fat_node_put(fn); 1176 (void) fat_node_put(fn);1177 1192 1178 1193 /* … … 1182 1197 */ 1183 1198 (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); 1199 fat_fs_close(service_id, fn); 1187 1200 1188 1201 void *data;
Note:
See TracChangeset
for help on using the changeset viewer.