Changes in uspace/srv/fs/fat/fat_ops.c [472c09d:dfddfcd] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_ops.c
r472c09d rdfddfcd 52 52 #include <adt/list.h> 53 53 #include <assert.h> 54 #include <fibril_sync h.h>54 #include <fibril_sync.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 *);74 73 static int fat_node_put(fs_node_t *); 75 74 static int fat_create_node(fs_node_t **, dev_handle_t, int); … … 84 83 static bool fat_is_directory(fs_node_t *); 85 84 static bool fat_is_file(fs_node_t *node); 86 static dev_handle_t fat_device_get(fs_node_t *node);87 85 88 86 /* … … 137 135 rc = block_put(b); 138 136 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 already149 * no nodes belonging to this instance with non-zero refcount. Therefore150 * 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 are177 * the last player on this playground and VFS is preventing new178 * 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;198 137 } 199 138 … … 468 407 } 469 408 470 int fat_node_open(fs_node_t *fn)471 {472 /*473 * Opening a file is stateless, nothing474 * to be done here.475 */476 return EOK;477 }478 479 409 int fat_node_put(fs_node_t *fn) 480 410 { … … 937 867 } 938 868 939 dev_handle_t fat_device_get(fs_node_t *node)940 {941 return 0;942 }943 944 869 /** libfs operations */ 945 870 libfs_ops_t fat_libfs_ops = { … … 947 872 .match = fat_match, 948 873 .node_get = fat_node_get, 949 .node_open = fat_node_open,950 874 .node_put = fat_node_put, 951 875 .create = fat_create_node, … … 957 881 .size_get = fat_size_get, 958 882 .lnkcnt_get = fat_lnkcnt_get, 959 .plb_get_char = 883 .plb_get_char = fat_plb_get_char, 960 884 .is_directory = fat_is_directory, 961 .is_file = fat_is_file, 962 .device_get = fat_device_get 885 .is_file = fat_is_file 963 886 }; 964 887 … … 974 897 uint16_t bps; 975 898 uint16_t rde; 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 } 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'; 985 922 986 923 /* Check for option enabling write through. */ … … 990 927 cmode = CACHE_MODE_WB; 991 928 992 free(opts);993 994 929 /* initialize libblock */ 995 930 rc = block_init(dev_handle, BS_SIZE); … … 1028 963 } 1029 964 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 1039 965 rc = fat_idx_init_by_dev_handle(dev_handle); 1040 966 if (rc != EOK) { 1041 (void) block_cache_fini(dev_handle);1042 967 block_fini(dev_handle); 1043 968 ipc_answer_0(rid, rc); … … 1048 973 fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t)); 1049 974 if (!rfn) { 1050 (void) block_cache_fini(dev_handle);1051 975 block_fini(dev_handle); 1052 976 fat_idx_fini_by_dev_handle(dev_handle); … … 1058 982 if (!rootp) { 1059 983 free(rfn); 1060 (void) block_cache_fini(dev_handle);1061 984 block_fini(dev_handle); 1062 985 fat_idx_fini_by_dev_handle(dev_handle); … … 1070 993 free(rfn); 1071 994 free(rootp); 1072 (void) block_cache_fini(dev_handle);1073 995 block_fini(dev_handle); 1074 996 fat_idx_fini_by_dev_handle(dev_handle); … … 1097 1019 { 1098 1020 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 the1117 * 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 and1133 * associated data. Write back this file system's dirty blocks and1134 * 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);1147 1021 } 1148 1022
Note:
See TracChangeset
for help on using the changeset viewer.