Changes in uspace/srv/vfs/vfs_register.c [b72efe8:ffa2c8ef] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_register.c
rb72efe8 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 /* … … 159 157 */ 160 158 dprintf("FS is already registered.\n"); 161 fibril_mutex_unlock(&fs_ list_lock);159 fibril_mutex_unlock(&fs_head_lock); 162 160 free(fs_info); 163 161 async_answer_0(rid, EEXISTS); … … 169 167 */ 170 168 dprintf("Inserting FS into the list of registered file systems.\n"); 171 list_append(&fs_info->fs_link, &fs_ list);169 list_append(&fs_info->fs_link, &fs_head); 172 170 173 171 /* … … 176 174 * which to forward VFS requests to it. 177 175 */ 178 fs_info->sess = async_callback_receive(EXCHANGE_PARALLEL); 179 if (!fs_info->sess) { 180 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)); 181 180 list_remove(&fs_info->fs_link); 182 fibril_mutex_unlock(&fs_list_lock); 183 free(fs_info); 181 fibril_mutex_unlock(&fs_head_lock); 182 free(fs_info); 183 async_answer_0(callid, EINVAL); 184 184 async_answer_0(rid, EINVAL); 185 185 return; 186 186 } 187 187 188 phone = IPC_GET_ARG5(call); 189 async_session_create(&fs_info->session, phone, 0); 190 async_answer_0(callid, EOK); 191 188 192 dprintf("Callback connection to FS created.\n"); 189 193 … … 193 197 194 198 size_t size; 195 ipc_callid_t callid;196 199 if (!async_share_in_receive(&callid, &size)) { 197 200 dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call)); 198 201 list_remove(&fs_info->fs_link); 199 fibril_mutex_unlock(&fs_list_lock); 200 async_hangup(fs_info->sess); 202 fibril_mutex_unlock(&fs_head_lock); 203 async_session_destroy(&fs_info->session); 204 async_hangup(phone); 201 205 free(fs_info); 202 206 async_answer_0(callid, EINVAL); … … 211 215 dprintf("Client suggests wrong size of PFB, size = %d\n", size); 212 216 list_remove(&fs_info->fs_link); 213 fibril_mutex_unlock(&fs_list_lock); 214 async_hangup(fs_info->sess); 217 fibril_mutex_unlock(&fs_head_lock); 218 async_session_destroy(&fs_info->session); 219 async_hangup(phone); 215 220 free(fs_info); 216 221 async_answer_0(callid, EINVAL); … … 235 240 async_answer_1(rid, EOK, (sysarg_t) fs_info->fs_handle); 236 241 237 fibril_condvar_broadcast(&fs_ list_cv);238 fibril_mutex_unlock(&fs_ list_lock);242 fibril_condvar_broadcast(&fs_head_cv); 243 fibril_mutex_unlock(&fs_head_lock); 239 244 240 245 dprintf("\"%.*s\" filesystem successfully registered, handle=%d.\n", … … 242 247 } 243 248 244 /** Begin an exchange for a given file system handle 245 * 246 * @param handle File system handle. 247 * 248 * @return Exchange for a multi-call request. 249 * @return NULL if no such file exists. 250 * 251 */ 252 async_exch_t *vfs_exchange_grab(fs_handle_t handle) 253 { 254 /* 255 * For now, we don't try to be very clever and very fast. 256 * We simply lookup the session in fs_list and 257 * begin an exchange. 258 */ 259 fibril_mutex_lock(&fs_list_lock); 260 261 list_foreach(fs_list, cur) { 262 fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link); 263 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); 264 272 if (fs->fs_handle == handle) { 265 fibril_mutex_unlock(&fs_list_lock); 266 267 assert(fs->sess); 268 async_exch_t *exch = async_exchange_begin(fs->sess); 269 270 assert(exch); 271 return exch; 272 } 273 } 274 275 fibril_mutex_unlock(&fs_list_lock); 276 277 return NULL; 278 } 279 280 /** End VFS server exchange. 281 * 282 * @param exch VFS server exchange. 283 * 284 */ 285 void vfs_exchange_release(async_exch_t *exch) 286 { 287 async_exchange_end(exch); 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); 288 305 } 289 306 290 307 /** Convert file system name to its handle. 291 308 * 292 * @param name File system name. 293 * @param lock If true, the function will lock and unlock the 294 * fs_list_lock. 295 * 296 * @return File system handle or zero if file system not found. 297 * 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. 298 314 */ 299 315 fs_handle_t fs_name_to_handle(char *name, bool lock) … … 302 318 303 319 if (lock) 304 fibril_mutex_lock(&fs_ list_lock);305 306 list_foreach(fs_list, cur) {320 fibril_mutex_lock(&fs_head_lock); 321 link_t *cur; 322 for (cur = fs_head.next; cur != &fs_head; cur = cur->next) { 307 323 fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link); 308 324 if (str_cmp(fs->vfs_info.name, name) == 0) { … … 311 327 } 312 328 } 313 314 329 if (lock) 315 fibril_mutex_unlock(&fs_list_lock); 316 330 fibril_mutex_unlock(&fs_head_lock); 317 331 return handle; 318 332 } … … 320 334 /** Find the VFS info structure. 321 335 * 322 * @param handle FS handle for which the VFS info structure is sought. 323 * 324 * @return VFS info structure on success or NULL otherwise. 325 * 336 * @param handle FS handle for which the VFS info structure is sought. 337 * @return VFS info structure on success or NULL otherwise. 326 338 */ 327 339 vfs_info_t *fs_handle_to_info(fs_handle_t handle) 328 340 { 329 341 vfs_info_t *info = NULL; 330 331 fibril_mutex_lock(&fs_list_lock); 332 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) { 333 346 fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link); 334 347 if (fs->fs_handle == handle) { … … 337 350 } 338 351 } 339 fibril_mutex_unlock(&fs_ list_lock);340 352 fibril_mutex_unlock(&fs_head_lock); 353 341 354 return info; 342 355 } … … 344 357 /** 345 358 * @} 346 */ 359 */
Note:
See TracChangeset
for help on using the changeset viewer.