From 87c89dd7330735d70cc9912483f6f4c7bc3ff19c Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 17 Nov 2005 17:03:00 -0800 Subject: [PATCH] [CIFS] Vectored and async i/o turned on and correct the writev and aio_write to flush properly. This is Christoph's patch merged with the new nobrl file operations Signed-off-by: Dave Kleikamp From: Christoph Hellwig - support vectored and async aio ops unconditionally - this is above the pagecache and transparent to the fs - remove cifs_read_wrapper. it was only doing silly checks and calling generic_file_write in all cases. - use do_sync_read/do_sync_write as read/write operations. They call ->readv/->writev which we now always implemente. - add the filemap_fdatawrite calls to writev/aio_write which were missing previously compared to plain write. no idea what the point behind them is, but let's be consistent at least.. Signed-off-by: Christoph Hellwig Signed-off-by: Steven French Signed-off-by: Andrew Morton --- fs/cifs/cifsfs.c | 123 ++++++++++++++++++----------------------------- 1 file changed, 48 insertions(+), 75 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 1433455c61ea..51548ed2e9cc 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -483,56 +483,29 @@ cifs_get_sb(struct file_system_type *fs_type, return sb; } -static ssize_t -cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size, - loff_t * poffset) -{ - if(file->f_dentry == NULL) - return -EIO; - else if(file->f_dentry->d_inode == NULL) - return -EIO; - - cFYI(1,("In read_wrapper size %zd at %lld",read_size,*poffset)); - - if(CIFS_I(file->f_dentry->d_inode)->clientCanCacheRead) { - return generic_file_read(file,read_data,read_size,poffset); - } else { - /* BB do we need to lock inode from here until after invalidate? */ -/* if(file->f_dentry->d_inode->i_mapping) { - filemap_fdatawrite(file->f_dentry->d_inode->i_mapping); - filemap_fdatawait(file->f_dentry->d_inode->i_mapping); - }*/ -/* cifs_revalidate(file->f_dentry);*/ /* BB fixme */ - - /* BB we should make timer configurable - perhaps - by simply calling cifs_revalidate here */ - /* invalidate_remote_inode(file->f_dentry->d_inode);*/ - return generic_file_read(file,read_data,read_size,poffset); - } -} - -static ssize_t -cifs_write_wrapper(struct file * file, const char __user *write_data, - size_t write_size, loff_t * poffset) +static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov, + unsigned long nr_segs, loff_t *ppos) { + struct inode *inode = file->f_dentry->d_inode; ssize_t written; - if(file->f_dentry == NULL) - return -EIO; - else if(file->f_dentry->d_inode == NULL) - return -EIO; - - cFYI(1,("In write_wrapper size %zd at %lld",write_size,*poffset)); - - written = generic_file_write(file,write_data,write_size,poffset); - if(!CIFS_I(file->f_dentry->d_inode)->clientCanCacheAll) { - if(file->f_dentry->d_inode->i_mapping) { - filemap_fdatawrite(file->f_dentry->d_inode->i_mapping); - } - } + written = generic_file_writev(file, iov, nr_segs, ppos); + if (!CIFS_I(inode)->clientCanCacheAll) + filemap_fdatawrite(inode->i_mapping); return written; } +static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf, + size_t count, loff_t pos) +{ + struct inode *inode = iocb->ki_filp->f_dentry->d_inode; + ssize_t written; + + written = generic_file_aio_write(iocb, buf, count, pos); + if (!CIFS_I(inode)->clientCanCacheAll) + filemap_fdatawrite(inode->i_mapping); + return written; +} static struct file_system_type cifs_fs_type = { .owner = THIS_MODULE, @@ -594,8 +567,12 @@ struct inode_operations cifs_symlink_inode_ops = { }; struct file_operations cifs_file_ops = { - .read = cifs_read_wrapper, - .write = cifs_write_wrapper, + .read = do_sync_read, + .write = do_sync_write, + .readv = generic_file_readv, + .writev = cifs_file_writev, + .aio_read = generic_file_aio_read, + .aio_write = cifs_file_aio_write, .open = cifs_open, .release = cifs_close, .lock = cifs_lock, @@ -608,10 +585,6 @@ struct file_operations cifs_file_ops = { #endif /* CONFIG_CIFS_POSIX */ #ifdef CONFIG_CIFS_EXPERIMENTAL - .readv = generic_file_readv, - .writev = generic_file_writev, - .aio_read = generic_file_aio_read, - .aio_write = generic_file_aio_write, .dir_notify = cifs_dir_notify, #endif /* CONFIG_CIFS_EXPERIMENTAL */ }; @@ -636,43 +609,43 @@ struct file_operations cifs_file_direct_ops = { #endif /* CONFIG_CIFS_EXPERIMENTAL */ }; struct file_operations cifs_file_nobrl_ops = { - .read = cifs_read_wrapper, - .write = cifs_write_wrapper, - .open = cifs_open, - .release = cifs_close, - .fsync = cifs_fsync, - .flush = cifs_flush, - .mmap = cifs_file_mmap, - .sendfile = generic_file_sendfile, + .read = do_sync_read, + .write = do_sync_write, + .readv = generic_file_readv, + .writev = cifs_file_writev, + .aio_read = generic_file_aio_read, + .aio_write = cifs_file_aio_write, + .open = cifs_open, + .release = cifs_close, + .fsync = cifs_fsync, + .flush = cifs_flush, + .mmap = cifs_file_mmap, + .sendfile = generic_file_sendfile, #ifdef CONFIG_CIFS_POSIX - .ioctl = cifs_ioctl, + .ioctl = cifs_ioctl, #endif /* CONFIG_CIFS_POSIX */ #ifdef CONFIG_CIFS_EXPERIMENTAL - .readv = generic_file_readv, - .writev = generic_file_writev, - .aio_read = generic_file_aio_read, - .aio_write = generic_file_aio_write, - .dir_notify = cifs_dir_notify, + .dir_notify = cifs_dir_notify, #endif /* CONFIG_CIFS_EXPERIMENTAL */ }; struct file_operations cifs_file_direct_nobrl_ops = { - /* no mmap, no aio, no readv - - BB reevaluate whether they can be done with directio, no cache */ - .read = cifs_user_read, - .write = cifs_user_write, - .open = cifs_open, - .release = cifs_close, - .fsync = cifs_fsync, - .flush = cifs_flush, - .sendfile = generic_file_sendfile, /* BB removeme BB */ + /* no mmap, no aio, no readv - + BB reevaluate whether they can be done with directio, no cache */ + .read = cifs_user_read, + .write = cifs_user_write, + .open = cifs_open, + .release = cifs_close, + .fsync = cifs_fsync, + .flush = cifs_flush, + .sendfile = generic_file_sendfile, /* BB removeme BB */ #ifdef CONFIG_CIFS_POSIX - .ioctl = cifs_ioctl, + .ioctl = cifs_ioctl, #endif /* CONFIG_CIFS_POSIX */ #ifdef CONFIG_CIFS_EXPERIMENTAL - .dir_notify = cifs_dir_notify, + .dir_notify = cifs_dir_notify, #endif /* CONFIG_CIFS_EXPERIMENTAL */ };