Bug 6955 - file size error by calling system call stat over Cifs mounted file system
Summary: file size error by calling system call stat over Cifs mounted file system
Status: RESOLVED INVALID
Alias: None
Product: CifsVFS
Classification: Unclassified
Component: kernel fs (show other bugs)
Version: 2.6
Hardware: x86 Linux
: P3 critical
Target Milestone: ---
Assignee: Jeff Layton
QA Contact:
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-12-02 07:44 UTC by Christof Will
Modified: 2009-12-08 06:07 UTC (History)
1 user (show)

See Also:


Attachments
file size using Linux system call stat (653 bytes, text/plain)
2009-12-03 02:17 UTC, Christof Will
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Christof Will 2009-12-02 07:44:09 UTC
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));

}
Comment 1 Christof Will 2009-12-03 02:17:53 UTC
Created attachment 5050 [details]
file size using Linux system call stat

compiled with gcc 4.1.2 against kernel 2.6.31.4
Comment 2 Jeff Layton 2009-12-08 05:25:38 UTC
Are you compiling the program below with -D_FILE_OFFSET_BITS=64 ?
Comment 3 Christof Will 2009-12-08 05:38:54 UTC
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.
Comment 4 Jeff Layton 2009-12-08 06:07:00 UTC
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.