2019-07-15 18:50:59 +03:00
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright ( C ) 2010 Red Hat , Inc .
2019-10-17 23:12:15 +03:00
* Copyright ( C ) 2016 - 2019 Christoph Hellwig .
2019-07-15 18:50:59 +03:00
*/
# include <linux/module.h>
# include <linux/compiler.h>
# include <linux/fs.h>
# include <linux/iomap.h>
# include <linux/pagemap.h>
# include <linux/uio.h>
# include <linux/buffer_head.h>
# include <linux/dax.h>
# include <linux/writeback.h>
2019-10-17 23:12:15 +03:00
# include <linux/list_sort.h>
2019-07-15 18:50:59 +03:00
# include <linux/swap.h>
# include <linux/bio.h>
# include <linux/sched/signal.h>
# include <linux/migrate.h>
2019-10-17 23:12:13 +03:00
# include "trace.h"
2019-07-15 18:50:59 +03:00
# include "../internal.h"
2019-10-17 23:12:19 +03:00
/*
2021-04-28 05:56:17 +03:00
* Structure allocated for each folio when block size < folio size
* to track sub - folio uptodate status and I / O completions .
2019-10-17 23:12:19 +03:00
*/
struct iomap_page {
2020-09-21 18:58:40 +03:00
atomic_t read_bytes_pending ;
2020-09-21 18:58:41 +03:00
atomic_t write_bytes_pending ;
2019-12-04 20:33:52 +03:00
spinlock_t uptodate_lock ;
2020-09-21 18:58:40 +03:00
unsigned long uptodate [ ] ;
2019-10-17 23:12:19 +03:00
} ;
2021-04-28 05:56:17 +03:00
static inline struct iomap_page * to_iomap_page ( struct folio * folio )
2019-10-17 23:12:19 +03:00
{
2021-04-28 05:56:17 +03:00
if ( folio_test_private ( folio ) )
return folio_get_private ( folio ) ;
2019-10-17 23:12:19 +03:00
return NULL ;
}
2019-10-17 23:12:15 +03:00
static struct bio_set iomap_ioend_bioset ;
2019-07-15 18:50:59 +03:00
static struct iomap_page *
2021-04-28 06:12:52 +03:00
iomap_page_create ( struct inode * inode , struct folio * folio )
2019-07-15 18:50:59 +03:00
{
2021-04-28 05:56:17 +03:00
struct iomap_page * iop = to_iomap_page ( folio ) ;
2021-04-28 06:12:52 +03:00
unsigned int nr_blocks = i_blocks_per_folio ( inode , folio ) ;
2019-07-15 18:50:59 +03:00
2020-09-21 18:58:40 +03:00
if ( iop | | nr_blocks < = 1 )
2019-07-15 18:50:59 +03:00
return iop ;
2020-09-21 18:58:40 +03:00
iop = kzalloc ( struct_size ( iop , uptodate , BITS_TO_LONGS ( nr_blocks ) ) ,
GFP_NOFS | __GFP_NOFAIL ) ;
2019-12-04 20:33:52 +03:00
spin_lock_init ( & iop - > uptodate_lock ) ;
2021-04-28 06:12:52 +03:00
if ( folio_test_uptodate ( folio ) )
2020-09-25 21:16:53 +03:00
bitmap_fill ( iop - > uptodate , nr_blocks ) ;
2021-04-28 06:12:52 +03:00
folio_attach_private ( folio , iop ) ;
2019-07-15 18:50:59 +03:00
return iop ;
}
2021-04-28 06:22:22 +03:00
static void iomap_page_release ( struct folio * folio )
2019-07-15 18:50:59 +03:00
{
2021-04-28 06:22:22 +03:00
struct iomap_page * iop = folio_detach_private ( folio ) ;
struct inode * inode = folio - > mapping - > host ;
unsigned int nr_blocks = i_blocks_per_folio ( inode , folio ) ;
2019-07-15 18:50:59 +03:00
if ( ! iop )
return ;
2020-09-21 18:58:40 +03:00
WARN_ON_ONCE ( atomic_read ( & iop - > read_bytes_pending ) ) ;
2020-09-21 18:58:41 +03:00
WARN_ON_ONCE ( atomic_read ( & iop - > write_bytes_pending ) ) ;
2020-09-21 18:58:40 +03:00
WARN_ON_ONCE ( bitmap_full ( iop - > uptodate , nr_blocks ) ! =
2021-04-28 06:22:22 +03:00
folio_test_uptodate ( folio ) ) ;
2019-07-15 18:50:59 +03:00
kfree ( iop ) ;
}
/*
2021-04-28 15:20:48 +03:00
* Calculate the range inside the folio that we actually need to read .
2019-07-15 18:50:59 +03:00
*/
2021-04-28 15:20:48 +03:00
static void iomap_adjust_read_range ( struct inode * inode , struct folio * folio ,
loff_t * pos , loff_t length , size_t * offp , size_t * lenp )
2019-07-15 18:50:59 +03:00
{
2021-04-28 15:20:48 +03:00
struct iomap_page * iop = to_iomap_page ( folio ) ;
2019-07-15 18:50:59 +03:00
loff_t orig_pos = * pos ;
loff_t isize = i_size_read ( inode ) ;
unsigned block_bits = inode - > i_blkbits ;
unsigned block_size = ( 1 < < block_bits ) ;
2021-04-28 15:20:48 +03:00
size_t poff = offset_in_folio ( folio , * pos ) ;
size_t plen = min_t ( loff_t , folio_size ( folio ) - poff , length ) ;
2019-07-15 18:50:59 +03:00
unsigned first = poff > > block_bits ;
unsigned last = ( poff + plen - 1 ) > > block_bits ;
/*
2021-08-03 00:46:31 +03:00
* If the block size is smaller than the page size , we need to check the
2019-07-15 18:50:59 +03:00
* per - block uptodate status and adjust the offset and length if needed
* to avoid reading in already uptodate ranges .
*/
if ( iop ) {
unsigned int i ;
/* move forward for each leading block marked uptodate */
for ( i = first ; i < = last ; i + + ) {
if ( ! test_bit ( i , iop - > uptodate ) )
break ;
* pos + = block_size ;
poff + = block_size ;
plen - = block_size ;
first + + ;
}
/* truncate len if we find any trailing uptodate block(s) */
for ( ; i < = last ; i + + ) {
if ( test_bit ( i , iop - > uptodate ) ) {
plen - = ( last - i + 1 ) * block_size ;
last = i - 1 ;
break ;
}
}
}
/*
2021-08-03 00:46:31 +03:00
* If the extent spans the block that contains the i_size , we need to
2019-07-15 18:50:59 +03:00
* handle both halves separately so that we properly zero data in the
* page cache for blocks that are entirely outside of i_size .
*/
if ( orig_pos < = isize & & orig_pos + length > isize ) {
2021-04-28 15:20:48 +03:00
unsigned end = offset_in_folio ( folio , isize - 1 ) > > block_bits ;
2019-07-15 18:50:59 +03:00
if ( first < = end & & last > end )
plen - = ( last - end ) * block_size ;
}
* offp = poff ;
* lenp = plen ;
}
2021-04-28 15:20:48 +03:00
static void iomap_iop_set_range_uptodate ( struct folio * folio ,
struct iomap_page * iop , size_t off , size_t len )
2019-07-15 18:50:59 +03:00
{
2021-04-28 15:20:48 +03:00
struct inode * inode = folio - > mapping - > host ;
2019-07-15 18:50:59 +03:00
unsigned first = off > > inode - > i_blkbits ;
unsigned last = ( off + len - 1 ) > > inode - > i_blkbits ;
2019-12-04 20:33:52 +03:00
unsigned long flags ;
2019-07-15 18:50:59 +03:00
2019-12-04 20:33:52 +03:00
spin_lock_irqsave ( & iop - > uptodate_lock , flags ) ;
2020-09-21 18:58:40 +03:00
bitmap_set ( iop - > uptodate , first , last - first + 1 ) ;
2021-04-28 15:20:48 +03:00
if ( bitmap_full ( iop - > uptodate , i_blocks_per_folio ( inode , folio ) ) )
folio_mark_uptodate ( folio ) ;
2019-12-04 20:33:52 +03:00
spin_unlock_irqrestore ( & iop - > uptodate_lock , flags ) ;
}
2021-04-28 15:20:48 +03:00
static void iomap_set_range_uptodate ( struct folio * folio ,
struct iomap_page * iop , size_t off , size_t len )
2019-12-04 20:33:52 +03:00
{
2021-04-28 15:20:48 +03:00
if ( folio_test_error ( folio ) )
2019-12-04 20:33:52 +03:00
return ;
2021-04-28 15:16:50 +03:00
if ( iop )
2021-04-28 15:20:48 +03:00
iomap_iop_set_range_uptodate ( folio , iop , off , len ) ;
2019-12-04 20:33:52 +03:00
else
2021-04-28 15:20:48 +03:00
folio_mark_uptodate ( folio ) ;
2019-07-15 18:50:59 +03:00
}
2021-01-02 00:53:26 +03:00
static void iomap_finish_folio_read ( struct folio * folio , size_t offset ,
size_t len , int error )
2019-07-15 18:50:59 +03:00
{
2021-04-28 05:56:17 +03:00
struct iomap_page * iop = to_iomap_page ( folio ) ;
2019-07-15 18:50:59 +03:00
if ( unlikely ( error ) ) {
2021-01-02 00:53:26 +03:00
folio_clear_uptodate ( folio ) ;
folio_set_error ( folio ) ;
2019-07-15 18:50:59 +03:00
} else {
2021-04-28 15:20:48 +03:00
iomap_set_range_uptodate ( folio , iop , offset , len ) ;
2019-07-15 18:50:59 +03:00
}
2021-01-02 00:53:26 +03:00
if ( ! iop | | atomic_sub_and_test ( len , & iop - > read_bytes_pending ) )
folio_unlock ( folio ) ;
2019-07-15 18:50:59 +03:00
}
2021-01-02 00:53:26 +03:00
static void iomap_read_end_io ( struct bio * bio )
2019-07-15 18:50:59 +03:00
{
int error = blk_status_to_errno ( bio - > bi_status ) ;
2021-01-02 00:53:26 +03:00
struct folio_iter fi ;
2019-07-15 18:50:59 +03:00
2021-01-02 00:53:26 +03:00
bio_for_each_folio_all ( fi , bio )
iomap_finish_folio_read ( fi . folio , fi . offset , fi . length , error ) ;
2019-07-15 18:50:59 +03:00
bio_put ( bio ) ;
}
struct iomap_readpage_ctx {
2021-04-28 16:39:51 +03:00
struct folio * cur_folio ;
bool cur_folio_in_bio ;
2019-07-15 18:50:59 +03:00
struct bio * bio ;
2020-06-02 07:47:34 +03:00
struct readahead_control * rac ;
2019-07-15 18:50:59 +03:00
} ;
2021-11-24 21:15:47 +03:00
/**
* iomap_read_inline_data - copy inline data into the page cache
* @ iter : iteration structure
2021-07-24 06:24:50 +03:00
* @ folio : folio to copy to
2021-11-24 21:15:47 +03:00
*
2021-07-24 06:24:50 +03:00
* Copy the inline data in @ iter into @ folio and zero out the rest of the folio .
2021-11-24 21:15:47 +03:00
* Only a single IOMAP_INLINE extent is allowed at the end of each file .
* Returns zero for success to complete the read , or the usual negative errno .
*/
static int iomap_read_inline_data ( const struct iomap_iter * iter ,
2021-07-24 06:24:50 +03:00
struct folio * folio )
2019-07-15 18:50:59 +03:00
{
2021-04-28 15:16:50 +03:00
struct iomap_page * iop ;
2021-08-11 04:33:16 +03:00
const struct iomap * iomap = iomap_iter_srcmap ( iter ) ;
2021-08-11 04:33:14 +03:00
size_t size = i_size_read ( iter - > inode ) - iomap - > offset ;
2021-08-03 00:45:57 +03:00
size_t poff = offset_in_page ( iomap - > offset ) ;
2021-04-28 15:20:48 +03:00
size_t offset = offset_in_folio ( folio , iomap - > offset ) ;
2019-07-15 18:50:59 +03:00
void * addr ;
2021-07-24 06:24:50 +03:00
if ( folio_test_uptodate ( folio ) )
2021-11-24 21:15:47 +03:00
return 0 ;
2019-07-15 18:50:59 +03:00
2021-08-05 06:07:34 +03:00
if ( WARN_ON_ONCE ( size > PAGE_SIZE - poff ) )
return - EIO ;
2021-08-03 19:38:22 +03:00
if ( WARN_ON_ONCE ( size > PAGE_SIZE -
offset_in_page ( iomap - > inline_data ) ) )
return - EIO ;
if ( WARN_ON_ONCE ( size > iomap - > length ) )
return - EIO ;
2021-04-28 15:20:48 +03:00
if ( offset > 0 )
2021-04-28 15:16:50 +03:00
iop = iomap_page_create ( iter - > inode , folio ) ;
else
iop = to_iomap_page ( folio ) ;
2019-07-15 18:50:59 +03:00
2021-07-24 06:24:50 +03:00
addr = kmap_local_folio ( folio , offset ) ;
2019-07-15 18:50:59 +03:00
memcpy ( addr , iomap - > inline_data , size ) ;
2021-08-03 00:45:57 +03:00
memset ( addr + size , 0 , PAGE_SIZE - poff - size ) ;
2021-08-05 06:07:33 +03:00
kunmap_local ( addr ) ;
2021-04-28 15:20:48 +03:00
iomap_set_range_uptodate ( folio , iop , offset , PAGE_SIZE - poff ) ;
2021-11-24 21:15:47 +03:00
return 0 ;
2019-07-15 18:50:59 +03:00
}
2021-08-11 04:33:16 +03:00
static inline bool iomap_block_needs_zeroing ( const struct iomap_iter * iter ,
2021-08-11 04:33:14 +03:00
loff_t pos )
2019-10-17 23:12:12 +03:00
{
2021-08-11 04:33:16 +03:00
const struct iomap * srcmap = iomap_iter_srcmap ( iter ) ;
2021-08-11 04:33:14 +03:00
return srcmap - > type ! = IOMAP_MAPPED | |
( srcmap - > flags & IOMAP_F_NEW ) | |
pos > = i_size_read ( iter - > inode ) ;
2019-10-17 23:12:12 +03:00
}
2021-08-11 04:33:16 +03:00
static loff_t iomap_readpage_iter ( const struct iomap_iter * iter ,
2021-08-11 04:33:08 +03:00
struct iomap_readpage_ctx * ctx , loff_t offset )
2019-07-15 18:50:59 +03:00
{
2021-08-11 04:33:16 +03:00
const struct iomap * iomap = & iter - > iomap ;
2021-08-11 04:33:08 +03:00
loff_t pos = iter - > pos + offset ;
loff_t length = iomap_length ( iter ) - offset ;
2021-04-28 16:39:51 +03:00
struct folio * folio = ctx - > cur_folio ;
2021-07-15 19:58:05 +03:00
struct iomap_page * iop ;
2019-07-15 18:50:59 +03:00
loff_t orig_pos = pos ;
2021-04-28 15:20:48 +03:00
size_t poff , plen ;
2019-07-15 18:50:59 +03:00
sector_t sector ;
2021-11-24 21:15:47 +03:00
if ( iomap - > type = = IOMAP_INLINE )
2021-07-24 06:24:50 +03:00
return iomap_read_inline_data ( iter , folio ) ;
2019-07-15 18:50:59 +03:00
/* zero post-eof blocks as the page may be mapped */
2021-04-28 06:12:52 +03:00
iop = iomap_page_create ( iter - > inode , folio ) ;
2021-04-28 15:20:48 +03:00
iomap_adjust_read_range ( iter - > inode , folio , & pos , length , & poff , & plen ) ;
2019-07-15 18:50:59 +03:00
if ( plen = = 0 )
goto done ;
2021-08-11 04:33:14 +03:00
if ( iomap_block_needs_zeroing ( iter , pos ) ) {
2021-04-28 15:20:48 +03:00
folio_zero_range ( folio , poff , plen ) ;
iomap_set_range_uptodate ( folio , iop , poff , plen ) ;
2019-07-15 18:50:59 +03:00
goto done ;
}
2021-04-28 16:39:51 +03:00
ctx - > cur_folio_in_bio = true ;
2020-09-21 18:58:40 +03:00
if ( iop )
atomic_add ( plen , & iop - > read_bytes_pending ) ;
2019-07-15 18:50:59 +03:00
sector = iomap_sector ( iomap , pos ) ;
2021-08-03 00:43:43 +03:00
if ( ! ctx - > bio | |
bio_end_sector ( ctx - > bio ) ! = sector | |
2021-04-28 15:20:48 +03:00
! bio_add_folio ( ctx - > bio , folio , plen , poff ) ) {
2021-04-28 16:39:51 +03:00
gfp_t gfp = mapping_gfp_constraint ( folio - > mapping , GFP_KERNEL ) ;
2020-04-02 19:08:53 +03:00
gfp_t orig_gfp = gfp ;
2021-01-29 07:38:57 +03:00
unsigned int nr_vecs = DIV_ROUND_UP ( length , PAGE_SIZE ) ;
2019-07-15 18:50:59 +03:00
if ( ctx - > bio )
submit_bio ( ctx - > bio ) ;
2020-06-02 07:47:34 +03:00
if ( ctx - > rac ) /* same as readahead_gfp_mask */
2019-07-15 18:50:59 +03:00
gfp | = __GFP_NORETRY | __GFP_NOWARN ;
2021-01-29 07:38:57 +03:00
ctx - > bio = bio_alloc ( gfp , bio_max_segs ( nr_vecs ) ) ;
2020-04-02 19:08:53 +03:00
/*
* If the bio_alloc fails , try it again for a single page to
* avoid having to deal with partial page reads . This emulates
* what do_mpage_readpage does .
*/
if ( ! ctx - > bio )
ctx - > bio = bio_alloc ( orig_gfp , 1 ) ;
2019-07-15 18:50:59 +03:00
ctx - > bio - > bi_opf = REQ_OP_READ ;
2020-06-02 07:47:34 +03:00
if ( ctx - > rac )
2019-07-15 18:50:59 +03:00
ctx - > bio - > bi_opf | = REQ_RAHEAD ;
ctx - > bio - > bi_iter . bi_sector = sector ;
bio_set_dev ( ctx - > bio , iomap - > bdev ) ;
ctx - > bio - > bi_end_io = iomap_read_end_io ;
2021-04-28 15:20:48 +03:00
bio_add_folio ( ctx - > bio , folio , plen , poff ) ;
2019-07-15 18:50:59 +03:00
}
2021-04-28 15:20:48 +03:00
2019-07-15 18:50:59 +03:00
done :
/*
* Move the caller beyond our range so that it keeps making progress .
2021-08-03 00:46:31 +03:00
* For that , we have to include any leading non - uptodate ranges , but
2019-07-15 18:50:59 +03:00
* we can skip trailing ones as they will be handled in the next
* iteration .
*/
return pos - orig_pos + plen ;
}
int
iomap_readpage ( struct page * page , const struct iomap_ops * ops )
{
2021-04-28 16:39:51 +03:00
struct folio * folio = page_folio ( page ) ;
2021-08-11 04:33:08 +03:00
struct iomap_iter iter = {
2021-04-28 16:39:51 +03:00
. inode = folio - > mapping - > host ,
. pos = folio_pos ( folio ) ,
. len = folio_size ( folio ) ,
2021-08-11 04:33:08 +03:00
} ;
struct iomap_readpage_ctx ctx = {
2021-04-28 16:39:51 +03:00
. cur_folio = folio ,
2021-08-11 04:33:08 +03:00
} ;
int ret ;
2019-07-15 18:50:59 +03:00
2021-04-28 16:39:51 +03:00
trace_iomap_readpage ( iter . inode , 1 ) ;
2019-10-17 23:12:13 +03:00
2021-08-11 04:33:08 +03:00
while ( ( ret = iomap_iter ( & iter , ops ) ) > 0 )
iter . processed = iomap_readpage_iter ( & iter , & ctx , 0 ) ;
if ( ret < 0 )
2021-04-28 16:39:51 +03:00
folio_set_error ( folio ) ;
2019-07-15 18:50:59 +03:00
if ( ctx . bio ) {
submit_bio ( ctx . bio ) ;
2021-04-28 16:39:51 +03:00
WARN_ON_ONCE ( ! ctx . cur_folio_in_bio ) ;
2019-07-15 18:50:59 +03:00
} else {
2021-04-28 16:39:51 +03:00
WARN_ON_ONCE ( ctx . cur_folio_in_bio ) ;
folio_unlock ( folio ) ;
2019-07-15 18:50:59 +03:00
}
/*
2021-08-03 00:46:31 +03:00
* Just like mpage_readahead and block_read_full_page , we always
2019-07-15 18:50:59 +03:00
* return 0 and just mark the page as PageError on errors . This
2021-08-03 00:46:31 +03:00
* should be cleaned up throughout the stack eventually .
2019-07-15 18:50:59 +03:00
*/
return 0 ;
}
EXPORT_SYMBOL_GPL ( iomap_readpage ) ;
2021-08-11 04:33:16 +03:00
static loff_t iomap_readahead_iter ( const struct iomap_iter * iter ,
2021-08-11 04:33:08 +03:00
struct iomap_readpage_ctx * ctx )
2019-07-15 18:50:59 +03:00
{
2021-08-11 04:33:08 +03:00
loff_t length = iomap_length ( iter ) ;
2019-07-15 18:50:59 +03:00
loff_t done , ret ;
for ( done = 0 ; done < length ; done + = ret ) {
2021-04-28 16:39:51 +03:00
if ( ctx - > cur_folio & &
offset_in_folio ( ctx - > cur_folio , iter - > pos + done ) = = 0 ) {
if ( ! ctx - > cur_folio_in_bio )
folio_unlock ( ctx - > cur_folio ) ;
ctx - > cur_folio = NULL ;
2019-07-15 18:50:59 +03:00
}
2021-04-28 16:39:51 +03:00
if ( ! ctx - > cur_folio ) {
ctx - > cur_folio = readahead_folio ( ctx - > rac ) ;
ctx - > cur_folio_in_bio = false ;
2019-07-15 18:50:59 +03:00
}
2021-08-11 04:33:08 +03:00
ret = iomap_readpage_iter ( iter , ctx , done ) ;
2021-11-18 04:59:01 +03:00
if ( ret < = 0 )
return ret ;
2019-07-15 18:50:59 +03:00
}
return done ;
}
2020-06-02 07:47:34 +03:00
/**
* iomap_readahead - Attempt to read pages from a file .
* @ rac : Describes the pages to be read .
* @ ops : The operations vector for the filesystem .
*
* This function is for filesystems to call to implement their readahead
* address_space operation .
*
* Context : The @ ops callbacks may submit I / O ( eg to read the addresses of
* blocks from disc ) , and may wait for it . The caller may be trying to
* access a different page , and so sleeping excessively should be avoided .
* It may allocate memory , but should avoid costly allocations . This
* function is called with memalloc_nofs set , so allocations will not cause
* the filesystem to be reentered .
*/
void iomap_readahead ( struct readahead_control * rac , const struct iomap_ops * ops )
2019-07-15 18:50:59 +03:00
{
2021-08-11 04:33:08 +03:00
struct iomap_iter iter = {
. inode = rac - > mapping - > host ,
. pos = readahead_pos ( rac ) ,
. len = readahead_length ( rac ) ,
} ;
2019-07-15 18:50:59 +03:00
struct iomap_readpage_ctx ctx = {
2020-06-02 07:47:34 +03:00
. rac = rac ,
2019-07-15 18:50:59 +03:00
} ;
2021-08-11 04:33:08 +03:00
trace_iomap_readahead ( rac - > mapping - > host , readahead_count ( rac ) ) ;
2019-10-17 23:12:13 +03:00
2021-08-11 04:33:08 +03:00
while ( iomap_iter ( & iter , ops ) > 0 )
iter . processed = iomap_readahead_iter ( & iter , & ctx ) ;
2020-06-02 07:47:34 +03:00
2019-07-15 18:50:59 +03:00
if ( ctx . bio )
submit_bio ( ctx . bio ) ;
2021-04-28 16:39:51 +03:00
if ( ctx . cur_folio ) {
if ( ! ctx . cur_folio_in_bio )
folio_unlock ( ctx . cur_folio ) ;
2019-07-15 18:50:59 +03:00
}
}
2020-06-02 07:47:34 +03:00
EXPORT_SYMBOL_GPL ( iomap_readahead ) ;
2019-07-15 18:50:59 +03:00
/*
* iomap_is_partially_uptodate checks whether blocks within a page are
* uptodate or not .
*
* Returns true if all blocks which correspond to a file portion
* we want to read within the page are uptodate .
*/
int
iomap_is_partially_uptodate ( struct page * page , unsigned long from ,
unsigned long count )
{
2021-04-28 05:56:17 +03:00
struct folio * folio = page_folio ( page ) ;
struct iomap_page * iop = to_iomap_page ( folio ) ;
2019-07-15 18:50:59 +03:00
struct inode * inode = page - > mapping - > host ;
unsigned len , first , last ;
unsigned i ;
/* Limit range to one page */
len = min_t ( unsigned , PAGE_SIZE - from , count ) ;
/* First and last blocks in range within page */
first = from > > inode - > i_blkbits ;
last = ( from + len - 1 ) > > inode - > i_blkbits ;
if ( iop ) {
for ( i = first ; i < = last ; i + + )
if ( ! test_bit ( i , iop - > uptodate ) )
return 0 ;
return 1 ;
}
return 0 ;
}
EXPORT_SYMBOL_GPL ( iomap_is_partially_uptodate ) ;
int
iomap_releasepage ( struct page * page , gfp_t gfp_mask )
{
2021-04-28 06:22:22 +03:00
struct folio * folio = page_folio ( page ) ;
2021-04-28 14:51:36 +03:00
trace_iomap_releasepage ( folio - > mapping - > host , folio_pos ( folio ) ,
folio_size ( folio ) ) ;
2019-10-17 23:12:13 +03:00
2019-07-15 18:50:59 +03:00
/*
* mm accommodates an old ext3 case where clean pages might not have had
* the dirty bit cleared . Thus , it can send actual dirty pages to
2021-08-03 00:46:31 +03:00
* - > releasepage ( ) via shrink_active_list ( ) ; skip those here .
2019-07-15 18:50:59 +03:00
*/
2021-04-28 14:51:36 +03:00
if ( folio_test_dirty ( folio ) | | folio_test_writeback ( folio ) )
2019-07-15 18:50:59 +03:00
return 0 ;
2021-04-28 06:22:22 +03:00
iomap_page_release ( folio ) ;
2019-07-15 18:50:59 +03:00
return 1 ;
}
EXPORT_SYMBOL_GPL ( iomap_releasepage ) ;
2021-04-28 14:51:36 +03:00
void iomap_invalidate_folio ( struct folio * folio , size_t offset , size_t len )
2019-07-15 18:50:59 +03:00
{
2021-04-28 14:51:36 +03:00
trace_iomap_invalidatepage ( folio - > mapping - > host , offset , len ) ;
2019-10-17 23:12:13 +03:00
2019-07-15 18:50:59 +03:00
/*
2021-01-13 18:48:49 +03:00
* If we ' re invalidating the entire folio , clear the dirty state
* from it and release it to avoid unnecessary buildup of the LRU .
2019-07-15 18:50:59 +03:00
*/
2021-04-28 14:51:36 +03:00
if ( offset = = 0 & & len = = folio_size ( folio ) ) {
WARN_ON_ONCE ( folio_test_writeback ( folio ) ) ;
folio_cancel_dirty ( folio ) ;
2021-04-28 06:22:22 +03:00
iomap_page_release ( folio ) ;
2021-01-13 18:48:49 +03:00
} else if ( folio_test_large ( folio ) ) {
/* Must release the iop so the page can be split */
WARN_ON_ONCE ( ! folio_test_uptodate ( folio ) & &
folio_test_dirty ( folio ) ) ;
iomap_page_release ( folio ) ;
2019-07-15 18:50:59 +03:00
}
}
2021-04-28 14:51:36 +03:00
EXPORT_SYMBOL_GPL ( iomap_invalidate_folio ) ;
void iomap_invalidatepage ( struct page * page , unsigned int offset ,
unsigned int len )
{
iomap_invalidate_folio ( page_folio ( page ) , offset , len ) ;
}
2019-07-15 18:50:59 +03:00
EXPORT_SYMBOL_GPL ( iomap_invalidatepage ) ;
# ifdef CONFIG_MIGRATION
int
iomap_migrate_page ( struct address_space * mapping , struct page * newpage ,
struct page * page , enum migrate_mode mode )
{
2021-05-07 22:08:09 +03:00
struct folio * folio = page_folio ( page ) ;
struct folio * newfolio = page_folio ( newpage ) ;
2019-07-15 18:50:59 +03:00
int ret ;
2021-05-07 22:08:09 +03:00
ret = folio_migrate_mapping ( mapping , newfolio , folio , 0 ) ;
2019-07-15 18:50:59 +03:00
if ( ret ! = MIGRATEPAGE_SUCCESS )
return ret ;
2021-05-07 22:08:09 +03:00
if ( folio_test_private ( folio ) )
folio_attach_private ( newfolio , folio_detach_private ( folio ) ) ;
2019-07-15 18:50:59 +03:00
if ( mode ! = MIGRATE_SYNC_NO_COPY )
2021-05-07 22:08:09 +03:00
folio_migrate_copy ( newfolio , folio ) ;
2019-07-15 18:50:59 +03:00
else
2021-05-07 22:08:09 +03:00
folio_migrate_flags ( newfolio , folio ) ;
2019-07-15 18:50:59 +03:00
return MIGRATEPAGE_SUCCESS ;
}
EXPORT_SYMBOL_GPL ( iomap_migrate_page ) ;
# endif /* CONFIG_MIGRATION */
static void
iomap_write_failed ( struct inode * inode , loff_t pos , unsigned len )
{
loff_t i_size = i_size_read ( inode ) ;
/*
* Only truncate newly allocated pages beyoned EOF , even if the
* write started inside the existing inode size .
*/
if ( pos + len > i_size )
truncate_pagecache_range ( inode , max ( pos , i_size ) , pos + len ) ;
}
2021-04-28 15:20:48 +03:00
static int iomap_read_folio_sync ( loff_t block_start , struct folio * folio ,
size_t poff , size_t plen , const struct iomap * iomap )
2019-07-15 18:50:59 +03:00
{
struct bio_vec bvec ;
struct bio bio ;
bio_init ( & bio , & bvec , 1 ) ;
bio . bi_opf = REQ_OP_READ ;
bio . bi_iter . bi_sector = iomap_sector ( iomap , block_start ) ;
bio_set_dev ( & bio , iomap - > bdev ) ;
2021-04-28 15:20:48 +03:00
bio_add_folio ( & bio , folio , plen , poff ) ;
2019-07-15 18:50:59 +03:00
return submit_bio_wait ( & bio ) ;
}
2021-08-11 04:33:16 +03:00
static int __iomap_write_begin ( const struct iomap_iter * iter , loff_t pos ,
2021-05-02 18:33:08 +03:00
size_t len , struct folio * folio )
2019-07-15 18:50:59 +03:00
{
2021-08-11 04:33:16 +03:00
const struct iomap * srcmap = iomap_iter_srcmap ( iter ) ;
2021-04-28 06:12:52 +03:00
struct iomap_page * iop = iomap_page_create ( iter - > inode , folio ) ;
2021-08-11 04:33:14 +03:00
loff_t block_size = i_blocksize ( iter - > inode ) ;
2020-09-10 18:38:06 +03:00
loff_t block_start = round_down ( pos , block_size ) ;
loff_t block_end = round_up ( pos + len , block_size ) ;
2021-04-28 15:20:48 +03:00
size_t from = offset_in_folio ( folio , pos ) , to = from + len ;
size_t poff , plen ;
2019-07-15 18:50:59 +03:00
2021-04-28 15:20:48 +03:00
if ( folio_test_uptodate ( folio ) )
2019-07-15 18:50:59 +03:00
return 0 ;
2021-04-28 15:20:48 +03:00
folio_clear_error ( folio ) ;
2019-07-15 18:50:59 +03:00
do {
2021-04-28 15:20:48 +03:00
iomap_adjust_read_range ( iter - > inode , folio , & block_start ,
2019-07-15 18:50:59 +03:00
block_end - block_start , & poff , & plen ) ;
if ( plen = = 0 )
break ;
2021-08-11 04:33:14 +03:00
if ( ! ( iter - > flags & IOMAP_UNSHARE ) & &
2019-10-19 02:42:50 +03:00
( from < = poff | | from > = poff + plen ) & &
2019-10-19 02:42:24 +03:00
( to < = poff | | to > = poff + plen ) )
continue ;
2021-08-11 04:33:14 +03:00
if ( iomap_block_needs_zeroing ( iter , block_start ) ) {
2021-08-11 04:33:14 +03:00
if ( WARN_ON_ONCE ( iter - > flags & IOMAP_UNSHARE ) )
2019-10-19 02:42:50 +03:00
return - EIO ;
2021-04-28 15:20:48 +03:00
folio_zero_segments ( folio , poff , from , to , poff + plen ) ;
2020-09-10 18:26:18 +03:00
} else {
2021-04-28 15:20:48 +03:00
int status = iomap_read_folio_sync ( block_start , folio ,
2020-09-10 18:26:18 +03:00
poff , plen , srcmap ) ;
if ( status )
return status ;
2019-07-15 18:50:59 +03:00
}
2021-04-28 15:20:48 +03:00
iomap_set_range_uptodate ( folio , iop , poff , plen ) ;
2019-07-15 18:50:59 +03:00
} while ( ( block_start + = plen ) < block_end ) ;
2019-10-19 02:42:24 +03:00
return 0 ;
2019-07-15 18:50:59 +03:00
}
2021-08-11 04:33:16 +03:00
static int iomap_write_begin_inline ( const struct iomap_iter * iter ,
2021-05-02 18:33:08 +03:00
struct folio * folio )
2021-08-03 19:38:22 +03:00
{
/* needs more work for the tailpacking case; disable for now */
2021-08-11 04:33:14 +03:00
if ( WARN_ON_ONCE ( iomap_iter_srcmap ( iter ) - > offset ! = 0 ) )
2021-08-03 19:38:22 +03:00
return - EIO ;
2021-07-24 06:24:50 +03:00
return iomap_read_inline_data ( iter , folio ) ;
2021-08-03 19:38:22 +03:00
}
2021-08-11 04:33:16 +03:00
static int iomap_write_begin ( const struct iomap_iter * iter , loff_t pos ,
2021-05-02 18:33:08 +03:00
size_t len , struct folio * * foliop )
2019-07-15 18:50:59 +03:00
{
2021-08-11 04:33:14 +03:00
const struct iomap_page_ops * page_ops = iter - > iomap . page_ops ;
2021-08-11 04:33:16 +03:00
const struct iomap * srcmap = iomap_iter_srcmap ( iter ) ;
2021-11-03 21:05:47 +03:00
struct folio * folio ;
2021-05-02 18:33:08 +03:00
unsigned fgp = FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE | FGP_NOFS ;
2019-07-15 18:50:59 +03:00
int status = 0 ;
2021-08-11 04:33:14 +03:00
BUG_ON ( pos + len > iter - > iomap . offset + iter - > iomap . length ) ;
if ( srcmap ! = & iter - > iomap )
2019-10-19 02:44:10 +03:00
BUG_ON ( pos + len > srcmap - > offset + srcmap - > length ) ;
2019-07-15 18:50:59 +03:00
if ( fatal_signal_pending ( current ) )
return - EINTR ;
2021-12-09 23:47:44 +03:00
if ( ! mapping_large_folio_support ( iter - > inode - > i_mapping ) )
len = min_t ( size_t , len , PAGE_SIZE - offset_in_page ( pos ) ) ;
2019-07-15 18:50:59 +03:00
if ( page_ops & & page_ops - > page_prepare ) {
2021-08-11 04:33:14 +03:00
status = page_ops - > page_prepare ( iter - > inode , pos , len ) ;
2019-07-15 18:50:59 +03:00
if ( status )
return status ;
}
2021-05-02 18:33:08 +03:00
folio = __filemap_get_folio ( iter - > inode - > i_mapping , pos > > PAGE_SHIFT ,
fgp , mapping_gfp_mask ( iter - > inode - > i_mapping ) ) ;
if ( ! folio ) {
2019-07-15 18:50:59 +03:00
status = - ENOMEM ;
goto out_no_page ;
}
2021-12-09 23:47:44 +03:00
if ( pos + len > folio_pos ( folio ) + folio_size ( folio ) )
len = folio_pos ( folio ) + folio_size ( folio ) - pos ;
2019-07-15 18:50:59 +03:00
2019-10-19 02:44:10 +03:00
if ( srcmap - > type = = IOMAP_INLINE )
2021-05-02 18:33:08 +03:00
status = iomap_write_begin_inline ( iter , folio ) ;
2021-08-11 04:33:14 +03:00
else if ( srcmap - > flags & IOMAP_F_BUFFER_HEAD )
2021-11-03 21:05:47 +03:00
status = __block_write_begin_int ( folio , pos , len , NULL , srcmap ) ;
2019-07-15 18:50:59 +03:00
else
2021-05-02 18:33:08 +03:00
status = __iomap_write_begin ( iter , pos , len , folio ) ;
2019-07-15 18:50:59 +03:00
if ( unlikely ( status ) )
goto out_unlock ;
2021-05-02 18:33:08 +03:00
* foliop = folio ;
2019-07-15 18:50:59 +03:00
return 0 ;
out_unlock :
2021-05-02 18:33:08 +03:00
folio_unlock ( folio ) ;
folio_put ( folio ) ;
2021-08-11 04:33:14 +03:00
iomap_write_failed ( iter - > inode , pos , len ) ;
2019-07-15 18:50:59 +03:00
out_no_page :
if ( page_ops & & page_ops - > page_done )
2021-08-11 04:33:14 +03:00
page_ops - > page_done ( iter - > inode , pos , 0 , NULL ) ;
2019-07-15 18:50:59 +03:00
return status ;
}
2020-09-21 18:58:41 +03:00
static size_t __iomap_write_end ( struct inode * inode , loff_t pos , size_t len ,
2021-05-02 18:33:08 +03:00
size_t copied , struct folio * folio )
2019-07-15 18:50:59 +03:00
{
2021-04-28 15:16:50 +03:00
struct iomap_page * iop = to_iomap_page ( folio ) ;
2021-05-02 18:33:08 +03:00
flush_dcache_folio ( folio ) ;
2019-07-15 18:50:59 +03:00
/*
* The blocks that were entirely written will now be uptodate , so we
* don ' t have to worry about a readpage reading them and overwriting a
2021-08-03 00:46:31 +03:00
* partial write . However , if we ' ve encountered a short write and only
2019-07-15 18:50:59 +03:00
* partially written into a block , it will not be marked uptodate , so a
* readpage might come in and destroy our partial write .
*
2021-08-03 00:46:31 +03:00
* Do the simplest thing and just treat any short write to a
* non - uptodate page as a zero - length write , and force the caller to
* redo the whole thing .
2019-07-15 18:50:59 +03:00
*/
2021-05-02 18:33:08 +03:00
if ( unlikely ( copied < len & & ! folio_test_uptodate ( folio ) ) )
2019-07-15 18:50:59 +03:00
return 0 ;
2021-04-28 15:20:48 +03:00
iomap_set_range_uptodate ( folio , iop , offset_in_folio ( folio , pos ) , len ) ;
2021-05-02 18:33:08 +03:00
filemap_dirty_folio ( inode - > i_mapping , folio ) ;
2019-07-15 18:50:59 +03:00
return copied ;
}
2021-08-11 04:33:16 +03:00
static size_t iomap_write_end_inline ( const struct iomap_iter * iter ,
2021-05-02 18:44:44 +03:00
struct folio * folio , loff_t pos , size_t copied )
2019-07-15 18:50:59 +03:00
{
2021-08-11 04:33:16 +03:00
const struct iomap * iomap = & iter - > iomap ;
2019-07-15 18:50:59 +03:00
void * addr ;
2021-05-02 18:44:44 +03:00
WARN_ON_ONCE ( ! folio_test_uptodate ( folio ) ) ;
2021-08-03 19:38:22 +03:00
BUG_ON ( ! iomap_inline_data_valid ( iomap ) ) ;
2019-07-15 18:50:59 +03:00
2021-05-02 18:44:44 +03:00
flush_dcache_folio ( folio ) ;
addr = kmap_local_folio ( folio , pos ) ;
2021-08-05 06:07:33 +03:00
memcpy ( iomap_inline_data ( iomap , pos ) , addr , copied ) ;
kunmap_local ( addr ) ;
2019-07-15 18:50:59 +03:00
2021-08-11 04:33:14 +03:00
mark_inode_dirty ( iter - > inode ) ;
2019-07-15 18:50:59 +03:00
return copied ;
}
2020-09-21 18:58:41 +03:00
/* Returns the number of bytes copied. May be 0. Cannot be an errno. */
2021-08-11 04:33:14 +03:00
static size_t iomap_write_end ( struct iomap_iter * iter , loff_t pos , size_t len ,
2021-05-02 18:33:08 +03:00
size_t copied , struct folio * folio )
2019-07-15 18:50:59 +03:00
{
2021-08-11 04:33:14 +03:00
const struct iomap_page_ops * page_ops = iter - > iomap . page_ops ;
2021-08-11 04:33:16 +03:00
const struct iomap * srcmap = iomap_iter_srcmap ( iter ) ;
2021-08-11 04:33:14 +03:00
loff_t old_size = iter - > inode - > i_size ;
2020-09-21 18:58:41 +03:00
size_t ret ;
2019-07-15 18:50:59 +03:00
2019-10-19 02:44:10 +03:00
if ( srcmap - > type = = IOMAP_INLINE ) {
2021-05-02 18:44:44 +03:00
ret = iomap_write_end_inline ( iter , folio , pos , copied ) ;
2019-10-19 02:44:10 +03:00
} else if ( srcmap - > flags & IOMAP_F_BUFFER_HEAD ) {
2021-08-11 04:33:14 +03:00
ret = block_write_end ( NULL , iter - > inode - > i_mapping , pos , len ,
2021-05-02 18:33:08 +03:00
copied , & folio - > page , NULL ) ;
2019-07-15 18:50:59 +03:00
} else {
2021-05-02 18:33:08 +03:00
ret = __iomap_write_end ( iter - > inode , pos , len , copied , folio ) ;
2019-07-15 18:50:59 +03:00
}
/*
* Update the in - memory inode size after copying the data into the page
* cache . It ' s up to the file system to write the updated size to disk ,
* preferably after I / O completion so that no stale data is exposed .
*/
if ( pos + ret > old_size ) {
2021-08-11 04:33:14 +03:00
i_size_write ( iter - > inode , pos + ret ) ;
iter - > iomap . flags | = IOMAP_F_SIZE_CHANGED ;
2019-07-15 18:50:59 +03:00
}
2021-05-02 18:33:08 +03:00
folio_unlock ( folio ) ;
2019-07-15 18:50:59 +03:00
if ( old_size < pos )
2021-08-11 04:33:14 +03:00
pagecache_isize_extended ( iter - > inode , old_size , pos ) ;
2019-07-15 18:50:59 +03:00
if ( page_ops & & page_ops - > page_done )
2021-05-02 18:33:08 +03:00
page_ops - > page_done ( iter - > inode , pos , ret , & folio - > page ) ;
folio_put ( folio ) ;
2019-07-15 18:50:59 +03:00
if ( ret < len )
2021-08-11 04:33:14 +03:00
iomap_write_failed ( iter - > inode , pos , len ) ;
2019-07-15 18:50:59 +03:00
return ret ;
}
2021-08-11 04:33:08 +03:00
static loff_t iomap_write_iter ( struct iomap_iter * iter , struct iov_iter * i )
2019-07-15 18:50:59 +03:00
{
2021-08-11 04:33:08 +03:00
loff_t length = iomap_length ( iter ) ;
loff_t pos = iter - > pos ;
2019-07-15 18:50:59 +03:00
ssize_t written = 0 ;
2021-08-11 04:33:08 +03:00
long status = 0 ;
2019-07-15 18:50:59 +03:00
do {
2021-05-02 18:33:08 +03:00
struct folio * folio ;
2019-07-15 18:50:59 +03:00
struct page * page ;
unsigned long offset ; /* Offset into pagecache page */
unsigned long bytes ; /* Bytes to write to page */
size_t copied ; /* Bytes copied from user */
offset = offset_in_page ( pos ) ;
bytes = min_t ( unsigned long , PAGE_SIZE - offset ,
iov_iter_count ( i ) ) ;
again :
if ( bytes > length )
bytes = length ;
/*
2021-08-03 00:46:31 +03:00
* Bring in the user page that we ' ll copy from _first_ .
2019-07-15 18:50:59 +03:00
* Otherwise there ' s a nasty deadlock on copying from the
* same page as we ' re writing to , without it being marked
* up - to - date .
*/
2021-08-02 15:54:16 +03:00
if ( unlikely ( fault_in_iov_iter_readable ( i , bytes ) ) ) {
2019-07-15 18:50:59 +03:00
status = - EFAULT ;
break ;
}
2021-05-02 18:33:08 +03:00
status = iomap_write_begin ( iter , pos , bytes , & folio ) ;
2019-07-15 18:50:59 +03:00
if ( unlikely ( status ) )
break ;
2021-05-02 18:33:08 +03:00
page = folio_file_page ( folio , pos > > PAGE_SHIFT ) ;
2021-08-11 04:33:08 +03:00
if ( mapping_writably_mapped ( iter - > inode - > i_mapping ) )
2019-07-15 18:50:59 +03:00
flush_dcache_page ( page ) ;
2021-04-30 17:26:41 +03:00
copied = copy_page_from_iter_atomic ( page , offset , bytes , i ) ;
2019-07-15 18:50:59 +03:00
2021-05-02 18:33:08 +03:00
status = iomap_write_end ( iter , pos , bytes , copied , folio ) ;
2019-07-15 18:50:59 +03:00
2021-04-30 17:26:41 +03:00
if ( unlikely ( copied ! = status ) )
iov_iter_revert ( i , copied - status ) ;
2019-07-15 18:50:59 +03:00
2021-04-30 17:26:41 +03:00
cond_resched ( ) ;
2021-05-31 07:32:44 +03:00
if ( unlikely ( status = = 0 ) ) {
2019-07-15 18:50:59 +03:00
/*
2021-05-31 07:32:44 +03:00
* A short copy made iomap_write_end ( ) reject the
* thing entirely . Might be memory poisoning
* halfway through , might be a race with munmap ,
* might be severe memory pressure .
2019-07-15 18:50:59 +03:00
*/
2021-05-31 07:32:44 +03:00
if ( copied )
bytes = copied ;
2019-07-15 18:50:59 +03:00
goto again ;
}
2021-04-30 17:26:41 +03:00
pos + = status ;
written + = status ;
length - = status ;
2019-07-15 18:50:59 +03:00
2021-08-11 04:33:08 +03:00
balance_dirty_pages_ratelimited ( iter - > inode - > i_mapping ) ;
2019-07-15 18:50:59 +03:00
} while ( iov_iter_count ( i ) & & length ) ;
return written ? written : status ;
}
ssize_t
2021-08-11 04:33:08 +03:00
iomap_file_buffered_write ( struct kiocb * iocb , struct iov_iter * i ,
2019-07-15 18:50:59 +03:00
const struct iomap_ops * ops )
{
2021-08-11 04:33:08 +03:00
struct iomap_iter iter = {
. inode = iocb - > ki_filp - > f_mapping - > host ,
. pos = iocb - > ki_pos ,
. len = iov_iter_count ( i ) ,
. flags = IOMAP_WRITE ,
} ;
int ret ;
2019-07-15 18:50:59 +03:00
2021-08-11 04:33:08 +03:00
while ( ( ret = iomap_iter ( & iter , ops ) ) > 0 )
iter . processed = iomap_write_iter ( & iter , i ) ;
if ( iter . pos = = iocb - > ki_pos )
return ret ;
return iter . pos - iocb - > ki_pos ;
2019-07-15 18:50:59 +03:00
}
EXPORT_SYMBOL_GPL ( iomap_file_buffered_write ) ;
2021-08-11 04:33:09 +03:00
static loff_t iomap_unshare_iter ( struct iomap_iter * iter )
2019-07-15 18:50:59 +03:00
{
2021-08-11 04:33:09 +03:00
struct iomap * iomap = & iter - > iomap ;
2021-08-11 04:33:16 +03:00
const struct iomap * srcmap = iomap_iter_srcmap ( iter ) ;
2021-08-11 04:33:09 +03:00
loff_t pos = iter - > pos ;
loff_t length = iomap_length ( iter ) ;
2019-07-15 18:50:59 +03:00
long status = 0 ;
2020-06-09 06:58:29 +03:00
loff_t written = 0 ;
2019-07-15 18:50:59 +03:00
2019-10-19 02:41:34 +03:00
/* don't bother with blocks that are not shared to start with */
if ( ! ( iomap - > flags & IOMAP_F_SHARED ) )
return length ;
/* don't bother with holes or unwritten extents */
2019-10-19 02:44:10 +03:00
if ( srcmap - > type = = IOMAP_HOLE | | srcmap - > type = = IOMAP_UNWRITTEN )
2019-10-19 02:41:34 +03:00
return length ;
2019-07-15 18:50:59 +03:00
do {
2019-10-19 02:42:50 +03:00
unsigned long offset = offset_in_page ( pos ) ;
unsigned long bytes = min_t ( loff_t , PAGE_SIZE - offset , length ) ;
2021-05-02 18:33:08 +03:00
struct folio * folio ;
2019-07-15 18:50:59 +03:00
2021-05-02 18:33:08 +03:00
status = iomap_write_begin ( iter , pos , bytes , & folio ) ;
2019-07-15 18:50:59 +03:00
if ( unlikely ( status ) )
return status ;
2021-05-02 18:33:08 +03:00
status = iomap_write_end ( iter , pos , bytes , bytes , folio ) ;
2020-09-21 18:58:41 +03:00
if ( WARN_ON_ONCE ( status = = 0 ) )
return - EIO ;
2019-07-15 18:50:59 +03:00
cond_resched ( ) ;
pos + = status ;
written + = status ;
length - = status ;
2021-08-11 04:33:09 +03:00
balance_dirty_pages_ratelimited ( iter - > inode - > i_mapping ) ;
2019-07-15 18:50:59 +03:00
} while ( length ) ;
return written ;
}
int
2019-10-19 02:41:34 +03:00
iomap_file_unshare ( struct inode * inode , loff_t pos , loff_t len ,
2019-07-15 18:50:59 +03:00
const struct iomap_ops * ops )
{
2021-08-11 04:33:09 +03:00
struct iomap_iter iter = {
. inode = inode ,
. pos = pos ,
. len = len ,
2021-08-11 04:33:14 +03:00
. flags = IOMAP_WRITE | IOMAP_UNSHARE ,
2021-08-11 04:33:09 +03:00
} ;
int ret ;
2019-07-15 18:50:59 +03:00
2021-08-11 04:33:09 +03:00
while ( ( ret = iomap_iter ( & iter , ops ) ) > 0 )
iter . processed = iomap_unshare_iter ( & iter ) ;
return ret ;
2019-07-15 18:50:59 +03:00
}
2019-10-19 02:41:34 +03:00
EXPORT_SYMBOL_GPL ( iomap_file_unshare ) ;
2019-07-15 18:50:59 +03:00
2021-08-11 04:33:14 +03:00
static s64 __iomap_zero_iter ( struct iomap_iter * iter , loff_t pos , u64 length )
2019-07-15 18:50:59 +03:00
{
2021-11-05 21:24:09 +03:00
struct folio * folio ;
2019-07-15 18:50:59 +03:00
int status ;
2021-11-05 21:24:09 +03:00
size_t offset ;
2021-05-02 18:33:08 +03:00
size_t bytes = min_t ( u64 , SIZE_MAX , length ) ;
2019-07-15 18:50:59 +03:00
2021-05-02 18:33:08 +03:00
status = iomap_write_begin ( iter , pos , bytes , & folio ) ;
2019-07-15 18:50:59 +03:00
if ( status )
return status ;
2021-11-05 21:24:09 +03:00
offset = offset_in_folio ( folio , pos ) ;
if ( bytes > folio_size ( folio ) - offset )
bytes = folio_size ( folio ) - offset ;
2019-07-15 18:50:59 +03:00
2021-11-05 21:24:09 +03:00
folio_zero_range ( folio , offset , bytes ) ;
folio_mark_accessed ( folio ) ;
2019-07-15 18:50:59 +03:00
2021-05-02 18:33:08 +03:00
return iomap_write_end ( iter , pos , bytes , bytes , folio ) ;
2019-07-15 18:50:59 +03:00
}
2021-08-11 04:33:09 +03:00
static loff_t iomap_zero_iter ( struct iomap_iter * iter , bool * did_zero )
2019-07-15 18:50:59 +03:00
{
2021-08-11 04:33:09 +03:00
struct iomap * iomap = & iter - > iomap ;
2021-08-11 04:33:16 +03:00
const struct iomap * srcmap = iomap_iter_srcmap ( iter ) ;
2021-08-11 04:33:09 +03:00
loff_t pos = iter - > pos ;
loff_t length = iomap_length ( iter ) ;
2019-07-15 18:50:59 +03:00
loff_t written = 0 ;
/* already zeroed? we're done. */
2019-10-19 02:44:10 +03:00
if ( srcmap - > type = = IOMAP_HOLE | | srcmap - > type = = IOMAP_UNWRITTEN )
2020-09-21 18:58:42 +03:00
return length ;
2019-07-15 18:50:59 +03:00
do {
2020-09-21 18:58:42 +03:00
s64 bytes ;
2019-07-15 18:50:59 +03:00
2021-08-11 04:33:09 +03:00
if ( IS_DAX ( iter - > inode ) )
2020-09-21 18:58:42 +03:00
bytes = dax_iomap_zero ( pos , length , iomap ) ;
2019-07-15 18:50:59 +03:00
else
2021-08-11 04:33:14 +03:00
bytes = __iomap_zero_iter ( iter , pos , length ) ;
2020-09-21 18:58:42 +03:00
if ( bytes < 0 )
return bytes ;
2019-07-15 18:50:59 +03:00
pos + = bytes ;
2020-09-21 18:58:42 +03:00
length - = bytes ;
2019-07-15 18:50:59 +03:00
written + = bytes ;
if ( did_zero )
* did_zero = true ;
2020-09-21 18:58:42 +03:00
} while ( length > 0 ) ;
2019-07-15 18:50:59 +03:00
return written ;
}
int
iomap_zero_range ( struct inode * inode , loff_t pos , loff_t len , bool * did_zero ,
const struct iomap_ops * ops )
{
2021-08-11 04:33:09 +03:00
struct iomap_iter iter = {
. inode = inode ,
. pos = pos ,
. len = len ,
. flags = IOMAP_ZERO ,
} ;
int ret ;
2019-07-15 18:50:59 +03:00
2021-08-11 04:33:09 +03:00
while ( ( ret = iomap_iter ( & iter , ops ) ) > 0 )
iter . processed = iomap_zero_iter ( & iter , did_zero ) ;
return ret ;
2019-07-15 18:50:59 +03:00
}
EXPORT_SYMBOL_GPL ( iomap_zero_range ) ;
int
iomap_truncate_page ( struct inode * inode , loff_t pos , bool * did_zero ,
const struct iomap_ops * ops )
{
unsigned int blocksize = i_blocksize ( inode ) ;
unsigned int off = pos & ( blocksize - 1 ) ;
/* Block boundary? Nothing to do */
if ( ! off )
return 0 ;
return iomap_zero_range ( inode , pos , blocksize - off , did_zero , ops ) ;
}
EXPORT_SYMBOL_GPL ( iomap_truncate_page ) ;
2021-04-29 05:32:02 +03:00
static loff_t iomap_folio_mkwrite_iter ( struct iomap_iter * iter ,
struct folio * folio )
2019-07-15 18:50:59 +03:00
{
2021-08-11 04:33:09 +03:00
loff_t length = iomap_length ( iter ) ;
2019-07-15 18:50:59 +03:00
int ret ;
2021-08-11 04:33:09 +03:00
if ( iter - > iomap . flags & IOMAP_F_BUFFER_HEAD ) {
2021-11-03 21:05:47 +03:00
ret = __block_write_begin_int ( folio , iter - > pos , length , NULL ,
2021-08-11 04:33:09 +03:00
& iter - > iomap ) ;
2019-07-15 18:50:59 +03:00
if ( ret )
return ret ;
2021-04-29 05:32:02 +03:00
block_commit_write ( & folio - > page , 0 , length ) ;
2019-07-15 18:50:59 +03:00
} else {
2021-04-29 05:32:02 +03:00
WARN_ON_ONCE ( ! folio_test_uptodate ( folio ) ) ;
folio_mark_dirty ( folio ) ;
2019-07-15 18:50:59 +03:00
}
return length ;
}
vm_fault_t iomap_page_mkwrite ( struct vm_fault * vmf , const struct iomap_ops * ops )
{
2021-08-11 04:33:09 +03:00
struct iomap_iter iter = {
. inode = file_inode ( vmf - > vma - > vm_file ) ,
. flags = IOMAP_WRITE | IOMAP_FAULT ,
} ;
2021-04-29 05:32:02 +03:00
struct folio * folio = page_folio ( vmf - > page ) ;
2019-07-15 18:50:59 +03:00
ssize_t ret ;
2021-04-29 05:32:02 +03:00
folio_lock ( folio ) ;
ret = folio_mkwrite_check_truncate ( folio , iter . inode ) ;
2020-01-06 19:58:23 +03:00
if ( ret < 0 )
2019-07-15 18:50:59 +03:00
goto out_unlock ;
2021-04-29 05:32:02 +03:00
iter . pos = folio_pos ( folio ) ;
2021-08-11 04:33:09 +03:00
iter . len = ret ;
while ( ( ret = iomap_iter ( & iter , ops ) ) > 0 )
2021-04-29 05:32:02 +03:00
iter . processed = iomap_folio_mkwrite_iter ( & iter , folio ) ;
2019-07-15 18:50:59 +03:00
2021-08-11 04:33:09 +03:00
if ( ret < 0 )
goto out_unlock ;
2021-04-29 05:32:02 +03:00
folio_wait_stable ( folio ) ;
2019-07-15 18:50:59 +03:00
return VM_FAULT_LOCKED ;
out_unlock :
2021-04-29 05:32:02 +03:00
folio_unlock ( folio ) ;
2019-07-15 18:50:59 +03:00
return block_page_mkwrite_return ( ret ) ;
}
EXPORT_SYMBOL_GPL ( iomap_page_mkwrite ) ;
2019-10-17 23:12:15 +03:00
2021-01-02 00:53:26 +03:00
static void iomap_finish_folio_write ( struct inode * inode , struct folio * folio ,
size_t len , int error )
2019-10-17 23:12:15 +03:00
{
2021-04-28 05:56:17 +03:00
struct iomap_page * iop = to_iomap_page ( folio ) ;
2019-10-17 23:12:15 +03:00
if ( error ) {
2021-01-02 00:53:26 +03:00
folio_set_error ( folio ) ;
2021-08-11 04:32:55 +03:00
mapping_set_error ( inode - > i_mapping , error ) ;
2019-10-17 23:12:15 +03:00
}
2021-01-02 00:53:26 +03:00
WARN_ON_ONCE ( i_blocks_per_folio ( inode , folio ) > 1 & & ! iop ) ;
2020-09-21 18:58:41 +03:00
WARN_ON_ONCE ( iop & & atomic_read ( & iop - > write_bytes_pending ) < = 0 ) ;
2019-10-17 23:12:15 +03:00
2020-09-21 18:58:41 +03:00
if ( ! iop | | atomic_sub_and_test ( len , & iop - > write_bytes_pending ) )
2021-01-02 00:53:26 +03:00
folio_end_writeback ( folio ) ;
2019-10-17 23:12:15 +03:00
}
/*
* We ' re now finished for good with this ioend structure . Update the page
* state , release holds on bios , and finally free up memory . Do not use the
* ioend after this .
*/
static void
iomap_finish_ioend ( struct iomap_ioend * ioend , int error )
{
struct inode * inode = ioend - > io_inode ;
struct bio * bio = & ioend - > io_inline_bio ;
struct bio * last = ioend - > io_bio , * next ;
u64 start = bio - > bi_iter . bi_sector ;
2019-12-05 09:59:02 +03:00
loff_t offset = ioend - > io_offset ;
2019-10-17 23:12:15 +03:00
bool quiet = bio_flagged ( bio , BIO_QUIET ) ;
for ( bio = & ioend - > io_inline_bio ; bio ; bio = next ) {
2021-01-02 00:53:26 +03:00
struct folio_iter fi ;
2019-10-17 23:12:15 +03:00
/*
* For the last bio , bi_private points to the ioend , so we
* need to explicitly end the iteration here .
*/
if ( bio = = last )
next = NULL ;
else
next = bio - > bi_private ;
2021-01-02 00:53:26 +03:00
/* walk all folios in bio, ending page IO on them */
bio_for_each_folio_all ( fi , bio )
iomap_finish_folio_write ( inode , fi . folio , fi . length ,
error ) ;
2019-10-17 23:12:15 +03:00
bio_put ( bio ) ;
}
2019-12-05 09:59:02 +03:00
/* The ioend has been freed by bio_put() */
2019-10-17 23:12:15 +03:00
if ( unlikely ( error & & ! quiet ) ) {
printk_ratelimited ( KERN_ERR
2019-10-18 00:02:07 +03:00
" %s: writeback error on inode %lu, offset %lld, sector %llu " ,
2019-12-05 09:59:02 +03:00
inode - > i_sb - > s_id , inode - > i_ino , offset , start ) ;
2019-10-17 23:12:15 +03:00
}
}
void
iomap_finish_ioends ( struct iomap_ioend * ioend , int error )
{
struct list_head tmp ;
list_replace_init ( & ioend - > io_list , & tmp ) ;
iomap_finish_ioend ( ioend , error ) ;
while ( ! list_empty ( & tmp ) ) {
ioend = list_first_entry ( & tmp , struct iomap_ioend , io_list ) ;
list_del_init ( & ioend - > io_list ) ;
iomap_finish_ioend ( ioend , error ) ;
}
}
EXPORT_SYMBOL_GPL ( iomap_finish_ioends ) ;
/*
* We can merge two adjacent ioends if they have the same set of work to do .
*/
static bool
iomap_ioend_can_merge ( struct iomap_ioend * ioend , struct iomap_ioend * next )
{
if ( ioend - > io_bio - > bi_status ! = next - > io_bio - > bi_status )
return false ;
if ( ( ioend - > io_flags & IOMAP_F_SHARED ) ^
( next - > io_flags & IOMAP_F_SHARED ) )
return false ;
if ( ( ioend - > io_type = = IOMAP_UNWRITTEN ) ^
( next - > io_type = = IOMAP_UNWRITTEN ) )
return false ;
if ( ioend - > io_offset + ioend - > io_size ! = next - > io_offset )
return false ;
return true ;
}
void
2021-05-04 18:54:29 +03:00
iomap_ioend_try_merge ( struct iomap_ioend * ioend , struct list_head * more_ioends )
2019-10-17 23:12:15 +03:00
{
struct iomap_ioend * next ;
INIT_LIST_HEAD ( & ioend - > io_list ) ;
while ( ( next = list_first_entry_or_null ( more_ioends , struct iomap_ioend ,
io_list ) ) ) {
if ( ! iomap_ioend_can_merge ( ioend , next ) )
break ;
list_move_tail ( & next - > io_list , & ioend - > io_list ) ;
ioend - > io_size + = next - > io_size ;
}
}
EXPORT_SYMBOL_GPL ( iomap_ioend_try_merge ) ;
static int
2021-04-08 21:28:34 +03:00
iomap_ioend_compare ( void * priv , const struct list_head * a ,
const struct list_head * b )
2019-10-17 23:12:15 +03:00
{
2019-10-17 23:12:20 +03:00
struct iomap_ioend * ia = container_of ( a , struct iomap_ioend , io_list ) ;
struct iomap_ioend * ib = container_of ( b , struct iomap_ioend , io_list ) ;
2019-10-17 23:12:15 +03:00
if ( ia - > io_offset < ib - > io_offset )
return - 1 ;
2019-10-17 23:12:20 +03:00
if ( ia - > io_offset > ib - > io_offset )
2019-10-17 23:12:15 +03:00
return 1 ;
return 0 ;
}
void
iomap_sort_ioends ( struct list_head * ioend_list )
{
list_sort ( NULL , ioend_list , iomap_ioend_compare ) ;
}
EXPORT_SYMBOL_GPL ( iomap_sort_ioends ) ;
static void iomap_writepage_end_bio ( struct bio * bio )
{
struct iomap_ioend * ioend = bio - > bi_private ;
iomap_finish_ioend ( ioend , blk_status_to_errno ( bio - > bi_status ) ) ;
}
/*
* Submit the final bio for an ioend .
*
* If @ error is non - zero , it means that we have a situation where some part of
2021-08-03 00:46:31 +03:00
* the submission process has failed after we ' ve marked pages for writeback
2019-10-17 23:12:15 +03:00
* and unlocked them . In this situation , we need to fail the bio instead of
* submitting it . This typically only happens on a filesystem shutdown .
*/
static int
iomap_submit_ioend ( struct iomap_writepage_ctx * wpc , struct iomap_ioend * ioend ,
int error )
{
ioend - > io_bio - > bi_private = ioend ;
ioend - > io_bio - > bi_end_io = iomap_writepage_end_bio ;
if ( wpc - > ops - > prepare_ioend )
error = wpc - > ops - > prepare_ioend ( ioend , error ) ;
if ( error ) {
/*
2021-08-03 00:46:31 +03:00
* If we ' re failing the IO now , just mark the ioend with an
2019-10-17 23:12:15 +03:00
* error and finish it . This will run IO completion immediately
* as there is only one reference to the ioend at this point in
* time .
*/
ioend - > io_bio - > bi_status = errno_to_blk_status ( error ) ;
bio_endio ( ioend - > io_bio ) ;
return error ;
}
submit_bio ( ioend - > io_bio ) ;
return 0 ;
}
static struct iomap_ioend *
iomap_alloc_ioend ( struct inode * inode , struct iomap_writepage_ctx * wpc ,
loff_t offset , sector_t sector , struct writeback_control * wbc )
{
struct iomap_ioend * ioend ;
struct bio * bio ;
2021-03-11 14:01:37 +03:00
bio = bio_alloc_bioset ( GFP_NOFS , BIO_MAX_VECS , & iomap_ioend_bioset ) ;
2019-10-17 23:12:15 +03:00
bio_set_dev ( bio , wpc - > iomap . bdev ) ;
bio - > bi_iter . bi_sector = sector ;
bio - > bi_opf = REQ_OP_WRITE | wbc_to_write_flags ( wbc ) ;
bio - > bi_write_hint = inode - > i_write_hint ;
wbc_init_bio ( wbc , bio ) ;
ioend = container_of ( bio , struct iomap_ioend , io_inline_bio ) ;
INIT_LIST_HEAD ( & ioend - > io_list ) ;
ioend - > io_type = wpc - > iomap . type ;
ioend - > io_flags = wpc - > iomap . flags ;
ioend - > io_inode = inode ;
ioend - > io_size = 0 ;
ioend - > io_offset = offset ;
ioend - > io_bio = bio ;
return ioend ;
}
/*
* Allocate a new bio , and chain the old bio to the new one .
*
2021-08-03 00:46:31 +03:00
* Note that we have to perform the chaining in this unintuitive order
2019-10-17 23:12:15 +03:00
* so that the bi_private linkage is set up in the right direction for the
* traversal in iomap_finish_ioend ( ) .
*/
static struct bio *
iomap_chain_bio ( struct bio * prev )
{
struct bio * new ;
2021-03-11 14:01:37 +03:00
new = bio_alloc ( GFP_NOFS , BIO_MAX_VECS ) ;
2019-10-17 23:12:15 +03:00
bio_copy_dev ( new , prev ) ; /* also copies over blkcg information */
new - > bi_iter . bi_sector = bio_end_sector ( prev ) ;
new - > bi_opf = prev - > bi_opf ;
new - > bi_write_hint = prev - > bi_write_hint ;
bio_chain ( prev , new ) ;
bio_get ( prev ) ; /* for iomap_finish_ioend */
submit_bio ( prev ) ;
return new ;
}
static bool
iomap_can_add_to_ioend ( struct iomap_writepage_ctx * wpc , loff_t offset ,
sector_t sector )
{
if ( ( wpc - > iomap . flags & IOMAP_F_SHARED ) ! =
( wpc - > ioend - > io_flags & IOMAP_F_SHARED ) )
return false ;
if ( wpc - > iomap . type ! = wpc - > ioend - > io_type )
return false ;
if ( offset ! = wpc - > ioend - > io_offset + wpc - > ioend - > io_size )
return false ;
if ( sector ! = bio_end_sector ( wpc - > ioend - > io_bio ) )
return false ;
return true ;
}
/*
* Test to see if we have an existing ioend structure that we could append to
2021-08-03 00:46:31 +03:00
* first ; otherwise finish off the current ioend and start another .
2019-10-17 23:12:15 +03:00
*/
static void
2021-11-02 19:45:12 +03:00
iomap_add_to_ioend ( struct inode * inode , loff_t pos , struct folio * folio ,
2019-10-17 23:12:15 +03:00
struct iomap_page * iop , struct iomap_writepage_ctx * wpc ,
struct writeback_control * wbc , struct list_head * iolist )
{
2021-11-02 19:45:12 +03:00
sector_t sector = iomap_sector ( & wpc - > iomap , pos ) ;
2019-10-17 23:12:15 +03:00
unsigned len = i_blocksize ( inode ) ;
2021-11-02 19:45:12 +03:00
size_t poff = offset_in_folio ( folio , pos ) ;
2019-10-17 23:12:15 +03:00
2021-11-02 19:45:12 +03:00
if ( ! wpc - > ioend | | ! iomap_can_add_to_ioend ( wpc , pos , sector ) ) {
2019-10-17 23:12:15 +03:00
if ( wpc - > ioend )
list_add ( & wpc - > ioend - > io_list , iolist ) ;
2021-11-02 19:45:12 +03:00
wpc - > ioend = iomap_alloc_ioend ( inode , wpc , pos , sector , wbc ) ;
2019-10-17 23:12:15 +03:00
}
2021-11-02 19:45:12 +03:00
if ( ! bio_add_folio ( wpc - > ioend - > io_bio , folio , len , poff ) ) {
2021-08-03 00:43:43 +03:00
wpc - > ioend - > io_bio = iomap_chain_bio ( wpc - > ioend - > io_bio ) ;
2021-11-02 19:45:12 +03:00
bio_add_folio ( wpc - > ioend - > io_bio , folio , len , poff ) ;
2019-10-17 23:12:15 +03:00
}
2021-08-03 00:43:43 +03:00
if ( iop )
atomic_add ( len , & iop - > write_bytes_pending ) ;
2019-10-17 23:12:15 +03:00
wpc - > ioend - > io_size + = len ;
2021-11-02 19:45:12 +03:00
wbc_account_cgroup_owner ( wbc , & folio - > page , len ) ;
2019-10-17 23:12:15 +03:00
}
/*
* We implement an immediate ioend submission policy here to avoid needing to
* chain multiple ioends and hence nest mempool allocations which can violate
2021-08-03 00:46:31 +03:00
* the forward progress guarantees we need to provide . The current ioend we ' re
* adding blocks to is cached in the writepage context , and if the new block
* doesn ' t append to the cached ioend , it will create a new ioend and cache that
2019-10-17 23:12:15 +03:00
* instead .
*
* If a new ioend is created and cached , the old ioend is returned and queued
* locally for submission once the entire page is processed or an error has been
* detected . While ioends are submitted immediately after they are completed ,
* batching optimisations are provided by higher level block plugging .
*
* At the end of a writeback pass , there will be a cached ioend remaining on the
* writepage context that the caller will need to submit .
*/
static int
iomap_writepage_map ( struct iomap_writepage_ctx * wpc ,
struct writeback_control * wbc , struct inode * inode ,
2021-11-02 19:45:12 +03:00
struct folio * folio , u64 end_pos )
2019-10-17 23:12:15 +03:00
{
2021-04-28 06:12:52 +03:00
struct iomap_page * iop = iomap_page_create ( inode , folio ) ;
2019-10-17 23:12:15 +03:00
struct iomap_ioend * ioend , * next ;
unsigned len = i_blocksize ( inode ) ;
2021-11-02 17:51:55 +03:00
unsigned nblocks = i_blocks_per_folio ( inode , folio ) ;
u64 pos = folio_pos ( folio ) ;
2019-10-17 23:12:15 +03:00
int error = 0 , count = 0 , i ;
LIST_HEAD ( submit_list ) ;
2020-09-21 18:58:41 +03:00
WARN_ON_ONCE ( iop & & atomic_read ( & iop - > write_bytes_pending ) ! = 0 ) ;
2019-10-17 23:12:15 +03:00
/*
2021-11-02 17:51:55 +03:00
* Walk through the folio to find areas to write back . If we
* run off the end of the current map or find the current map
* invalid , grab a new one .
2019-10-17 23:12:15 +03:00
*/
2021-11-02 17:51:55 +03:00
for ( i = 0 ; i < nblocks & & pos < end_pos ; i + + , pos + = len ) {
2019-10-17 23:12:15 +03:00
if ( iop & & ! test_bit ( i , iop - > uptodate ) )
continue ;
2021-11-02 17:51:55 +03:00
error = wpc - > ops - > map_blocks ( wpc , inode , pos ) ;
2019-10-17 23:12:15 +03:00
if ( error )
break ;
2019-10-17 23:12:17 +03:00
if ( WARN_ON_ONCE ( wpc - > iomap . type = = IOMAP_INLINE ) )
continue ;
2019-10-17 23:12:15 +03:00
if ( wpc - > iomap . type = = IOMAP_HOLE )
continue ;
2021-11-02 19:45:12 +03:00
iomap_add_to_ioend ( inode , pos , folio , iop , wpc , wbc ,
2019-10-17 23:12:15 +03:00
& submit_list ) ;
count + + ;
}
WARN_ON_ONCE ( ! wpc - > ioend & & ! list_empty ( & submit_list ) ) ;
2021-11-02 19:45:12 +03:00
WARN_ON_ONCE ( ! folio_test_locked ( folio ) ) ;
WARN_ON_ONCE ( folio_test_writeback ( folio ) ) ;
WARN_ON_ONCE ( folio_test_dirty ( folio ) ) ;
2019-10-17 23:12:15 +03:00
/*
* We cannot cancel the ioend directly here on error . We may have
* already set other pages under writeback and hence we have to run I / O
* completion to mark the error state of the pages under writeback
* appropriately .
*/
if ( unlikely ( error ) ) {
2020-10-30 00:30:48 +03:00
/*
* Let the filesystem know what portion of the current page
2021-08-03 00:46:31 +03:00
* failed to map . If the page hasn ' t been added to ioend , it
2020-10-30 00:30:48 +03:00
* won ' t be affected by I / O completion and we must unlock it
* now .
*/
2021-07-30 16:56:05 +03:00
if ( wpc - > ops - > discard_folio )
2021-11-02 17:51:55 +03:00
wpc - > ops - > discard_folio ( folio , pos ) ;
2019-10-17 23:12:15 +03:00
if ( ! count ) {
2021-11-02 19:45:12 +03:00
folio_clear_uptodate ( folio ) ;
folio_unlock ( folio ) ;
2019-10-17 23:12:15 +03:00
goto done ;
}
}
2021-11-02 19:45:12 +03:00
folio_start_writeback ( folio ) ;
folio_unlock ( folio ) ;
2019-10-17 23:12:15 +03:00
/*
2021-08-03 00:46:31 +03:00
* Preserve the original error if there was one ; catch
2019-10-17 23:12:15 +03:00
* submission errors here and propagate into subsequent ioend
* submissions .
*/
list_for_each_entry_safe ( ioend , next , & submit_list , io_list ) {
int error2 ;
list_del_init ( & ioend - > io_list ) ;
error2 = iomap_submit_ioend ( wpc , ioend , error ) ;
if ( error2 & & ! error )
error = error2 ;
}
/*
* We can end up here with no error and nothing to write only if we race
* with a partial page truncate on a sub - page block sized filesystem .
*/
if ( ! count )
2021-11-02 19:45:12 +03:00
folio_end_writeback ( folio ) ;
2019-10-17 23:12:15 +03:00
done :
2021-11-02 19:45:12 +03:00
mapping_set_error ( folio - > mapping , error ) ;
2019-10-17 23:12:15 +03:00
return error ;
}
/*
* Write out a dirty page .
*
2021-08-03 00:46:31 +03:00
* For delalloc space on the page , we need to allocate space and flush it .
* For unwritten space on the page , we need to start the conversion to
2019-10-17 23:12:15 +03:00
* regular allocated space .
*/
static int
iomap_do_writepage ( struct page * page , struct writeback_control * wbc , void * data )
{
2021-11-02 19:45:12 +03:00
struct folio * folio = page_folio ( page ) ;
2019-10-17 23:12:15 +03:00
struct iomap_writepage_ctx * wpc = data ;
2021-11-02 19:45:12 +03:00
struct inode * inode = folio - > mapping - > host ;
2021-11-02 18:41:16 +03:00
u64 end_pos , isize ;
2019-10-17 23:12:15 +03:00
2021-11-02 19:45:12 +03:00
trace_iomap_writepage ( inode , folio_pos ( folio ) , folio_size ( folio ) ) ;
2019-10-17 23:12:15 +03:00
/*
2021-11-02 19:45:12 +03:00
* Refuse to write the folio out if we ' re called from reclaim context .
2019-10-17 23:12:15 +03:00
*
* This avoids stack overflows when called from deeply used stacks in
* random callers for direct reclaim or memcg reclaim . We explicitly
* allow reclaim from kswapd as the stack usage there is relatively low .
*
* This should never happen except in the case of a VM regression so
* warn about it .
*/
if ( WARN_ON_ONCE ( ( current - > flags & ( PF_MEMALLOC | PF_KSWAPD ) ) = =
PF_MEMALLOC ) )
goto redirty ;
/*
2021-11-02 19:45:12 +03:00
* Is this folio beyond the end of the file ?
2019-10-17 23:12:15 +03:00
*
2021-11-02 19:45:12 +03:00
* The folio index is less than the end_index , adjust the end_pos
* to the highest offset that this folio should represent .
2019-10-17 23:12:15 +03:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* | file mapping | < EOF > |
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* | Page . . . | Page N - 2 | Page N - 1 | Page N | |
* ^ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ^ - - - - - - - - - - | - - - - - - - -
* | desired writeback range | see else |
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ^ - - - - - - - - - - - - - - - - - - |
*/
2021-11-02 18:41:16 +03:00
isize = i_size_read ( inode ) ;
2021-11-02 19:45:12 +03:00
end_pos = folio_pos ( folio ) + folio_size ( folio ) ;
2021-11-02 18:41:16 +03:00
if ( end_pos > isize ) {
2019-10-17 23:12:15 +03:00
/*
* Check whether the page to write out is beyond or straddles
* i_size or not .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* | file mapping | < EOF > |
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* | Page . . . | Page N - 2 | Page N - 1 | Page N | Beyond |
* ^ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ^ - - - - - - - - - - - | - - - - - - - - -
* | | Straddles |
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ^ - - - - - - - - - - - | - - - - - - - - |
*/
2021-11-02 19:45:12 +03:00
size_t poff = offset_in_folio ( folio , isize ) ;
2021-11-02 18:41:16 +03:00
pgoff_t end_index = isize > > PAGE_SHIFT ;
2019-10-17 23:12:15 +03:00
/*
2021-08-03 00:46:31 +03:00
* Skip the page if it ' s fully outside i_size , e . g . due to a
* truncate operation that ' s in progress . We must redirty the
2019-10-17 23:12:15 +03:00
* page so that reclaim stops reclaiming it . Otherwise
* iomap_vm_releasepage ( ) is called on it and gets confused .
*
2021-08-03 00:46:31 +03:00
* Note that the end_index is unsigned long . If the given
* offset is greater than 16 TB on a 32 - bit system then if we
* checked if the page is fully outside i_size with
* " if (page->index >= end_index + 1) " , " end_index + 1 " would
* overflow and evaluate to 0. Hence this page would be
* redirtied and written out repeatedly , which would result in
* an infinite loop ; the user program performing this operation
* would hang . Instead , we can detect this situation by
* checking if the page is totally beyond i_size or if its
2019-10-17 23:12:15 +03:00
* offset is just equal to the EOF .
*/
2021-11-02 19:45:12 +03:00
if ( folio - > index > end_index | |
( folio - > index = = end_index & & poff = = 0 ) )
2019-10-17 23:12:15 +03:00
goto redirty ;
/*
* The page straddles i_size . It must be zeroed out on each
* and every writepage invocation because it may be mmapped .
* " A file is mapped in multiples of the page size. For a file
* that is not a multiple of the page size , the remaining
* memory is zeroed when mapped , and writes to that region are
* not written out to the file . "
*/
2021-11-02 19:45:12 +03:00
folio_zero_segment ( folio , poff , folio_size ( folio ) ) ;
2021-11-02 18:41:16 +03:00
end_pos = isize ;
2019-10-17 23:12:15 +03:00
}
2021-11-02 19:45:12 +03:00
return iomap_writepage_map ( wpc , wbc , inode , folio , end_pos ) ;
2019-10-17 23:12:15 +03:00
redirty :
2021-11-02 19:45:12 +03:00
folio_redirty_for_writepage ( wbc , folio ) ;
folio_unlock ( folio ) ;
2019-10-17 23:12:15 +03:00
return 0 ;
}
int
iomap_writepage ( struct page * page , struct writeback_control * wbc ,
struct iomap_writepage_ctx * wpc ,
const struct iomap_writeback_ops * ops )
{
int ret ;
wpc - > ops = ops ;
ret = iomap_do_writepage ( page , wbc , wpc ) ;
if ( ! wpc - > ioend )
return ret ;
return iomap_submit_ioend ( wpc , wpc - > ioend , ret ) ;
}
EXPORT_SYMBOL_GPL ( iomap_writepage ) ;
int
iomap_writepages ( struct address_space * mapping , struct writeback_control * wbc ,
struct iomap_writepage_ctx * wpc ,
const struct iomap_writeback_ops * ops )
{
int ret ;
wpc - > ops = ops ;
ret = write_cache_pages ( mapping , wbc , iomap_do_writepage , wpc ) ;
if ( ! wpc - > ioend )
return ret ;
return iomap_submit_ioend ( wpc , wpc - > ioend , ret ) ;
}
EXPORT_SYMBOL_GPL ( iomap_writepages ) ;
static int __init iomap_init ( void )
{
return bioset_init ( & iomap_ioend_bioset , 4 * ( PAGE_SIZE / SECTOR_SIZE ) ,
offsetof ( struct iomap_ioend , io_inline_bio ) ,
BIOSET_NEED_BVECS ) ;
}
fs_initcall ( iomap_init ) ;