@@ -194,10 +194,6 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
194
194
struct fuse_conn * fc = get_fuse_conn (inode );
195
195
int err ;
196
196
197
- /* VFS checks this, but only _after_ ->open() */
198
- if (file -> f_flags & O_DIRECT )
199
- return - EINVAL ;
200
-
201
197
err = generic_file_open (inode , file );
202
198
if (err )
203
199
return err ;
@@ -932,17 +928,23 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
932
928
struct file * file = iocb -> ki_filp ;
933
929
struct address_space * mapping = file -> f_mapping ;
934
930
size_t count = 0 ;
931
+ size_t ocount = 0 ;
935
932
ssize_t written = 0 ;
933
+ ssize_t written_buffered = 0 ;
936
934
struct inode * inode = mapping -> host ;
937
935
ssize_t err ;
938
936
struct iov_iter i ;
937
+ loff_t endbyte = 0 ;
939
938
940
939
WARN_ON (iocb -> ki_pos != pos );
941
940
942
- err = generic_segment_checks (iov , & nr_segs , & count , VERIFY_READ );
941
+ ocount = 0 ;
942
+ err = generic_segment_checks (iov , & nr_segs , & ocount , VERIFY_READ );
943
943
if (err )
944
944
return err ;
945
945
946
+ count = ocount ;
947
+
946
948
mutex_lock (& inode -> i_mutex );
947
949
vfs_check_frozen (inode -> i_sb , SB_FREEZE_WRITE );
948
950
@@ -962,11 +964,41 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
962
964
963
965
file_update_time (file );
964
966
965
- iov_iter_init (& i , iov , nr_segs , count , 0 );
966
- written = fuse_perform_write (file , mapping , & i , pos );
967
- if (written >= 0 )
968
- iocb -> ki_pos = pos + written ;
967
+ if (file -> f_flags & O_DIRECT ) {
968
+ written = generic_file_direct_write (iocb , iov , & nr_segs ,
969
+ pos , & iocb -> ki_pos ,
970
+ count , ocount );
971
+ if (written < 0 || written == count )
972
+ goto out ;
973
+
974
+ pos += written ;
975
+ count -= written ;
969
976
977
+ iov_iter_init (& i , iov , nr_segs , count , written );
978
+ written_buffered = fuse_perform_write (file , mapping , & i , pos );
979
+ if (written_buffered < 0 ) {
980
+ err = written_buffered ;
981
+ goto out ;
982
+ }
983
+ endbyte = pos + written_buffered - 1 ;
984
+
985
+ err = filemap_write_and_wait_range (file -> f_mapping , pos ,
986
+ endbyte );
987
+ if (err )
988
+ goto out ;
989
+
990
+ invalidate_mapping_pages (file -> f_mapping ,
991
+ pos >> PAGE_CACHE_SHIFT ,
992
+ endbyte >> PAGE_CACHE_SHIFT );
993
+
994
+ written += written_buffered ;
995
+ iocb -> ki_pos = pos + written_buffered ;
996
+ } else {
997
+ iov_iter_init (& i , iov , nr_segs , count , 0 );
998
+ written = fuse_perform_write (file , mapping , & i , pos );
999
+ if (written >= 0 )
1000
+ iocb -> ki_pos = pos + written ;
1001
+ }
970
1002
out :
971
1003
current -> backing_dev_info = NULL ;
972
1004
mutex_unlock (& inode -> i_mutex );
@@ -1101,30 +1133,41 @@ static ssize_t fuse_direct_read(struct file *file, char __user *buf,
1101
1133
return res ;
1102
1134
}
1103
1135
1104
- static ssize_t fuse_direct_write (struct file * file , const char __user * buf ,
1105
- size_t count , loff_t * ppos )
1136
+ static ssize_t __fuse_direct_write (struct file * file , const char __user * buf ,
1137
+ size_t count , loff_t * ppos )
1106
1138
{
1107
1139
struct inode * inode = file -> f_path .dentry -> d_inode ;
1108
1140
ssize_t res ;
1109
1141
1110
- if (is_bad_inode (inode ))
1111
- return - EIO ;
1112
-
1113
- /* Don't allow parallel writes to the same file */
1114
- mutex_lock (& inode -> i_mutex );
1115
1142
res = generic_write_checks (file , ppos , & count , 0 );
1116
1143
if (!res ) {
1117
1144
res = fuse_direct_io (file , buf , count , ppos , 1 );
1118
1145
if (res > 0 )
1119
1146
fuse_write_update_size (inode , * ppos );
1120
1147
}
1121
- mutex_unlock (& inode -> i_mutex );
1122
1148
1123
1149
fuse_invalidate_attr (inode );
1124
1150
1125
1151
return res ;
1126
1152
}
1127
1153
1154
+ static ssize_t fuse_direct_write (struct file * file , const char __user * buf ,
1155
+ size_t count , loff_t * ppos )
1156
+ {
1157
+ struct inode * inode = file -> f_path .dentry -> d_inode ;
1158
+ ssize_t res ;
1159
+
1160
+ if (is_bad_inode (inode ))
1161
+ return - EIO ;
1162
+
1163
+ /* Don't allow parallel writes to the same file */
1164
+ mutex_lock (& inode -> i_mutex );
1165
+ res = __fuse_direct_write (file , buf , count , ppos );
1166
+ mutex_unlock (& inode -> i_mutex );
1167
+
1168
+ return res ;
1169
+ }
1170
+
1128
1171
static void fuse_writepage_free (struct fuse_conn * fc , struct fuse_req * req )
1129
1172
{
1130
1173
__free_page (req -> pages [0 ]);
@@ -2077,6 +2120,57 @@ int fuse_notify_poll_wakeup(struct fuse_conn *fc,
2077
2120
return 0 ;
2078
2121
}
2079
2122
2123
+ static ssize_t fuse_loop_dio (struct file * filp , const struct iovec * iov ,
2124
+ unsigned long nr_segs , loff_t * ppos , int rw )
2125
+ {
2126
+ const struct iovec * vector = iov ;
2127
+ ssize_t ret = 0 ;
2128
+
2129
+ while (nr_segs > 0 ) {
2130
+ void __user * base ;
2131
+ size_t len ;
2132
+ ssize_t nr ;
2133
+
2134
+ base = vector -> iov_base ;
2135
+ len = vector -> iov_len ;
2136
+ vector ++ ;
2137
+ nr_segs -- ;
2138
+
2139
+ if (rw == WRITE )
2140
+ nr = __fuse_direct_write (filp , base , len , ppos );
2141
+ else
2142
+ nr = fuse_direct_read (filp , base , len , ppos );
2143
+
2144
+ if (nr < 0 ) {
2145
+ if (!ret )
2146
+ ret = nr ;
2147
+ break ;
2148
+ }
2149
+ ret += nr ;
2150
+ if (nr != len )
2151
+ break ;
2152
+ }
2153
+
2154
+ return ret ;
2155
+ }
2156
+
2157
+
2158
+ static ssize_t
2159
+ fuse_direct_IO (int rw , struct kiocb * iocb , const struct iovec * iov ,
2160
+ loff_t offset , unsigned long nr_segs )
2161
+ {
2162
+ ssize_t ret = 0 ;
2163
+ struct file * file = NULL ;
2164
+ loff_t pos = 0 ;
2165
+
2166
+ file = iocb -> ki_filp ;
2167
+ pos = offset ;
2168
+
2169
+ ret = fuse_loop_dio (file , iov , nr_segs , & pos , rw );
2170
+
2171
+ return ret ;
2172
+ }
2173
+
2080
2174
static const struct file_operations fuse_file_operations = {
2081
2175
.llseek = fuse_file_llseek ,
2082
2176
.read = do_sync_read ,
@@ -2120,6 +2214,7 @@ static const struct address_space_operations fuse_file_aops = {
2120
2214
.readpages = fuse_readpages ,
2121
2215
.set_page_dirty = __set_page_dirty_nobuffers ,
2122
2216
.bmap = fuse_bmap ,
2217
+ .direct_IO = fuse_direct_IO ,
2123
2218
};
2124
2219
2125
2220
void fuse_init_file_inode (struct inode * inode )
0 commit comments