home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!bonnie.concordia.ca!IRO.UMontreal.CA!matrox!altitude!Nyongwa.CAM.ORG!steve
- From: steve@Nyongwa.CAM.ORG (Steve M. Robbins)
- Newsgroups: comp.os.linux
- Subject: Re: Why GNU cp is flakey under Linux
- Message-ID: <Bt6ryI.F4B@Nyongwa.CAM.ORG>
- Date: 18 Aug 92 15:49:29 GMT
- References: <1992Aug12.063534.4178@muddcs.claremont.edu> <JRS.92Aug12190300@lepton.world.std.com>
- Organization: Chiral Symmetry Breakers of Montreal
- Lines: 66
-
- In article <JRS.92Aug12190300@lepton.world.std.com> jrs@world.std.com (Rick Sladkey) writes:
- >>>>>> 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)
-
- I ran into this the other day, trying to recompile gnu's cp. I don't have
- DEV_BSIZE defined anywhere (it's quite possible I've goofed my /usr/include)
- so I just defined it to be 1024.
-
- Looking at the code, though, I decided that it wouldn't make any difference
- what I did, because DEV_BSIZE is only used to guess if holes should be
- attempted, the actual holes are made using lseek(). Making it too large would
- mean it would sometimes miss the chance to make holes, and making it too small
- would mean it would make holes where none existed. No harm either way that
- I could see. [except for shoelace apparently]
-
- From the reply Linus made, it seems that the most proper thing to do would
- be to replace DEV_BSIZE with sb.st_blocksize in cp.c, right?
-
- >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
- --
- Steve Robbins -- steve@nyongwa.cam.org
- The World is rather sick and twisted. Why should I be any different?
-