Skip to content

Commit

Permalink
move readv/writev to the kernel
Browse files Browse the repository at this point in the history
currently, nuttx implements readv/writev on the top of read/write.
while it might work for the simplest cases, it's broken by design.
for example, it's impossible to make it work correctly for files
which need to preserve data boundaries without allocating a single
contiguous buffer. (udp socket, some character devices, etc)

this change is a start of the migration to a better design.
that is, implement read/write on the top of readv/writev.

to avoid a single huge change, following things will NOT be done in
this commit:

* fix actual bugs caused by the original readv-based-on-read design.
  (cf. apache/nuttx#12674)

* adapt filesystems/drivers to actually benefit from the new interface.
  (except a few trivial examples)

* eventually retire the old interface.

* retire read/write syscalls. implement them in libc instead.

* pread/pwrite/preadv/pwritev (except the introduction of struct uio,
  which is a preparation to back these variations with the new
  interface.)
  • Loading branch information
yamt authored and guohao15 committed Dec 27, 2024
1 parent 6bc5cb2 commit 821128f
Show file tree
Hide file tree
Showing 68 changed files with 782 additions and 398 deletions.
4 changes: 3 additions & 1 deletion arch/arm/src/cxd56xx/cxd56_hostif.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ static const struct file_operations g_hif_fops =
hif_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
hif_poll /* poll */
hif_poll, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, hif_unlink /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/bch/bchdev_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ const struct file_operations g_bch_fops =
bch_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
bch_poll /* poll */
bch_poll, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, bch_unlink /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/i2c/i2c_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ static const struct file_operations g_i2cdrvr_fops =
i2cdrvr_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
NULL /* poll */
NULL, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, i2cdrvr_unlink /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/i2c/i2c_slave_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ static const struct file_operations g_i2cslavefops =
NULL, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
i2c_slave_poll /* poll */
i2c_slave_poll, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, i2c_slave_unlink /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/i3c/i3c_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ static const struct file_operations g_i3cdrvr_fops =
i3cdrvr_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
NULL /* poll */
NULL, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, i3cdrvr_unlink /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/input/gt9xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ static const struct file_operations g_gt9xx_fileops =
NULL, /* ioctl */
NULL, /* truncate */
NULL, /* mmap */
gt9xx_poll /* poll */
gt9xx_poll, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, NULL /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/lcd/ft80x.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ static const struct file_operations g_ft80x_fops =
ft80x_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
NULL /* poll */
NULL, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, ft80x_unlink /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/lcd/pcf8574_lcd_backpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ static const struct file_operations g_pcf8574_lcd_fops =
pcf8574_lcd_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
pcf8574_lcd_poll /* poll */
pcf8574_lcd_poll, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, pcf8574_lcd_unlink /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/lcd/tda19988.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ static const struct file_operations g_tda19988_fops =
tda19988_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
tda19988_poll /* poll */
tda19988_poll, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, tda19988_unlink /* unlink */
#endif
Expand Down
27 changes: 16 additions & 11 deletions drivers/loop/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
* Private Function Prototypes
****************************************************************************/

static ssize_t loop_read(FAR struct file *filep, FAR char *buffer,
size_t buflen);
static ssize_t loop_write(FAR struct file *filep, FAR const char *buffer,
size_t buflen);
static ssize_t loop_readv(FAR struct file *filep,
FAR const struct uio *uio);
static ssize_t loop_writev(FAR struct file *filep,
FAR const struct uio *uio);
static int loop_ioctl(FAR struct file *filep, int cmd,
unsigned long arg);

Expand All @@ -53,10 +53,15 @@ static const struct file_operations g_loop_fops =
{
NULL, /* open */
NULL, /* close */
loop_read, /* read */
loop_write, /* write */
NULL, /* read */
NULL, /* write */
NULL, /* seek */
loop_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
NULL, /* poll */
loop_readv, /* readv */
loop_writev /* writev */
};

/****************************************************************************
Expand All @@ -67,8 +72,8 @@ static const struct file_operations g_loop_fops =
* Name: loop_read
****************************************************************************/

static ssize_t loop_read(FAR struct file *filep, FAR char *buffer,
size_t len)
static ssize_t loop_readv(FAR struct file *filep,
FAR const struct uio *uio)
{
return 0; /* Return EOF */
}
Expand All @@ -77,10 +82,10 @@ static ssize_t loop_read(FAR struct file *filep, FAR char *buffer,
* Name: loop_write
****************************************************************************/

static ssize_t loop_write(FAR struct file *filep, FAR const char *buffer,
size_t len)
static ssize_t loop_writev(FAR struct file *filep,
FAR const struct uio *uio)
{
return len; /* Say that everything was written */
return uio_total_len(uio); /* Say that everything was written */
}

/****************************************************************************
Expand Down
42 changes: 21 additions & 21 deletions drivers/misc/dev_null.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
* Private Function Prototypes
****************************************************************************/

static ssize_t devnull_read(FAR struct file *filep, FAR char *buffer,
size_t buflen);
static ssize_t devnull_write(FAR struct file *filep, FAR const char *buffer,
size_t buflen);
static ssize_t devnull_readv(FAR struct file *filep,
FAR const struct uio *uio);
static ssize_t devnull_writev(FAR struct file *filep,
FAR const struct uio *uio);
static int devnull_poll(FAR struct file *filep, FAR struct pollfd *fds,
bool setup);

Expand All @@ -51,15 +51,17 @@ static int devnull_poll(FAR struct file *filep, FAR struct pollfd *fds,

static const struct file_operations g_devnull_fops =
{
NULL, /* open */
NULL, /* close */
devnull_read, /* read */
devnull_write, /* write */
NULL, /* seek */
NULL, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
devnull_poll /* poll */
NULL, /* open */
NULL, /* close */
NULL, /* read */
NULL, /* writev */
NULL, /* seek */
NULL, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
devnull_poll, /* poll */
devnull_readv, /* readv */
devnull_writev /* writev */
};

/****************************************************************************
Expand All @@ -70,12 +72,11 @@ static const struct file_operations g_devnull_fops =
* Name: devnull_read
****************************************************************************/

static ssize_t devnull_read(FAR struct file *filep, FAR char *buffer,
size_t len)
static ssize_t devnull_readv(FAR struct file *filep,
FAR const struct uio *uio)
{
UNUSED(filep);
UNUSED(buffer);
UNUSED(len);
UNUSED(uio);

return 0; /* Return EOF */
}
Expand All @@ -84,13 +85,12 @@ static ssize_t devnull_read(FAR struct file *filep, FAR char *buffer,
* Name: devnull_write
****************************************************************************/

static ssize_t devnull_write(FAR struct file *filep, FAR const char *buffer,
size_t len)
static ssize_t devnull_writev(FAR struct file *filep,
FAR const struct uio *uio)
{
UNUSED(filep);
UNUSED(buffer);

return len; /* Say that everything was written */
return uio_total_len(uio); /* Say that everything was written */
}

/****************************************************************************
Expand Down
57 changes: 36 additions & 21 deletions drivers/misc/dev_zero.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
* Private Function Prototypes
****************************************************************************/

static ssize_t devzero_read(FAR struct file *filep, FAR char *buffer,
size_t buflen);
static ssize_t devzero_write(FAR struct file *filep, FAR const char *buffer,
size_t buflen);
static ssize_t devzero_readv(FAR struct file *filep,
FAR const struct uio *uio);
static ssize_t devzero_writev(FAR struct file *filep,
FAR const struct uio *uio);
static int devzero_poll(FAR struct file *filep, FAR struct pollfd *fds,
bool setup);

Expand All @@ -51,15 +51,17 @@ static int devzero_poll(FAR struct file *filep, FAR struct pollfd *fds,

static const struct file_operations g_devzero_fops =
{
NULL, /* open */
NULL, /* close */
devzero_read, /* read */
devzero_write, /* write */
NULL, /* seek */
NULL, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
devzero_poll /* poll */
NULL, /* open */
NULL, /* close */
NULL, /* read */
NULL, /* write */
NULL, /* seek */
NULL, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
devzero_poll, /* poll */
devzero_readv, /* readv */
devzero_writev /* writev */
};

/****************************************************************************
Expand All @@ -70,26 +72,39 @@ static const struct file_operations g_devzero_fops =
* Name: devzero_read
****************************************************************************/

static ssize_t devzero_read(FAR struct file *filep, FAR char *buffer,
size_t len)
static ssize_t devzero_readv(FAR struct file *filep,
FAR const struct uio *uio)
{
ssize_t total = uio_total_len(uio);
FAR const struct iovec *iov = uio->uio_iov;
int iovcnt = uio->uio_iovcnt;
int i;

UNUSED(filep);

memset(buffer, 0, len);
return len;
if (total < 0)
{
return total;
}

for (i = 0; i < iovcnt; i++)
{
memset(iov[i].iov_base, 0, iov[i].iov_len);
}

return total;
}

/****************************************************************************
* Name: devzero_write
****************************************************************************/

static ssize_t devzero_write(FAR struct file *filep, FAR const char *buffer,
size_t len)
static ssize_t devzero_writev(FAR struct file *filep,
FAR const struct uio *uio)
{
UNUSED(filep);
UNUSED(buffer);

return len;
return uio_total_len(uio);
}

/****************************************************************************
Expand Down
4 changes: 3 additions & 1 deletion drivers/pci/pci_uio_ivshmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ static const struct file_operations g_uio_ivshmem_fops =
NULL, /* ioctl */
uio_ivshmem_mmap, /* mmap */
NULL, /* truncate */
uio_ivshmem_poll /* poll */
uio_ivshmem_poll, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, NULL /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/pipes/fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ static const struct file_operations g_fifo_fops =
pipecommon_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
pipecommon_poll /* poll */
pipecommon_poll, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, pipecommon_unlink /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/sensors/aht10.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ static const struct file_operations g_aht10fops =
aht10_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
NULL /* poll */
NULL, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, aht10_unlink /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/sensors/hdc1008.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ static const struct file_operations g_hdc1008fops =
hdc1008_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
NULL /* poll */
NULL, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, hdc1008_unlink /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/sensors/scd30.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,9 @@ static const struct file_operations g_scd30fops =
scd30_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
NULL /* poll */
NULL, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, scd30_unlink /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/sensors/scd41.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ static const struct file_operations g_scd41fops =
scd41_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
NULL /* poll */
NULL, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, scd41_unlink /* unlink */
#endif
Expand Down
4 changes: 3 additions & 1 deletion drivers/sensors/sgp30.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ static const struct file_operations g_sgp30fops =
sgp30_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* truncate */
NULL /* poll */
NULL, /* poll */
NULL, /* readv */
NULL /* writev */
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, sgp30_unlink /* unlink */
#endif
Expand Down
Loading

0 comments on commit 821128f

Please sign in to comment.