Date: Thu, 18 Feb 2010 19:34:59 +0100 From: Juergen Lock <nox@jelal.kn-bremen.de> To: Tim Kientzle <kientzle@freebsd.org> Cc: freebsd-hackers@freebsd.org, Juergen Lock <nox@jelal.kn-bremen.de> Subject: Re: "tar tfv /dev/cd0" speedup patch Message-ID: <20100218183459.GA65508@triton8.kn-bremen.de> In-Reply-To: <4B7CE066.4030403@freebsd.org> References: <20100217215940.GA19713@triton8.kn-bremen.de> <4B7CE066.4030403@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
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__ + /* + * 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)); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100218183459.GA65508>