75 WS_ASSERT(rq); |
97 WS_ASSERT(rq); |
76 |
98 |
77 VFSContext *ctx = pool_malloc(sn->pool, sizeof(VFSContext)); |
99 VFSContext *ctx = pool_malloc(sn->pool, sizeof(VFSContext)); |
78 ctx->sn = sn; |
100 ctx->sn = sn; |
79 ctx->rq = rq; |
101 ctx->rq = rq; |
80 ctx->vfs = rq->vfs; |
102 ctx->vfs = rq->vfs ? rq->vfs : &sys_vfs; |
81 ctx->user = acllist_getuser(sn, rq, rq->acllist); |
103 ctx->user = acllist_getuser(sn, rq, rq->acllist); |
82 ctx->acllist = rq->acllist; |
104 ctx->acllist = rq->acllist; |
83 ctx->aclreqaccess = rq->aclreqaccess; |
105 ctx->aclreqaccess = rq->aclreqaccess; |
84 ctx->pool = sn->pool; |
106 ctx->pool = sn->pool; |
85 ctx->vfs_errno = 0; |
107 ctx->vfs_errno = 0; |
86 return ctx; |
108 return ctx; |
87 } |
109 } |
88 |
110 |
89 SYS_FILE vfs_open(VFSContext *ctx, char *path, int oflags) { |
111 SYS_FILE vfs_open(VFSContext *ctx, char *path, int oflags) { |
|
112 WS_ASSERT(ctx); |
90 WS_ASSERT(path); |
113 WS_ASSERT(path); |
91 |
114 |
92 Session *sn; |
115 uint32_t access_mask = ctx->aclreqaccess | acl_oflag2mask(oflags); |
93 Request *rq; |
116 |
94 pool_handle_t *pool; |
117 // ctx->aclreqaccess should be the complete access mask |
95 uint32_t access_mask; |
118 uint32_t m = ctx->aclreqaccess; // save original access mask |
96 |
119 ctx->aclreqaccess = access_mask; // set mask for vfs->open call |
97 if(ctx) { |
120 if((ctx->vfs->flags & VFS_CHECKS_ACL) != VFS_CHECKS_ACL) { |
98 access_mask = ctx->aclreqaccess; |
121 // VFS does not evaluates the ACL itself, so we have to do it here |
99 access_mask |= acl_oflag2mask(oflags); |
122 SysACL sysacl; |
100 if(!ctx->pool) { |
123 if(sys_acl_check(ctx, access_mask, &sysacl)) { |
101 // TODO: log warning |
124 return NULL; |
102 // broken VFSContext |
125 } |
103 } |
126 } |
104 if(ctx->vfs) { |
127 SYS_FILE file = ctx->vfs->open(ctx, path, oflags); |
105 // ctx->aclreqaccess should be the complete access mask |
128 ctx->aclreqaccess = m; // restore original access mask |
106 uint32_t m = ctx->aclreqaccess; // save original access mask |
129 return file; |
107 ctx->aclreqaccess = access_mask; // set mask for vfs->open call |
130 } |
108 SYS_FILE file = ctx->vfs->open(ctx, path, oflags); |
131 |
109 ctx->aclreqaccess = m; // restore original access mask |
132 SYS_FILE vfs_openRO(VFSContext *ctx, char *path) { |
110 return file; |
133 return vfs_open(ctx, path, O_RDONLY); |
111 } else { |
134 } |
112 pool = ctx->pool; |
135 |
113 } |
136 SYS_FILE vfs_openWO(VFSContext *ctx, char *path) { |
|
137 return vfs_open(ctx, path, O_WRONLY | O_CREAT); |
|
138 } |
|
139 |
|
140 SYS_FILE vfs_openRW(VFSContext *ctx, char *path) { |
|
141 return vfs_open(ctx, path, O_RDONLY | O_WRONLY | O_CREAT); |
|
142 } |
|
143 |
|
144 int vfs_stat(VFSContext *ctx, char *path, struct stat *buf) { |
|
145 WS_ASSERT(ctx); |
|
146 WS_ASSERT(path); |
|
147 |
|
148 uint32_t access_mask = ctx->aclreqaccess | ACL_READ_ATTRIBUTES; |
|
149 |
|
150 // ctx->aclreqaccess should be the complete access mask |
|
151 uint32_t m = ctx->aclreqaccess; // save original access mask |
|
152 ctx->aclreqaccess = access_mask; // set mask for vfs->open call |
|
153 if((ctx->vfs->flags & VFS_CHECKS_ACL) != VFS_CHECKS_ACL) { |
|
154 // VFS does not evaluates the ACL itself, so we have to do it here |
|
155 SysACL sysacl; |
|
156 if(sys_acl_check(ctx, access_mask, &sysacl)) { |
|
157 return -1; |
|
158 } |
|
159 } |
|
160 int ret = ctx->vfs->stat(ctx, path, buf); |
|
161 ctx->aclreqaccess = m; // restore original access mask |
|
162 return ret; |
|
163 } |
|
164 |
|
165 int vfs_fstat(VFSContext *ctx, SYS_FILE fd, struct stat *buf) { |
|
166 WS_ASSERT(ctx); |
|
167 WS_ASSERT(fd); |
|
168 WS_ASSERT(buf); |
|
169 |
|
170 return ctx->vfs->fstat(ctx, fd, buf); |
|
171 } |
|
172 |
|
173 void vfs_close(SYS_FILE fd) { |
|
174 WS_ASSERT(fd); |
|
175 |
|
176 fd->io->close(fd); |
|
177 if(fd->ctx) { |
|
178 pool_free(fd->ctx->pool, fd); |
114 } else { |
179 } else { |
115 sn = NULL; |
180 free(fd); |
116 rq = NULL; |
181 } |
117 pool = NULL; |
182 } |
118 access_mask = acl_oflag2mask(oflags); |
183 |
119 } |
184 VFS_DIR vfs_opendir(VFSContext *ctx, char *path) { |
|
185 WS_ASSERT(ctx); |
|
186 WS_ASSERT(path); |
|
187 |
|
188 uint32_t access_mask = ctx->aclreqaccess | ACL_LIST; |
|
189 |
|
190 // ctx->aclreqaccess should be the complete access mask |
|
191 uint32_t m = ctx->aclreqaccess; // save original access mask |
|
192 ctx->aclreqaccess = access_mask; // set mask for vfs->open call |
|
193 if((ctx->vfs->flags & VFS_CHECKS_ACL) != VFS_CHECKS_ACL) { |
|
194 // VFS does not evaluates the ACL itself, so we have to do it here |
|
195 SysACL sysacl; |
|
196 if(sys_acl_check(ctx, access_mask, &sysacl)) { |
|
197 return NULL; |
|
198 } |
|
199 } |
|
200 VFS_DIR dir = ctx->vfs->opendir(ctx, path); |
|
201 ctx->aclreqaccess = m; // restore original access mask |
|
202 return dir; |
|
203 } |
|
204 |
|
205 int vfs_readdir(VFS_DIR dir, VFS_ENTRY *entry) { |
|
206 WS_ASSERT(dir); |
|
207 WS_ASSERT(entry); |
|
208 |
|
209 return dir->io->readdir(dir, entry, 0); |
|
210 } |
|
211 |
|
212 int vfs_readdir_stat(VFS_DIR dir, VFS_ENTRY *entry) { |
|
213 WS_ASSERT(dir); |
|
214 WS_ASSERT(entry); |
|
215 |
|
216 return dir->io->readdir(dir, entry, 1); |
|
217 } |
|
218 |
|
219 void vfs_closedir(VFS_DIR dir) { |
|
220 WS_ASSERT(dir); |
|
221 |
|
222 dir->io->close(dir); |
|
223 if(dir->ctx) { |
|
224 VFS_FREE(dir->ctx->pool, dir); |
|
225 } else { |
|
226 free(dir); |
|
227 } |
|
228 } |
|
229 |
|
230 int vfs_mkdir(VFSContext *ctx, char *path) { |
|
231 WS_ASSERT(ctx); |
|
232 WS_ASSERT(path); |
|
233 |
|
234 return vfs_path_op(ctx, path, ctx->vfs->mkdir, ACL_ADD_FILE); |
|
235 } |
|
236 |
|
237 int vfs_unlink(VFSContext *ctx, char *path) { |
|
238 WS_ASSERT(ctx); |
|
239 WS_ASSERT(path); |
|
240 |
|
241 return vfs_path_op(ctx, path, ctx->vfs->unlink, ACL_DELETE); |
|
242 } |
|
243 |
|
244 |
|
245 // private |
|
246 int vfs_path_op(VFSContext *ctx, char *path, vfs_op_f op, uint32_t access) { |
|
247 uint32_t access_mask = ctx->aclreqaccess; |
|
248 access_mask |= access; |
|
249 |
|
250 // ctx->aclreqaccess should be the complete access mask |
|
251 uint32_t m = ctx->aclreqaccess; // save original access mask |
|
252 ctx->aclreqaccess = access_mask; // set mask for vfs function call |
|
253 if((ctx->vfs->flags & VFS_CHECKS_ACL) != VFS_CHECKS_ACL) { |
|
254 // VFS does not evaluates the ACL itself, so we have to do it here |
|
255 SysACL sysacl; |
|
256 if(sys_acl_check(ctx, access_mask, &sysacl)) { |
|
257 return -1; |
|
258 } |
|
259 } |
|
260 int ret = op(ctx, path); |
|
261 ctx->aclreqaccess = m; // restore original access mask |
|
262 return ret; |
|
263 } |
|
264 |
|
265 /* system vfs implementation */ |
|
266 |
|
267 SYS_FILE sys_vfs_open(VFSContext *ctx, char *path, int oflags) { |
|
268 uint32_t access_mask = ctx->aclreqaccess; |
|
269 pool_handle_t *pool = ctx->pool; |
120 |
270 |
121 // check ACLs |
271 // check ACLs |
122 SysACL sysacl; |
272 SysACL sysacl; |
123 if(sys_acl_check(ctx, access_mask, &sysacl)) { |
273 if(sys_acl_check(ctx, access_mask, &sysacl)) { |
124 return NULL; |
274 return NULL; |
163 file->fd = fd; |
311 file->fd = fd; |
164 file->io = &sys_file_io; |
312 file->io = &sys_file_io; |
165 return file; |
313 return file; |
166 } |
314 } |
167 |
315 |
168 SYS_FILE vfs_openRO(VFSContext *ctx, char *path) { |
316 int sys_vfs_stat(VFSContext *ctx, char *path, struct stat *buf) { |
169 return vfs_open(ctx, path, O_RDONLY); |
317 uint32_t access_mask = ctx->aclreqaccess; |
170 } |
|
171 |
|
172 SYS_FILE vfs_openWO(VFSContext *ctx, char *path) { |
|
173 return vfs_open(ctx, path, O_WRONLY | O_CREAT); |
|
174 } |
|
175 |
|
176 SYS_FILE vfs_openRW(VFSContext *ctx, char *path) { |
|
177 return vfs_open(ctx, path, O_RDONLY | O_WRONLY | O_CREAT); |
|
178 } |
|
179 |
|
180 int vfs_stat(VFSContext *ctx, char *path, struct stat *buf) { |
|
181 Session *sn; |
|
182 Request *rq; |
|
183 uint32_t access_mask; |
|
184 |
|
185 if(ctx) { |
|
186 access_mask = ctx->aclreqaccess; |
|
187 access_mask |= ACL_READ_ATTRIBUTES; |
|
188 if(!ctx->pool) { |
|
189 // TODO: log warning |
|
190 // broken VFSContext |
|
191 } |
|
192 if(ctx->vfs) { |
|
193 // ctx->aclreqaccess should be the complete access mask |
|
194 uint32_t m = ctx->aclreqaccess; // save original access mask |
|
195 ctx->aclreqaccess = access_mask; // set mask for vfs->fstat call |
|
196 int ret = ctx->vfs->stat(ctx, path, buf); |
|
197 ctx->aclreqaccess = m; // restore original access mask |
|
198 return ret; |
|
199 } |
|
200 } else { |
|
201 sn = NULL; |
|
202 rq = NULL; |
|
203 access_mask = ACL_READ_ATTRIBUTES; |
|
204 } |
|
205 |
318 |
206 // check ACLs |
319 // check ACLs |
207 SysACL sysacl; |
320 SysACL sysacl; |
208 if(sys_acl_check(ctx, access_mask, &sysacl)) { |
321 if(sys_acl_check(ctx, access_mask, &sysacl)) { |
209 return -1; |
322 return -1; |
325 sys_set_error_status(ctx); |
391 sys_set_error_status(ctx); |
326 } |
392 } |
327 return NULL; |
393 return NULL; |
328 } |
394 } |
329 |
395 |
330 SysVFSDir *dir_data = pool ? |
396 SysVFSDir *dir_data = VFS_MALLOC(pool, sizeof(SysVFSDir)); |
331 pool_malloc(pool, sizeof(SysVFSDir)) : malloc(sizeof(SysVFSDir)); |
|
332 if(!dir_data) { |
397 if(!dir_data) { |
333 closedir(sys_dir); |
398 closedir(sys_dir); |
334 return NULL; |
399 return NULL; |
335 } |
400 } |
336 long maxfilelen = fpathconf(dir_fd, _PC_NAME_MAX); |
401 long maxfilelen = fpathconf(dir_fd, _PC_NAME_MAX); |
337 size_t entry_len = offsetof(struct dirent, d_name) + maxfilelen + 1; |
402 size_t entry_len = offsetof(struct dirent, d_name) + maxfilelen + 1; |
338 dir_data->cur = pool ? |
403 dir_data->cur = VFS_MALLOC(pool, entry_len); |
339 pool_malloc(pool, entry_len) : malloc(entry_len); |
|
340 if(!dir_data->cur) { |
404 if(!dir_data->cur) { |
341 closedir(sys_dir); |
405 closedir(sys_dir); |
|
406 VFS_FREE(pool, dir_data); |
342 return NULL; |
407 return NULL; |
343 } |
408 } |
344 dir_data->dir = sys_dir; |
409 dir_data->dir = sys_dir; |
345 |
410 |
346 VFSDir *dir = pool ? |
411 VFSDir *dir = VFS_MALLOC(pool, sizeof(VFSDir)); |
347 pool_malloc(pool, sizeof(VFSDir)) : malloc(sizeof(VFSDir)); |
|
348 if(!dir) { |
412 if(!dir) { |
349 closedir(sys_dir); |
413 closedir(sys_dir); |
|
414 VFS_FREE(pool, dir_data->cur); |
|
415 VFS_FREE(pool, dir_data); |
350 return NULL; |
416 return NULL; |
351 } |
417 } |
352 dir->ctx = ctx; |
418 dir->ctx = ctx; |
353 dir->data = dir_data; |
419 dir->data = dir_data; |
354 dir->fd = dir_fd; |
420 dir->fd = dir_fd; |
355 dir->io = &sys_dir_io; |
421 dir->io = &sys_dir_io; |
356 return dir; |
422 return dir; |
357 } |
423 } |
358 |
424 |
359 int vfs_readdir(VFS_DIR dir, VFS_ENTRY *entry) { |
425 int sys_vfs_mkdir(VFSContext *ctx, char *path) { |
360 return dir->io->readdir(dir, entry, 0); |
426 return sys_path_op(ctx, path, sys_mkdir); |
361 } |
427 } |
362 |
428 |
363 int vfs_readdir_stat(VFS_DIR dir, VFS_ENTRY *entry) { |
429 int sys_vfs_unlink(VFSContext *ctx, char *path) { |
364 return dir->io->readdir(dir, entry, 1); |
430 return sys_path_op(ctx, path, sys_unlink); |
365 } |
431 } |
366 |
432 |
367 void vfs_closedir(VFS_DIR dir) { |
433 |
368 dir->io->close(dir); |
434 int sys_path_op(VFSContext *ctx, char *path, sys_op_f op) { |
369 if(dir->ctx) { |
|
370 pool_free(dir->ctx->pool, dir); |
|
371 } else { |
|
372 free(dir); |
|
373 } |
|
374 } |
|
375 |
|
376 int vfs_mkdir(VFSContext *ctx, char *path) { |
|
377 if(ctx && ctx->vfs) { |
|
378 return vfs_path_op(ctx, path, ctx->vfs->mkdir, ACL_ADD_FILE); |
|
379 } else { |
|
380 return sys_path_op(ctx, path, sys_mkdir, ACL_ADD_FILE); |
|
381 } |
|
382 } |
|
383 |
|
384 int vfs_unlink(VFSContext *ctx, char *path) { |
|
385 if(ctx && ctx->vfs) { |
|
386 return vfs_path_op(ctx, path, ctx->vfs->unlink, ACL_DELETE); |
|
387 } else { |
|
388 return sys_path_op(ctx, path, sys_unlink, ACL_DELETE); |
|
389 } |
|
390 } |
|
391 |
|
392 |
|
393 // private |
|
394 int vfs_path_op(VFSContext *ctx, char *path, vfs_op_f op, uint32_t access) { |
|
395 Session *sn; |
|
396 Request *rq; |
|
397 |
|
398 uint32_t access_mask = ctx->aclreqaccess; |
435 uint32_t access_mask = ctx->aclreqaccess; |
399 access_mask |= access; |
|
400 if(!ctx->pool) { |
|
401 // TODO: log warning |
|
402 // broken VFSContext |
|
403 return -1; |
|
404 } |
|
405 |
|
406 // ctx->aclreqaccess should be the complete access mask |
|
407 uint32_t m = ctx->aclreqaccess; // save original access mask |
|
408 ctx->aclreqaccess = access_mask; // set mask for vfs function call |
|
409 int ret = op(ctx, path); |
|
410 ctx->aclreqaccess = m; // restore original access mask |
|
411 return ret; |
|
412 } |
|
413 |
|
414 int sys_path_op(VFSContext *ctx, char *path, sys_op_f op, uint32_t access) { |
|
415 if(ctx) { |
|
416 access |= ctx->aclreqaccess; |
|
417 } |
|
418 |
436 |
419 // check ACLs |
437 // check ACLs |
420 SysACL sysacl; |
438 SysACL sysacl; |
421 if(sys_acl_check(ctx, access, &sysacl)) { |
439 if(sys_acl_check(ctx, access_mask, &sysacl)) { |
422 return -1; |
440 return -1; |
423 } |
441 } |
424 |
442 |
425 if(sysacl.acl) { |
443 if(sysacl.acl) { |
426 if(!fs_acl_check(&sysacl, ctx->user, path, access)) { |
444 if(!fs_acl_check(&sysacl, ctx->user, path, access_mask)) { |
427 acl_set_error_status(ctx->sn, ctx->rq, sysacl.acl, ctx->user); |
445 acl_set_error_status(ctx->sn, ctx->rq, sysacl.acl, ctx->user); |
428 return -1; |
446 return -1; |
429 } |
447 } |
430 } |
448 } |
431 |
449 |
432 // do path operation |
450 // do path operation |
433 if(op(ctx, path, &sysacl)) { |
451 if(op(ctx, path, &sysacl)) { |
434 // error |
452 // error |
435 if(ctx) { |
453 ctx->vfs_errno = errno; |
436 ctx->vfs_errno = errno; |
454 sys_set_error_status(ctx); |
437 sys_set_error_status(ctx); |
|
438 } |
|
439 return -1; |
455 return -1; |
440 } |
456 } |
441 |
457 |
442 return 0; |
458 return 0; |
443 } |
459 } |
480 |
496 |
481 ssize_t sys_file_write(SYS_FILE fd, const void *buf, size_t nbyte) { |
497 ssize_t sys_file_write(SYS_FILE fd, const void *buf, size_t nbyte) { |
482 return write(fd->fd, buf, nbyte); |
498 return write(fd->fd, buf, nbyte); |
483 } |
499 } |
484 |
500 |
|
501 ssize_t sys_file_pread(SYS_FILE fd, void *buf, size_t nbyte, off_t offset) { |
|
502 return pread(fd->fd, buf, nbyte, offset); |
|
503 } |
|
504 |
|
505 ssize_t sys_file_pwrite(SYS_FILE fd, const void *buf, size_t nbyte, off_t offset) { |
|
506 return pwrite(fd->fd, buf, nbyte, offset); |
|
507 } |
|
508 |
485 off_t sys_file_seek(SYS_FILE fd, off_t offset, int whence) { |
509 off_t sys_file_seek(SYS_FILE fd, off_t offset, int whence) { |
486 return lseek(fd->fd, offset, whence); |
510 return lseek(fd->fd, offset, whence); |
487 } |
511 } |
488 |
512 |
489 void sys_file_close(SYS_FILE fd) { |
513 void sys_file_close(SYS_FILE fd) { |
490 system_close(fd->fd); |
514 system_close(fd->fd); |
491 } |
515 } |
|
516 |
|
517 int sys_file_aioread(aiocb_s *aiocb) { |
|
518 WS_ASSERT(aiocb->buf); |
|
519 WS_ASSERT(aiocb->nbytes > 0); |
|
520 return ev_aioread(aiocb->filedes->fd, aiocb); |
|
521 } |
|
522 |
|
523 int sys_file_aiowrite(aiocb_s *aiocb) { |
|
524 WS_ASSERT(aiocb->buf); |
|
525 WS_ASSERT(aiocb->nbytes > 0); |
|
526 return ev_aiowrite(aiocb->filedes->fd, aiocb); |
|
527 } |
|
528 |
492 |
529 |
493 int sys_dir_read(VFS_DIR dir, VFS_ENTRY *entry, int getstat) { |
530 int sys_dir_read(VFS_DIR dir, VFS_ENTRY *entry, int getstat) { |
494 SysVFSDir *dirdata = dir->data; |
531 SysVFSDir *dirdata = dir->data; |
495 struct dirent *result = NULL; |
532 struct dirent *result = NULL; |
496 int s = readdir_r(dirdata->dir, dirdata->cur, &result); |
533 int s = readdir_r(dirdata->dir, dirdata->cur, &result); |
561 |
592 |
562 NSAPI_PUBLIC int system_fwrite(SYS_FILE fd, const void *buf, int nbyte) { |
593 NSAPI_PUBLIC int system_fwrite(SYS_FILE fd, const void *buf, int nbyte) { |
563 return fd->io->write(fd, buf, nbyte); |
594 return fd->io->write(fd, buf, nbyte); |
564 } |
595 } |
565 |
596 |
|
597 NSAPI_PUBLIC int system_pread(SYS_FILE fd, void *buf, int nbyte, off_t offset) { |
|
598 return fd->io->pread(fd, buf, nbyte, offset); |
|
599 } |
|
600 |
|
601 NSAPI_PUBLIC int system_pwrite(SYS_FILE fd, const void *buf, int nbyte, off_t offset) { |
|
602 return fd->io->pwrite(fd, buf, nbyte, offset); |
|
603 } |
|
604 |
566 NSAPI_PUBLIC off_t system_lseek(SYS_FILE fd, off_t offset, int whence) { |
605 NSAPI_PUBLIC off_t system_lseek(SYS_FILE fd, off_t offset, int whence) { |
567 return fd->io->seek(fd, offset, whence); |
606 return fd->io->seek(fd, offset, whence); |
568 } |
607 } |
569 |
608 |
570 NSAPI_PUBLIC int system_fclose(SYS_FILE fd) { |
609 NSAPI_PUBLIC int system_fclose(SYS_FILE fd) { |
571 vfs_close(fd); |
610 vfs_close(fd); |
572 return 0; |
611 return 0; |
573 } |
612 } |
|
613 |
|
614 // AIO API |
|
615 |
|
616 NSAPI_PUBLIC int system_aio_read(aiocb_s *aiocb) { |
|
617 if(!aiocb->event || !aiocb->evhandler) { |
|
618 return -1; |
|
619 } |
|
620 |
|
621 SYS_FILE file = aiocb->filedes; |
|
622 aiocb->event->object = (intptr_t)aiocb; |
|
623 if(file->io->opt_aioread) { |
|
624 return file->io->opt_aioread(aiocb); |
|
625 } else { |
|
626 vfs_queue_aio(aiocb, VFS_AIO_READ); |
|
627 return 0; |
|
628 } |
|
629 } |
|
630 |
|
631 NSAPI_PUBLIC int system_aio_write(aiocb_s *aiocb) { |
|
632 if(!aiocb->event || !aiocb->evhandler) { |
|
633 return -1; |
|
634 } |
|
635 |
|
636 SYS_FILE file = aiocb->filedes; |
|
637 aiocb->event->object = (intptr_t)aiocb; |
|
638 if(file->io->opt_aiowrite) { |
|
639 return file->io->opt_aiowrite(aiocb); |
|
640 } else { |
|
641 vfs_queue_aio(aiocb, VFS_AIO_WRITE); |
|
642 return 0; |
|
643 } |
|
644 } |
|
645 |
|
646 static void* vfs_aio_read(aiocb_s *aiocb) { |
|
647 int result = system_pread(aiocb->filedes, aiocb->buf, aiocb->nbytes, aiocb->offset); |
|
648 aiocb->result = result; |
|
649 if(result < 0) { |
|
650 aiocb->result_errno = errno; |
|
651 } |
|
652 event_send(aiocb->evhandler, aiocb->event); |
|
653 return NULL; |
|
654 } |
|
655 |
|
656 static void* vfs_aio_write(aiocb_s *aiocb) { |
|
657 int result = system_pwrite(aiocb->filedes, aiocb->buf, aiocb->nbytes, aiocb->offset); |
|
658 aiocb->result = result; |
|
659 if(result < 0) { |
|
660 aiocb->result_errno = errno; |
|
661 } |
|
662 event_send(aiocb->evhandler, aiocb->event); |
|
663 return NULL; |
|
664 } |
|
665 |
|
666 void vfs_queue_aio(aiocb_s *aiocb, VFSAioOp op) { |
|
667 threadpool_t *pool = get_default_iopool(); // TODO: use specific IOPool |
|
668 if(op == VFS_AIO_READ) { |
|
669 threadpool_run(pool, (job_callback_f)vfs_aio_read, aiocb); |
|
670 } else if(VFS_AIO_WRITE) { |
|
671 threadpool_run(pool, (job_callback_f)vfs_aio_write, aiocb); |
|
672 } |
|
673 } |