[PATCH] libmisc/untar: Use a larger block size to read and write files

Joel Sherrill joel at rtems.org
Fri Apr 1 03:27:58 UTC 2022


On Thu, Mar 31, 2022, 10:17 PM Chris Johns <chrisj at rtems.org> wrote:

> On 1/4/2022 11:14 am, Joel Sherrill wrote:
> > This looks ok. Does it impact any array declaration that I missed? I'm
> just
> > worrying about changes in stack consumption.
>
> Not that I could see. A buffer allocated on the heap is now bigger to hold
> the
> larger data block and that has been adjusted.
>

Ok. That's there only issue I had.


> I have an application where the JFFS slowed down from 4.11 to 6 and the
> only
> difference I could see was 6 had a lot more, I would say 50%, small blocks
> being
> written to the flash device over 4.11. This change makes using untar on
> JFFS
> much more efficient.
>

That's odd by itself to have more smaller blocks but great to get the
performance boost.

>
> Chris
>
> >
> > On Thu, Mar 31, 2022, 6:26 PM <chrisj at rtems.org <mailto:chrisj at rtems.org>>
> wrote:
> >
> >     From: Chris Johns <chrisj at rtems.org <mailto:chrisj at rtems.org>>
> >
> >     - A larger block size lets files systems work better. On JFFS
> >       a 512 byte compressed block means lots of small flash updates
> >
> >     Closes #4635
> >     ---
> >      cpukit/libmisc/untar/untar.c | 53
> ++++++++++++++++++++++--------------
> >      1 file changed, 33 insertions(+), 20 deletions(-)
> >
> >     diff --git a/cpukit/libmisc/untar/untar.c
> b/cpukit/libmisc/untar/untar.c
> >     index 7bc1fff02a..fff737db68 100644
> >     --- a/cpukit/libmisc/untar/untar.c
> >     +++ b/cpukit/libmisc/untar/untar.c
> >     @@ -84,6 +84,14 @@
> >
> >      #define MAX_NAME_FIELD_SIZE      99
> >
> >     +#define TAR_BLOCK_SIZE           512
> >     +#define TAR_BLOCK_SIZE_MASK      (TAR_BLOCK_SIZE - 1)
> >     +
> >     +/*
> >     + * Number of blocks read or written
> >     + */
> >     +#define TAR_WORK_BLOCKS          16
> >     +
> >      static int _rtems_tar_header_checksum(const char *bufr);
> >
> >      /*
> >     @@ -240,7 +248,8 @@ Untar_ProcessHeader(
> >        } else if (ctx->linkflag == REGTYPE) {
> >          rtems_printf(ctx->printer, "untar: file: %s (s:%lu,m:%04lo)\n",
> >                       ctx->file_path, ctx->file_size, ctx->mode);
> >     -    ctx->nblocks = (((ctx->file_size) + 511) & ~511) / 512;
> >     +    ctx->nblocks =
> >     +      (((ctx->file_size) + TAR_BLOCK_SIZE_MASK) &
> ~TAR_BLOCK_SIZE_MASK) /
> >     TAR_BLOCK_SIZE;
> >        } else if (ctx->linkflag == DIRTYPE) {
> >          rtems_printf(ctx->printer, "untar: dir: %s\n", ctx->file_path);
> >          r = mkdir(ctx->file_path, ctx->mode);
> >     @@ -311,14 +320,14 @@ Untar_FromMemory_Print(
> >
> >        ptr = 0;
> >        while (true) {
> >     -    if (ptr + 512 > size) {
> >     +    if (ptr + TAR_BLOCK_SIZE > size) {
> >            retval = UNTAR_SUCCESSFUL;
> >            break;
> >          }
> >
> >          /* Read the header */
> >          bufr = &tar_ptr[ptr];
> >     -    ptr += 512;
> >     +    ptr += TAR_BLOCK_SIZE;
> >
> >          retval = Untar_ProcessHeader(&ctx, bufr);
> >
> >     @@ -329,27 +338,26 @@ Untar_FromMemory_Print(
> >            if ((fd = open(ctx.file_path,
> >                           O_TRUNC | O_CREAT | O_WRONLY, ctx.mode)) ==
> -1) {
> >              Print_Error(printer, "open", ctx.file_path);
> >     -        ptr += 512 * ctx.nblocks;
> >     +        ptr += TAR_BLOCK_SIZE * ctx.nblocks;
> >            } else {
> >     -        unsigned long sizeToGo = ctx.file_size;
> >     -        ssize_t       len;
> >     -        ssize_t       i;
> >     -        ssize_t       n;
> >     -
> >              /*
> >               * Read out the data.  There are nblocks of data where
> nblocks is the
> >               * file_size rounded to the nearest 512-byte boundary.
> >               */
> >     -        for (i = 0; i < ctx.nblocks; i++) {
> >     -          len = ((sizeToGo < 512L) ? (sizeToGo) : (512L));
> >     -          n = write(fd, &tar_ptr[ptr], len);
> >     +        ssize_t file_size = ctx.file_size;
> >     +        size_t blocks = ctx.nblocks;
> >     +        while (blocks > 0) {
> >     +          size_t blks = blocks > TAR_WORK_BLOCKS ? TAR_WORK_BLOCKS
> : blocks;
> >     +          ssize_t len = MIN(blks * TAR_BLOCK_SIZE, file_size);
> >     +          ssize_t n = write(fd, &tar_ptr[ptr], len);
> >                if (n != len) {
> >                  Print_Error(printer, "write", ctx.file_path);
> >                  retval  = UNTAR_FAIL;
> >                  break;
> >                }
> >     -          ptr += 512;
> >     -          sizeToGo -= n;
> >     +          ptr += blks * TAR_BLOCK_SIZE;
> >     +          file_size -= n;
> >     +          blocks -= blks;
> >              }
> >              close(fd);
> >            }
> >     @@ -419,7 +427,6 @@ Untar_FromFile_Print(
> >        char                *bufr;
> >        ssize_t              n;
> >        int                  retval;
> >     -  unsigned long        i;
> >        char                 buf[UNTAR_FILE_NAME_SIZE];
> >        Untar_HeaderContext  ctx;
> >
> >     @@ -429,7 +436,7 @@ Untar_FromFile_Print(
> >          return UNTAR_FAIL;
> >        }
> >
> >     -  bufr = (char *)malloc(512);
> >     +  bufr = (char *)malloc(TAR_WORK_BLOCKS * TAR_BLOCK_SIZE);
> >        if (bufr == NULL) {
> >          close(fd);
> >          return(UNTAR_FAIL);
> >     @@ -442,7 +449,7 @@ Untar_FromFile_Print(
> >        while (1) {
> >          /* Read the header */
> >          /* If the header read fails, we just consider it the end of the
> tarfile. */
> >     -    if ((n = read(fd, bufr, 512)) != 512) {
> >     +    if ((n = read(fd, bufr, TAR_BLOCK_SIZE)) != TAR_BLOCK_SIZE) {
> >            break;
> >          }
> >
> >     @@ -464,10 +471,16 @@ Untar_FromFile_Print(
> >              retval = UNTAR_FAIL;
> >              break;
> >            } else {
> >     -        for (i = 0; i < ctx.nblocks; i++) {
> >     -          n = read(fd, bufr, 512);
> >     -          n = MIN(n, ctx.file_size - (i * 512UL));
> >     +        ssize_t file_size = ctx.file_size;
> >     +        size_t blocks = ctx.nblocks;
> >     +        while (blocks > 0) {
> >     +          size_t blks = blocks > TAR_WORK_BLOCKS ? TAR_WORK_BLOCKS
> : blocks;
> >     +          size_t bytes = blks * TAR_BLOCK_SIZE;
> >     +          n = read(fd, bufr, bytes);
> >     +          n = MIN(n, file_size);
> >                (void) write(out_fd, bufr, n);
> >     +          file_size -= n;
> >     +          blocks -= blks;
> >              }
> >              close(out_fd);
> >            }
> >     --
> >     2.24.1
> >
> >     _______________________________________________
> >     devel mailing list
> >     devel at rtems.org <mailto:devel at rtems.org>
> >     http://lists.rtems.org/mailman/listinfo/devel
> >     <http://lists.rtems.org/mailman/listinfo/devel>
> >
>


More information about the devel mailing list