On current/amd64 I created a MSDOS filesystem on a CF card
inserted into a USB card reader

        # newfs_msdos -F 32 -L SHERLOCK sd3i         

and tried to copy some files to it

        # mount /dev/sd3i /mnt
        # cp * /mnt
        cp: /mnt/202.the-hounds-of-baskerville.avi: Argument list too long
        cp: /mnt/201.a-scandal-in-belgravia.avi: Argument list too long
        cp: /mnt/102.the-blind-banker.avi: Argument list too long

These three files are not copied fully.
The other files are copied alright.

On another run, this happens with _other_ files.
Indeed, it is a problem with the card:

        sd3(umass1:1:0): Check Condition (error 0x70) on opcode 0x2a
        SENSE KEY: Media Error
        ASC/ASCQ: Peripheral Device Write Fault

However, it is not the case that the argument list is too long:

        # ls -1
        101.study-in-pink.avi
        101.study-in-pink.srt
        102.the-blind-banker.avi
        102.the-blind-banker.srt
        103.the-great-game.avi
        103.the-great-game.srt
        104.extras.mkv
        201.a-scandal-in-belgravia.avi
        201.a-scandal-in-belgravia.srt
        202.the-hounds-of-baskerville.avi
        202.the-hounds-of-baskerville.srt
        203.the-reichenbach-fall.avi
        203.the-reichenbach-fall.srt

Somehow, the wrong error condition is reported:
E2BIG instead of a failed write(2).

The code that gives the warning messages is
the following block in /usr/src/bin/cp/utils.c:


int skipholes = 0;
struct stat tosb;
if (!fstat(to_fd, &tosb) && S_ISREG(tosb.st_mode))
        skipholes = 1;
while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) {
        if (skipholes && memcmp(buf, zeroes, rcount) == 0)
                wcount = lseek(to_fd, rcount, SEEK_CUR) == -1 ? -1 : rcount;
        else
                wcount = write(to_fd, buf, rcount);
        if (rcount != wcount || wcount == -1) {
                warn("%s", to.p_path);
                rval = 1;
                break;
        }
}


If I am reading this right, getting the warn() message means
that either the lseek() or the write() must have failed;
but both of them set errno, and not to E2BIG.
So why does the warn() report E2BIG?


                Jan

Reply via email to