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