Changes in uspace/srv/vfs/vfs_register.c [ffa2c8ef:b72efe8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_register.c
rffa2c8ef rb72efe8 52 52 #include "vfs.h" 53 53 54 FIBRIL_CONDVAR_INITIALIZE(fs_ head_cv);55 FIBRIL_MUTEX_INITIALIZE(fs_ head_lock);56 LIST_INITIALIZE(fs_ head);54 FIBRIL_CONDVAR_INITIALIZE(fs_list_cv); 55 FIBRIL_MUTEX_INITIALIZE(fs_list_lock); 56 LIST_INITIALIZE(fs_list); 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. 64 * @param info Info structure to be verified. 65 * 66 * @return Non-zero if the info structure is sane, zero otherwise. 67 * 67 68 */ 68 69 static bool vfs_info_sane(vfs_info_t *info) 69 70 { 70 71 int i; 71 72 72 73 /* 73 74 * Check if the name is non-empty and is composed solely of ASCII … … 78 79 return false; 79 80 } 81 80 82 for (i = 1; i < FS_NAME_MAXLEN; i++) { 81 83 if (!(islower(info->name[i]) || isdigit(info->name[i])) && … … 90 92 } 91 93 } 94 92 95 /* 93 96 * This check is not redundant. It ensures that the name is … … 104 107 /** VFS_REGISTER protocol function. 105 108 * 106 * @param rid Hash of the call with the request. 107 * @param request Call structure with the request. 109 * @param rid Hash of the call with the request. 110 * @param request Call structure with the request. 111 * 108 112 */ 109 113 void vfs_register(ipc_callid_t rid, ipc_call_t *request) 110 114 { 111 int phone;112 113 115 dprintf("Processing VFS_REGISTER request received from %p.\n", 114 116 request->in_phone_hash); … … 147 149 } 148 150 149 fibril_mutex_lock(&fs_ head_lock);151 fibril_mutex_lock(&fs_list_lock); 150 152 151 153 /* … … 157 159 */ 158 160 dprintf("FS is already registered.\n"); 159 fibril_mutex_unlock(&fs_ head_lock);161 fibril_mutex_unlock(&fs_list_lock); 160 162 free(fs_info); 161 163 async_answer_0(rid, EEXISTS); … … 167 169 */ 168 170 dprintf("Inserting FS into the list of registered file systems.\n"); 169 list_append(&fs_info->fs_link, &fs_ head);171 list_append(&fs_info->fs_link, &fs_list); 170 172 171 173 /* … … 174 176 * which to forward VFS requests to it. 175 177 */ 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)); 178 fs_info->sess = async_callback_receive(EXCHANGE_PARALLEL); 179 if (!fs_info->sess) { 180 dprintf("Callback connection expected\n"); 180 181 list_remove(&fs_info->fs_link); 181 fibril_mutex_unlock(&fs_head_lock); 182 free(fs_info); 183 async_answer_0(callid, EINVAL); 182 fibril_mutex_unlock(&fs_list_lock); 183 free(fs_info); 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 192 188 dprintf("Callback connection to FS created.\n"); 193 189 … … 197 193 198 194 size_t size; 195 ipc_callid_t callid; 199 196 if (!async_share_in_receive(&callid, &size)) { 200 197 dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call)); 201 198 list_remove(&fs_info->fs_link); 202 fibril_mutex_unlock(&fs_head_lock); 203 async_session_destroy(&fs_info->session); 204 async_hangup(phone); 199 fibril_mutex_unlock(&fs_list_lock); 200 async_hangup(fs_info->sess); 205 201 free(fs_info); 206 202 async_answer_0(callid, EINVAL); … … 215 211 dprintf("Client suggests wrong size of PFB, size = %d\n", size); 216 212 list_remove(&fs_info->fs_link); 217 fibril_mutex_unlock(&fs_head_lock); 218 async_session_destroy(&fs_info->session); 219 async_hangup(phone); 213 fibril_mutex_unlock(&fs_list_lock); 214 async_hangup(fs_info->sess); 220 215 free(fs_info); 221 216 async_answer_0(callid, EINVAL); … … 240 235 async_answer_1(rid, EOK, (sysarg_t) fs_info->fs_handle); 241 236 242 fibril_condvar_broadcast(&fs_ head_cv);243 fibril_mutex_unlock(&fs_ head_lock);237 fibril_condvar_broadcast(&fs_list_cv); 238 fibril_mutex_unlock(&fs_list_lock); 244 239 245 240 dprintf("\"%.*s\" filesystem successfully registered, handle=%d.\n", … … 247 242 } 248 243 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); 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 272 264 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; 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; 278 272 } 279 273 } 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); 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); 305 288 } 306 289 307 290 /** Convert file system name to its handle. 308 291 * 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. 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 * 314 298 */ 315 299 fs_handle_t fs_name_to_handle(char *name, bool lock) … … 318 302 319 303 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) {304 fibril_mutex_lock(&fs_list_lock); 305 306 list_foreach(fs_list, cur) { 323 307 fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link); 324 308 if (str_cmp(fs->vfs_info.name, name) == 0) { … … 327 311 } 328 312 } 313 329 314 if (lock) 330 fibril_mutex_unlock(&fs_head_lock); 315 fibril_mutex_unlock(&fs_list_lock); 316 331 317 return handle; 332 318 } … … 334 320 /** Find the VFS info structure. 335 321 * 336 * @param handle FS handle for which the VFS info structure is sought. 337 * @return VFS info structure on success or NULL otherwise. 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 * 338 326 */ 339 327 vfs_info_t *fs_handle_to_info(fs_handle_t handle) 340 328 { 341 329 vfs_info_t *info = NULL; 342 link_t *cur; 343 344 fibril_mutex_lock(&fs_head_lock); 345 for (cur = fs_head.next; cur != &fs_head; cur = cur->next) { 330 331 fibril_mutex_lock(&fs_list_lock); 332 list_foreach(fs_list, cur) { 346 333 fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link); 347 334 if (fs->fs_handle == handle) { … … 350 337 } 351 338 } 352 fibril_mutex_unlock(&fs_ head_lock);353 339 fibril_mutex_unlock(&fs_list_lock); 340 354 341 return info; 355 342 } … … 357 344 /** 358 345 * @} 359 */ 346 */
Note:
See TracChangeset
for help on using the changeset viewer.