Changeset a35b458 in mainline for uspace/srv/vfs
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- Location:
- uspace/srv/vfs
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs.c
r3061bc1 ra35b458 62 62 ipc_call_t call; 63 63 ipc_callid_t callid = async_get_call(&call); 64 64 65 65 if (!IPC_GET_IMETHOD(call)) 66 66 break; 67 67 68 68 switch (IPC_GET_IMETHOD(call)) { 69 69 case IPC_M_PAGE_IN: … … 91 91 92 92 printf("%s: HelenOS VFS server\n", NAME); 93 93 94 94 /* 95 95 * Initialize VFS node hash table. … … 100 100 return ENOMEM; 101 101 } 102 102 103 103 /* 104 104 * Allocate and initialize the Path Lookup Buffer. … … 111 111 } 112 112 memset(plb, 0, PLB_SIZE); 113 113 114 114 /* 115 115 * Set client data constructor and destructor. … … 138 138 async_event_task_subscribe(EVENT_TASK_STATE_CHANGE, notification_handler, 139 139 NULL); 140 140 141 141 /* 142 142 * Register at the naming service. … … 147 147 return rc; 148 148 } 149 149 150 150 /* 151 151 * Start accepting connections. -
uspace/srv/vfs/vfs.h
r3061bc1 ra35b458 110 110 */ 111 111 unsigned refcnt; 112 112 113 113 ht_link_t nh_link; /**< Node hash-table link. */ 114 114 … … 121 121 */ 122 122 fibril_rwlock_t contents_rwlock; 123 123 124 124 struct _vfs_node *mount; 125 125 } vfs_node_t; … … 134 134 135 135 vfs_node_t *node; 136 136 137 137 /** Number of file handles referencing this file. */ 138 138 unsigned refcnt; -
uspace/srv/vfs/vfs_file.c
r3061bc1 ra35b458 94 94 (void) _vfs_fd_free(vfs_data, i); 95 95 } 96 96 97 97 free(vfs_data->files); 98 98 … … 100 100 link_t *lnk; 101 101 vfs_boxed_handle_t *bh; 102 102 103 103 lnk = list_first(&vfs_data->passed_handles); 104 104 list_remove(lnk); … … 120 120 vfs_data->files = NULL; 121 121 } 122 122 123 123 return vfs_data; 124 124 } … … 136 136 { 137 137 assert(!file->refcnt); 138 138 139 139 async_exch_t *exch = vfs_exchange_grab(file->node->fs_handle); 140 140 141 141 ipc_call_t answer; 142 142 aid_t msg = async_send_2(exch, VFS_OUT_CLOSE, file->node->service_id, 143 143 file->node->index, &answer); 144 144 145 145 vfs_exchange_release(exch); 146 146 147 147 errno_t rc; 148 148 async_wait_for(msg, &rc); 149 149 150 150 return IPC_GET_RETVAL(answer); 151 151 } … … 179 179 * endpoint FS and drop our reference to the underlying VFS node. 180 180 */ 181 181 182 182 if (file->node != NULL) { 183 183 if (file->open_read || file->open_write) { … … 196 196 if (!vfs_files_init(vfs_data)) 197 197 return ENOMEM; 198 198 199 199 unsigned int i; 200 200 if (desc) … … 202 202 else 203 203 i = 0; 204 204 205 205 fibril_mutex_lock(&vfs_data->lock); 206 206 while (true) { … … 211 211 return ENOMEM; 212 212 } 213 214 213 214 215 215 memset(vfs_data->files[i], 0, sizeof(vfs_file_t)); 216 216 217 217 fibril_mutex_initialize(&vfs_data->files[i]->_lock); 218 218 fibril_mutex_lock(&vfs_data->files[i]->_lock); 219 219 vfs_file_addref(vfs_data, vfs_data->files[i]); 220 220 221 221 *file = vfs_data->files[i]; 222 222 vfs_file_addref(vfs_data, *file); 223 223 224 224 fibril_mutex_unlock(&vfs_data->lock); 225 225 *out_fd = (int) i; 226 226 return EOK; 227 227 } 228 228 229 229 if (desc) { 230 230 if (i == 0) 231 231 break; 232 232 233 233 i--; 234 234 } else { 235 235 if (i == MAX_OPEN_FILES - 1) 236 236 break; 237 237 238 238 i++; 239 239 } 240 240 } 241 241 fibril_mutex_unlock(&vfs_data->lock); 242 242 243 243 return EMFILE; 244 244 } … … 280 280 rc = _vfs_fd_free_locked(vfs_data, fd); 281 281 fibril_mutex_unlock(&vfs_data->lock); 282 282 283 283 return rc; 284 284 } … … 319 319 (void) _vfs_fd_free_locked(VFS_DATA, fd); 320 320 assert(FILES[fd] == NULL); 321 321 322 322 FILES[fd] = file; 323 323 vfs_file_addref(VFS_DATA, FILES[fd]); 324 324 fibril_mutex_unlock(&VFS_DATA->lock); 325 325 326 326 return EOK; 327 327 } … … 330 330 { 331 331 fibril_mutex_unlock(&file->_lock); 332 332 333 333 fibril_mutex_lock(&vfs_data->lock); 334 334 vfs_file_delref(vfs_data, file); … … 340 340 if (!vfs_files_init(vfs_data)) 341 341 return NULL; 342 342 343 343 fibril_mutex_lock(&vfs_data->lock); 344 344 if ((fd >= 0) && (fd < MAX_OPEN_FILES)) { … … 347 347 vfs_file_addref(vfs_data, file); 348 348 fibril_mutex_unlock(&vfs_data->lock); 349 349 350 350 fibril_mutex_lock(&file->_lock); 351 351 if (file->node == NULL) { … … 359 359 } 360 360 fibril_mutex_unlock(&vfs_data->lock); 361 361 362 362 return NULL; 363 363 } … … 432 432 { 433 433 vfs_client_data_t *vfs_data = VFS_DATA; 434 434 435 435 fibril_mutex_lock(&vfs_data->lock); 436 436 while (list_empty(&vfs_data->passed_handles)) … … 449 449 return rc; 450 450 } 451 451 452 452 file->node = bh->node; 453 453 file->permissions = bh->permissions; -
uspace/srv/vfs/vfs_ipc.c
r3061bc1 ra35b458 40 40 int newfd = IPC_GET_ARG2(*request); 41 41 bool desc = IPC_GET_ARG3(*request); 42 42 43 43 int outfd = -1; 44 44 errno_t rc = vfs_op_clone(oldfd, newfd, desc, &outfd); … … 54 54 size_t len; 55 55 errno_t rc; 56 56 57 57 /* 58 58 * Now we expect the client to send us data with the name of the file … … 65 65 return; 66 66 } 67 67 68 68 rc = vfs_op_fsprobe(fs_name, service_id, &info); 69 69 async_answer_0(rid, rc); 70 70 if (rc != EOK) 71 71 goto out; 72 72 73 73 /* Now we should get a read request */ 74 74 if (!async_data_read_receive(&callid, &len)) … … 114 114 { 115 115 int mpfd = IPC_GET_ARG1(*request); 116 116 117 117 /* 118 118 * We expect the library to do the device-name to device-handle … … 121 121 */ 122 122 service_id_t service_id = (service_id_t) IPC_GET_ARG2(*request); 123 123 124 124 unsigned int flags = (unsigned int) IPC_GET_ARG3(*request); 125 125 unsigned int instance = IPC_GET_ARG4(*request); 126 126 127 127 char *opts = NULL; 128 128 char *fs_name = NULL; 129 129 130 130 /* Now we expect to receive the mount options. */ 131 131 errno_t rc = async_data_write_accept((void **) &opts, true, 0, … … 135 135 return; 136 136 } 137 137 138 138 /* Now, we expect the client to send us data with the name of the file 139 139 * system. … … 146 146 return; 147 147 } 148 148 149 149 int outfd = 0; 150 150 rc = vfs_op_mount(mpfd, service_id, flags, instance, opts, fs_name, 151 151 &outfd); 152 152 async_answer_1(rid, rc, outfd); 153 153 154 154 free(opts); 155 155 free(fs_name); … … 190 190 char *new = NULL; 191 191 errno_t rc; 192 192 193 193 basefd = IPC_GET_ARG1(*request); 194 194 195 195 /* Retrieve the old path. */ 196 196 rc = async_data_write_accept((void **) &old, true, 0, 0, 0, NULL); 197 197 if (rc != EOK) 198 198 goto out; 199 199 200 200 /* Retrieve the new path. */ 201 201 rc = async_data_write_accept((void **) &new, true, 0, 0, 0, NULL); 202 202 if (rc != EOK) 203 203 goto out; 204 204 205 205 size_t olen; 206 206 size_t nlen; 207 207 char *oldc = canonify(old, &olen); 208 208 char *newc = canonify(new, &nlen); 209 209 210 210 if ((!oldc) || (!newc)) { 211 211 rc = EINVAL; 212 212 goto out; 213 213 } 214 214 215 215 assert(oldc[olen] == '\0'); 216 216 assert(newc[nlen] == '\0'); 217 217 218 218 rc = vfs_op_rename(basefd, oldc, newc); 219 219 … … 245 245 { 246 246 int fd = (int) IPC_GET_ARG1(*request); 247 247 248 248 errno_t rc = vfs_op_statfs(fd); 249 249 async_answer_0(rid, rc); … … 261 261 int parentfd = IPC_GET_ARG1(*request); 262 262 int expectfd = IPC_GET_ARG2(*request); 263 263 264 264 char *path; 265 265 errno_t rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL); 266 266 if (rc == EOK) 267 267 rc = vfs_op_unlink(parentfd, expectfd, path); 268 268 269 269 async_answer_0(rid, rc); 270 270 } … … 293 293 int parentfd = IPC_GET_ARG1(*request); 294 294 int flags = IPC_GET_ARG2(*request); 295 295 296 296 int fd = 0; 297 297 char *path; … … 318 318 { 319 319 bool cont = true; 320 320 321 321 /* 322 322 * The connection was opened via the IPC_CONNECT_ME_TO call. … … 324 324 */ 325 325 async_answer_0(iid, EOK); 326 326 327 327 while (cont) { 328 328 ipc_call_t call; 329 329 ipc_callid_t callid = async_get_call(&call); 330 330 331 331 if (!IPC_GET_IMETHOD(call)) 332 332 break; 333 333 334 334 switch (IPC_GET_IMETHOD(call)) { 335 335 case VFS_IN_CLONE: … … 393 393 } 394 394 } 395 395 396 396 /* 397 397 * Open files for this client will be cleaned up when its last -
uspace/srv/vfs/vfs_lookup.c
r3061bc1 ra35b458 108 108 */ 109 109 list_append(&entry->plb_link, &plb_entries); 110 110 111 111 fibril_mutex_unlock(&plb_mutex); 112 112 … … 116 116 size_t cnt1 = min(len, (PLB_SIZE - first) + 1); 117 117 size_t cnt2 = len - cnt1; 118 118 119 119 memcpy(&plb[first], path, cnt1); 120 120 memcpy(plb, &path[cnt1], cnt2); … … 145 145 assert(child->fs_handle); 146 146 assert(path != NULL); 147 147 148 148 vfs_lookup_res_t res; 149 149 char component[NAME_MAX + 1]; 150 150 errno_t rc; 151 151 152 152 size_t len; 153 153 char *npath = canonify(path, &len); … … 157 157 } 158 158 path = npath; 159 159 160 160 vfs_triplet_t *triplet; 161 161 162 162 char *slash = str_rchr(path, L'/'); 163 163 if (slash && slash != path) { … … 166 166 goto out; 167 167 } 168 168 169 169 memcpy(component, slash + 1, str_size(slash)); 170 170 *slash = 0; 171 171 172 172 rc = vfs_lookup_internal(base, path, L_DIRECTORY, &res); 173 173 if (rc != EOK) 174 174 goto out; 175 175 triplet = &res.triplet; 176 176 177 177 *slash = '/'; 178 178 } else { … … 181 181 goto out; 182 182 } 183 183 184 184 memcpy(component, path + 1, str_size(path)); 185 185 triplet = (vfs_triplet_t *) base; 186 186 } 187 187 188 188 if (triplet->fs_handle != child->fs_handle || 189 189 triplet->service_id != child->service_id) { … … 191 191 goto out; 192 192 } 193 193 194 194 async_exch_t *exch = vfs_exchange_grab(triplet->fs_handle); 195 195 aid_t req = async_send_3(exch, VFS_OUT_LINK, triplet->service_id, 196 196 triplet->index, child->index, NULL); 197 197 198 198 rc = async_data_write_start(exch, component, str_size(component) + 1); 199 199 errno_t orig_rc; … … 202 202 if (orig_rc != EOK) 203 203 rc = orig_rc; 204 204 205 205 out: 206 206 return rc; … … 212 212 assert(base); 213 213 assert(result); 214 214 215 215 errno_t rc; 216 216 ipc_call_t answer; … … 221 221 async_wait_for(req, &rc); 222 222 vfs_exchange_release(exch); 223 223 224 224 if (rc != EOK) 225 225 return rc; 226 226 227 227 unsigned last = *pfirst + *plen; 228 228 *pfirst = IPC_GET_ARG3(answer) & 0xffff; 229 229 *plen = last - *pfirst; 230 230 231 231 result->triplet.fs_handle = (fs_handle_t) IPC_GET_ARG1(answer); 232 232 result->triplet.service_id = base->service_id; … … 248 248 if (rc != EOK) 249 249 return rc; 250 250 251 251 size_t next = first; 252 252 size_t nlen = len; 253 253 254 254 vfs_lookup_res_t res; 255 255 256 256 /* Resolve path as long as there are mount points to cross. */ 257 257 while (nlen > 0) { … … 261 261 goto out; 262 262 } 263 263 264 264 base = base->mount; 265 265 } 266 266 267 267 rc = out_lookup((vfs_triplet_t *) base, &next, &nlen, lflag, 268 268 &res); 269 269 if (rc != EOK) 270 270 goto out; 271 271 272 272 if (nlen > 0) { 273 273 base = vfs_node_peek(&res); … … 288 288 } 289 289 } 290 290 291 291 assert(nlen == 0); 292 292 rc = EOK; 293 293 294 294 if (result != NULL) { 295 295 /* The found file may be a mount point. Try to cross it. */ … … 303 303 base = nbase; 304 304 } 305 305 306 306 result->triplet = *((vfs_triplet_t *) base); 307 307 result->type = base->type; … … 316 316 *result = res; 317 317 } 318 318 319 319 out: 320 320 plb_clear_entry(&entry, first, len); … … 339 339 assert(base != NULL); 340 340 assert(path != NULL); 341 341 342 342 size_t len; 343 343 errno_t rc; … … 348 348 } 349 349 path = npath; 350 350 351 351 assert(path[0] == '/'); 352 352 … … 367 367 char *slash = str_rchr(path, L'/'); 368 368 vfs_node_t *parent = base; 369 369 370 370 if (slash != path) { 371 371 int tflag = lflag; … … 392 392 rc = _vfs_lookup_internal(base, path, lflag, result, len); 393 393 } 394 394 395 395 return rc; 396 396 } -
uspace/srv/vfs/vfs_node.c
r3061bc1 ra35b458 108 108 { 109 109 bool free_node = false; 110 111 fibril_mutex_lock(&nodes_mutex); 112 110 111 fibril_mutex_lock(&nodes_mutex); 112 113 113 node->refcnt--; 114 114 if (node->refcnt == 0) { … … 117 117 * Remove it from the VFS node hash table. 118 118 */ 119 119 120 120 hash_table_remove_item(&nodes, &node->nh_link); 121 121 free_node = true; 122 122 } 123 124 fibril_mutex_unlock(&nodes_mutex); 125 123 124 fibril_mutex_unlock(&nodes_mutex); 125 126 126 if (free_node) { 127 127 /* … … 129 129 * are no more hard links. 130 130 */ 131 131 132 132 async_exch_t *exch = vfs_exchange_grab(node->fs_handle); 133 133 async_msg_2(exch, VFS_OUT_DESTROY, (sysarg_t) node->service_id, … … 239 239 (node->service_id == rd->service_id)) 240 240 rd->refcnt += node->refcnt; 241 241 242 242 return true; 243 243 } … … 268 268 { 269 269 async_exch_t *exch = vfs_exchange_grab(node->fs_handle); 270 270 271 271 ipc_call_t answer; 272 272 aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE, 273 273 (sysarg_t) node->service_id, (sysarg_t) node->index, &answer); 274 274 275 275 vfs_exchange_release(exch); 276 276 277 277 errno_t rc; 278 278 async_wait_for(req, &rc); 279 279 280 280 return rc; 281 281 } … … 311 311 .index = node->index 312 312 }; 313 313 314 314 return tri; 315 315 } -
uspace/srv/vfs/vfs_ops.c
r3061bc1 ra35b458 64 64 { 65 65 size_t res = 0; 66 66 67 67 while (a[res] == b[res] && a[res] != 0) 68 68 res++; 69 69 70 70 if (a[res] == b[res]) 71 71 return res; 72 72 73 73 res--; 74 74 while (a[res] != '/') … … 93 93 if (oldfd == newfd) 94 94 return EOK; 95 95 96 96 /* Lookup the file structure corresponding to fd. */ 97 97 vfs_file_t *oldfile = vfs_file_get(oldfd); … … 112 112 newfile->permissions = oldfile->permissions; 113 113 vfs_node_addref(newfile->node); 114 114 115 115 vfs_file_put(newfile); 116 116 } 117 117 } 118 118 vfs_file_put(oldfile); 119 119 120 120 return rc; 121 121 } … … 131 131 { 132 132 fs_handle_t fs_handle = 0; 133 133 134 134 fibril_mutex_lock(&fs_list_lock); 135 135 while (true) { 136 136 fs_handle = fs_name_to_handle(instance, fsname, false); 137 137 138 138 if (fs_handle != 0 || !(flags & VFS_MOUNT_BLOCKING)) 139 139 break; 140 140 141 141 fibril_condvar_wait(&fs_list_cv, &fs_list_lock); 142 142 } … … 145 145 if (fs_handle == 0) 146 146 return ENOFS; 147 147 148 148 /* Tell the mountee that it is being mounted. */ 149 149 ipc_call_t answer; … … 164 164 return rc; 165 165 } 166 166 167 167 vfs_lookup_res_t res; 168 168 res.triplet.fs_handle = fs_handle; … … 172 172 IPC_GET_ARG3(answer)); 173 173 res.type = VFS_NODE_DIRECTORY; 174 174 175 175 /* Add reference to the mounted root. */ 176 176 *root = vfs_node_get(&res); … … 182 182 return ENOMEM; 183 183 } 184 184 185 185 vfs_exchange_release(exch); 186 186 … … 194 194 errno_t rc; 195 195 errno_t retval; 196 196 197 197 fibril_mutex_lock(&fs_list_lock); 198 198 fs_handle = fs_name_to_handle(0, fs_name, false); 199 199 fibril_mutex_unlock(&fs_list_lock); 200 200 201 201 if (fs_handle == 0) 202 202 return ENOFS; 203 203 204 204 /* Send probe request to the file system server */ 205 205 ipc_call_t answer; … … 209 209 if (msg == 0) 210 210 return EINVAL; 211 211 212 212 /* Read probe information */ 213 213 retval = async_data_read_start(exch, info, sizeof(*info)); … … 216 216 return retval; 217 217 } 218 218 219 219 async_wait_for(msg, &rc); 220 220 vfs_exchange_release(exch); … … 229 229 vfs_file_t *file = NULL; 230 230 *out_fd = -1; 231 231 232 232 if (!(flags & VFS_MOUNT_CONNECT_ONLY)) { 233 233 mp = vfs_file_get(mpfd); … … 236 236 goto out; 237 237 } 238 238 239 239 if (mp->node->mount != NULL) { 240 240 rc = EBUSY; 241 241 goto out; 242 242 } 243 243 244 244 if (mp->node->type != VFS_NODE_DIRECTORY) { 245 245 rc = ENOTDIR; 246 246 goto out; 247 247 } 248 248 249 249 if (vfs_node_has_children(mp->node)) { 250 250 rc = ENOTEMPTY; … … 252 252 } 253 253 } 254 254 255 255 if (!(flags & VFS_MOUNT_NO_REF)) { 256 256 rc = vfs_fd_alloc(&file, false, out_fd); … … 259 259 } 260 260 } 261 261 262 262 vfs_node_t *root = NULL; 263 263 264 264 fibril_rwlock_write_lock(&namespace_rwlock); 265 265 … … 271 271 mp->node->mount = root; 272 272 } 273 273 274 274 fibril_rwlock_write_unlock(&namespace_rwlock); 275 275 276 276 if (rc != EOK) 277 277 goto out; 278 278 279 279 if (flags & VFS_MOUNT_NO_REF) { 280 280 vfs_node_delref(root); 281 281 } else { 282 282 assert(file != NULL); 283 283 284 284 file->node = root; 285 285 file->permissions = MODE_READ | MODE_WRITE | MODE_APPEND; … … 287 287 file->open_write = false; 288 288 } 289 289 290 290 out: 291 291 if (mp) … … 298 298 *out_fd = -1; 299 299 } 300 300 301 301 return rc; 302 302 } … … 310 310 if (!file) 311 311 return EBADF; 312 312 313 313 if ((mode & ~file->permissions) != 0) { 314 314 vfs_file_put(file); 315 315 return EPERM; 316 316 } 317 317 318 318 if (file->open_read || file->open_write) { 319 319 vfs_file_put(file); 320 320 return EBUSY; 321 321 } 322 322 323 323 file->open_read = (mode & MODE_READ) != 0; 324 324 file->open_write = (mode & (MODE_WRITE | MODE_APPEND)) != 0; 325 325 file->append = (mode & MODE_APPEND) != 0; 326 326 327 327 if (!file->open_read && !file->open_write) { 328 328 vfs_file_put(file); 329 329 return EINVAL; 330 330 } 331 331 332 332 if (file->node->type == VFS_NODE_DIRECTORY && file->open_write) { 333 333 file->open_read = file->open_write = false; … … 335 335 return EINVAL; 336 336 } 337 337 338 338 errno_t rc = vfs_open_node_remote(file->node); 339 339 if (rc != EOK) { … … 342 342 return rc; 343 343 } 344 344 345 345 vfs_file_put(file); 346 346 return EOK; … … 385 385 if (exch == NULL) 386 386 return ENOENT; 387 387 388 388 aid_t msg = async_send_fast(exch, read ? VFS_OUT_READ : VFS_OUT_WRITE, 389 389 file->node->service_id, file->node->index, LOWER32(pos), … … 397 397 return retval; 398 398 } 399 399 400 400 errno_t rc; 401 401 async_wait_for(msg, &rc); 402 402 403 403 chunk->size = IPC_GET_ARG1(*answer); 404 404 … … 418 418 * open files supports parallel access! 419 419 */ 420 420 421 421 /* Lookup the file structure corresponding to the file descriptor. */ 422 422 vfs_file_t *file = vfs_file_get(fd); 423 423 if (!file) 424 424 return EBADF; 425 425 426 426 if ((read && !file->open_read) || (!read && !file->open_write)) { 427 427 vfs_file_put(file); 428 428 return EINVAL; 429 429 } 430 430 431 431 vfs_info_t *fs_info = fs_handle_to_info(file->node->fs_handle); 432 432 assert(fs_info); 433 433 434 434 bool rlock = read || 435 435 (fs_info->concurrent_read_write && fs_info->write_retains_size); 436 436 437 437 /* 438 438 * Lock the file's node so that no other client can read/write to it at … … 444 444 else 445 445 fibril_rwlock_write_lock(&file->node->contents_rwlock); 446 446 447 447 if (file->node->type == VFS_NODE_DIRECTORY) { 448 448 /* … … 450 450 * while we are in readdir(). 451 451 */ 452 452 453 453 if (!read) { 454 454 if (rlock) { … … 462 462 return EINVAL; 463 463 } 464 464 465 465 fibril_rwlock_read_lock(&namespace_rwlock); 466 466 } 467 467 468 468 async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle); 469 469 470 470 if (!read && file->append) 471 471 pos = file->node->size; 472 472 473 473 /* 474 474 * Handle communication with the endpoint FS. … … 476 476 ipc_call_t answer; 477 477 errno_t rc = ipc_cb(fs_exch, file, pos, &answer, read, ipc_cb_data); 478 478 479 479 vfs_exchange_release(fs_exch); 480 480 481 481 if (file->node->type == VFS_NODE_DIRECTORY) 482 482 fibril_rwlock_read_unlock(&namespace_rwlock); 483 483 484 484 /* Unlock the VFS node. */ 485 485 if (rlock) { … … 493 493 fibril_rwlock_write_unlock(&file->node->contents_rwlock); 494 494 } 495 495 496 496 vfs_file_put(file); 497 497 … … 518 518 vfs_node_addref(base); 519 519 vfs_file_put(base_file); 520 520 521 521 vfs_lookup_res_t base_lr; 522 522 vfs_lookup_res_t old_lr; 523 523 vfs_lookup_res_t new_lr_orig; 524 524 bool orig_unlinked = false; 525 525 526 526 errno_t rc; 527 527 528 528 size_t shared = shared_path(old, new); 529 529 530 530 /* Do not allow one path to be a prefix of the other. */ 531 531 if (old[shared] == 0 || new[shared] == 0) { … … 535 535 assert(old[shared] == '/'); 536 536 assert(new[shared] == '/'); 537 537 538 538 fibril_rwlock_write_lock(&namespace_rwlock); 539 539 540 540 /* Resolve the shared portion of the path first. */ 541 541 if (shared != 0) { … … 547 547 return rc; 548 548 } 549 549 550 550 vfs_node_put(base); 551 551 base = vfs_node_get(&base_lr); … … 565 565 return rc; 566 566 } 567 567 568 568 rc = vfs_lookup_internal(base, new, L_UNLINK | L_DISABLE_MOUNTS, 569 569 &new_lr_orig); … … 595 595 return rc; 596 596 } 597 597 598 598 /* If the node is not held by anyone, try to destroy it. */ 599 599 if (orig_unlinked) { … … 604 604 vfs_node_put(node); 605 605 } 606 606 607 607 vfs_node_put(base); 608 608 fibril_rwlock_write_unlock(&namespace_rwlock); … … 617 617 618 618 fibril_rwlock_write_lock(&file->node->contents_rwlock); 619 619 620 620 errno_t rc = vfs_truncate_internal(file->node->fs_handle, 621 621 file->node->service_id, file->node->index, size); 622 622 if (rc == EOK) 623 623 file->node->size = size; 624 624 625 625 fibril_rwlock_write_unlock(&file->node->contents_rwlock); 626 626 vfs_file_put(file); … … 640 640 node->service_id, node->index, true, 0, NULL); 641 641 vfs_exchange_release(exch); 642 642 643 643 vfs_file_put(file); 644 644 return rc; … … 667 667 if (!file) 668 668 return EBADF; 669 669 670 670 async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle); 671 671 672 672 aid_t msg; 673 673 ipc_call_t answer; 674 674 msg = async_send_2(fs_exch, VFS_OUT_SYNC, file->node->service_id, 675 675 file->node->index, &answer); 676 676 677 677 vfs_exchange_release(fs_exch); 678 678 679 679 errno_t rc; 680 680 async_wait_for(msg, &rc); 681 681 682 682 vfs_file_put(file); 683 683 return rc; 684 684 685 685 } 686 686 … … 693 693 UPPER32(size)); 694 694 vfs_exchange_release(exch); 695 695 696 696 return (errno_t) rc; 697 697 } … … 702 702 vfs_file_t *parent = NULL; 703 703 vfs_file_t *expect = NULL; 704 704 705 705 if (parentfd == expectfd) 706 706 return EINVAL; 707 707 708 708 fibril_rwlock_write_lock(&namespace_rwlock); 709 709 710 710 /* 711 711 * Files are retrieved in order of file descriptors, to prevent … … 719 719 } 720 720 } 721 721 722 722 if (expectfd >= 0) { 723 723 expect = vfs_file_get(expectfd); … … 727 727 } 728 728 } 729 729 730 730 if (parentfd > expectfd) { 731 731 parent = vfs_file_get(parentfd); … … 735 735 } 736 736 } 737 737 738 738 assert(parent != NULL); 739 739 740 740 if (expectfd >= 0) { 741 741 vfs_lookup_res_t lr; … … 743 743 if (rc != EOK) 744 744 goto exit; 745 745 746 746 vfs_node_t *found_node = vfs_node_peek(&lr); 747 747 vfs_node_put(found_node); … … 750 750 goto exit; 751 751 } 752 752 753 753 vfs_file_put(expect); 754 754 expect = NULL; 755 755 } 756 756 757 757 vfs_lookup_res_t lr; 758 758 rc = vfs_lookup_internal(parent->node, path, L_UNLINK, &lr); … … 783 783 if (mp == NULL) 784 784 return EBADF; 785 785 786 786 if (mp->node->mount == NULL) { 787 787 vfs_file_put(mp); 788 788 return ENOENT; 789 789 } 790 790 791 791 fibril_rwlock_write_lock(&namespace_rwlock); 792 792 793 793 /* 794 794 * Count the total number of references for the mounted file system. We … … 804 804 return EBUSY; 805 805 } 806 806 807 807 async_exch_t *exch = vfs_exchange_grab(mp->node->mount->fs_handle); 808 808 errno_t rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED, 809 809 mp->node->mount->service_id); 810 810 vfs_exchange_release(exch); 811 811 812 812 if (rc != EOK) { 813 813 vfs_file_put(mp); … … 815 815 return rc; 816 816 } 817 817 818 818 vfs_node_forget(mp->node->mount); 819 819 vfs_node_put(mp->node); 820 820 mp->node->mount = NULL; 821 821 822 822 fibril_rwlock_write_unlock(&namespace_rwlock); 823 823 824 824 vfs_file_put(mp); 825 825 return EOK; … … 866 866 if (!walk_flags_valid(flags)) 867 867 return EINVAL; 868 868 869 869 vfs_file_t *parent = vfs_file_get(parentfd); 870 870 if (!parent) 871 871 return EBADF; 872 872 873 873 fibril_rwlock_read_lock(&namespace_rwlock); 874 874 875 875 vfs_lookup_res_t lr; 876 876 errno_t rc = vfs_lookup_internal(parent->node, path, … … 881 881 return rc; 882 882 } 883 883 884 884 vfs_node_t *node = vfs_node_get(&lr); 885 885 if (!node) { … … 888 888 return ENOMEM; 889 889 } 890 890 891 891 vfs_file_t *file; 892 892 rc = vfs_fd_alloc(&file, false, out_fd); … … 897 897 } 898 898 assert(file != NULL); 899 899 900 900 file->node = node; 901 901 file->permissions = parent->permissions; 902 902 file->open_read = false; 903 903 file->open_write = false; 904 904 905 905 vfs_file_put(file); 906 906 vfs_file_put(parent); 907 907 908 908 fibril_rwlock_read_unlock(&namespace_rwlock); 909 909 -
uspace/srv/vfs/vfs_register.c
r3061bc1 ra35b458 71 71 { 72 72 int i; 73 73 74 74 /* 75 75 * Check if the name is non-empty and is composed solely of ASCII … … 80 80 return false; 81 81 } 82 82 83 83 for (i = 1; i < FS_NAME_MAXLEN; i++) { 84 84 if (!(islower(info->name[i]) || isdigit(info->name[i])) && … … 93 93 } 94 94 } 95 95 96 96 /* 97 97 * This check is not redundant. It ensures that the name is … … 102 102 return false; 103 103 } 104 104 105 105 return true; 106 106 } … … 116 116 dprintf("Processing VFS_REGISTER request received from %zx.\n", 117 117 request->in_phone_hash); 118 118 119 119 vfs_info_t *vfs_info; 120 120 errno_t rc = async_data_write_accept((void **) &vfs_info, false, 121 121 sizeof(vfs_info_t), sizeof(vfs_info_t), 0, NULL); 122 122 123 123 if (rc != EOK) { 124 124 dprintf("Failed to deliver the VFS info into our AS, rc=%d.\n", … … 127 127 return; 128 128 } 129 129 130 130 /* 131 131 * Allocate and initialize a buffer for the fs_info structure. … … 137 137 return; 138 138 } 139 139 140 140 link_initialize(&fs_info->fs_link); 141 141 fs_info->vfs_info = *vfs_info; 142 142 free(vfs_info); 143 143 144 144 dprintf("VFS info delivered.\n"); 145 145 146 146 if (!vfs_info_sane(&fs_info->vfs_info)) { 147 147 free(fs_info); … … 149 149 return; 150 150 } 151 151 152 152 fibril_mutex_lock(&fs_list_lock); 153 153 154 154 /* 155 155 * Check for duplicit registrations. … … 166 166 return; 167 167 } 168 168 169 169 /* 170 170 * Add fs_info to the list of registered FS's. … … 172 172 dprintf("Inserting FS into the list of registered file systems.\n"); 173 173 list_append(&fs_info->fs_link, &fs_list); 174 174 175 175 /* 176 176 * Now we want the client to send us the IPC_M_CONNECT_TO_ME call so … … 187 187 return; 188 188 } 189 189 190 190 dprintf("Callback connection to FS created.\n"); 191 191 192 192 /* 193 193 * The client will want us to send him the address space area with PLB. 194 194 */ 195 195 196 196 size_t size; 197 197 ipc_callid_t callid; … … 206 206 return; 207 207 } 208 208 209 209 /* 210 210 * We can only send the client address space area PLB_SIZE bytes long. … … 220 220 return; 221 221 } 222 222 223 223 /* 224 224 * Commit to read-only sharing the PLB with the client. … … 226 226 (void) async_share_in_finalize(callid, plb, 227 227 AS_AREA_READ | AS_AREA_CACHEABLE); 228 228 229 229 dprintf("Sharing PLB.\n"); 230 230 231 231 /* 232 232 * That was it. The FS has been registered. … … 236 236 fs_info->fs_handle = (fs_handle_t) atomic_postinc(&fs_handle_next); 237 237 async_answer_1(rid, EOK, (sysarg_t) fs_info->fs_handle); 238 238 239 239 fibril_condvar_broadcast(&fs_list_cv); 240 240 fibril_mutex_unlock(&fs_list_lock); 241 241 242 242 dprintf("\"%.*s\" filesystem successfully registered, handle=%d.\n", 243 243 FS_NAME_MAXLEN, fs_info->vfs_info.name, fs_info->fs_handle); … … 260 260 */ 261 261 fibril_mutex_lock(&fs_list_lock); 262 262 263 263 list_foreach(fs_list, fs_link, fs_info_t, fs) { 264 264 if (fs->fs_handle == handle) { 265 265 fibril_mutex_unlock(&fs_list_lock); 266 266 267 267 assert(fs->sess); 268 268 async_exch_t *exch = async_exchange_begin(fs->sess); 269 269 270 270 assert(exch); 271 271 return exch; 272 272 } 273 273 } 274 274 275 275 fibril_mutex_unlock(&fs_list_lock); 276 276 277 277 return NULL; 278 278 } … … 300 300 { 301 301 int handle = 0; 302 302 303 303 if (lock) 304 304 fibril_mutex_lock(&fs_list_lock); 305 305 306 306 list_foreach(fs_list, fs_link, fs_info_t, fs) { 307 307 if (str_cmp(fs->vfs_info.name, name) == 0 && … … 311 311 } 312 312 } 313 313 314 314 if (lock) 315 315 fibril_mutex_unlock(&fs_list_lock); 316 316 317 317 return handle; 318 318 } … … 328 328 { 329 329 vfs_info_t *info = NULL; 330 330 331 331 fibril_mutex_lock(&fs_list_lock); 332 332 list_foreach(fs_list, fs_link, fs_info_t, fs) { … … 337 337 } 338 338 fibril_mutex_unlock(&fs_list_lock); 339 339 340 340 return info; 341 341 } … … 355 355 356 356 fibril_mutex_lock(&fs_list_lock); 357 357 358 358 size = 0; 359 359 count = 0; … … 362 362 count++; 363 363 } 364 364 365 365 if (size == 0) 366 366 size = 1; 367 367 368 368 fstypes->buf = calloc(1, size); 369 369 if (fstypes->buf == NULL) { … … 371 371 return ENOMEM; 372 372 } 373 373 374 374 fstypes->fstypes = calloc(sizeof(char *), count); 375 375 if (fstypes->fstypes == NULL) { … … 379 379 return ENOMEM; 380 380 } 381 381 382 382 fstypes->size = size; 383 383 384 384 size = 0; count = 0; 385 385 list_foreach(fs_list, fs_link, fs_info_t, fs) {
Note:
See TracChangeset
for help on using the changeset viewer.