xiaoxiang781216 commented on code in PR #14898: URL: https://github.com/apache/nuttx/pull/14898#discussion_r1868215509
########## drivers/misc/dev_null.c: ########## @@ -87,12 +84,17 @@ static ssize_t devnull_readv(FAR struct file *filep, * Name: devnull_writev ****************************************************************************/ -static ssize_t devnull_writev(FAR struct file *filep, - FAR const struct uio *uio) +static ssize_t devnull_writev(FAR struct file *filep, FAR struct uio *uio) { UNUSED(filep); - return uio_total_len(uio); /* Say that everything was written */ + ssize_t ret = uio_total_len(uio); /* Say that everything was written */ + if (ret >= 0) + { + uio_advance(uio, ret); Review Comment: can we advance one by one to avoid iterate the vector twice ########## drivers/misc/dev_zero.c: ########## @@ -94,19 +91,27 @@ static ssize_t devzero_readv(FAR struct file *filep, memset(iov[i].iov_base, 0, iov[i].iov_len); } + uio_advance(uio, total); Review Comment: can we advance one by one to avoid iterate the vector three times ########## fs/vfs/fs_uio.c: ########## @@ -51,18 +51,69 @@ ssize_t uio_total_len(FAR const struct uio *uio) { const struct iovec *iov = uio->uio_iov; int iovcnt = uio->uio_iovcnt; + size_t offset_in_iov = uio->uio_offset_in_iov; size_t len = 0; Review Comment: change ssIze_t ########## fs/vfs/fs_read.c: ########## @@ -251,6 +256,7 @@ ssize_t nx_readv(int fd, FAR const struct iovec *iov, int iovcnt) /* Then let file_readv do all of the work. */ + uio_init(&uio); Review Comment: ditto ########## fs/vfs/fs_write.c: ########## @@ -102,6 +102,11 @@ static ssize_t file_writev_compat(FAR struct file *filep, remaining -= nwritten; } + if (ntotal >= 0) + { + uio_advance(uio, ntotal); Review Comment: move into for loop ########## fs/vfs/fs_uio.c: ########## @@ -117,3 +117,97 @@ void uio_init(FAR struct uio *uio) { memset(uio, 0, sizeof(*uio)); } + +/**************************************************************************** + * Name: uio_copyfrom + * + * Description: + * Copy data from the linear buffer to uio. + * + ****************************************************************************/ + +void uio_copyfrom(FAR struct uio *uio, size_t offset, FAR const void *buf, + size_t len) +{ + FAR const struct iovec *iov = uio->uio_iov; + + DEBUGASSERT(uio_resid(uio) >= 0); + DEBUGASSERT(len <= uio_resid(uio)); + DEBUGASSERT(offset <= uio_resid(uio) - len); + DEBUGASSERT(SSIZE_MAX - offset >= uio->uio_offset_in_iov); + + offset += uio->uio_offset_in_iov; + while (offset > iov->iov_len) + { + offset -= iov->iov_len; + iov++; + } + + while (len > 0) + { + size_t blen = len; + if (blen > iov->iov_len - offset) + { + blen = iov->iov_len - offset; + } + + memcpy((FAR uint8_t *)iov->iov_base + offset, buf, blen); + + len -= blen; + if (len == 0) Review Comment: remove ########## fs/vfs/fs_write.c: ########## @@ -205,6 +210,7 @@ ssize_t file_write(FAR struct file *filep, FAR const void *buf, iov.iov_base = (FAR void *)buf; iov.iov_len = nbytes; + uio_init(&uio); Review Comment: ditto ########## fs/vfs/fs_uio.c: ########## @@ -39,15 +39,15 @@ ****************************************************************************/ /**************************************************************************** - * Name: uio_total_len + * Name: uio_resid * * Description: - * Return the total length of data in bytes. + * Return the remaining length of data in bytes. * Or -EOVERFLOW. * ****************************************************************************/ -ssize_t uio_total_len(FAR const struct uio *uio) +ssize_t uio_resid(FAR const struct uio *uio) Review Comment: Ok, can we follow https://man.freebsd.org/cgi/man.cgi?uio(9) as much as possible, which define uio_offset and uio_resid? ########## fs/vfs/fs_read.c: ########## @@ -207,6 +211,7 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes) iov.iov_base = buf; iov.iov_len = nbytes; + uio_init(&uio); Review Comment: should we add `iov` and `count` argument to uio_init? ########## drivers/loop/loop.c: ########## @@ -84,10 +81,17 @@ static ssize_t loop_readv(FAR struct file *filep, * Name: loop_writev ****************************************************************************/ -static ssize_t loop_writev(FAR struct file *filep, - FAR const struct uio *uio) +static ssize_t loop_writev(FAR struct file *filep, FAR struct uio *uio) { - return uio_total_len(uio); /* Say that everything was written */ + /* Say that everything was written */ + + ssize_t ret = uio_total_len(uio); + if (ret >= 0) + { + uio_advance(uio, ret); Review Comment: can we advance one by one to avoid iterate the vector twice ########## fs/vfs/fs_uio.c: ########## @@ -117,3 +117,97 @@ void uio_init(FAR struct uio *uio) { memset(uio, 0, sizeof(*uio)); } + +/**************************************************************************** + * Name: uio_copyfrom + * + * Description: + * Copy data from the linear buffer to uio. + * + ****************************************************************************/ + +void uio_copyfrom(FAR struct uio *uio, size_t offset, FAR const void *buf, + size_t len) +{ + FAR const struct iovec *iov = uio->uio_iov; + + DEBUGASSERT(uio_resid(uio) >= 0); + DEBUGASSERT(len <= uio_resid(uio)); + DEBUGASSERT(offset <= uio_resid(uio) - len); + DEBUGASSERT(SSIZE_MAX - offset >= uio->uio_offset_in_iov); + + offset += uio->uio_offset_in_iov; + while (offset > iov->iov_len) + { + offset -= iov->iov_len; + iov++; + } + + while (len > 0) + { + size_t blen = len; + if (blen > iov->iov_len - offset) + { + blen = iov->iov_len - offset; + } + + memcpy((FAR uint8_t *)iov->iov_base + offset, buf, blen); + + len -= blen; + if (len == 0) + { + break; + } + + buf = (const uint8_t *)buf + blen; + iov++; + offset = 0; + } +} + +/**************************************************************************** + * Name: uio_copyto + * + * Description: + * Copy data to the linear buffer from uio. + * + ****************************************************************************/ + +void uio_copyto(FAR struct uio *uio, size_t offset, FAR void *buf, + size_t len) +{ + FAR const struct iovec *iov = uio->uio_iov; + + DEBUGASSERT(uio_resid(uio) >= 0); + DEBUGASSERT(len <= uio_resid(uio)); + DEBUGASSERT(offset <= uio_resid(uio) - len); + DEBUGASSERT(SSIZE_MAX - offset >= uio->uio_offset_in_iov); Review Comment: ditto ########## drivers/misc/dev_zero.c: ########## @@ -94,19 +91,27 @@ static ssize_t devzero_readv(FAR struct file *filep, memset(iov[i].iov_base, 0, iov[i].iov_len); } + uio_advance(uio, total); + return total; } /**************************************************************************** * Name: devzero_writev ****************************************************************************/ -static ssize_t devzero_writev(FAR struct file *filep, - FAR const struct uio *uio) +static ssize_t devzero_writev(FAR struct file *filep, FAR struct uio *uio) { + ssize_t total; UNUSED(filep); - return uio_total_len(uio); + total = uio_total_len(uio); + if (total >= 0) + { + uio_advance(uio, total); Review Comment: can we advance one by one to avoid iterate the vector twice ########## drivers/serial/serial.c: ########## @@ -1408,9 +1469,9 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, */ uart_disabletxint(dev); - for (; buflen; buflen--) + for (; buflen; uio_advance(uio, 1), buflen--) Review Comment: merge line 1474 ########## fs/vfs/fs_read.c: ########## @@ -102,6 +101,11 @@ static ssize_t file_readv_compat(FAR struct file *filep, remaining -= nread; } + if (ntotal >= 0) + { + uio_advance(uio, ntotal); Review Comment: can we advance in the loop to avoid iterate the vector twice ########## drivers/loop/loop.c: ########## @@ -85,7 +85,7 @@ static ssize_t loop_writev(FAR struct file *filep, FAR struct uio *uio) { /* Say that everything was written */ - ssize_t ret = uio_total_len(uio); + ssize_t ret = uio_resid(uio); Review Comment: merge to previous patch ########## fs/vfs/fs_uio.c: ########## @@ -117,3 +117,97 @@ void uio_init(FAR struct uio *uio) { memset(uio, 0, sizeof(*uio)); } + +/**************************************************************************** + * Name: uio_copyfrom + * + * Description: + * Copy data from the linear buffer to uio. + * + ****************************************************************************/ + +void uio_copyfrom(FAR struct uio *uio, size_t offset, FAR const void *buf, + size_t len) +{ + FAR const struct iovec *iov = uio->uio_iov; + + DEBUGASSERT(uio_resid(uio) >= 0); + DEBUGASSERT(len <= uio_resid(uio)); + DEBUGASSERT(offset <= uio_resid(uio) - len); + DEBUGASSERT(SSIZE_MAX - offset >= uio->uio_offset_in_iov); + + offset += uio->uio_offset_in_iov; + while (offset > iov->iov_len) + { + offset -= iov->iov_len; + iov++; + } + + while (len > 0) + { + size_t blen = len; + if (blen > iov->iov_len - offset) + { + blen = iov->iov_len - offset; + } + + memcpy((FAR uint8_t *)iov->iov_base + offset, buf, blen); + + len -= blen; + if (len == 0) + { + break; + } + + buf = (const uint8_t *)buf + blen; + iov++; + offset = 0; + } +} + +/**************************************************************************** + * Name: uio_copyto + * + * Description: + * Copy data to the linear buffer from uio. + * + ****************************************************************************/ + +void uio_copyto(FAR struct uio *uio, size_t offset, FAR void *buf, + size_t len) +{ + FAR const struct iovec *iov = uio->uio_iov; + + DEBUGASSERT(uio_resid(uio) >= 0); + DEBUGASSERT(len <= uio_resid(uio)); + DEBUGASSERT(offset <= uio_resid(uio) - len); + DEBUGASSERT(SSIZE_MAX - offset >= uio->uio_offset_in_iov); + + offset += uio->uio_offset_in_iov; + while (offset > iov->iov_len) + { + offset -= iov->iov_len; + iov++; + } + + while (len > 0) + { + size_t blen = len; + if (blen > iov->iov_len - offset) + { + blen = iov->iov_len - offset; + } + + memcpy(buf, (FAR const uint8_t *)iov->iov_base + offset, blen); + + len -= blen; + if (len == 0) Review Comment: remove ########## fs/vfs/fs_uio.c: ########## @@ -117,3 +117,97 @@ void uio_init(FAR struct uio *uio) { memset(uio, 0, sizeof(*uio)); } + +/**************************************************************************** + * Name: uio_copyfrom + * + * Description: + * Copy data from the linear buffer to uio. + * + ****************************************************************************/ + +void uio_copyfrom(FAR struct uio *uio, size_t offset, FAR const void *buf, + size_t len) +{ + FAR const struct iovec *iov = uio->uio_iov; + + DEBUGASSERT(uio_resid(uio) >= 0); + DEBUGASSERT(len <= uio_resid(uio)); + DEBUGASSERT(offset <= uio_resid(uio) - len); + DEBUGASSERT(SSIZE_MAX - offset >= uio->uio_offset_in_iov); Review Comment: SSIZE_MAX to SIZE_MAX ########## fs/vfs/fs_write.c: ########## @@ -252,6 +258,7 @@ ssize_t nx_writev(int fd, FAR const struct iovec *iov, int iovcnt) * index. Note that file_writev() will return the errno on failure. */ + uio_init(&uio); Review Comment: ditto ########## drivers/serial/serial.c: ########## @@ -1363,12 +1418,18 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, #endif flags = enter_critical_section(); - ret = uart_irqwrite(dev, buffer, buflen); + ret = uart_irqwritev(dev, uio); leave_critical_section(flags); return ret; } + buflen = nwritten = uio_resid(uio); + if (nwritten < 0) Review Comment: why add the additional check -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org