Skip to content

Commit 7f105ac

Browse files
yixinghua121unicornx
authored andcommitted
lwp: fix large file read&write
Signed-off-by: yixinghua <[email protected]>
1 parent ae31b98 commit 7f105ac

File tree

1 file changed

+65
-28
lines changed

1 file changed

+65
-28
lines changed

components/lwp/lwp_syscall.c

+65-28
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ void lwp_cleanup(struct rt_thread *tid);
116116

117117
#ifdef ARCH_MM_MMU
118118
#define ALLOC_KERNEL_STACK_SIZE 5120
119+
#define KMEM_MAX_SIZE (64 * 1024)
119120

120121
static void *kmem_get(size_t size)
121122
{
@@ -386,40 +387,55 @@ ssize_t sys_read(int fd, void *buf, size_t nbyte)
386387
#ifdef ARCH_MM_MMU
387388
void *kmem = RT_NULL;
388389
ssize_t ret = -1;
390+
ssize_t size = 0, rd_byte;
389391

390392
if (!nbyte)
391393
{
392394
return -EINVAL;
393395
}
394396

395-
if (!lwp_user_accessable((void *)buf, nbyte))
397+
if (!lwp_user_accessable(buf, nbyte))
396398
{
397399
return -EFAULT;
398400
}
399401

400-
kmem = kmem_get(nbyte);
402+
kmem = kmem_get(nbyte > KMEM_MAX_SIZE ? KMEM_MAX_SIZE : nbyte);
401403
if (!kmem)
402404
{
403405
return -ENOMEM;
404406
}
405407

406-
ret = read(fd, kmem, nbyte);
407-
if (ret > 0)
408-
{
409-
if (ret != lwp_put_to_user(buf, kmem, ret))
410-
return -EFAULT;
411-
}
412-
413-
if (ret < 0)
408+
while (nbyte)
414409
{
415-
ret = GET_ERRNO();
410+
rd_byte = nbyte > KMEM_MAX_SIZE ? KMEM_MAX_SIZE : nbyte;
411+
ret = read(fd, kmem, rd_byte);
412+
if (ret > 0)
413+
{
414+
if (ret != lwp_put_to_user(buf, kmem, ret))
415+
{
416+
ret = -EFAULT;
417+
break;
418+
}
419+
buf += ret;
420+
size += ret;
421+
nbyte -= ret;
422+
if (ret == rd_byte)
423+
{
424+
continue;
425+
}
426+
}
427+
else if (ret < 0)
428+
{
429+
ret = GET_ERRNO();
430+
}
431+
break;
416432
}
417433

418434
kmem_put(kmem);
419435

420-
return ret;
436+
return ret < 0 ? ret : size;
421437
#else
422-
if (!lwp_user_accessable((void *)buf, nbyte))
438+
if (!lwp_user_accessable(buf, nbyte))
423439
{
424440
return -EFAULT;
425441
}
@@ -434,32 +450,53 @@ ssize_t sys_write(int fd, const void *buf, size_t nbyte)
434450
#ifdef ARCH_MM_MMU
435451
void *kmem = RT_NULL;
436452
ssize_t ret = -1;
453+
ssize_t size = 0, wr_byte;
437454

438-
if (nbyte)
455+
if (!nbyte)
439456
{
440-
if (!lwp_user_accessable((void *)buf, nbyte))
441-
{
442-
return -EFAULT;
443-
}
457+
return -EINVAL;
458+
}
444459

445-
kmem = kmem_get(nbyte);
446-
if (!kmem)
447-
{
448-
return -ENOMEM;
449-
}
460+
if (!lwp_user_accessable((void *)buf, nbyte))
461+
{
462+
return -EFAULT;
463+
}
450464

451-
lwp_get_from_user(kmem, (void *)buf, nbyte);
465+
kmem = kmem_get(nbyte > KMEM_MAX_SIZE ? KMEM_MAX_SIZE : nbyte);
466+
if (!kmem)
467+
{
468+
return -ENOMEM;
452469
}
453470

454-
ret = write(fd, kmem, nbyte);
455-
if (ret < 0)
471+
while (nbyte)
456472
{
457-
ret = GET_ERRNO();
473+
wr_byte = nbyte > KMEM_MAX_SIZE ? KMEM_MAX_SIZE : nbyte;
474+
if (wr_byte != lwp_get_from_user(kmem, (void *)buf, wr_byte))
475+
{
476+
ret = -EFAULT;
477+
break;
478+
}
479+
ret = write(fd, kmem, wr_byte);
480+
if (ret > 0)
481+
{
482+
buf += ret;
483+
size += ret;
484+
nbyte -= ret;
485+
if (ret == wr_byte)
486+
{
487+
continue;
488+
}
489+
}
490+
else if (ret < 0)
491+
{
492+
ret = GET_ERRNO();
493+
}
494+
break;
458495
}
459496

460497
kmem_put(kmem);
461498

462-
return ret;
499+
return ret < 0 ? ret : size;
463500
#else
464501
if (!lwp_user_accessable((void *)buf, nbyte))
465502
{

0 commit comments

Comments
 (0)