Daichi GOTO wrote: > > # cd /localapps/qemu/ > # tar cpf - disk0image | tar xpf - -S -C /nfshome/user/ > > gets follow error message. > > # tar cpf - disk0image | tar xpf - -S -C /nfshome/user/ > disk0image: Write request too large > tar: Error exit delayed from previous errors. Please try the attached patch to lib/libarchive/archive_write_disk.c, which should fix this. Cheers, Tim Index: archive_write_disk.c =================================================================== --- archive_write_disk.c (revision 187703) +++ archive_write_disk.c (revision 187704) _at__at_ -178,6 +178,8 _at__at_ int fd; /* Current offset for writing data to the file. */ off_t offset; + /* Last offset actually written to disk. */ + off_t fd_offset; /* Maximum size of file, -1 if unknown. */ off_t filesize; /* Dir we were in before this restore; only for deep paths. */ _at__at_ -187,8 +189,6 _at__at_ /* UID/GID to use in restoring this entry. */ uid_t uid; gid_t gid; - /* Last offset written to disk. */ - off_t last_offset; }; /* _at__at_ -235,7 +235,7 _at__at_ static gid_t trivial_lookup_gid(void *, const char *, gid_t); static uid_t trivial_lookup_uid(void *, const char *, uid_t); static ssize_t write_data_block(struct archive_write_disk *, - const char *, size_t, off_t); + const char *, size_t); static struct archive_vtable *archive_write_disk_vtable(void); _at__at_ -337,7 +337,7 _at__at_ } a->entry = archive_entry_clone(entry); a->fd = -1; - a->last_offset = 0; + a->fd_offset = 0; a->offset = 0; a->uid = a->user_uid; a->mode = archive_entry_mode(a->entry); _at__at_ -513,9 +513,9 _at__at_ } static ssize_t -write_data_block(struct archive_write_disk *a, - const char *buff, size_t size, off_t offset) +write_data_block(struct archive_write_disk *a, const char *buff, size_t size) { + uint64_t start_size = size; ssize_t bytes_written = 0; ssize_t block_size = 0, bytes_to_write; _at__at_ -538,8 +538,9 _at__at_ #endif } - if (a->filesize >= 0 && (off_t)(offset + size) > a->filesize) - size = (size_t)(a->filesize - offset); + /* If this write would run beyond the file size, truncate it. */ + if (a->filesize >= 0 && (off_t)(a->offset + size) > a->filesize) + start_size = size = (size_t)(a->filesize - a->offset); /* Write the data. */ while (size > 0) { _at__at_ -555,7 +556,7 _at__at_ if (*p != '\0') break; } - offset += p - buff; + a->offset += p - buff; size -= p - buff; buff = p; if (size == 0) _at__at_ -563,22 +564,25 _at__at_ /* Calculate next block boundary after offset. */ block_end - = (offset / block_size) * block_size + block_size; + = (a->offset / block_size + 1) * block_size; /* If the adjusted write would cross block boundary, * truncate it to the block boundary. */ bytes_to_write = size; - if (offset + bytes_to_write > block_end) - bytes_to_write = block_end - offset; + if (a->offset + bytes_to_write > block_end) + bytes_to_write = block_end - a->offset; } /* Seek if necessary to the specified offset. */ - if (offset != a->last_offset) { - if (lseek(a->fd, offset, SEEK_SET) < 0) { + if (a->offset != a->fd_offset) { + if (lseek(a->fd, a->offset, SEEK_SET) < 0) { archive_set_error(&a->archive, errno, "Seek failed"); return (ARCHIVE_FATAL); } + a->fd_offset = a->offset; + a->archive.file_position = a->offset; + a->archive.raw_position = a->offset; } bytes_written = write(a->fd, buff, bytes_to_write); if (bytes_written < 0) { _at__at_ -587,12 +591,12 @@ } buff += bytes_written; size -= bytes_written; - offset += bytes_written; + a->offset += bytes_written; a->archive.file_position += bytes_written; a->archive.raw_position += bytes_written; - a->last_offset = a->offset = offset; + a->fd_offset = a->offset; } - return (bytes_written); + return (start_size - size); } static ssize_t _at__at_ -605,9 +609,9 @@ __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, ARCHIVE_STATE_DATA, "archive_write_disk_block"); - r = write_data_block(a, buff, size, offset); - - if (r < 0) + a->offset = offset; + r = write_data_block(a, buff, size); + if (r < ARCHIVE_OK) return (r); if ((size_t)r < size) { archive_set_error(&a->archive, 0, _at__at_ -625,7 +629,7 _at__at_ __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, ARCHIVE_STATE_DATA, "archive_write_data"); - return (write_data_block(a, buff, size, a->offset)); + return (write_data_block(a, buff, size)); } static int _at__at_ -646,7 +650,7 _at__at_ /* There's no file. */ } else if (a->filesize < 0) { /* File size is unknown, so we can't set the size. */ - } else if (a->last_offset == a->filesize) { + } else if (a->fd_offset == a->filesize) { /* Last write ended at exactly the filesize; we're done. */ /* Hopefully, this is the common case. */ } else {Received on Mon Jan 26 2009 - 04:50:41 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:41 UTC