diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2011-03-10 02:11:05 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2011-05-19 10:10:51 -0400 |
commit | 0b81c1c405c063f3ecea66c2f5e9c3aefc5359c8 (patch) | |
tree | b284b86c0e17c24affff9f6d1e1f2ab2d217021f /fs/cifs | |
parent | be8e3b0044a68e1f1002c432f6b40d290cf0701d (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.c | 18 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 8 | ||||
-rw-r--r-- | fs/cifs/file.c | 103 |
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 | ||
762 | const struct file_operations cifs_file_direct_ops = { | 762 | const 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 | ||
817 | const struct file_operations cifs_file_direct_nobrl_ops = { | 818 | const 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; | |||
80 | extern int cifs_open(struct inode *inode, struct file *file); | 80 | extern int cifs_open(struct inode *inode, struct file *file); |
81 | extern int cifs_close(struct inode *inode, struct file *file); | 81 | extern int cifs_close(struct inode *inode, struct file *file); |
82 | extern int cifs_closedir(struct inode *inode, struct file *file); | 82 | extern int cifs_closedir(struct inode *inode, struct file *file); |
83 | extern ssize_t cifs_user_read(struct file *file, char __user *read_data, | 83 | extern 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); |
85 | extern ssize_t cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov, | 85 | extern 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); |
87 | extern ssize_t cifs_user_write(struct file *file, const char __user *write_data, | 87 | extern 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); |
89 | extern ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, | 89 | extern 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); |
91 | extern int cifs_lock(struct file *, int, struct file_lock *); | 91 | extern 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 | ||
860 | ssize_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 | |||
949 | static ssize_t cifs_write(struct cifsFileInfo *open_file, | 860 | static 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 | ||
1744 | static ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov, | 1655 | ssize_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 | ||
1867 | ssize_t cifs_user_read(struct file *file, char __user *read_data, | 1778 | ssize_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 | |||
1877 | static 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; |