Changes in uspace/srv/vfs/vfs_register.c [286286c:ffa2c8ef] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_register.c
r286286c rffa2c8ef 52 52 #include "vfs.h" 53 53 54 FIBRIL_CONDVAR_INITIALIZE(fs_ list_cv);55 FIBRIL_MUTEX_INITIALIZE(fs_ list_lock);56 LIST_INITIALIZE(fs_ list);54 FIBRIL_CONDVAR_INITIALIZE(fs_head_cv); 55 FIBRIL_MUTEX_INITIALIZE(fs_head_lock); 56 LIST_INITIALIZE(fs_head); 57 57 58 58 atomic_t fs_handle_next = { … … 62 62 /** Verify the VFS info structure. 63 63 * 64 * @param info Info structure to be verified. 65 * 66 * @return Non-zero if the info structure is sane, zero otherwise. 67 * 64 * @param info Info structure to be verified. 65 * 66 * @return Non-zero if the info structure is sane, zero otherwise. 68 67 */ 69 68 static bool vfs_info_sane(vfs_info_t *info) 70 69 { 71 70 int i; 72 71 73 72 /* 74 73 * Check if the name is non-empty and is composed solely of ASCII … … 79 78 return false; 80 79 } 81 82 80 for (i = 1; i < FS_NAME_MAXLEN; i++) { 83 81 if (!(islower(info->name[i]) || isdigit(info->name[i])) && … … 92 90 } 93 91 } 94 95 92 /* 96 93 * This check is not redundant. It ensures that the name is … … 107 104 /** VFS_REGISTER protocol function. 108 105 * 109 * @param rid Hash of the call with the request. 110 * @param request Call structure with the request. 111 * 106 * @param rid Hash of the call with the request. 107 * @param request Call structure with the request. 112 108 */ 113 109 void vfs_register(ipc_callid_t rid, ipc_call_t *request) 114 110 { 111 int phone; 112 115 113 dprintf("Processing VFS_REGISTER request received from %p.\n", 116 114 request->in_phone_hash); … … 149 147 } 150 148 151 fibril_mutex_lock(&fs_ list_lock);149 fibril_mutex_lock(&fs_head_lock); 152 150 153 151 /* 154 152 * Check for duplicit registrations. 155 153 */ 156 if (fs_name_to_handle(fs_info->vfs_info.instance, 157 fs_info->vfs_info.name, false)) { 154 if (fs_name_to_handle(fs_info->vfs_info.name, false)) { 158 155 /* 159 156 * We already register a fs like this. 160 157 */ 161 158 dprintf("FS is already registered.\n"); 162 fibril_mutex_unlock(&fs_ list_lock);159 fibril_mutex_unlock(&fs_head_lock); 163 160 free(fs_info); 164 161 async_answer_0(rid, EEXISTS); … … 170 167 */ 171 168 dprintf("Inserting FS into the list of registered file systems.\n"); 172 list_append(&fs_info->fs_link, &fs_ list);169 list_append(&fs_info->fs_link, &fs_head); 173 170 174 171 /* … … 177 174 * which to forward VFS requests to it. 178 175 */ 179 fs_info->sess = async_callback_receive(EXCHANGE_PARALLEL); 180 if (!fs_info->sess) { 181 dprintf("Callback connection expected\n"); 176 ipc_call_t call; 177 ipc_callid_t callid = async_get_call(&call); 178 if (IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) { 179 dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call)); 182 180 list_remove(&fs_info->fs_link); 183 fibril_mutex_unlock(&fs_list_lock); 184 free(fs_info); 181 fibril_mutex_unlock(&fs_head_lock); 182 free(fs_info); 183 async_answer_0(callid, EINVAL); 185 184 async_answer_0(rid, EINVAL); 186 185 return; 187 186 } 188 187 188 phone = IPC_GET_ARG5(call); 189 async_session_create(&fs_info->session, phone, 0); 190 async_answer_0(callid, EOK); 191 189 192 dprintf("Callback connection to FS created.\n"); 190 193 … … 194 197 195 198 size_t size; 196 ipc_callid_t callid;197 199 if (!async_share_in_receive(&callid, &size)) { 198 200 dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call)); 199 201 list_remove(&fs_info->fs_link); 200 fibril_mutex_unlock(&fs_list_lock); 201 async_hangup(fs_info->sess); 202 fibril_mutex_unlock(&fs_head_lock); 203 async_session_destroy(&fs_info->session); 204 async_hangup(phone); 202 205 free(fs_info); 203 206 async_answer_0(callid, EINVAL); … … 212 215 dprintf("Client suggests wrong size of PFB, size = %d\n", size); 213 216 list_remove(&fs_info->fs_link); 214 fibril_mutex_unlock(&fs_list_lock); 215 async_hangup(fs_info->sess); 217 fibril_mutex_unlock(&fs_head_lock); 218 async_session_destroy(&fs_info->session); 219 async_hangup(phone); 216 220 free(fs_info); 217 221 async_answer_0(callid, EINVAL); … … 236 240 async_answer_1(rid, EOK, (sysarg_t) fs_info->fs_handle); 237 241 238 fibril_condvar_broadcast(&fs_ list_cv);239 fibril_mutex_unlock(&fs_ list_lock);242 fibril_condvar_broadcast(&fs_head_cv); 243 fibril_mutex_unlock(&fs_head_lock); 240 244 241 245 dprintf("\"%.*s\" filesystem successfully registered, handle=%d.\n", … … 243 247 } 244 248 245 /** Begin an exchange for a given file system handle 246 * 247 * @param handle File system handle. 248 * 249 * @return Exchange for a multi-call request. 250 * @return NULL if no such file exists. 251 * 252 */ 253 async_exch_t *vfs_exchange_grab(fs_handle_t handle) 254 { 255 /* 256 * For now, we don't try to be very clever and very fast. 257 * We simply lookup the session in fs_list and 258 * begin an exchange. 259 */ 260 fibril_mutex_lock(&fs_list_lock); 261 262 list_foreach(fs_list, cur) { 249 /** For a given file system handle, implement policy for allocating a phone. 250 * 251 * @param handle File system handle. 252 * 253 * @return Phone over which a multi-call request can be safely 254 * sent. Return 0 if no phone was found. 255 */ 256 int vfs_grab_phone(fs_handle_t handle) 257 { 258 link_t *cur; 259 fs_info_t *fs; 260 int phone; 261 262 /* 263 * For now, we don't try to be very clever and very fast. We simply 264 * lookup the phone in the fs_head list and duplicate it. The duplicate 265 * phone will be returned to the client and the client will use it for 266 * communication. In the future, we should cache the connections so 267 * that they do not have to be reestablished over and over again. 268 */ 269 fibril_mutex_lock(&fs_head_lock); 270 for (cur = fs_head.next; cur != &fs_head; cur = cur->next) { 271 fs = list_get_instance(cur, fs_info_t, fs_link); 272 if (fs->fs_handle == handle) { 273 fibril_mutex_unlock(&fs_head_lock); 274 phone = async_exchange_begin(&fs->session); 275 276 assert(phone > 0); 277 return phone; 278 } 279 } 280 fibril_mutex_unlock(&fs_head_lock); 281 return 0; 282 } 283 284 /** Tell VFS that the phone is not needed anymore. 285 * 286 * @param phone Phone to FS task. 287 */ 288 void vfs_release_phone(fs_handle_t handle, int phone) 289 { 290 link_t *cur; 291 fs_info_t *fs; 292 293 fibril_mutex_lock(&fs_head_lock); 294 for (cur = fs_head.next; cur != &fs_head; cur = cur->next) { 295 fs = list_get_instance(cur, fs_info_t, fs_link); 296 if (fs->fs_handle == handle) { 297 fibril_mutex_unlock(&fs_head_lock); 298 async_exchange_end(&fs->session, phone); 299 return; 300 } 301 } 302 /* should not really get here */ 303 abort(); 304 fibril_mutex_unlock(&fs_head_lock); 305 } 306 307 /** Convert file system name to its handle. 308 * 309 * @param name File system name. 310 * @param lock If true, the function will lock and unlock the 311 * fs_head_lock. 312 * 313 * @return File system handle or zero if file system not found. 314 */ 315 fs_handle_t fs_name_to_handle(char *name, bool lock) 316 { 317 int handle = 0; 318 319 if (lock) 320 fibril_mutex_lock(&fs_head_lock); 321 link_t *cur; 322 for (cur = fs_head.next; cur != &fs_head; cur = cur->next) { 263 323 fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link); 264 265 if (fs->fs_handle == handle) { 266 fibril_mutex_unlock(&fs_list_lock); 267 268 assert(fs->sess); 269 async_exch_t *exch = async_exchange_begin(fs->sess); 270 271 assert(exch); 272 return exch; 273 } 274 } 275 276 fibril_mutex_unlock(&fs_list_lock); 277 278 return NULL; 279 } 280 281 /** End VFS server exchange. 282 * 283 * @param exch VFS server exchange. 284 * 285 */ 286 void vfs_exchange_release(async_exch_t *exch) 287 { 288 async_exchange_end(exch); 289 } 290 291 /** Convert file system name to its handle. 292 * 293 * @param name File system name. 294 * @param lock If true, the function will lock and unlock the 295 * fs_list_lock. 296 * 297 * @return File system handle or zero if file system not found. 298 * 299 */ 300 fs_handle_t fs_name_to_handle(unsigned int instance, char *name, bool lock) 301 { 302 int handle = 0; 303 304 if (lock) 305 fibril_mutex_lock(&fs_list_lock); 306 307 list_foreach(fs_list, cur) { 308 fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link); 309 if (str_cmp(fs->vfs_info.name, name) == 0 && 310 instance == fs->vfs_info.instance) { 324 if (str_cmp(fs->vfs_info.name, name) == 0) { 311 325 handle = fs->fs_handle; 312 326 break; 313 327 } 314 328 } 315 316 329 if (lock) 317 fibril_mutex_unlock(&fs_list_lock); 318 330 fibril_mutex_unlock(&fs_head_lock); 319 331 return handle; 320 332 } … … 322 334 /** Find the VFS info structure. 323 335 * 324 * @param handle FS handle for which the VFS info structure is sought. 325 * 326 * @return VFS info structure on success or NULL otherwise. 327 * 336 * @param handle FS handle for which the VFS info structure is sought. 337 * @return VFS info structure on success or NULL otherwise. 328 338 */ 329 339 vfs_info_t *fs_handle_to_info(fs_handle_t handle) 330 340 { 331 341 vfs_info_t *info = NULL; 332 333 fibril_mutex_lock(&fs_list_lock); 334 list_foreach(fs_list, cur) { 342 link_t *cur; 343 344 fibril_mutex_lock(&fs_head_lock); 345 for (cur = fs_head.next; cur != &fs_head; cur = cur->next) { 335 346 fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link); 336 347 if (fs->fs_handle == handle) { … … 339 350 } 340 351 } 341 fibril_mutex_unlock(&fs_ list_lock);342 352 fibril_mutex_unlock(&fs_head_lock); 353 343 354 return info; 344 355 } … … 346 357 /** 347 358 * @} 348 */ 359 */
Note:
See TracChangeset
for help on using the changeset viewer.