"tar tfv /dev/cd0" speedup patch
Garrett Cooper
yanefbsd at gmail.com
Fri Feb 19 06:12:25 UTC 2010
On Thu, Feb 18, 2010 at 10:34 AM, Juergen Lock <nox at jelal.kn-bremen.de> wrote:
> On Wed, Feb 17, 2010 at 10:38:30PM -0800, Tim Kientzle wrote:
>> Juergen Lock wrote:
>> >
>> > ... since bsdtar/libarchive know iso9660 I just did the command in the
>> > Subject. It worked, but it was sloow... :( Apparently it read all of
>> > the disc without seeking. The following patch fixes this, is something
>> > like this desired? If yes I could look how to do the same for Linux,
>>
>> Juergen,
>>
>> This is great! If you can figure out how to get this
>> right, I would really appreciate it. If you have a
>> tape drive handy, definitely test with that. My first
>> attempts here actually broke reading from tape drives,
>> which is why the current code is so conservative.
>>
> Hmm I can't test on a tape atm but if I look at the kernel,
> http://fxr.watson.org/fxr/ident?i=DIOCGMEDIASIZE
> DIOCGMEDIASIZE is only handled for geom, xen block devices, old CD drives
> and pc98 floppies, and I'm pretty sure tapes don't use geom. :)
>
>> Minor style comments:
>> > else if (S_ISCHR(st.st_mode) &&
>> > !ioctl(fd, DIOCGMEDIASIZE, &mediasize) && mediasize) {
>>
>> Please be explicit: S_ISCHR() && ioctl() == 0 && mediasize > 0
>>
>> > archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
>>
>> extract_skip_file isn't needed here; we don't read the
>> contents of device nodes.
>>
>> Let me know as soon as you have something you're confident of.
>
> Ok here is a new version of the patch with these things fixed and the
> Linux case added: (Linux case not tested yet, and yes I did this on
> stable/8.)
>
> Index: src/lib/libarchive/archive_read_open_filename.c
> ===================================================================
> RCS file: /home/scvs/src/lib/libarchive/archive_read_open_filename.c,v
> retrieving revision 1.25.2.1
> diff -u -p -r1.25.2.1 archive_read_open_filename.c
> --- src/lib/libarchive/archive_read_open_filename.c 3 Aug 2009 08:13:06 -0000 1.25.2.1
> +++ src/lib/libarchive/archive_read_open_filename.c 18 Feb 2010 18:14:16 -0000
> @@ -44,6 +44,10 @@ __FBSDID("$FreeBSD: src/lib/libarchive/a
> #ifdef HAVE_UNISTD_H
> #include <unistd.h>
> #endif
> +#ifdef __FreeBSD__
> +#include <sys/ioctl.h>
> +#include <sys/disk.h>
> +#endif
>
> #include "archive.h"
>
> @@ -83,6 +87,9 @@ archive_read_open_filename(struct archiv
> struct read_file_data *mine;
> void *b;
> int fd;
> +#ifdef __FreeBSD__
> + off_t mediasize = 0;
> +#endif
>
> archive_clear_error(a);
> if (filename == NULL || filename[0] == '\0') {
> @@ -143,6 +150,27 @@ archive_read_open_filename(struct archiv
> */
> mine->can_skip = 1;
> }
> +#ifdef __FreeBSD__
> + /*
> + * on FreeBSD if a device supports the DIOCGMEDIASIZE ioctl
> + * it is a disk-like device and should be seekable.
> + */
> + else if (S_ISCHR(st.st_mode) &&
> + ioctl(fd, DIOCGMEDIASIZE, &mediasize) == 0 && mediasize > 0) {
> + mine->can_skip = 1;
> + }
> +#endif
> +#ifdef __linux__
Is there any reason why a) you wouldn't check for other BSDs? b) you
aren't doing something of the flavor...
#if defined(__FreeBSD__)
#elif defined(__linux__)
#endif
> + /*
> + * on Linux just check whether its a block device and that
> + * lseek works. (Tapes are character devices there.)
> + */
> + else if (S_ISBLK(st.st_mode) &&
> + lseek(fd, 0, SEEK_CUR) == 0 && lseek(fd, 0, SEEK_SET) == 0 &&
> + lseek(fd, 0, SEEK_END) > 0 && lseek(fd, 0, SEEK_SET) == 0) {
> + mine->can_skip = 1;
> + }
> +#endif
> return (archive_read_open2(a, mine,
> NULL, file_read, file_skip, file_close));
> }
Cheers!
-Garrett
More information about the freebsd-hackers
mailing list