Date: Wed, 1 Oct 2014 01:18:25 +0000 (UTC) From: Marcel Moolenaar <marcel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r272338 - user/marcel/mkimg Message-ID: <201410010118.s911IPb0039776@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: marcel Date: Wed Oct 1 01:18:25 2014 New Revision: 272338 URL: http://svnweb.freebsd.org/changeset/base/272338 Log: Implement image_copyout_region(): This is the one function that is responsible for writing to the output file. For eack chunk that covers all or parts of the region to write, call a corresponding function that knows how to write a chunk of that type: image_copyout_memory(): Use write(2) to write the buffer. image_copyout_zeroes(): Try and seek forward to create a sparse file. If that fails, scribble zeroes to the output file to support writing to stdout. Use image_copyout_memoryIO for that. image_copyout_file(): Iteratively map bits of the input file and use image_copyout_memory() to write the bits to the output file. With this commit all unit tests pass again. Modified: user/marcel/mkimg/image.c Modified: user/marcel/mkimg/image.c ============================================================================== --- user/marcel/mkimg/image.c Tue Sep 30 23:29:06 2014 (r272337) +++ user/marcel/mkimg/image.c Wed Oct 1 01:18:25 2014 (r272338) @@ -499,6 +499,10 @@ image_copyin(lba_t blk, int fd, uint64_t return (error); } +/* + * Output/sink file handling. + */ + int image_copyout(int fd) { @@ -523,46 +527,103 @@ image_copyout_done(int fd) return (error); } -int -image_copyout_region(int fd, lba_t blk, lba_t size) +static int +image_copyout_memory(int fd, size_t size, void *ptr) { - char *buffer; - off_t ofs; - size_t bufsz, sz; - ssize_t rdsz, wrsz; + + if (write(fd, ptr, size) == -1) + return (errno); + return (0); +} + +static int +image_copyout_zeroes(int fd, size_t size) +{ + static uint8_t *zeroes = NULL; + size_t sz; int error; - bufsz = secsz * image_swap_pgsz; + if (lseek(fd, (off_t)size, SEEK_CUR) != -1) + return (0); - ofs = lseek(fd, 0L, SEEK_CUR); + /* + * If we can't seek, we must write. + */ + + if (zeroes == NULL) { + zeroes = calloc(1, secsz); + if (zeroes == NULL) + return (ENOMEM); + } + + while (size > 0) { + sz = (size > secsz) ? secsz : size; + error = image_copyout_memory(fd, sz, zeroes); + if (error) + return (error); + size -= sz; + } + return (0); +} + +static int +image_copyout_file(int fd, size_t size, int ifd, off_t iofs) +{ + void *buf; + size_t iosz, sz; + int error; + + iosz = secsz * image_swap_pgsz; + + while (size > 0) { + sz = (size > iosz) ? iosz : size; + buf = image_file_map(ifd, iofs, sz); + if (buf == NULL) + return (errno); + error = image_copyout_memory(fd, sz, buf); + image_file_unmap(buf, sz); + if (error) + return (error); + size -= sz; + iofs += sz; + } + return (0); +} + +int +image_copyout_region(int fd, lba_t blk, lba_t size) +{ + struct chunk *ch; + size_t ofs, sz; + int error; - blk *= secsz; - if (lseek(image_swap_fd, blk, SEEK_SET) != blk) - return (errno); - buffer = malloc(bufsz); - if (buffer == NULL) - return (errno); - error = 0; size *= secsz; + while (size > 0) { - sz = ((ssize_t)bufsz < size) ? bufsz : (size_t)size; - rdsz = read(image_swap_fd, buffer, sz); - if (rdsz <= 0) { - error = (rdsz < 0) ? errno : 0; + ch = image_chunk_find(blk); + if (ch == NULL) + return (EINVAL); + ofs = (blk - ch->ch_block) * secsz; + sz = ch->ch_size - ofs; + sz = ((lba_t)sz < size) ? sz : (size_t)size; + switch (ch->ch_type) { + case CH_TYPE_ZEROES: + error = image_copyout_zeroes(fd, sz); break; - } - wrsz = (ofs == -1) ? - write(fd, buffer, rdsz) : - sparse_write(fd, buffer, rdsz); - if (wrsz < 0) { - error = errno; + case CH_TYPE_FILE: + error = image_copyout_file(fd, sz, ch->ch_u.file.fd, + ch->ch_u.file.ofs + ofs); break; + case CH_TYPE_MEMORY: + error = image_copyout_memory(fd, sz, ch->ch_u.mem.ptr); + break; + default: + return (EDOOFUS); } - assert(wrsz == rdsz); - size -= rdsz; + size -= sz; + blk += sz / secsz; } - free(buffer); - return (error); + return (0); } int
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201410010118.s911IPb0039776>