[linux-cifs-client] Re: io blksize problem with cifs

Dave Kleikamp shaggy at austin.ibm.com
Tue Sep 19 15:53:53 GMT 2006


On Tue, 2006-09-19 at 08:27 -0700, Andrew Morton wrote:
> On Tue, 19 Sep 2006 15:46:58 +0200
> sbenni at gmx.de wrote:
> 
> > 
> > Hello,
> > 
> > Since I have changed from kernel version 2.6.17 to 2.6.17-mm6 I get the following error when I type ls in a cifs mounted directory with more than a certain number of files in it. 
> > 
> > rupi at pluto:/mnt/test$ ls
> > ls: reading directory .: Invalid argument
> > 
> > digest from "strace -v ls" :
> > 
> > open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY) = 3
> > fstat(3, {st_dev=makedev(0, 18), st_ino=2, st_mode=S_IFDIR|0777, st_nlink=176, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=0, st_atime=2006/09/19-13:18:15, st_mtime=2006/08/16-10:44:24, st_ctime=2006/08/16-10:44:24}) = 0
> > fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
> > getdents64(3, 0x51a518, 4096)           = -1 EINVAL (Invalid argument)
> > 
> > Note, that st_blksize is 4096 instead of 16384 as with version 2.6.17
> > 
> > 
> > Tested with 3.0.14a-3sarge2 from Debian and 3.0.22-0bpo1 from backports on the server side,
> > same result everytime. 
> > 
> > But it works with Windows 2003 Server, although the io blksize is also 4096 :
> > 
> > fstat(3, {st_mode=S_IFDIR|0777, st_size=0, ...}) = 0
> > fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
> > getdents64(3, /* 48 entries */, 4096)   = 1608
> > getdents64(3, /* 26 entries */, 4096)   = 1824
> > getdents64(3, /* 25 entries */, 4096)   = 1792
> > getdents64(3, /* 23 entries */, 4096)   = 1312
> > getdents64(3, /* 0 entries */, 4096)    = 0
> > 
> > 
> > Output of /proc/fs/cifs/DebugData on the client side :
> > 
> > Display Internal CIFS Data Structures for Debugging
> > ---------------------------------------------------
> > CIFS Version 1.44
> > Active VFS Requests: 0
> > Servers:
> > 1) Name: 192.168.111.5  Domain: MILKY.WAY Mounts: 1 OS: Unix  
> >         NOS: Samba 3.0.14a-Debian       Capability: 0x80e3fd
> >         SMB session status: 3   TCP status: 1
> >         Local Users To Server: 1 SecMode: 0x3 Req On Wire: 0
> > MIDs:
> > 
> > Shares:
> > 1) \\192.168.111.5\public Uses: 1 Type: NTFS DevInfo: 0x0 Attributes: 0x2b
> > PathComponentMax: 255 Status: 3 type: 0         DISCONNECTED 
> > 
> > 
> > 
> > Unfortunatley I couldn't find the reason, but perhaps it has to do something with the fact that the i_blksize variable of the inode struct has been removed  ?
> > 
> > I have attached cifs debug output of mounting a share and ls on it.
> > 
> 
> erk, good point.  We have:
> 
> --- a/fs/stat.c~inode-diet-eliminate-i_blksize-and-use-a-per-superblock-default
> +++ a/fs/stat.c
> @@ -14,6 +14,7 @@
>  #include <linux/namei.h>
>  #include <linux/security.h>
>  #include <linux/syscalls.h>
> +#include <linux/pagemap.h>
>  
>  #include <asm/uaccess.h>
>  #include <asm/unistd.h>
> @@ -32,7 +33,7 @@ void generic_fillattr(struct inode *inod
>  	stat->ctime = inode->i_ctime;
>  	stat->size = i_size_read(inode);
>  	stat->blocks = inode->i_blocks;
> -	stat->blksize = inode->i_blksize;
> +	stat->blksize = PAGE_CACHE_SIZE;
>  }
>  
>  EXPORT_SYMBOL(generic_fillattr);
> 
> Ted, how come that's not (1 << inode->i_blkbits)?

I'm not Ted, but it's probably because stat->blksize isn't really tied
to the file system's block size.

from STAT(2):

       The st_blksize field gives the "preferred" blocksize for efficient file
       system  I/O.  (Writing to a file in smaller chunks may cause an ineffi-
       cient read-modify-rewrite.)

PAGE_CACHE_SIZE seems a reasonable default.  The file system is free to
overwrite this after calling generic_fillattr().
-- 
David Kleikamp
IBM Linux Technology Center



More information about the linux-cifs-client mailing list