"tar tfv /dev/cd0" speedup patch
Juergen Lock
nox at jelal.kn-bremen.de
Thu Feb 18 18:38:05 UTC 2010
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));
}
More information about the freebsd-hackers
mailing list