On Debian Linux 2.6.31.4 up to 2.6.31.6 with CIFS 1.60 the file size can't requested over system call stat(). Errno would be set to 75: Value too large for defined data type. Is this a problem with 32Bit int and 64Bit int of large file support over CIFS? The error is reproduceable on small and large files. On Linux 2.6.30.9 with CIFS 1.58 it works. Please have a look over the test program. If the file is copied to local device or ramdisk the test program returns the correct file size. All programs, own build and GNU tools, on the system, which are using stat(), fstat() or lstat() over CIFS mounts are failing, sometimes crashing because of memalloc of wrong file size. The client is a Linux system with above errors, the server is a Windows XP Professional system or Windows XP Embedded system with SP2 installed. #include <fcntl.h> /* open */ #include <unistd.h> /* exit */ #include <stdio.h> #include <memory.h> #include <time.h> #include <stdlib.h> #include <stdarg.h> #include <ctype.h> #include <sys/ioctl.h> /* ioctl */ #include <sys/types.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/time.h> #include <errno.h> int main(int argc, char *argv[]) { off_t size; struct stat filestat; errno = 0; stat(argv[1],&filestat); size=filestat.st_size; printf("file %s size %d errno=%d\n sizeof(off_t)=%d sizeof(stat)=%d\n\n", argv[1],(int)size, errno, sizeof(off_t), sizeof(filestat)); }
Created attachment 5050 [details] file size using Linux system call stat compiled with gcc 4.1.2 against kernel 2.6.31.4
Are you compiling the program below with -D_FILE_OFFSET_BITS=64 ?
Are you compiling the program below with -D_FILE_OFFSET_BITS=64 ? No. sizeof(off_t) returns 4 Bytes = 32 Bit on a 32Bit system. The problem is, that all tools and libraries, which are using stat(), have to be recompiled with this option. Using a Debian kernel 2.6.30.9 with CIFS 1.58 works without recompiling tools and libs. Debian kernel 2.6.31.4 and 2.6.31.4 with CIFS 1.60 doesn't work.
The default behavior for CIFS is now to use server inode numbers when they're available. That changed in 2.6.31 (IIRC), so that's probably the behavioral difference you're seeing. Legacy stat() calls can't handle 64-bit inode numbers. glibc() will turn those stat() library calls into stat64() system calls. The kernel then dutifully returns a 64-bit inode number (as it was requested to do). That doesn't fit in the supplied buffer though, so glibc then generates EOVERFLOW in userspace and returns that to the application. The best fix is to compile everything with -D_FILE_OFFSET_BITS=64, but you may be able to work around it by using the "noserverino" mount option. I'm going to close this as "INVALID", please reopen if you have questions.