On Thu, Feb 18, 2010 at 10:34 AM, Juergen Lock <n...@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 _______________________________________________ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"