2017-03-16 22:18:50 -08:00
/* SPDX-License-Identifier: GPL-2.0 */
# ifndef _BCACHEFS_FS_IO_H
# define _BCACHEFS_FS_IO_H
# ifndef NO_BCACHEFS_FS
# include "buckets.h"
2023-08-03 18:18:21 -04:00
# include "fs.h"
2023-09-10 18:05:17 -04:00
# include "io_write_types.h"
2023-08-03 18:18:21 -04:00
# include "quota.h"
2017-03-16 22:18:50 -08:00
# include <linux/uio.h>
2023-08-03 18:18:21 -04:00
struct folio_vec {
struct folio * fv_folio ;
size_t fv_offset ;
size_t fv_len ;
} ;
static inline struct folio_vec biovec_to_foliovec ( struct bio_vec bv )
{
struct folio * folio = page_folio ( bv . bv_page ) ;
size_t offset = ( folio_page_idx ( folio , bv . bv_page ) < < PAGE_SHIFT ) +
bv . bv_offset ;
size_t len = min_t ( size_t , folio_size ( folio ) - offset , bv . bv_len ) ;
return ( struct folio_vec ) {
. fv_folio = folio ,
. fv_offset = offset ,
. fv_len = len ,
} ;
}
static inline struct folio_vec bio_iter_iovec_folio ( struct bio * bio ,
struct bvec_iter iter )
{
return biovec_to_foliovec ( bio_iter_iovec ( bio , iter ) ) ;
}
# define __bio_for_each_folio(bvl, bio, iter, start) \
for ( iter = ( start ) ; \
( iter ) . bi_size & & \
( ( bvl = bio_iter_iovec_folio ( ( bio ) , ( iter ) ) ) , 1 ) ; \
bio_advance_iter_single ( ( bio ) , & ( iter ) , ( bvl ) . fv_len ) )
/**
* bio_for_each_folio - iterate over folios within a bio
*
* Like other non - _all versions , this iterates over what bio - > bi_iter currently
* points to . This version is for drivers , where the bio may have previously
* been split or cloned .
*/
# define bio_for_each_folio(bvl, bio, iter) \
__bio_for_each_folio ( bvl , bio , iter , ( bio ) - > bi_iter )
struct quota_res {
u64 sectors ;
} ;
# ifdef CONFIG_BCACHEFS_QUOTA
static inline void __bch2_quota_reservation_put ( struct bch_fs * c ,
struct bch_inode_info * inode ,
struct quota_res * res )
{
BUG_ON ( res - > sectors > inode - > ei_quota_reserved ) ;
bch2_quota_acct ( c , inode - > ei_qid , Q_SPC ,
- ( ( s64 ) res - > sectors ) , KEY_TYPE_QUOTA_PREALLOC ) ;
inode - > ei_quota_reserved - = res - > sectors ;
res - > sectors = 0 ;
}
static inline void bch2_quota_reservation_put ( struct bch_fs * c ,
struct bch_inode_info * inode ,
struct quota_res * res )
{
if ( res - > sectors ) {
mutex_lock ( & inode - > ei_quota_lock ) ;
__bch2_quota_reservation_put ( c , inode , res ) ;
mutex_unlock ( & inode - > ei_quota_lock ) ;
}
}
static inline int bch2_quota_reservation_add ( struct bch_fs * c ,
struct bch_inode_info * inode ,
struct quota_res * res ,
u64 sectors ,
bool check_enospc )
{
int ret ;
if ( test_bit ( EI_INODE_SNAPSHOT , & inode - > ei_flags ) )
return 0 ;
mutex_lock ( & inode - > ei_quota_lock ) ;
ret = bch2_quota_acct ( c , inode - > ei_qid , Q_SPC , sectors ,
check_enospc ? KEY_TYPE_QUOTA_PREALLOC : KEY_TYPE_QUOTA_NOCHECK ) ;
if ( likely ( ! ret ) ) {
inode - > ei_quota_reserved + = sectors ;
res - > sectors + = sectors ;
}
mutex_unlock ( & inode - > ei_quota_lock ) ;
return ret ;
}
2019-08-16 09:59:56 -04:00
2023-08-03 18:18:21 -04:00
# else
static inline void __bch2_quota_reservation_put ( struct bch_fs * c ,
struct bch_inode_info * inode ,
struct quota_res * res ) { }
2019-08-16 09:59:56 -04:00
2023-08-03 18:18:21 -04:00
static inline void bch2_quota_reservation_put ( struct bch_fs * c ,
struct bch_inode_info * inode ,
struct quota_res * res ) { }
2017-03-16 22:18:50 -08:00
2023-08-03 18:18:21 -04:00
static inline int bch2_quota_reservation_add ( struct bch_fs * c ,
struct bch_inode_info * inode ,
struct quota_res * res ,
unsigned sectors ,
bool check_enospc )
{
return 0 ;
}
2017-03-16 22:18:50 -08:00
2023-08-03 18:18:21 -04:00
# endif
2017-03-16 22:18:50 -08:00
2023-08-03 18:18:21 -04:00
void __bch2_i_sectors_acct ( struct bch_fs * , struct bch_inode_info * ,
struct quota_res * , s64 ) ;
static inline void bch2_i_sectors_acct ( struct bch_fs * c , struct bch_inode_info * inode ,
struct quota_res * quota_res , s64 sectors )
{
if ( sectors ) {
mutex_lock ( & inode - > ei_quota_lock ) ;
__bch2_i_sectors_acct ( c , inode , quota_res , sectors ) ;
mutex_unlock ( & inode - > ei_quota_lock ) ;
}
}
static inline struct address_space * faults_disabled_mapping ( void )
{
return ( void * ) ( ( ( unsigned long ) current - > faults_disabled_mapping ) & ~ 1UL ) ;
}
static inline void set_fdm_dropped_locks ( void )
{
current - > faults_disabled_mapping =
( void * ) ( ( ( unsigned long ) current - > faults_disabled_mapping ) | 1 ) ;
}
static inline bool fdm_dropped_locks ( void )
{
return ( ( unsigned long ) current - > faults_disabled_mapping ) & 1 ;
}
void bch2_inode_flush_nocow_writes_async ( struct bch_fs * ,
struct bch_inode_info * , struct closure * ) ;
int __must_check bch2_write_inode_size ( struct bch_fs * ,
struct bch_inode_info * ,
loff_t , unsigned ) ;
2017-03-16 22:18:50 -08:00
int bch2_fsync ( struct file * , loff_t , loff_t , int ) ;
2023-09-04 05:38:30 -04:00
int bchfs_truncate ( struct mnt_idmap * ,
2021-06-14 22:29:54 -04:00
struct bch_inode_info * , struct iattr * ) ;
2017-03-16 22:18:50 -08:00
long bch2_fallocate_dispatch ( struct file * , int , loff_t , loff_t ) ;
2019-08-16 09:59:56 -04:00
loff_t bch2_remap_file_range ( struct file * , loff_t , struct file * ,
loff_t , loff_t , unsigned ) ;
2017-03-16 22:18:50 -08:00
loff_t bch2_llseek ( struct file * , loff_t , int ) ;
void bch2_fs_fsio_exit ( struct bch_fs * ) ;
int bch2_fs_fsio_init ( struct bch_fs * ) ;
# else
static inline void bch2_fs_fsio_exit ( struct bch_fs * c ) { }
static inline int bch2_fs_fsio_init ( struct bch_fs * c ) { return 0 ; }
# endif
# endif /* _BCACHEFS_FS_IO_H */