"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