home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.os.linux
- Path: sparky!uunet!decwrl!world!jrs
- From: jrs@world.std.com (Rick Sladkey)
- Subject: Why GNU cp is flakey under Linux
- In-Reply-To: jwinstea@jarthur.claremont.edu's message of Wed, 12 Aug 1992 06:35:34 GMT
- Message-ID: <JRS.92Aug12190300@lepton.world.std.com>
- Lines: 48
- Sender: jrs@world.std.com (Rick Sladkey)
- Organization: The Internet
- References: <1992Aug12.043754.21260@ennews.eas.asu.edu>
- <1992Aug12.053539.14825@mnemosyne.cs.du.edu>
- <1992Aug12.060338.24805@ennews.eas.asu.edu>
- <1992Aug12.063534.4178@muddcs.claremont.edu>
- Date: Wed, 12 Aug 1992 23:02:59 GMT
-
- >>>>> On Wed, 12 Aug 1992 06:35:34 GMT, jwinstea@jarthur.claremont.edu
- >>>>> (Jim Winstead Jr.) said:
-
- Jim> Not necessarily true - GNU cp contains the optimization that it will
- Jim> use lseek() to 'write' holes in a file instead of writing out all the
- Jim> individual null bits. This is what causes shoelace to break for some
- Jim> people. I'm not sure what effect this has on copying to a floppy with
- Jim> the cp command - but I *know* dd is safe.
-
- An examination of the source code shows that GNU cp only performs this
- optimization if it thinks that the original file also had holes. The
- way GNU cp determines this is by comparing the number of blocks used
- with the actual file size. Furthermore, it only does this when it is
- compiled without ST_BLOCKS_MISSING defined. Note that the kernel is
- created by build and does not have any holes.
-
- So if your cp is creating holes ROUTINELY then:
-
- * fstat is broken and returns incorrect values for st_blocks, or
- * you manually defined an incorrect value of DEV_BSIZE (i.e. too small)
-
- Here is the relevant code from GNU cp.c:
-
- +-----
- | #ifndef ST_BLOCKS_MISSING
- | if (S_ISREG (sb.st_mode))
- | {
- | /* Find out whether the file contains any sparse blocks. */
- |
- | if (fstat (source_desc, &sb))
- | {
- | error (0, errno, "%s", src_path);
- | return_val = -1;
- | goto ret;
- | }
- |
- | /* If the file has fewer blocks than would normally
- | be needed for a file of its size, then
- | at least one of the blocks in the file is a hole. */
- | if (S_ISREG (sb.st_mode) &&
- | sb.st_size - (sb.st_blocks * DEV_BSIZE) >= DEV_BSIZE)
- | make_holes = 1;
- | }
- | #endif
- +-----
- --
- Rick Sladkey
- jrs@world.std.com
-