summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc/untar
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2022-03-29 18:35:40 +1100
committerChris Johns <chrisj@rtems.org>2022-04-06 08:02:30 +1000
commit500e69639e3009ae542c6677b8600af591ad7d2f (patch)
treeba9b2d9b15f6ffde5e4f1d60fb18cd3220919f40 /cpukit/libmisc/untar
parentsp0*/*.doc: Remove junk UTF-8 character (diff)
downloadrtems-500e69639e3009ae542c6677b8600af591ad7d2f.tar.bz2
libmisc/untar: Use a larger block size to read and write files
- A larger block size lets files systems work better. On JFFS a 512 byte compressed block means lots of small flash updates Closes #4635
Diffstat (limited to 'cpukit/libmisc/untar')
-rw-r--r--cpukit/libmisc/untar/untar.c53
1 files 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);
}