Commit 4ea5dc72 authored by Trond Myklebust's avatar Trond Myklebust

NFS: In 2.4, NFS O_DIRECT used the VFS's O_DIRECT logic to provide

   direct I/O support for NFS files.  The 2.4 VFS O_DIRECT logic was
   block based, thus the NFS client had to provide a minimum
   allowable blocksize for O_DIRECT reads and writes on NFS files. 
   For various reasons we chose 512 bytes. In 2.6, there is no
   requirement for a minimum blocksize.  NFS O_DIRECT reads and
   writes can go to any byte at any offset in a file.  Thus we revert
   the blocksize setting for NFS file systems to the previous
   behavior, which was to advertise the "wsize" setting as the
   optimal I/O block size.  This improves the performance of
   applications like 'cp' which use this value as their transfer
   size.

This patch also exposes the server's reported disk block size in the
   f_frsize of the vfsstat structure.
Signed-off-by: default avatarChuck Lever <cel@netapp.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@fys.uio.no>
parent 7d4e31b1
...@@ -270,14 +270,6 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor) ...@@ -270,14 +270,6 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
server->rsize = nfs_block_size(fsinfo.rtpref, NULL); server->rsize = nfs_block_size(fsinfo.rtpref, NULL);
if (server->wsize == 0) if (server->wsize == 0)
server->wsize = nfs_block_size(fsinfo.wtpref, NULL); server->wsize = nfs_block_size(fsinfo.wtpref, NULL);
if (sb->s_blocksize == 0) {
if (fsinfo.wtmult == 0) {
sb->s_blocksize = 512;
sb->s_blocksize_bits = 9;
} else
sb->s_blocksize = nfs_block_bits(fsinfo.wtmult,
&sb->s_blocksize_bits);
}
if (fsinfo.rtmax >= 512 && server->rsize > fsinfo.rtmax) if (fsinfo.rtmax >= 512 && server->rsize > fsinfo.rtmax)
server->rsize = nfs_block_size(fsinfo.rtmax, NULL); server->rsize = nfs_block_size(fsinfo.rtmax, NULL);
...@@ -296,6 +288,11 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor) ...@@ -296,6 +288,11 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
server->wsize = server->wpages << PAGE_CACHE_SHIFT; server->wsize = server->wpages << PAGE_CACHE_SHIFT;
} }
if (sb->s_blocksize == 0)
sb->s_blocksize = nfs_block_bits(server->wsize,
&sb->s_blocksize_bits);
server->wtmult = nfs_block_bits(fsinfo.wtmult, NULL);
server->dtsize = nfs_block_size(fsinfo.dtpref, NULL); server->dtsize = nfs_block_size(fsinfo.dtpref, NULL);
if (server->dtsize > PAGE_CACHE_SIZE) if (server->dtsize > PAGE_CACHE_SIZE)
server->dtsize = PAGE_CACHE_SIZE; server->dtsize = PAGE_CACHE_SIZE;
...@@ -482,6 +479,7 @@ nfs_statfs(struct super_block *sb, struct kstatfs *buf) ...@@ -482,6 +479,7 @@ nfs_statfs(struct super_block *sb, struct kstatfs *buf)
if (error < 0) if (error < 0)
goto out_err; goto out_err;
buf->f_frsize = server->wtmult;
buf->f_bsize = sb->s_blocksize; buf->f_bsize = sb->s_blocksize;
blockbits = sb->s_blocksize_bits; blockbits = sb->s_blocksize_bits;
blockres = (1 << blockbits) - 1; blockres = (1 << blockbits) - 1;
......
...@@ -18,6 +18,7 @@ struct nfs_server { ...@@ -18,6 +18,7 @@ struct nfs_server {
unsigned int rpages; /* read size (in pages) */ unsigned int rpages; /* read size (in pages) */
unsigned int wsize; /* write size */ unsigned int wsize; /* write size */
unsigned int wpages; /* write size (in pages) */ unsigned int wpages; /* write size (in pages) */
unsigned int wtmult; /* server disk block size */
unsigned int dtsize; /* readdir size */ unsigned int dtsize; /* readdir size */
unsigned int bsize; /* server block size */ unsigned int bsize; /* server block size */
unsigned int acregmin; /* attr cache timeouts */ unsigned int acregmin; /* attr cache timeouts */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment