Date: Wed, 7 Jul 2010 10:24:41 -0700 From: "Ming Fu" <Ming.Fu@watchguard.com> To: <freebsd-net@freebsd.org> Subject: kern/123095 kern/131602 sendfile Message-ID: <7C3D15DD6E8F464998CA1470D8A322F302BB9F72@ES02CO.wgti.net>
next in thread | raw e-mail | index | archive | help
Hi, I was trying to use sendfile and hit with problem very similar to the 123095 and 131602.=20 It seems that when the file is large enough (in megs), the file can be corrupted even if it is open read-only and exist on disk as read-only file, though the filesystem is mounted read-write. I have a small program to reliably reproduce the problem. ---------- corrupt.c ----------------- #include <sys/types.h> #include <sys/socket.h> #include <sys/uio.h> #include <fcntl.h> #include <netinet/in.h> #include <sys/select.h> #include <sys/stat.h> #include <strings.h> #include <stdio.h> #include <err.h> main () { int s, f; struct sockaddr_in addr; int flags; char str[32]=3D"\r\n800\r\n"; char *p =3D str; struct stat sb; int n; fd_set wset; int64_t size; off_t sbytes; off_t sent =3D 0; int chunk; s =3D socket(AF_INET, SOCK_STREAM, 0); bzero(&addr, sizeof(addr)); addr.sin_family =3D AF_INET; addr.sin_port =3D htons(7000); addr.sin_addr.s_addr =3D inet_addr("10.1.19.16"); n =3D connect(s, (struct sockaddr *)&addr, sizeof (addr)); if (n < 0) warn ("fail to connect"); flags =3D fcntl(s, F_GETFL); flags |=3D O_NONBLOCK; fcntl(s, F_SETFL); f =3D open("large", O_RDONLY); if (f<0) warn("fail to open file"); n =3D fstat(f, &sb); if (n<0) warn("fstat failed"); size =3D sb.st_size; chunk =3D 0; while (size > 0) { FD_ZERO(&wset); FD_SET(s, &wset); n =3D select(f+1, NULL, &wset, NULL, NULL); if (n < 0) continue; if (chunk > 0) { sbytes =3D 0; n =3D sendfile(f, s, sent, chunk, NULL, &sbytes, 0); if (n < 0) continue; chunk -=3D sbytes; size -=3D sbytes; sent +=3D sbytes; continue; } if (size > 2048) chunk =3D 2048; else chunk =3D size; n =3D sprintf(str, "\r\n%x\r\n", 2048); p =3D str; write(s, p, n); } } ------------- end --------------------------------------------- Run nc to receive the sendfile $ nc -l 7000 Copy a large from for sendfile to send $ cp /usr/lib/libc_pic.a large $ md5 large MD5 (large) =3D 252def82f9d75df11df7123e9fd376f6 $ cc -o co corrupt.c $./co $ md5 large=20 MD5 (large) =3D 81ee84e55f4611434459f637c83b892e I run this on 8.0-RELEASE. The same happens on 7.2 and 6.3. The disk are SATA ide. I run all these command under unprivileged user account. I also run the same program on several different hardware, the result is the same. Although the corrupted file is not the same. The corruption looks random to me. I know a bit of the network side of FreeBSD kernel code, but the I have no idea how the filesystem side work. I can dig a bit further if someone give me a hint as where to look. Best Regards, Ming
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?7C3D15DD6E8F464998CA1470D8A322F302BB9F72>