2
2
#include "kernel/calls.h"
3
3
#include "kernel/task.h"
4
4
#include "kernel/aio.h"
5
+ #include "kernel/fs.h"
5
6
#include "fs/aio.h"
6
7
#include "fs/fd.h"
7
8
@@ -186,7 +187,9 @@ dword_t sys_io_cancel(dword_t ctx_id, addr_t iocb, addr_t result) {
186
187
* Do a single PREAD operation, falling back to seek-and-read if necessary.
187
188
*
188
189
* The return code corresponds to the 'sync error' concept of fallback_submit,
189
- * while async errors should be flagged by writing to *err.
190
+ * while async errors should be flagged by writing to `*err`.
191
+ *
192
+ * `*err` also is used to return the total number of bytes read.
190
193
*/
191
194
static signed int __aio_fallback_pread (
192
195
struct fd * fd ,
@@ -243,7 +246,9 @@ static signed int __aio_fallback_pread(
243
246
* Do a single PWRITE operation, falling back to seek-and-write if necessary.
244
247
*
245
248
* The return code corresponds to the 'sync error' concept of fallback_submit,
246
- * while async errors should be flagged by writing to *err.
249
+ * while async errors should be flagged by writing to `*err`.
250
+ *
251
+ * `*err` also is used to return the total number of bytes written.
247
252
*/
248
253
static signed int __aio_fallback_pwrite (
249
254
struct fd * fd ,
@@ -316,7 +321,7 @@ int aio_fallback_submit(struct fd *fd, struct aioctx *ctx, unsigned int event_id
316
321
return sync_err ;
317
322
}
318
323
319
- char * buf = NULL ;
324
+ struct iovec_ * iov_list = NULL ;
320
325
switch (evt -> op ) {
321
326
case AIOCTX_PREAD :
322
327
sync_err = __aio_fallback_pread (fd , (addr_t )evt -> buf , evt -> nbytes , evt -> offset , & async_result0 );
@@ -337,7 +342,63 @@ int aio_fallback_submit(struct fd *fd, struct aioctx *ctx, unsigned int event_id
337
342
async_result0 = 0 ;
338
343
sync_err = 0 ;
339
344
break ;
340
- //TODO: AIOCTX_POLL, AIOCTX_PREADV, AIOCTX_PWRITEV
345
+ case AIOCTX_PREADV :
346
+ iov_list = read_iovec ((addr_t )evt -> buf , evt -> nbytes );
347
+ if (IS_ERR (iov_list )) {
348
+ sync_err = PTR_ERR (iov_list );
349
+ break ;
350
+ }
351
+
352
+ ssize_t total_read = 0 ;
353
+
354
+ for (unsigned int i = 0 ; i < evt -> nbytes ; i += 1 ) {
355
+ signed int cur_read = 0 ;
356
+ sync_err = __aio_fallback_pread (fd , iov_list [i ].base , iov_list [i ].len , evt -> offset + total_read , & cur_read );
357
+ if (sync_err < 0 || cur_read < 0 ) {
358
+ async_result0 = cur_read ;
359
+ break ;
360
+ }
361
+
362
+ total_read += cur_read ;
363
+
364
+ if ((uint_t )cur_read < iov_list [i ].len ) break ;
365
+ }
366
+
367
+ free (iov_list );
368
+
369
+ if (sync_err < 0 || async_result0 < 0 ) break ;
370
+
371
+ async_result0 = total_read ;
372
+ break ;
373
+ case AIOCTX_PWRITEV :
374
+ iov_list = read_iovec ((addr_t )evt -> buf , evt -> nbytes );
375
+ if (IS_ERR (iov_list )) {
376
+ sync_err = PTR_ERR (iov_list );
377
+ break ;
378
+ }
379
+
380
+ ssize_t total_write = 0 ;
381
+
382
+ for (unsigned int i = 0 ; i < evt -> nbytes ; i += 1 ) {
383
+ signed int cur_write = 0 ;
384
+ sync_err = __aio_fallback_pwrite (fd , iov_list [i ].base , iov_list [i ].len , evt -> offset + total_write , & cur_write );
385
+ if (sync_err < 0 || cur_write < 0 ) {
386
+ async_result0 = cur_write ;
387
+ break ;
388
+ }
389
+
390
+ total_write += cur_write ;
391
+
392
+ if ((uint_t )cur_write < iov_list [i ].len ) break ;
393
+ }
394
+
395
+ free (iov_list );
396
+
397
+ if (sync_err < 0 || async_result0 < 0 ) break ;
398
+
399
+ async_result0 = total_write ;
400
+ break ;
401
+ //TODO: AIOCTX_POLL
341
402
default :
342
403
sync_err = _EINVAL ;
343
404
break ;
0 commit comments