aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorPavel Shilovsky <piastry@etersoft.ru>2011-03-10 02:11:05 -0500
committerSteve French <sfrench@us.ibm.com>2011-05-19 10:10:51 -0400
commit0b81c1c405c063f3ecea66c2f5e9c3aefc5359c8 (patch)
treeb284b86c0e17c24affff9f6d1e1f2ab2d217021f /fs/cifs
parentbe8e3b0044a68e1f1002c432f6b40d290cf0701d (diff)
CIFS: directio read/write cleanups
Recently introduced strictcache mode brought a new code that can be efficiently used by directio part. That's let us add vectored operations and break unnecessary cifs_user_read and cifs_user_write. Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsfs.c18
-rw-r--r--fs/cifs/cifsfs.h8
-rw-r--r--fs/cifs/file.c103
3 files changed, 16 insertions, 113 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 6c1d738418f1..f736d8a2e771 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -760,10 +760,11 @@ const struct file_operations cifs_file_strict_ops = {
760}; 760};
761 761
762const struct file_operations cifs_file_direct_ops = { 762const struct file_operations cifs_file_direct_ops = {
763 /* no aio, no readv - 763 /* BB reevaluate whether they can be done with directio, no cache */
764 BB reevaluate whether they can be done with directio, no cache */ 764 .read = do_sync_read,
765 .read = cifs_user_read, 765 .write = do_sync_write,
766 .write = cifs_user_write, 766 .aio_read = cifs_user_readv,
767 .aio_write = cifs_user_writev,
767 .open = cifs_open, 768 .open = cifs_open,
768 .release = cifs_close, 769 .release = cifs_close,
769 .lock = cifs_lock, 770 .lock = cifs_lock,
@@ -815,10 +816,11 @@ const struct file_operations cifs_file_strict_nobrl_ops = {
815}; 816};
816 817
817const struct file_operations cifs_file_direct_nobrl_ops = { 818const struct file_operations cifs_file_direct_nobrl_ops = {
818 /* no mmap, no aio, no readv - 819 /* BB reevaluate whether they can be done with directio, no cache */
819 BB reevaluate whether they can be done with directio, no cache */ 820 .read = do_sync_read,
820 .read = cifs_user_read, 821 .write = do_sync_write,
821 .write = cifs_user_write, 822 .aio_read = cifs_user_readv,
823 .aio_write = cifs_user_writev,
822 .open = cifs_open, 824 .open = cifs_open,
823 .release = cifs_close, 825 .release = cifs_close,
824 .fsync = cifs_fsync, 826 .fsync = cifs_fsync,
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 371d021815b1..bb64313fd750 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -80,12 +80,12 @@ extern const struct file_operations cifs_file_strict_nobrl_ops;
80extern int cifs_open(struct inode *inode, struct file *file); 80extern int cifs_open(struct inode *inode, struct file *file);
81extern int cifs_close(struct inode *inode, struct file *file); 81extern int cifs_close(struct inode *inode, struct file *file);
82extern int cifs_closedir(struct inode *inode, struct file *file); 82extern int cifs_closedir(struct inode *inode, struct file *file);
83extern ssize_t cifs_user_read(struct file *file, char __user *read_data, 83extern ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov,
84 size_t read_size, loff_t *poffset); 84 unsigned long nr_segs, loff_t pos);
85extern ssize_t cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov, 85extern ssize_t cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov,
86 unsigned long nr_segs, loff_t pos); 86 unsigned long nr_segs, loff_t pos);
87extern ssize_t cifs_user_write(struct file *file, const char __user *write_data, 87extern ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov,
88 size_t write_size, loff_t *poffset); 88 unsigned long nr_segs, loff_t pos);
89extern ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, 89extern ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
90 unsigned long nr_segs, loff_t pos); 90 unsigned long nr_segs, loff_t pos);
91extern int cifs_lock(struct file *, int, struct file_lock *); 91extern int cifs_lock(struct file *, int, struct file_lock *);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 00b466e667ab..0aeaaf7bf153 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -857,95 +857,6 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
857 cifsi->server_eof = end_of_write; 857 cifsi->server_eof = end_of_write;
858} 858}
859 859
860ssize_t cifs_user_write(struct file *file, const char __user *write_data,
861 size_t write_size, loff_t *poffset)
862{
863 struct inode *inode = file->f_path.dentry->d_inode;
864 int rc = 0;
865 unsigned int bytes_written = 0;
866 unsigned int total_written;
867 struct cifs_sb_info *cifs_sb;
868 struct cifsTconInfo *pTcon;
869 int xid;
870 struct cifsFileInfo *open_file;
871 struct cifsInodeInfo *cifsi = CIFS_I(inode);
872
873 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
874
875 /* cFYI(1, " write %d bytes to offset %lld of %s", write_size,
876 *poffset, file->f_path.dentry->d_name.name); */
877
878 if (file->private_data == NULL)
879 return -EBADF;
880
881 open_file = file->private_data;
882 pTcon = tlink_tcon(open_file->tlink);
883
884 rc = generic_write_checks(file, poffset, &write_size, 0);
885 if (rc)
886 return rc;
887
888 xid = GetXid();
889
890 for (total_written = 0; write_size > total_written;
891 total_written += bytes_written) {
892 rc = -EAGAIN;
893 while (rc == -EAGAIN) {
894 if (file->private_data == NULL) {
895 /* file has been closed on us */
896 FreeXid(xid);
897 /* if we have gotten here we have written some data
898 and blocked, and the file has been freed on us while
899 we blocked so return what we managed to write */
900 return total_written;
901 }
902 if (open_file->invalidHandle) {
903 /* we could deadlock if we called
904 filemap_fdatawait from here so tell
905 reopen_file not to flush data to server
906 now */
907 rc = cifs_reopen_file(open_file, false);
908 if (rc != 0)
909 break;
910 }
911
912 rc = CIFSSMBWrite(xid, pTcon,
913 open_file->netfid,
914 min_t(const int, cifs_sb->wsize,
915 write_size - total_written),
916 *poffset, &bytes_written,
917 NULL, write_data + total_written, 0);
918 }
919 if (rc || (bytes_written == 0)) {
920 if (total_written)
921 break;
922 else {
923 FreeXid(xid);
924 return rc;
925 }
926 } else {
927 cifs_update_eof(cifsi, *poffset, bytes_written);
928 *poffset += bytes_written;
929 }
930 }
931
932 cifs_stats_bytes_written(pTcon, total_written);
933
934/* Do not update local mtime - server will set its actual value on write
935 * inode->i_ctime = inode->i_mtime =
936 * current_fs_time(inode->i_sb);*/
937 if (total_written > 0) {
938 spin_lock(&inode->i_lock);
939 if (*poffset > inode->i_size)
940 i_size_write(inode, *poffset);
941 spin_unlock(&inode->i_lock);
942 }
943 mark_inode_dirty_sync(inode);
944
945 FreeXid(xid);
946 return total_written;
947}
948
949static ssize_t cifs_write(struct cifsFileInfo *open_file, 860static ssize_t cifs_write(struct cifsFileInfo *open_file,
950 const char *write_data, size_t write_size, 861 const char *write_data, size_t write_size,
951 loff_t *poffset) 862 loff_t *poffset)
@@ -1741,7 +1652,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
1741 return total_written; 1652 return total_written;
1742} 1653}
1743 1654
1744static ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov, 1655ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov,
1745 unsigned long nr_segs, loff_t pos) 1656 unsigned long nr_segs, loff_t pos)
1746{ 1657{
1747 ssize_t written; 1658 ssize_t written;
@@ -1864,17 +1775,7 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
1864 return total_read; 1775 return total_read;
1865} 1776}
1866 1777
1867ssize_t cifs_user_read(struct file *file, char __user *read_data, 1778ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov,
1868 size_t read_size, loff_t *poffset)
1869{
1870 struct iovec iov;
1871 iov.iov_base = read_data;
1872 iov.iov_len = read_size;
1873
1874 return cifs_iovec_read(file, &iov, 1, poffset);
1875}
1876
1877static ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov,
1878 unsigned long nr_segs, loff_t pos) 1779 unsigned long nr_segs, loff_t pos)
1879{ 1780{
1880 ssize_t read; 1781 ssize_t read;