[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