Changes in uspace/srv/fs/fat/fat_ops.c [dfddfcd:472c09d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_ops.c
rdfddfcd r472c09d 52 52 #include <adt/list.h> 53 53 #include <assert.h> 54 #include <fibril_sync .h>54 #include <fibril_synch.h> 55 55 #include <sys/mman.h> 56 56 #include <align.h> … … 71 71 static int fat_match(fs_node_t **, fs_node_t *, const char *); 72 72 static int fat_node_get(fs_node_t **, dev_handle_t, fs_index_t); 73 static int fat_node_open(fs_node_t *); 73 74 static int fat_node_put(fs_node_t *); 74 75 static int fat_create_node(fs_node_t **, dev_handle_t, int); … … 83 84 static bool fat_is_directory(fs_node_t *); 84 85 static bool fat_is_file(fs_node_t *node); 86 static dev_handle_t fat_device_get(fs_node_t *node); 85 87 86 88 /* … … 135 137 rc = block_put(b); 136 138 return rc; 139 } 140 141 static int fat_node_fini_by_dev_handle(dev_handle_t dev_handle) 142 { 143 link_t *lnk; 144 fat_node_t *nodep; 145 int rc; 146 147 /* 148 * We are called from fat_unmounted() and assume that there are already 149 * no nodes belonging to this instance with non-zero refcount. Therefore 150 * it is sufficient to clean up only the FAT free node list. 151 */ 152 153 restart: 154 fibril_mutex_lock(&ffn_mutex); 155 for (lnk = ffn_head.next; lnk != &ffn_head; lnk = lnk->next) { 156 nodep = list_get_instance(lnk, fat_node_t, ffn_link); 157 if (!fibril_mutex_trylock(&nodep->lock)) { 158 fibril_mutex_unlock(&ffn_mutex); 159 goto restart; 160 } 161 if (!fibril_mutex_trylock(&nodep->idx->lock)) { 162 fibril_mutex_unlock(&nodep->lock); 163 fibril_mutex_unlock(&ffn_mutex); 164 goto restart; 165 } 166 if (nodep->idx->dev_handle != dev_handle) { 167 fibril_mutex_unlock(&nodep->idx->lock); 168 fibril_mutex_unlock(&nodep->lock); 169 continue; 170 } 171 172 list_remove(&nodep->ffn_link); 173 fibril_mutex_unlock(&ffn_mutex); 174 175 /* 176 * We can unlock the node and its index structure because we are 177 * the last player on this playground and VFS is preventing new 178 * players from entering. 179 */ 180 fibril_mutex_unlock(&nodep->idx->lock); 181 fibril_mutex_unlock(&nodep->lock); 182 183 if (nodep->dirty) { 184 rc = fat_node_sync(nodep); 185 if (rc != EOK) 186 return rc; 187 } 188 nodep->idx->nodep = NULL; 189 free(nodep->bp); 190 free(nodep); 191 192 /* Need to restart because we changed the ffn_head list. */ 193 goto restart; 194 } 195 fibril_mutex_unlock(&ffn_mutex); 196 197 return EOK; 137 198 } 138 199 … … 407 468 } 408 469 470 int fat_node_open(fs_node_t *fn) 471 { 472 /* 473 * Opening a file is stateless, nothing 474 * to be done here. 475 */ 476 return EOK; 477 } 478 409 479 int fat_node_put(fs_node_t *fn) 410 480 { … … 867 937 } 868 938 939 dev_handle_t fat_device_get(fs_node_t *node) 940 { 941 return 0; 942 } 943 869 944 /** libfs operations */ 870 945 libfs_ops_t fat_libfs_ops = { … … 872 947 .match = fat_match, 873 948 .node_get = fat_node_get, 949 .node_open = fat_node_open, 874 950 .node_put = fat_node_put, 875 951 .create = fat_create_node, … … 881 957 .size_get = fat_size_get, 882 958 .lnkcnt_get = fat_lnkcnt_get, 883 .plb_get_char = 959 .plb_get_char = fat_plb_get_char, 884 960 .is_directory = fat_is_directory, 885 .is_file = fat_is_file 961 .is_file = fat_is_file, 962 .device_get = fat_device_get 886 963 }; 887 964 … … 897 974 uint16_t bps; 898 975 uint16_t rde; 899 int rc; 900 901 /* accept the mount options */ 902 ipc_callid_t callid; 903 size_t size; 904 if (!async_data_write_receive(&callid, &size)) { 905 ipc_answer_0(callid, EINVAL); 906 ipc_answer_0(rid, EINVAL); 907 return; 908 } 909 char *opts = malloc(size + 1); 910 if (!opts) { 911 ipc_answer_0(callid, ENOMEM); 912 ipc_answer_0(rid, ENOMEM); 913 return; 914 } 915 ipcarg_t retval = async_data_write_finalize(callid, opts, size); 916 if (retval != EOK) { 917 ipc_answer_0(rid, retval); 918 free(opts); 919 return; 920 } 921 opts[size] = '\0'; 976 977 /* Accept the mount options */ 978 char *opts; 979 int rc = async_string_receive(&opts, 0, NULL); 980 981 if (rc != EOK) { 982 ipc_answer_0(rid, rc); 983 return; 984 } 922 985 923 986 /* Check for option enabling write through. */ … … 927 990 cmode = CACHE_MODE_WB; 928 991 992 free(opts); 993 929 994 /* initialize libblock */ 930 995 rc = block_init(dev_handle, BS_SIZE); … … 963 1028 } 964 1029 1030 /* Do some simple sanity checks on the file system. */ 1031 rc = fat_sanity_check(bs, dev_handle); 1032 if (rc != EOK) { 1033 (void) block_cache_fini(dev_handle); 1034 block_fini(dev_handle); 1035 ipc_answer_0(rid, rc); 1036 return; 1037 } 1038 965 1039 rc = fat_idx_init_by_dev_handle(dev_handle); 966 1040 if (rc != EOK) { 1041 (void) block_cache_fini(dev_handle); 967 1042 block_fini(dev_handle); 968 1043 ipc_answer_0(rid, rc); … … 973 1048 fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t)); 974 1049 if (!rfn) { 1050 (void) block_cache_fini(dev_handle); 975 1051 block_fini(dev_handle); 976 1052 fat_idx_fini_by_dev_handle(dev_handle); … … 982 1058 if (!rootp) { 983 1059 free(rfn); 1060 (void) block_cache_fini(dev_handle); 984 1061 block_fini(dev_handle); 985 1062 fat_idx_fini_by_dev_handle(dev_handle); … … 993 1070 free(rfn); 994 1071 free(rootp); 1072 (void) block_cache_fini(dev_handle); 995 1073 block_fini(dev_handle); 996 1074 fat_idx_fini_by_dev_handle(dev_handle); … … 1019 1097 { 1020 1098 libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1099 } 1100 1101 void fat_unmounted(ipc_callid_t rid, ipc_call_t *request) 1102 { 1103 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 1104 fs_node_t *fn; 1105 fat_node_t *nodep; 1106 int rc; 1107 1108 rc = fat_root_get(&fn, dev_handle); 1109 if (rc != EOK) { 1110 ipc_answer_0(rid, rc); 1111 return; 1112 } 1113 nodep = FAT_NODE(fn); 1114 1115 /* 1116 * We expect exactly two references on the root node. One for the 1117 * fat_root_get() above and one created in fat_mounted(). 1118 */ 1119 if (nodep->refcnt != 2) { 1120 (void) fat_node_put(fn); 1121 ipc_answer_0(rid, EBUSY); 1122 return; 1123 } 1124 1125 /* 1126 * Put the root node and force it to the FAT free node list. 1127 */ 1128 (void) fat_node_put(fn); 1129 (void) fat_node_put(fn); 1130 1131 /* 1132 * Perform cleanup of the node structures, index structures and 1133 * associated data. Write back this file system's dirty blocks and 1134 * stop using libblock for this instance. 1135 */ 1136 (void) fat_node_fini_by_dev_handle(dev_handle); 1137 fat_idx_fini_by_dev_handle(dev_handle); 1138 (void) block_cache_fini(dev_handle); 1139 block_fini(dev_handle); 1140 1141 ipc_answer_0(rid, EOK); 1142 } 1143 1144 void fat_unmount(ipc_callid_t rid, ipc_call_t *request) 1145 { 1146 libfs_unmount(&fat_libfs_ops, rid, request); 1021 1147 } 1022 1148
Note:
See TracChangeset
for help on using the changeset viewer.