@@ -1833,7 +1833,7 @@ static void fuse_writepage_finish(struct fuse_writepage_args *wpa)
1833
1833
* scope of the fi->lock alleviates xarray lock
1834
1834
* contention and noticeably improves performance.
1835
1835
*/
1836
- folio_end_writeback ( ap -> folios [i ]);
1836
+ iomap_finish_folio_write ( inode , ap -> folios [i ], 1 );
1837
1837
dec_wb_stat (& bdi -> wb , WB_WRITEBACK );
1838
1838
wb_writeout_inc (& bdi -> wb );
1839
1839
}
@@ -2020,19 +2020,20 @@ static void fuse_writepage_add_to_bucket(struct fuse_conn *fc,
2020
2020
}
2021
2021
2022
2022
static void fuse_writepage_args_page_fill (struct fuse_writepage_args * wpa , struct folio * folio ,
2023
- uint32_t folio_index )
2023
+ uint32_t folio_index , loff_t offset , unsigned len )
2024
2024
{
2025
2025
struct inode * inode = folio -> mapping -> host ;
2026
2026
struct fuse_args_pages * ap = & wpa -> ia .ap ;
2027
2027
2028
2028
ap -> folios [folio_index ] = folio ;
2029
- ap -> descs [folio_index ].offset = 0 ;
2030
- ap -> descs [folio_index ].length = folio_size ( folio ) ;
2029
+ ap -> descs [folio_index ].offset = offset ;
2030
+ ap -> descs [folio_index ].length = len ;
2031
2031
2032
2032
inc_wb_stat (& inode_to_bdi (inode )-> wb , WB_WRITEBACK );
2033
2033
}
2034
2034
2035
2035
static struct fuse_writepage_args * fuse_writepage_args_setup (struct folio * folio ,
2036
+ size_t offset ,
2036
2037
struct fuse_file * ff )
2037
2038
{
2038
2039
struct inode * inode = folio -> mapping -> host ;
@@ -2045,7 +2046,7 @@ static struct fuse_writepage_args *fuse_writepage_args_setup(struct folio *folio
2045
2046
return NULL ;
2046
2047
2047
2048
fuse_writepage_add_to_bucket (fc , wpa );
2048
- fuse_write_args_fill (& wpa -> ia , ff , folio_pos (folio ), 0 );
2049
+ fuse_write_args_fill (& wpa -> ia , ff , folio_pos (folio ) + offset , 0 );
2049
2050
wpa -> ia .write .in .write_flags |= FUSE_WRITE_CACHE ;
2050
2051
wpa -> inode = inode ;
2051
2052
wpa -> ia .ff = ff ;
@@ -2071,7 +2072,7 @@ static int fuse_writepage_locked(struct folio *folio)
2071
2072
if (!ff )
2072
2073
goto err ;
2073
2074
2074
- wpa = fuse_writepage_args_setup (folio , ff );
2075
+ wpa = fuse_writepage_args_setup (folio , 0 , ff );
2075
2076
error = - ENOMEM ;
2076
2077
if (!wpa )
2077
2078
goto err_writepage_args ;
@@ -2080,7 +2081,7 @@ static int fuse_writepage_locked(struct folio *folio)
2080
2081
ap -> num_folios = 1 ;
2081
2082
2082
2083
folio_start_writeback (folio );
2083
- fuse_writepage_args_page_fill (wpa , folio , 0 );
2084
+ fuse_writepage_args_page_fill (wpa , folio , 0 , 0 , folio_size ( folio ) );
2084
2085
2085
2086
spin_lock (& fi -> lock );
2086
2087
list_add_tail (& wpa -> queue_entry , & fi -> queued_writes );
@@ -2101,7 +2102,12 @@ struct fuse_fill_wb_data {
2101
2102
struct fuse_file * ff ;
2102
2103
struct inode * inode ;
2103
2104
unsigned int max_folios ;
2104
- unsigned int nr_pages ;
2105
+ /*
2106
+ * nr_bytes won't overflow since fuse_writepage_need_send() caps
2107
+ * wb requests to never exceed fc->max_pages (which has an upper bound
2108
+ * of U16_MAX).
2109
+ */
2110
+ unsigned int nr_bytes ;
2105
2111
};
2106
2112
2107
2113
static bool fuse_pages_realloc (struct fuse_fill_wb_data * data )
@@ -2142,22 +2148,30 @@ static void fuse_writepages_send(struct fuse_fill_wb_data *data)
2142
2148
spin_unlock (& fi -> lock );
2143
2149
}
2144
2150
2145
- static bool fuse_writepage_need_send (struct fuse_conn * fc , struct folio * folio ,
2146
- struct fuse_args_pages * ap ,
2151
+ static bool fuse_writepage_need_send (struct fuse_conn * fc , loff_t pos ,
2152
+ unsigned len , struct fuse_args_pages * ap ,
2147
2153
struct fuse_fill_wb_data * data )
2148
2154
{
2155
+ struct folio * prev_folio ;
2156
+ struct fuse_folio_desc prev_desc ;
2157
+ unsigned bytes = data -> nr_bytes + len ;
2158
+ loff_t prev_pos ;
2159
+
2149
2160
WARN_ON (!ap -> num_folios );
2150
2161
2151
2162
/* Reached max pages */
2152
- if (data -> nr_pages + folio_nr_pages ( folio ) > fc -> max_pages )
2163
+ if (( bytes + PAGE_SIZE - 1 ) >> PAGE_SHIFT > fc -> max_pages )
2153
2164
return true;
2154
2165
2155
2166
/* Reached max write bytes */
2156
- if (( data -> nr_pages * PAGE_SIZE ) + folio_size ( folio ) > fc -> max_write )
2167
+ if (bytes > fc -> max_write )
2157
2168
return true;
2158
2169
2159
2170
/* Discontinuity */
2160
- if (folio_next_index (ap -> folios [ap -> num_folios - 1 ]) != folio -> index )
2171
+ prev_folio = ap -> folios [ap -> num_folios - 1 ];
2172
+ prev_desc = ap -> descs [ap -> num_folios - 1 ];
2173
+ prev_pos = folio_pos (prev_folio ) + prev_desc .offset + prev_desc .length ;
2174
+ if (prev_pos != pos )
2161
2175
return true;
2162
2176
2163
2177
/* Need to grow the pages array? If so, did the expansion fail? */
@@ -2167,85 +2181,102 @@ static bool fuse_writepage_need_send(struct fuse_conn *fc, struct folio *folio,
2167
2181
return false;
2168
2182
}
2169
2183
2170
- static int fuse_writepages_fill (struct folio * folio ,
2171
- struct writeback_control * wbc , void * _data )
2184
+ static ssize_t fuse_iomap_writeback_range (struct iomap_writepage_ctx * wpc ,
2185
+ struct folio * folio , u64 pos ,
2186
+ unsigned len , u64 end_pos )
2172
2187
{
2173
- struct fuse_fill_wb_data * data = _data ;
2188
+ struct fuse_fill_wb_data * data = wpc -> wb_ctx ;
2174
2189
struct fuse_writepage_args * wpa = data -> wpa ;
2175
2190
struct fuse_args_pages * ap = & wpa -> ia .ap ;
2176
2191
struct inode * inode = data -> inode ;
2177
2192
struct fuse_inode * fi = get_fuse_inode (inode );
2178
2193
struct fuse_conn * fc = get_fuse_conn (inode );
2179
- int err ;
2194
+ loff_t offset = offset_in_folio (folio , pos );
2195
+
2196
+ WARN_ON_ONCE (!data );
2197
+ /* len will always be page aligned */
2198
+ WARN_ON_ONCE (len & (PAGE_SIZE - 1 ));
2180
2199
2181
2200
if (!data -> ff ) {
2182
- err = - EIO ;
2183
2201
data -> ff = fuse_write_file_get (fi );
2184
2202
if (!data -> ff )
2185
- goto out_unlock ;
2203
+ return - EIO ;
2186
2204
}
2187
2205
2188
- if (wpa && fuse_writepage_need_send (fc , folio , ap , data )) {
2206
+ if (wpa && fuse_writepage_need_send (fc , pos , len , ap , data )) {
2189
2207
fuse_writepages_send (data );
2190
2208
data -> wpa = NULL ;
2191
- data -> nr_pages = 0 ;
2209
+ data -> nr_bytes = 0 ;
2192
2210
}
2193
2211
2194
2212
if (data -> wpa == NULL ) {
2195
- err = - ENOMEM ;
2196
- wpa = fuse_writepage_args_setup (folio , data -> ff );
2213
+ wpa = fuse_writepage_args_setup (folio , offset , data -> ff );
2197
2214
if (!wpa )
2198
- goto out_unlock ;
2215
+ return - ENOMEM ;
2199
2216
fuse_file_get (wpa -> ia .ff );
2200
2217
data -> max_folios = 1 ;
2201
2218
ap = & wpa -> ia .ap ;
2202
2219
}
2203
- folio_start_writeback (folio );
2204
2220
2205
- fuse_writepage_args_page_fill (wpa , folio , ap -> num_folios );
2206
- data -> nr_pages += folio_nr_pages (folio );
2221
+ iomap_start_folio_write (inode , folio , 1 );
2222
+ fuse_writepage_args_page_fill (wpa , folio , ap -> num_folios ,
2223
+ offset , len );
2224
+ data -> nr_bytes += len ;
2207
2225
2208
- err = 0 ;
2209
2226
ap -> num_folios ++ ;
2210
2227
if (!data -> wpa )
2211
2228
data -> wpa = wpa ;
2212
- out_unlock :
2213
- folio_unlock (folio );
2214
2229
2215
- return err ;
2230
+ return len ;
2231
+ }
2232
+
2233
+ static int fuse_iomap_writeback_submit (struct iomap_writepage_ctx * wpc ,
2234
+ int error )
2235
+ {
2236
+ struct fuse_fill_wb_data * data = wpc -> wb_ctx ;
2237
+
2238
+ WARN_ON_ONCE (!data );
2239
+
2240
+ if (data -> wpa ) {
2241
+ WARN_ON (!data -> wpa -> ia .ap .num_folios );
2242
+ fuse_writepages_send (data );
2243
+ }
2244
+
2245
+ if (data -> ff )
2246
+ fuse_file_put (data -> ff , false);
2247
+
2248
+ return error ;
2216
2249
}
2217
2250
2251
+ static const struct iomap_writeback_ops fuse_writeback_ops = {
2252
+ .writeback_range = fuse_iomap_writeback_range ,
2253
+ .writeback_submit = fuse_iomap_writeback_submit ,
2254
+ };
2255
+
2218
2256
static int fuse_writepages (struct address_space * mapping ,
2219
2257
struct writeback_control * wbc )
2220
2258
{
2221
2259
struct inode * inode = mapping -> host ;
2222
2260
struct fuse_conn * fc = get_fuse_conn (inode );
2223
- struct fuse_fill_wb_data data ;
2224
- int err ;
2261
+ struct fuse_fill_wb_data data = {
2262
+ .inode = inode ,
2263
+ };
2264
+ struct iomap_writepage_ctx wpc = {
2265
+ .inode = inode ,
2266
+ .iomap .type = IOMAP_MAPPED ,
2267
+ .wbc = wbc ,
2268
+ .ops = & fuse_writeback_ops ,
2269
+ .wb_ctx = & data ,
2270
+ };
2225
2271
2226
- err = - EIO ;
2227
2272
if (fuse_is_bad (inode ))
2228
- goto out ;
2273
+ return - EIO ;
2229
2274
2230
2275
if (wbc -> sync_mode == WB_SYNC_NONE &&
2231
2276
fc -> num_background >= fc -> congestion_threshold )
2232
2277
return 0 ;
2233
2278
2234
- data .inode = inode ;
2235
- data .wpa = NULL ;
2236
- data .ff = NULL ;
2237
- data .nr_pages = 0 ;
2238
-
2239
- err = write_cache_pages (mapping , wbc , fuse_writepages_fill , & data );
2240
- if (data .wpa ) {
2241
- WARN_ON (!data .wpa -> ia .ap .num_folios );
2242
- fuse_writepages_send (& data );
2243
- }
2244
- if (data .ff )
2245
- fuse_file_put (data .ff , false);
2246
-
2247
- out :
2248
- return err ;
2279
+ return iomap_writepages (& wpc );
2249
2280
}
2250
2281
2251
2282
static int fuse_launder_folio (struct folio * folio )
@@ -3105,7 +3136,7 @@ static const struct address_space_operations fuse_file_aops = {
3105
3136
.readahead = fuse_readahead ,
3106
3137
.writepages = fuse_writepages ,
3107
3138
.launder_folio = fuse_launder_folio ,
3108
- .dirty_folio = filemap_dirty_folio ,
3139
+ .dirty_folio = iomap_dirty_folio ,
3109
3140
.release_folio = iomap_release_folio ,
3110
3141
.migrate_folio = filemap_migrate_folio ,
3111
3142
.bmap = fuse_bmap ,
0 commit comments