@@ -1833,7 +1833,7 @@ static void fuse_writepage_finish(struct fuse_writepage_args *wpa)
18331833 * scope of the fi->lock alleviates xarray lock
18341834 * contention and noticeably improves performance.
18351835 */
1836- folio_end_writeback ( ap -> folios [i ]);
1836+ iomap_finish_folio_write ( inode , ap -> folios [i ], 1 );
18371837 dec_wb_stat (& bdi -> wb , WB_WRITEBACK );
18381838 wb_writeout_inc (& bdi -> wb );
18391839 }
@@ -2020,19 +2020,20 @@ static void fuse_writepage_add_to_bucket(struct fuse_conn *fc,
20202020}
20212021
20222022static 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 )
20242024{
20252025 struct inode * inode = folio -> mapping -> host ;
20262026 struct fuse_args_pages * ap = & wpa -> ia .ap ;
20272027
20282028 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 ;
20312031
20322032 inc_wb_stat (& inode_to_bdi (inode )-> wb , WB_WRITEBACK );
20332033}
20342034
20352035static struct fuse_writepage_args * fuse_writepage_args_setup (struct folio * folio ,
2036+ size_t offset ,
20362037 struct fuse_file * ff )
20372038{
20382039 struct inode * inode = folio -> mapping -> host ;
@@ -2045,7 +2046,7 @@ static struct fuse_writepage_args *fuse_writepage_args_setup(struct folio *folio
20452046 return NULL ;
20462047
20472048 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 );
20492050 wpa -> ia .write .in .write_flags |= FUSE_WRITE_CACHE ;
20502051 wpa -> inode = inode ;
20512052 wpa -> ia .ff = ff ;
@@ -2071,7 +2072,7 @@ static int fuse_writepage_locked(struct folio *folio)
20712072 if (!ff )
20722073 goto err ;
20732074
2074- wpa = fuse_writepage_args_setup (folio , ff );
2075+ wpa = fuse_writepage_args_setup (folio , 0 , ff );
20752076 error = - ENOMEM ;
20762077 if (!wpa )
20772078 goto err_writepage_args ;
@@ -2080,7 +2081,7 @@ static int fuse_writepage_locked(struct folio *folio)
20802081 ap -> num_folios = 1 ;
20812082
20822083 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 ) );
20842085
20852086 spin_lock (& fi -> lock );
20862087 list_add_tail (& wpa -> queue_entry , & fi -> queued_writes );
@@ -2101,7 +2102,12 @@ struct fuse_fill_wb_data {
21012102 struct fuse_file * ff ;
21022103 struct inode * inode ;
21032104 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 ;
21052111};
21062112
21072113static 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)
21422148 spin_unlock (& fi -> lock );
21432149}
21442150
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 ,
21472153 struct fuse_fill_wb_data * data )
21482154{
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+
21492160 WARN_ON (!ap -> num_folios );
21502161
21512162 /* 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 )
21532164 return true;
21542165
21552166 /* Reached max write bytes */
2156- if (( data -> nr_pages * PAGE_SIZE ) + folio_size ( folio ) > fc -> max_write )
2167+ if (bytes > fc -> max_write )
21572168 return true;
21582169
21592170 /* 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 )
21612175 return true;
21622176
21632177 /* 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,
21672181 return false;
21682182}
21692183
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 )
21722187{
2173- struct fuse_fill_wb_data * data = _data ;
2188+ struct fuse_fill_wb_data * data = wpc -> wb_ctx ;
21742189 struct fuse_writepage_args * wpa = data -> wpa ;
21752190 struct fuse_args_pages * ap = & wpa -> ia .ap ;
21762191 struct inode * inode = data -> inode ;
21772192 struct fuse_inode * fi = get_fuse_inode (inode );
21782193 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 ));
21802199
21812200 if (!data -> ff ) {
2182- err = - EIO ;
21832201 data -> ff = fuse_write_file_get (fi );
21842202 if (!data -> ff )
2185- goto out_unlock ;
2203+ return - EIO ;
21862204 }
21872205
2188- if (wpa && fuse_writepage_need_send (fc , folio , ap , data )) {
2206+ if (wpa && fuse_writepage_need_send (fc , pos , len , ap , data )) {
21892207 fuse_writepages_send (data );
21902208 data -> wpa = NULL ;
2191- data -> nr_pages = 0 ;
2209+ data -> nr_bytes = 0 ;
21922210 }
21932211
21942212 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 );
21972214 if (!wpa )
2198- goto out_unlock ;
2215+ return - ENOMEM ;
21992216 fuse_file_get (wpa -> ia .ff );
22002217 data -> max_folios = 1 ;
22012218 ap = & wpa -> ia .ap ;
22022219 }
2203- folio_start_writeback (folio );
22042220
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 ;
22072225
2208- err = 0 ;
22092226 ap -> num_folios ++ ;
22102227 if (!data -> wpa )
22112228 data -> wpa = wpa ;
2212- out_unlock :
2213- folio_unlock (folio );
22142229
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 ;
22162249}
22172250
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+
22182256static int fuse_writepages (struct address_space * mapping ,
22192257 struct writeback_control * wbc )
22202258{
22212259 struct inode * inode = mapping -> host ;
22222260 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+ };
22252271
2226- err = - EIO ;
22272272 if (fuse_is_bad (inode ))
2228- goto out ;
2273+ return - EIO ;
22292274
22302275 if (wbc -> sync_mode == WB_SYNC_NONE &&
22312276 fc -> num_background >= fc -> congestion_threshold )
22322277 return 0 ;
22332278
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 );
22492280}
22502281
22512282static int fuse_launder_folio (struct folio * folio )
@@ -3105,7 +3136,7 @@ static const struct address_space_operations fuse_file_aops = {
31053136 .readahead = fuse_readahead ,
31063137 .writepages = fuse_writepages ,
31073138 .launder_folio = fuse_launder_folio ,
3108- .dirty_folio = filemap_dirty_folio ,
3139+ .dirty_folio = iomap_dirty_folio ,
31093140 .release_folio = iomap_release_folio ,
31103141 .migrate_folio = filemap_migrate_folio ,
31113142 .bmap = fuse_bmap ,
0 commit comments