mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 17:25:38 +00:00
f2fs update for 6.11-rc1
It's a pretty small update including mostly minor bug fixes in zoned storage along with the large section support. Enhancement: - add support for FS_IOC_GETFSSYSFSPATH - enable atgc dynamically if conditions are met - use new ioprio Macro to get ckpt thread ioprio level - remove unreachable lazytime mount option parsing Bug fix: - fix null reference error when checking end of zone - fix start segno of large section - fix to cover read extent cache access with lock - don't dirty inode for readonly filesystem - allocate a new section if curseg is not the first seg in its zone - only fragment segment in the same section - truncate preallocated blocks in f2fs_file_open() - fix to avoid use SSR allocate when do defragment - fix to force buffered IO on inline_data inode And, it includes some minor code clean-ups, and sanity checks. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE00UqedjCtOrGVvQiQBSofoJIUNIFAmagGLkACgkQQBSofoJI UNLsvA//U1u2hr+VEmSIxZ+CcM8vBM7wmbuggdUikEW0uj07YpvovLikifV7p6kK 00p/GsqIqNRsVcTxRI9wBTPiltJRei/w6K3EXnSGKgTPtq1QMSv/GKiBUUaYsRu0 F6W5AqouTquDZz61/ULhMc7WvWqUIZ1m4QX/DMEUGPSnQ2+yIsnz/PT4ZXaKBH7K lIh4WiFAyKO6/UWftcGmnvPiqj4YvqFOhLLV/fgF/VY8IVcENrDH+8+SJM2NtT0F 6gT0bN2Jscc8o43ejo6dlwc7+0qhmH7H2IOCC1XSYGCsveUYgqgKgpBP4ryKjZvt LrbYKaL+auGuJMcLYCG/6IDPl5xkJo3SuRE7YnJdeTNc3InC6BUr17pkmU8n5ib4 xKSeH2XQXk/nu3l9srtKb87Zdwjr90GgvjEZwsCTe+6ihjJ7SGWfpvVLhm3pHale SHPSLaVGqTlqdrNLtfhtNEg6xcvUVxTPbqzoCAmS6onEZfv8BldtQDSea0Tuw7UG Ic4AbfJ/gVCKyCDw/QiV0B1n8GHsVIhlBXss2/xEuO2/2Pso8YFIAXCyH0kBXIN2 0/VesfguJLBIGyyFZ2M5AGZehr5s1n2IThe+qGjeoHfNQz7Br+xBTc25VpowUenC nET3UoAmUkLFrItDMMqJbJ8DwW/Idei+YH/xnDZSKkz5rgHclsg= =4m67 -----END PGP SIGNATURE----- Merge tag 'f2fs-for-6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs Pull f2fs updates from Jaegeuk Kim: "A pretty small update including mostly minor bug fixes in zoned storage along with the large section support. Enhancements: - add support for FS_IOC_GETFSSYSFSPATH - enable atgc dynamically if conditions are met - use new ioprio Macro to get ckpt thread ioprio level - remove unreachable lazytime mount option parsing Bug fixes: - fix null reference error when checking end of zone - fix start segno of large section - fix to cover read extent cache access with lock - don't dirty inode for readonly filesystem - allocate a new section if curseg is not the first seg in its zone - only fragment segment in the same section - truncate preallocated blocks in f2fs_file_open() - fix to avoid use SSR allocate when do defragment - fix to force buffered IO on inline_data inode And some minor code clean-ups and sanity checks" * tag 'f2fs-for-6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (26 commits) f2fs: clean up addrs_per_{inode,block}() f2fs: clean up F2FS_I() f2fs: use meta inode for GC of COW file f2fs: use meta inode for GC of atomic file f2fs: only fragment segment in the same section f2fs: fix to update user block counts in block_operations() f2fs: remove unreachable lazytime mount option parsing f2fs: fix null reference error when checking end of zone f2fs: fix start segno of large section f2fs: remove redundant sanity check in sanity_check_inode() f2fs: assign CURSEG_ALL_DATA_ATGC if blkaddr is valid f2fs: fix to use mnt_{want,drop}_write_file replace file_{start,end}_wrtie f2fs: clean up set REQ_RAHEAD given rac f2fs: enable atgc dynamically if conditions are met f2fs: fix to truncate preallocated blocks in f2fs_file_open() f2fs: fix to cover read extent cache access with lock f2fs: fix return value of f2fs_convert_inline_inode() f2fs: use new ioprio Macro to get ckpt thread ioprio level f2fs: fix to don't dirty inode for readonly filesystem f2fs: fix to avoid use SSR allocate when do defragment ...
This commit is contained in:
commit
5ad7ff8738
@ -1186,6 +1186,11 @@ static void __prepare_cp_block(struct f2fs_sb_info *sbi)
|
||||
ckpt->valid_node_count = cpu_to_le32(valid_node_count(sbi));
|
||||
ckpt->valid_inode_count = cpu_to_le32(valid_inode_count(sbi));
|
||||
ckpt->next_free_nid = cpu_to_le32(last_nid);
|
||||
|
||||
/* update user_block_counts */
|
||||
sbi->last_valid_block_count = sbi->total_valid_block_count;
|
||||
percpu_counter_set(&sbi->alloc_valid_block_count, 0);
|
||||
percpu_counter_set(&sbi->rf_node_block_count, 0);
|
||||
}
|
||||
|
||||
static bool __need_flush_quota(struct f2fs_sb_info *sbi)
|
||||
@ -1575,11 +1580,6 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
|
||||
start_blk += NR_CURSEG_NODE_TYPE;
|
||||
}
|
||||
|
||||
/* update user_block_counts */
|
||||
sbi->last_valid_block_count = sbi->total_valid_block_count;
|
||||
percpu_counter_set(&sbi->alloc_valid_block_count, 0);
|
||||
percpu_counter_set(&sbi->rf_node_block_count, 0);
|
||||
|
||||
/* Here, we have one bio having CP pack except cp pack 2 page */
|
||||
f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
|
||||
/* Wait for all dirty meta pages to be submitted for IO */
|
||||
@ -1718,6 +1718,7 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
|
||||
}
|
||||
|
||||
f2fs_restore_inmem_curseg(sbi);
|
||||
f2fs_reinit_atgc_curseg(sbi);
|
||||
stat_inc_cp_count(sbi);
|
||||
stop:
|
||||
unblock_operations(sbi);
|
||||
|
@ -1100,7 +1100,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc,
|
||||
struct bio *bio = NULL;
|
||||
|
||||
ret = f2fs_read_multi_pages(cc, &bio, cc->cluster_size,
|
||||
&last_block_in_bio, false, true);
|
||||
&last_block_in_bio, NULL, true);
|
||||
f2fs_put_rpages(cc);
|
||||
f2fs_destroy_compress_ctx(cc, true);
|
||||
if (ret)
|
||||
|
@ -925,6 +925,7 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio)
|
||||
#ifdef CONFIG_BLK_DEV_ZONED
|
||||
static bool is_end_zone_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr)
|
||||
{
|
||||
struct block_device *bdev = sbi->sb->s_bdev;
|
||||
int devi = 0;
|
||||
|
||||
if (f2fs_is_multi_device(sbi)) {
|
||||
@ -935,8 +936,9 @@ static bool is_end_zone_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr)
|
||||
return false;
|
||||
}
|
||||
blkaddr -= FDEV(devi).start_blk;
|
||||
bdev = FDEV(devi).bdev;
|
||||
}
|
||||
return bdev_is_zoned(FDEV(devi).bdev) &&
|
||||
return bdev_is_zoned(bdev) &&
|
||||
f2fs_blkz_is_seq(sbi, devi, blkaddr) &&
|
||||
(blkaddr % sbi->blocks_per_blkz == sbi->blocks_per_blkz - 1);
|
||||
}
|
||||
@ -2067,12 +2069,17 @@ static inline loff_t f2fs_readpage_limit(struct inode *inode)
|
||||
return i_size_read(inode);
|
||||
}
|
||||
|
||||
static inline blk_opf_t f2fs_ra_op_flags(struct readahead_control *rac)
|
||||
{
|
||||
return rac ? REQ_RAHEAD : 0;
|
||||
}
|
||||
|
||||
static int f2fs_read_single_page(struct inode *inode, struct folio *folio,
|
||||
unsigned nr_pages,
|
||||
struct f2fs_map_blocks *map,
|
||||
struct bio **bio_ret,
|
||||
sector_t *last_block_in_bio,
|
||||
bool is_readahead)
|
||||
struct readahead_control *rac)
|
||||
{
|
||||
struct bio *bio = *bio_ret;
|
||||
const unsigned blocksize = blks_to_bytes(inode, 1);
|
||||
@ -2148,7 +2155,7 @@ static int f2fs_read_single_page(struct inode *inode, struct folio *folio,
|
||||
}
|
||||
if (bio == NULL) {
|
||||
bio = f2fs_grab_read_bio(inode, block_nr, nr_pages,
|
||||
is_readahead ? REQ_RAHEAD : 0, index,
|
||||
f2fs_ra_op_flags(rac), index,
|
||||
false);
|
||||
if (IS_ERR(bio)) {
|
||||
ret = PTR_ERR(bio);
|
||||
@ -2178,7 +2185,7 @@ static int f2fs_read_single_page(struct inode *inode, struct folio *folio,
|
||||
#ifdef CONFIG_F2FS_FS_COMPRESSION
|
||||
int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
|
||||
unsigned nr_pages, sector_t *last_block_in_bio,
|
||||
bool is_readahead, bool for_write)
|
||||
struct readahead_control *rac, bool for_write)
|
||||
{
|
||||
struct dnode_of_data dn;
|
||||
struct inode *inode = cc->inode;
|
||||
@ -2301,7 +2308,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
|
||||
|
||||
if (!bio) {
|
||||
bio = f2fs_grab_read_bio(inode, blkaddr, nr_pages,
|
||||
is_readahead ? REQ_RAHEAD : 0,
|
||||
f2fs_ra_op_flags(rac),
|
||||
page->index, for_write);
|
||||
if (IS_ERR(bio)) {
|
||||
ret = PTR_ERR(bio);
|
||||
@ -2399,7 +2406,7 @@ static int f2fs_mpage_readpages(struct inode *inode,
|
||||
ret = f2fs_read_multi_pages(&cc, &bio,
|
||||
max_nr_pages,
|
||||
&last_block_in_bio,
|
||||
rac != NULL, false);
|
||||
rac, false);
|
||||
f2fs_destroy_compress_ctx(&cc, false);
|
||||
if (ret)
|
||||
goto set_error_page;
|
||||
@ -2449,7 +2456,7 @@ static int f2fs_mpage_readpages(struct inode *inode,
|
||||
ret = f2fs_read_multi_pages(&cc, &bio,
|
||||
max_nr_pages,
|
||||
&last_block_in_bio,
|
||||
rac != NULL, false);
|
||||
rac, false);
|
||||
f2fs_destroy_compress_ctx(&cc, false);
|
||||
}
|
||||
}
|
||||
@ -2601,7 +2608,7 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio)
|
||||
return true;
|
||||
if (IS_NOQUOTA(inode))
|
||||
return true;
|
||||
if (f2fs_is_atomic_file(inode))
|
||||
if (f2fs_used_in_atomic_write(inode))
|
||||
return true;
|
||||
/* rewrite low ratio compress data w/ OPU mode to avoid fragmentation */
|
||||
if (f2fs_compressed_file(inode) &&
|
||||
@ -2688,7 +2695,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
|
||||
}
|
||||
|
||||
/* wait for GCed page writeback via META_MAPPING */
|
||||
if (fio->post_read)
|
||||
if (fio->meta_gc)
|
||||
f2fs_wait_on_block_writeback(inode, fio->old_blkaddr);
|
||||
|
||||
/*
|
||||
@ -2783,7 +2790,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
|
||||
.submitted = 0,
|
||||
.compr_blocks = compr_blocks,
|
||||
.need_lock = compr_blocks ? LOCK_DONE : LOCK_RETRY,
|
||||
.post_read = f2fs_post_read_required(inode) ? 1 : 0,
|
||||
.meta_gc = f2fs_meta_inode_gc_required(inode) ? 1 : 0,
|
||||
.io_type = io_type,
|
||||
.io_wbc = wbc,
|
||||
.bio = bio,
|
||||
|
@ -19,33 +19,23 @@
|
||||
#include "node.h"
|
||||
#include <trace/events/f2fs.h>
|
||||
|
||||
bool sanity_check_extent_cache(struct inode *inode)
|
||||
bool sanity_check_extent_cache(struct inode *inode, struct page *ipage)
|
||||
{
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
struct extent_tree *et = fi->extent_tree[EX_READ];
|
||||
struct extent_info *ei;
|
||||
struct f2fs_extent *i_ext = &F2FS_INODE(ipage)->i_ext;
|
||||
struct extent_info ei;
|
||||
|
||||
if (!et)
|
||||
get_read_extent_info(&ei, i_ext);
|
||||
|
||||
if (!ei.len)
|
||||
return true;
|
||||
|
||||
ei = &et->largest;
|
||||
if (!ei->len)
|
||||
return true;
|
||||
|
||||
/* Let's drop, if checkpoint got corrupted. */
|
||||
if (is_set_ckpt_flags(sbi, CP_ERROR_FLAG)) {
|
||||
ei->len = 0;
|
||||
et->largest_updated = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!f2fs_is_valid_blkaddr(sbi, ei->blk, DATA_GENERIC_ENHANCE) ||
|
||||
!f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1,
|
||||
if (!f2fs_is_valid_blkaddr(sbi, ei.blk, DATA_GENERIC_ENHANCE) ||
|
||||
!f2fs_is_valid_blkaddr(sbi, ei.blk + ei.len - 1,
|
||||
DATA_GENERIC_ENHANCE)) {
|
||||
f2fs_warn(sbi, "%s: inode (ino=%lx) extent info [%u, %u, %u] is incorrect, run fsck to fix",
|
||||
__func__, inode->i_ino,
|
||||
ei->blk, ei->fofs, ei->len);
|
||||
ei.blk, ei.fofs, ei.len);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -394,24 +384,22 @@ void f2fs_init_read_extent_tree(struct inode *inode, struct page *ipage)
|
||||
|
||||
if (!__may_extent_tree(inode, EX_READ)) {
|
||||
/* drop largest read extent */
|
||||
if (i_ext && i_ext->len) {
|
||||
if (i_ext->len) {
|
||||
f2fs_wait_on_page_writeback(ipage, NODE, true, true);
|
||||
i_ext->len = 0;
|
||||
set_page_dirty(ipage);
|
||||
}
|
||||
goto out;
|
||||
set_inode_flag(inode, FI_NO_EXTENT);
|
||||
return;
|
||||
}
|
||||
|
||||
et = __grab_extent_tree(inode, EX_READ);
|
||||
|
||||
if (!i_ext || !i_ext->len)
|
||||
goto out;
|
||||
|
||||
get_read_extent_info(&ei, i_ext);
|
||||
|
||||
write_lock(&et->lock);
|
||||
if (atomic_read(&et->node_cnt))
|
||||
goto unlock_out;
|
||||
if (atomic_read(&et->node_cnt) || !ei.len)
|
||||
goto skip;
|
||||
|
||||
en = __attach_extent_node(sbi, et, &ei, NULL,
|
||||
&et->root.rb_root.rb_node, true);
|
||||
@ -423,11 +411,13 @@ void f2fs_init_read_extent_tree(struct inode *inode, struct page *ipage)
|
||||
list_add_tail(&en->list, &eti->extent_list);
|
||||
spin_unlock(&eti->extent_lock);
|
||||
}
|
||||
unlock_out:
|
||||
skip:
|
||||
/* Let's drop, if checkpoint got corrupted. */
|
||||
if (f2fs_cp_error(sbi)) {
|
||||
et->largest.len = 0;
|
||||
et->largest_updated = true;
|
||||
}
|
||||
write_unlock(&et->lock);
|
||||
out:
|
||||
if (!F2FS_I(inode)->extent_tree[EX_READ])
|
||||
set_inode_flag(inode, FI_NO_EXTENT);
|
||||
}
|
||||
|
||||
void f2fs_init_age_extent_tree(struct inode *inode)
|
||||
|
@ -803,6 +803,7 @@ enum {
|
||||
FI_COW_FILE, /* indicate COW file */
|
||||
FI_ATOMIC_COMMITTED, /* indicate atomic commit completed except disk sync */
|
||||
FI_ATOMIC_REPLACE, /* indicate atomic replace */
|
||||
FI_OPENED_FILE, /* indicate file has been opened */
|
||||
FI_MAX, /* max flag, never be used */
|
||||
};
|
||||
|
||||
@ -842,7 +843,11 @@ struct f2fs_inode_info {
|
||||
struct task_struct *atomic_write_task; /* store atomic write task */
|
||||
struct extent_tree *extent_tree[NR_EXTENT_CACHES];
|
||||
/* cached extent_tree entry */
|
||||
struct inode *cow_inode; /* copy-on-write inode for atomic write */
|
||||
union {
|
||||
struct inode *cow_inode; /* copy-on-write inode for atomic write */
|
||||
struct inode *atomic_inode;
|
||||
/* point to atomic_inode, available only for cow_inode */
|
||||
};
|
||||
|
||||
/* avoid racing between foreground op and gc */
|
||||
struct f2fs_rwsem i_gc_rwsem[2];
|
||||
@ -1210,7 +1215,7 @@ struct f2fs_io_info {
|
||||
unsigned int in_list:1; /* indicate fio is in io_list */
|
||||
unsigned int is_por:1; /* indicate IO is from recovery or not */
|
||||
unsigned int encrypted:1; /* indicate file is encrypted */
|
||||
unsigned int post_read:1; /* require post read */
|
||||
unsigned int meta_gc:1; /* require meta inode GC */
|
||||
enum iostat_type io_type; /* io type */
|
||||
struct writeback_control *io_wbc; /* writeback control */
|
||||
struct bio **bio; /* bio for ipu */
|
||||
@ -3222,21 +3227,15 @@ static inline bool f2fs_need_compress_data(struct inode *inode)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline unsigned int addrs_per_inode(struct inode *inode)
|
||||
static inline unsigned int addrs_per_page(struct inode *inode,
|
||||
bool is_inode)
|
||||
{
|
||||
unsigned int addrs = CUR_ADDRS_PER_INODE(inode) -
|
||||
get_inline_xattr_addrs(inode);
|
||||
unsigned int addrs = is_inode ? (CUR_ADDRS_PER_INODE(inode) -
|
||||
get_inline_xattr_addrs(inode)) : DEF_ADDRS_PER_BLOCK;
|
||||
|
||||
if (!f2fs_compressed_file(inode))
|
||||
return addrs;
|
||||
return ALIGN_DOWN(addrs, F2FS_I(inode)->i_cluster_size);
|
||||
}
|
||||
|
||||
static inline unsigned int addrs_per_block(struct inode *inode)
|
||||
{
|
||||
if (!f2fs_compressed_file(inode))
|
||||
return DEF_ADDRS_PER_BLOCK;
|
||||
return ALIGN_DOWN(DEF_ADDRS_PER_BLOCK, F2FS_I(inode)->i_cluster_size);
|
||||
if (f2fs_compressed_file(inode))
|
||||
return ALIGN_DOWN(addrs, F2FS_I(inode)->i_cluster_size);
|
||||
return addrs;
|
||||
}
|
||||
|
||||
static inline void *inline_xattr_addr(struct inode *inode, struct page *page)
|
||||
@ -3706,6 +3705,7 @@ void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
|
||||
int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
|
||||
bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, int segno);
|
||||
int f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
|
||||
int f2fs_reinit_atgc_curseg(struct f2fs_sb_info *sbi);
|
||||
void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
|
||||
void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
|
||||
int f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
|
||||
@ -4163,7 +4163,7 @@ extern struct kmem_cache *f2fs_inode_entry_slab;
|
||||
* inline.c
|
||||
*/
|
||||
bool f2fs_may_inline_data(struct inode *inode);
|
||||
bool f2fs_sanity_check_inline_data(struct inode *inode);
|
||||
bool f2fs_sanity_check_inline_data(struct inode *inode, struct page *ipage);
|
||||
bool f2fs_may_inline_dentry(struct inode *inode);
|
||||
void f2fs_do_read_inline_data(struct folio *folio, struct page *ipage);
|
||||
void f2fs_truncate_inline_inode(struct inode *inode,
|
||||
@ -4204,7 +4204,7 @@ void f2fs_leave_shrinker(struct f2fs_sb_info *sbi);
|
||||
/*
|
||||
* extent_cache.c
|
||||
*/
|
||||
bool sanity_check_extent_cache(struct inode *inode);
|
||||
bool sanity_check_extent_cache(struct inode *inode, struct page *ipage);
|
||||
void f2fs_init_extent_tree(struct inode *inode);
|
||||
void f2fs_drop_extent_tree(struct inode *inode);
|
||||
void f2fs_destroy_extent_node(struct inode *inode);
|
||||
@ -4275,6 +4275,16 @@ static inline bool f2fs_post_read_required(struct inode *inode)
|
||||
f2fs_compressed_file(inode);
|
||||
}
|
||||
|
||||
static inline bool f2fs_used_in_atomic_write(struct inode *inode)
|
||||
{
|
||||
return f2fs_is_atomic_file(inode) || f2fs_is_cow_file(inode);
|
||||
}
|
||||
|
||||
static inline bool f2fs_meta_inode_gc_required(struct inode *inode)
|
||||
{
|
||||
return f2fs_post_read_required(inode) || f2fs_used_in_atomic_write(inode);
|
||||
}
|
||||
|
||||
/*
|
||||
* compress.c
|
||||
*/
|
||||
@ -4310,7 +4320,7 @@ void f2fs_update_read_extent_tree_range_compressed(struct inode *inode,
|
||||
unsigned int llen, unsigned int c_len);
|
||||
int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
|
||||
unsigned nr_pages, sector_t *last_block_in_bio,
|
||||
bool is_readahead, bool for_write);
|
||||
struct readahead_control *rac, bool for_write);
|
||||
struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc);
|
||||
void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,
|
||||
bool in_task);
|
||||
@ -4401,22 +4411,18 @@ static inline int set_compress_context(struct inode *inode)
|
||||
{
|
||||
#ifdef CONFIG_F2FS_FS_COMPRESSION
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
|
||||
F2FS_I(inode)->i_compress_algorithm =
|
||||
F2FS_OPTION(sbi).compress_algorithm;
|
||||
F2FS_I(inode)->i_log_cluster_size =
|
||||
F2FS_OPTION(sbi).compress_log_size;
|
||||
F2FS_I(inode)->i_compress_flag =
|
||||
F2FS_OPTION(sbi).compress_chksum ?
|
||||
BIT(COMPRESS_CHKSUM) : 0;
|
||||
F2FS_I(inode)->i_cluster_size =
|
||||
BIT(F2FS_I(inode)->i_log_cluster_size);
|
||||
if ((F2FS_I(inode)->i_compress_algorithm == COMPRESS_LZ4 ||
|
||||
F2FS_I(inode)->i_compress_algorithm == COMPRESS_ZSTD) &&
|
||||
fi->i_compress_algorithm = F2FS_OPTION(sbi).compress_algorithm;
|
||||
fi->i_log_cluster_size = F2FS_OPTION(sbi).compress_log_size;
|
||||
fi->i_compress_flag = F2FS_OPTION(sbi).compress_chksum ?
|
||||
BIT(COMPRESS_CHKSUM) : 0;
|
||||
fi->i_cluster_size = BIT(fi->i_log_cluster_size);
|
||||
if ((fi->i_compress_algorithm == COMPRESS_LZ4 ||
|
||||
fi->i_compress_algorithm == COMPRESS_ZSTD) &&
|
||||
F2FS_OPTION(sbi).compress_level)
|
||||
F2FS_I(inode)->i_compress_level =
|
||||
F2FS_OPTION(sbi).compress_level;
|
||||
F2FS_I(inode)->i_flags |= F2FS_COMPR_FL;
|
||||
fi->i_compress_level = F2FS_OPTION(sbi).compress_level;
|
||||
fi->i_flags |= F2FS_COMPR_FL;
|
||||
set_inode_flag(inode, FI_COMPRESSED_FILE);
|
||||
stat_inc_compr_inode(inode);
|
||||
inc_compr_inode_stat(inode);
|
||||
@ -4431,15 +4437,15 @@ static inline bool f2fs_disable_compressed_file(struct inode *inode)
|
||||
{
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
|
||||
f2fs_down_write(&F2FS_I(inode)->i_sem);
|
||||
f2fs_down_write(&fi->i_sem);
|
||||
|
||||
if (!f2fs_compressed_file(inode)) {
|
||||
f2fs_up_write(&F2FS_I(inode)->i_sem);
|
||||
f2fs_up_write(&fi->i_sem);
|
||||
return true;
|
||||
}
|
||||
if (f2fs_is_mmap_file(inode) ||
|
||||
(S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode))) {
|
||||
f2fs_up_write(&F2FS_I(inode)->i_sem);
|
||||
f2fs_up_write(&fi->i_sem);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4448,7 +4454,7 @@ static inline bool f2fs_disable_compressed_file(struct inode *inode)
|
||||
clear_inode_flag(inode, FI_COMPRESSED_FILE);
|
||||
f2fs_mark_inode_dirty_sync(inode, true);
|
||||
|
||||
f2fs_up_write(&F2FS_I(inode)->i_sem);
|
||||
f2fs_up_write(&fi->i_sem);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
135
fs/f2fs/file.c
135
fs/f2fs/file.c
@ -554,6 +554,42 @@ static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int finish_preallocate_blocks(struct inode *inode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
inode_lock(inode);
|
||||
if (is_inode_flag_set(inode, FI_OPENED_FILE)) {
|
||||
inode_unlock(inode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!file_should_truncate(inode)) {
|
||||
set_inode_flag(inode, FI_OPENED_FILE);
|
||||
inode_unlock(inode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
|
||||
truncate_setsize(inode, i_size_read(inode));
|
||||
ret = f2fs_truncate(inode);
|
||||
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
|
||||
if (!ret)
|
||||
set_inode_flag(inode, FI_OPENED_FILE);
|
||||
|
||||
inode_unlock(inode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
file_dont_truncate(inode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int f2fs_file_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
int err = fscrypt_file_open(inode, filp);
|
||||
@ -571,7 +607,11 @@ static int f2fs_file_open(struct inode *inode, struct file *filp)
|
||||
filp->f_mode |= FMODE_NOWAIT;
|
||||
filp->f_mode |= FMODE_CAN_ODIRECT;
|
||||
|
||||
return dquot_file_open(inode, filp);
|
||||
err = dquot_file_open(inode, filp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return finish_preallocate_blocks(inode);
|
||||
}
|
||||
|
||||
void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
|
||||
@ -825,6 +865,8 @@ static bool f2fs_force_buffered_io(struct inode *inode, int rw)
|
||||
return true;
|
||||
if (f2fs_compressed_file(inode))
|
||||
return true;
|
||||
if (f2fs_has_inline_data(inode))
|
||||
return true;
|
||||
|
||||
/* disallow direct IO if any of devices has unaligned blksize */
|
||||
if (f2fs_is_multi_device(sbi) && !sbi->aligned_blksize)
|
||||
@ -937,6 +979,7 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct iattr *attr)
|
||||
{
|
||||
struct inode *inode = d_inode(dentry);
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
int err;
|
||||
|
||||
if (unlikely(f2fs_cp_error(F2FS_I_SB(inode))))
|
||||
@ -955,7 +998,7 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
return -EOPNOTSUPP;
|
||||
if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED) &&
|
||||
!IS_ALIGNED(attr->ia_size,
|
||||
F2FS_BLK_TO_BYTES(F2FS_I(inode)->i_cluster_size)))
|
||||
F2FS_BLK_TO_BYTES(fi->i_cluster_size)))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1009,7 +1052,7 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
return err;
|
||||
}
|
||||
|
||||
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
|
||||
truncate_setsize(inode, attr->ia_size);
|
||||
@ -1021,14 +1064,14 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
* larger than i_size.
|
||||
*/
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
spin_lock(&F2FS_I(inode)->i_size_lock);
|
||||
spin_lock(&fi->i_size_lock);
|
||||
inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
|
||||
F2FS_I(inode)->last_disk_size = i_size_read(inode);
|
||||
spin_unlock(&F2FS_I(inode)->i_size_lock);
|
||||
fi->last_disk_size = i_size_read(inode);
|
||||
spin_unlock(&fi->i_size_lock);
|
||||
}
|
||||
|
||||
__setattr_copy(idmap, inode, attr);
|
||||
@ -1038,7 +1081,7 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
|
||||
if (is_inode_flag_set(inode, FI_ACL_MODE)) {
|
||||
if (!err)
|
||||
inode->i_mode = F2FS_I(inode)->i_acl_mode;
|
||||
inode->i_mode = fi->i_acl_mode;
|
||||
clear_inode_flag(inode, FI_ACL_MODE);
|
||||
}
|
||||
}
|
||||
@ -1946,15 +1989,15 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
f2fs_down_write(&F2FS_I(inode)->i_sem);
|
||||
f2fs_down_write(&fi->i_sem);
|
||||
if (!f2fs_may_compress(inode) ||
|
||||
(S_ISREG(inode->i_mode) &&
|
||||
F2FS_HAS_BLOCKS(inode))) {
|
||||
f2fs_up_write(&F2FS_I(inode)->i_sem);
|
||||
f2fs_up_write(&fi->i_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
err = set_compress_context(inode);
|
||||
f2fs_up_write(&F2FS_I(inode)->i_sem);
|
||||
f2fs_up_write(&fi->i_sem);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
@ -2139,6 +2182,9 @@ static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate)
|
||||
|
||||
set_inode_flag(fi->cow_inode, FI_COW_FILE);
|
||||
clear_inode_flag(fi->cow_inode, FI_INLINE_DATA);
|
||||
|
||||
/* Set the COW inode's atomic_inode to the atomic inode */
|
||||
F2FS_I(fi->cow_inode)->atomic_inode = inode;
|
||||
} else {
|
||||
/* Reuse the already created COW inode */
|
||||
ret = f2fs_do_truncate_blocks(fi->cow_inode, 0, true);
|
||||
@ -3541,6 +3587,7 @@ static int release_compress_blocks(struct dnode_of_data *dn, pgoff_t count)
|
||||
static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
|
||||
{
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
pgoff_t page_idx = 0, last_idx;
|
||||
unsigned int released_blocks = 0;
|
||||
@ -3578,7 +3625,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (!atomic_read(&F2FS_I(inode)->i_compr_blocks)) {
|
||||
if (!atomic_read(&fi->i_compr_blocks)) {
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
@ -3587,7 +3634,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
|
||||
inode_set_ctime_current(inode);
|
||||
f2fs_mark_inode_dirty_sync(inode, true);
|
||||
|
||||
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
|
||||
last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
|
||||
@ -3613,7 +3660,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
|
||||
|
||||
end_offset = ADDRS_PER_PAGE(dn.node_page, inode);
|
||||
count = min(end_offset - dn.ofs_in_node, last_idx - page_idx);
|
||||
count = round_up(count, F2FS_I(inode)->i_cluster_size);
|
||||
count = round_up(count, fi->i_cluster_size);
|
||||
|
||||
ret = release_compress_blocks(&dn, count);
|
||||
|
||||
@ -3629,7 +3676,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
|
||||
}
|
||||
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
|
||||
out:
|
||||
if (released_blocks)
|
||||
f2fs_update_time(sbi, REQ_TIME);
|
||||
@ -3640,14 +3687,14 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
|
||||
if (ret >= 0) {
|
||||
ret = put_user(released_blocks, (u64 __user *)arg);
|
||||
} else if (released_blocks &&
|
||||
atomic_read(&F2FS_I(inode)->i_compr_blocks)) {
|
||||
atomic_read(&fi->i_compr_blocks)) {
|
||||
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
||||
f2fs_warn(sbi, "%s: partial blocks were released i_ino=%lx "
|
||||
"iblocks=%llu, released=%u, compr_blocks=%u, "
|
||||
"run fsck to fix.",
|
||||
__func__, inode->i_ino, inode->i_blocks,
|
||||
released_blocks,
|
||||
atomic_read(&F2FS_I(inode)->i_compr_blocks));
|
||||
atomic_read(&fi->i_compr_blocks));
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -3736,6 +3783,7 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
|
||||
static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
|
||||
{
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
pgoff_t page_idx = 0, last_idx;
|
||||
unsigned int reserved_blocks = 0;
|
||||
@ -3761,10 +3809,10 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
|
||||
goto unlock_inode;
|
||||
}
|
||||
|
||||
if (atomic_read(&F2FS_I(inode)->i_compr_blocks))
|
||||
if (atomic_read(&fi->i_compr_blocks))
|
||||
goto unlock_inode;
|
||||
|
||||
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
|
||||
last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
|
||||
@ -3790,7 +3838,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
|
||||
|
||||
end_offset = ADDRS_PER_PAGE(dn.node_page, inode);
|
||||
count = min(end_offset - dn.ofs_in_node, last_idx - page_idx);
|
||||
count = round_up(count, F2FS_I(inode)->i_cluster_size);
|
||||
count = round_up(count, fi->i_cluster_size);
|
||||
|
||||
ret = reserve_compress_blocks(&dn, count, &reserved_blocks);
|
||||
|
||||
@ -3805,7 +3853,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
|
||||
}
|
||||
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
|
||||
|
||||
if (!ret) {
|
||||
clear_inode_flag(inode, FI_COMPRESS_RELEASED);
|
||||
@ -3821,14 +3869,14 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
|
||||
if (!ret) {
|
||||
ret = put_user(reserved_blocks, (u64 __user *)arg);
|
||||
} else if (reserved_blocks &&
|
||||
atomic_read(&F2FS_I(inode)->i_compr_blocks)) {
|
||||
atomic_read(&fi->i_compr_blocks)) {
|
||||
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
||||
f2fs_warn(sbi, "%s: partial blocks were reserved i_ino=%lx "
|
||||
"iblocks=%llu, reserved=%u, compr_blocks=%u, "
|
||||
"run fsck to fix.",
|
||||
__func__, inode->i_ino, inode->i_blocks,
|
||||
reserved_blocks,
|
||||
atomic_read(&F2FS_I(inode)->i_compr_blocks));
|
||||
atomic_read(&fi->i_compr_blocks));
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -3891,7 +3939,9 @@ static int f2fs_sec_trim_file(struct file *filp, unsigned long arg)
|
||||
IS_ENCRYPTED(inode) && f2fs_is_multi_device(sbi)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
file_start_write(filp);
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
inode_lock(inode);
|
||||
|
||||
if (f2fs_is_atomic_file(inode) || f2fs_compressed_file(inode) ||
|
||||
@ -4017,7 +4067,7 @@ static int f2fs_sec_trim_file(struct file *filp, unsigned long arg)
|
||||
f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
err:
|
||||
inode_unlock(inode);
|
||||
file_end_write(filp);
|
||||
mnt_drop_write_file(filp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -4052,6 +4102,7 @@ static int f2fs_ioc_get_compress_option(struct file *filp, unsigned long arg)
|
||||
static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg)
|
||||
{
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
struct f2fs_comp_option option;
|
||||
int ret = 0;
|
||||
@ -4071,7 +4122,9 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg)
|
||||
option.algorithm >= COMPRESS_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
file_start_write(filp);
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
inode_lock(inode);
|
||||
|
||||
f2fs_down_write(&F2FS_I(inode)->i_sem);
|
||||
@ -4090,27 +4143,27 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg)
|
||||
goto out;
|
||||
}
|
||||
|
||||
F2FS_I(inode)->i_compress_algorithm = option.algorithm;
|
||||
F2FS_I(inode)->i_log_cluster_size = option.log_cluster_size;
|
||||
F2FS_I(inode)->i_cluster_size = BIT(option.log_cluster_size);
|
||||
fi->i_compress_algorithm = option.algorithm;
|
||||
fi->i_log_cluster_size = option.log_cluster_size;
|
||||
fi->i_cluster_size = BIT(option.log_cluster_size);
|
||||
/* Set default level */
|
||||
if (F2FS_I(inode)->i_compress_algorithm == COMPRESS_ZSTD)
|
||||
F2FS_I(inode)->i_compress_level = F2FS_ZSTD_DEFAULT_CLEVEL;
|
||||
if (fi->i_compress_algorithm == COMPRESS_ZSTD)
|
||||
fi->i_compress_level = F2FS_ZSTD_DEFAULT_CLEVEL;
|
||||
else
|
||||
F2FS_I(inode)->i_compress_level = 0;
|
||||
fi->i_compress_level = 0;
|
||||
/* Adjust mount option level */
|
||||
if (option.algorithm == F2FS_OPTION(sbi).compress_algorithm &&
|
||||
F2FS_OPTION(sbi).compress_level)
|
||||
F2FS_I(inode)->i_compress_level = F2FS_OPTION(sbi).compress_level;
|
||||
fi->i_compress_level = F2FS_OPTION(sbi).compress_level;
|
||||
f2fs_mark_inode_dirty_sync(inode, true);
|
||||
|
||||
if (!f2fs_is_compress_backend_ready(inode))
|
||||
f2fs_warn(sbi, "compression algorithm is successfully set, "
|
||||
"but current kernel doesn't support this algorithm.");
|
||||
out:
|
||||
f2fs_up_write(&F2FS_I(inode)->i_sem);
|
||||
f2fs_up_write(&fi->i_sem);
|
||||
inode_unlock(inode);
|
||||
file_end_write(filp);
|
||||
mnt_drop_write_file(filp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -4167,7 +4220,9 @@ static int f2fs_ioc_decompress_file(struct file *filp)
|
||||
|
||||
f2fs_balance_fs(sbi, true);
|
||||
|
||||
file_start_write(filp);
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
inode_lock(inode);
|
||||
|
||||
if (!f2fs_is_compress_backend_ready(inode)) {
|
||||
@ -4222,7 +4277,7 @@ static int f2fs_ioc_decompress_file(struct file *filp)
|
||||
f2fs_update_time(sbi, REQ_TIME);
|
||||
out:
|
||||
inode_unlock(inode);
|
||||
file_end_write(filp);
|
||||
mnt_drop_write_file(filp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -4244,7 +4299,9 @@ static int f2fs_ioc_compress_file(struct file *filp)
|
||||
|
||||
f2fs_balance_fs(sbi, true);
|
||||
|
||||
file_start_write(filp);
|
||||
ret = mnt_want_write_file(filp);
|
||||
if (ret)
|
||||
return ret;
|
||||
inode_lock(inode);
|
||||
|
||||
if (!f2fs_is_compress_backend_ready(inode)) {
|
||||
@ -4300,7 +4357,7 @@ static int f2fs_ioc_compress_file(struct file *filp)
|
||||
f2fs_update_time(sbi, REQ_TIME);
|
||||
out:
|
||||
inode_unlock(inode);
|
||||
file_end_write(filp);
|
||||
mnt_drop_write_file(filp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
24
fs/f2fs/gc.c
24
fs/f2fs/gc.c
@ -1171,7 +1171,8 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
|
||||
static int ra_data_block(struct inode *inode, pgoff_t index)
|
||||
{
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
struct address_space *mapping = inode->i_mapping;
|
||||
struct address_space *mapping = f2fs_is_cow_file(inode) ?
|
||||
F2FS_I(inode)->atomic_inode->i_mapping : inode->i_mapping;
|
||||
struct dnode_of_data dn;
|
||||
struct page *page;
|
||||
struct f2fs_io_info fio = {
|
||||
@ -1260,6 +1261,8 @@ static int ra_data_block(struct inode *inode, pgoff_t index)
|
||||
static int move_data_block(struct inode *inode, block_t bidx,
|
||||
int gc_type, unsigned int segno, int off)
|
||||
{
|
||||
struct address_space *mapping = f2fs_is_cow_file(inode) ?
|
||||
F2FS_I(inode)->atomic_inode->i_mapping : inode->i_mapping;
|
||||
struct f2fs_io_info fio = {
|
||||
.sbi = F2FS_I_SB(inode),
|
||||
.ino = inode->i_ino,
|
||||
@ -1282,7 +1285,7 @@ static int move_data_block(struct inode *inode, block_t bidx,
|
||||
CURSEG_ALL_DATA_ATGC : CURSEG_COLD_DATA;
|
||||
|
||||
/* do not read out */
|
||||
page = f2fs_grab_cache_page(inode->i_mapping, bidx, false);
|
||||
page = f2fs_grab_cache_page(mapping, bidx, false);
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1563,6 +1566,16 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (f2fs_has_inline_data(inode)) {
|
||||
iput(inode);
|
||||
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
||||
f2fs_err_ratelimited(sbi,
|
||||
"inode %lx has both inline_data flag and "
|
||||
"data block, nid=%u, ofs_in_node=%u",
|
||||
inode->i_ino, dni.nid, ofs_in_node);
|
||||
continue;
|
||||
}
|
||||
|
||||
err = f2fs_gc_pinned_control(inode, gc_type, segno);
|
||||
if (err == -EAGAIN) {
|
||||
iput(inode);
|
||||
@ -1579,7 +1592,7 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
|
||||
start_bidx = f2fs_start_bidx_of_node(nofs, inode) +
|
||||
ofs_in_node;
|
||||
|
||||
if (f2fs_post_read_required(inode)) {
|
||||
if (f2fs_meta_inode_gc_required(inode)) {
|
||||
int err = ra_data_block(inode, start_bidx);
|
||||
|
||||
f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
@ -1630,7 +1643,7 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
|
||||
|
||||
start_bidx = f2fs_start_bidx_of_node(nofs, inode)
|
||||
+ ofs_in_node;
|
||||
if (f2fs_post_read_required(inode))
|
||||
if (f2fs_meta_inode_gc_required(inode))
|
||||
err = move_data_block(inode, start_bidx,
|
||||
gc_type, segno, off);
|
||||
else
|
||||
@ -1638,7 +1651,7 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
|
||||
segno, off);
|
||||
|
||||
if (!err && (gc_type == FG_GC ||
|
||||
f2fs_post_read_required(inode)))
|
||||
f2fs_meta_inode_gc_required(inode)))
|
||||
submitted++;
|
||||
|
||||
if (locked) {
|
||||
@ -1742,7 +1755,6 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
|
||||
if (type != GET_SUM_TYPE((&sum->footer))) {
|
||||
f2fs_err(sbi, "Inconsistent segment (%u) type [%d, %d] in SSA and SIT",
|
||||
segno, type, GET_SUM_TYPE((&sum->footer)));
|
||||
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
||||
f2fs_stop_checkpoint(sbi, false,
|
||||
STOP_CP_REASON_CORRUPTED_SUMMARY);
|
||||
goto skip;
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
static bool support_inline_data(struct inode *inode)
|
||||
{
|
||||
if (f2fs_is_atomic_file(inode))
|
||||
if (f2fs_used_in_atomic_write(inode))
|
||||
return false;
|
||||
if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode))
|
||||
return false;
|
||||
@ -33,11 +33,29 @@ bool f2fs_may_inline_data(struct inode *inode)
|
||||
return !f2fs_post_read_required(inode);
|
||||
}
|
||||
|
||||
bool f2fs_sanity_check_inline_data(struct inode *inode)
|
||||
static bool inode_has_blocks(struct inode *inode, struct page *ipage)
|
||||
{
|
||||
struct f2fs_inode *ri = F2FS_INODE(ipage);
|
||||
int i;
|
||||
|
||||
if (F2FS_HAS_BLOCKS(inode))
|
||||
return true;
|
||||
|
||||
for (i = 0; i < DEF_NIDS_PER_INODE; i++) {
|
||||
if (ri->i_nid[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool f2fs_sanity_check_inline_data(struct inode *inode, struct page *ipage)
|
||||
{
|
||||
if (!f2fs_has_inline_data(inode))
|
||||
return false;
|
||||
|
||||
if (inode_has_blocks(inode, ipage))
|
||||
return false;
|
||||
|
||||
if (!support_inline_data(inode))
|
||||
return true;
|
||||
|
||||
@ -203,8 +221,10 @@ int f2fs_convert_inline_inode(struct inode *inode)
|
||||
struct page *ipage, *page;
|
||||
int err = 0;
|
||||
|
||||
if (!f2fs_has_inline_data(inode) ||
|
||||
f2fs_hw_is_readonly(sbi) || f2fs_readonly(sbi->sb))
|
||||
if (f2fs_hw_is_readonly(sbi) || f2fs_readonly(sbi->sb))
|
||||
return -EROFS;
|
||||
|
||||
if (!f2fs_has_inline_data(inode))
|
||||
return 0;
|
||||
|
||||
err = f2fs_dquot_initialize(inode);
|
||||
|
@ -29,6 +29,9 @@ void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync)
|
||||
if (is_inode_flag_set(inode, FI_NEW_INODE))
|
||||
return;
|
||||
|
||||
if (f2fs_readonly(F2FS_I_SB(inode)->sb))
|
||||
return;
|
||||
|
||||
if (f2fs_inode_dirtied(inode, sync))
|
||||
return;
|
||||
|
||||
@ -310,10 +313,6 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page)
|
||||
if (!sanity_check_compress_inode(inode, ri))
|
||||
return false;
|
||||
}
|
||||
} else if (f2fs_sb_has_flexible_inline_xattr(sbi)) {
|
||||
f2fs_warn(sbi, "%s: corrupted inode ino=%lx, run fsck to fix.",
|
||||
__func__, inode->i_ino);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!f2fs_sb_has_extra_attr(sbi)) {
|
||||
@ -344,7 +343,7 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page)
|
||||
}
|
||||
}
|
||||
|
||||
if (f2fs_sanity_check_inline_data(inode)) {
|
||||
if (f2fs_sanity_check_inline_data(inode, node_page)) {
|
||||
f2fs_warn(sbi, "%s: inode (ino=%lx, mode=%u) should not have inline_data, run fsck to fix",
|
||||
__func__, inode->i_ino, inode->i_mode);
|
||||
return false;
|
||||
@ -508,16 +507,16 @@ static int do_read_inode(struct inode *inode)
|
||||
|
||||
init_idisk_time(inode);
|
||||
|
||||
/* Need all the flag bits */
|
||||
f2fs_init_read_extent_tree(inode, node_page);
|
||||
f2fs_init_age_extent_tree(inode);
|
||||
|
||||
if (!sanity_check_extent_cache(inode)) {
|
||||
if (!sanity_check_extent_cache(inode, node_page)) {
|
||||
f2fs_put_page(node_page, 1);
|
||||
f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
/* Need all the flag bits */
|
||||
f2fs_init_read_extent_tree(inode, node_page);
|
||||
f2fs_init_age_extent_tree(inode);
|
||||
|
||||
f2fs_put_page(node_page, 1);
|
||||
|
||||
stat_inc_inline_xattr(inode);
|
||||
@ -610,14 +609,6 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
|
||||
}
|
||||
f2fs_set_inode_flags(inode);
|
||||
|
||||
if (file_should_truncate(inode) &&
|
||||
!is_sbi_flag_set(sbi, SBI_POR_DOING)) {
|
||||
ret = f2fs_truncate(inode);
|
||||
if (ret)
|
||||
goto bad_inode;
|
||||
file_dont_truncate(inode);
|
||||
}
|
||||
|
||||
unlock_new_inode(inode);
|
||||
trace_f2fs_iget(inode);
|
||||
return inode;
|
||||
@ -645,8 +636,9 @@ struct inode *f2fs_iget_retry(struct super_block *sb, unsigned long ino)
|
||||
|
||||
void f2fs_update_inode(struct inode *inode, struct page *node_page)
|
||||
{
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
struct f2fs_inode *ri;
|
||||
struct extent_tree *et = F2FS_I(inode)->extent_tree[EX_READ];
|
||||
struct extent_tree *et = fi->extent_tree[EX_READ];
|
||||
|
||||
f2fs_wait_on_page_writeback(node_page, NODE, true, true);
|
||||
set_page_dirty(node_page);
|
||||
@ -656,7 +648,7 @@ void f2fs_update_inode(struct inode *inode, struct page *node_page)
|
||||
ri = F2FS_INODE(node_page);
|
||||
|
||||
ri->i_mode = cpu_to_le16(inode->i_mode);
|
||||
ri->i_advise = F2FS_I(inode)->i_advise;
|
||||
ri->i_advise = fi->i_advise;
|
||||
ri->i_uid = cpu_to_le32(i_uid_read(inode));
|
||||
ri->i_gid = cpu_to_le32(i_gid_read(inode));
|
||||
ri->i_links = cpu_to_le32(inode->i_nlink);
|
||||
@ -682,58 +674,49 @@ void f2fs_update_inode(struct inode *inode, struct page *node_page)
|
||||
ri->i_ctime_nsec = cpu_to_le32(inode_get_ctime_nsec(inode));
|
||||
ri->i_mtime_nsec = cpu_to_le32(inode_get_mtime_nsec(inode));
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
ri->i_current_depth =
|
||||
cpu_to_le32(F2FS_I(inode)->i_current_depth);
|
||||
ri->i_current_depth = cpu_to_le32(fi->i_current_depth);
|
||||
else if (S_ISREG(inode->i_mode))
|
||||
ri->i_gc_failures = cpu_to_le16(F2FS_I(inode)->i_gc_failures);
|
||||
ri->i_xattr_nid = cpu_to_le32(F2FS_I(inode)->i_xattr_nid);
|
||||
ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags);
|
||||
ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino);
|
||||
ri->i_gc_failures = cpu_to_le16(fi->i_gc_failures);
|
||||
ri->i_xattr_nid = cpu_to_le32(fi->i_xattr_nid);
|
||||
ri->i_flags = cpu_to_le32(fi->i_flags);
|
||||
ri->i_pino = cpu_to_le32(fi->i_pino);
|
||||
ri->i_generation = cpu_to_le32(inode->i_generation);
|
||||
ri->i_dir_level = F2FS_I(inode)->i_dir_level;
|
||||
ri->i_dir_level = fi->i_dir_level;
|
||||
|
||||
if (f2fs_has_extra_attr(inode)) {
|
||||
ri->i_extra_isize = cpu_to_le16(F2FS_I(inode)->i_extra_isize);
|
||||
ri->i_extra_isize = cpu_to_le16(fi->i_extra_isize);
|
||||
|
||||
if (f2fs_sb_has_flexible_inline_xattr(F2FS_I_SB(inode)))
|
||||
ri->i_inline_xattr_size =
|
||||
cpu_to_le16(F2FS_I(inode)->i_inline_xattr_size);
|
||||
cpu_to_le16(fi->i_inline_xattr_size);
|
||||
|
||||
if (f2fs_sb_has_project_quota(F2FS_I_SB(inode)) &&
|
||||
F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize,
|
||||
i_projid)) {
|
||||
F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, i_projid)) {
|
||||
projid_t i_projid;
|
||||
|
||||
i_projid = from_kprojid(&init_user_ns,
|
||||
F2FS_I(inode)->i_projid);
|
||||
i_projid = from_kprojid(&init_user_ns, fi->i_projid);
|
||||
ri->i_projid = cpu_to_le32(i_projid);
|
||||
}
|
||||
|
||||
if (f2fs_sb_has_inode_crtime(F2FS_I_SB(inode)) &&
|
||||
F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize,
|
||||
i_crtime)) {
|
||||
ri->i_crtime =
|
||||
cpu_to_le64(F2FS_I(inode)->i_crtime.tv_sec);
|
||||
ri->i_crtime_nsec =
|
||||
cpu_to_le32(F2FS_I(inode)->i_crtime.tv_nsec);
|
||||
F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, i_crtime)) {
|
||||
ri->i_crtime = cpu_to_le64(fi->i_crtime.tv_sec);
|
||||
ri->i_crtime_nsec = cpu_to_le32(fi->i_crtime.tv_nsec);
|
||||
}
|
||||
|
||||
if (f2fs_sb_has_compression(F2FS_I_SB(inode)) &&
|
||||
F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize,
|
||||
F2FS_FITS_IN_INODE(ri, fi->i_extra_isize,
|
||||
i_compress_flag)) {
|
||||
unsigned short compress_flag;
|
||||
|
||||
ri->i_compr_blocks =
|
||||
cpu_to_le64(atomic_read(
|
||||
&F2FS_I(inode)->i_compr_blocks));
|
||||
ri->i_compress_algorithm =
|
||||
F2FS_I(inode)->i_compress_algorithm;
|
||||
compress_flag = F2FS_I(inode)->i_compress_flag |
|
||||
F2FS_I(inode)->i_compress_level <<
|
||||
ri->i_compr_blocks = cpu_to_le64(
|
||||
atomic_read(&fi->i_compr_blocks));
|
||||
ri->i_compress_algorithm = fi->i_compress_algorithm;
|
||||
compress_flag = fi->i_compress_flag |
|
||||
fi->i_compress_level <<
|
||||
COMPRESS_LEVEL_OFFSET;
|
||||
ri->i_compress_flag = cpu_to_le16(compress_flag);
|
||||
ri->i_log_cluster_size =
|
||||
F2FS_I(inode)->i_log_cluster_size;
|
||||
ri->i_log_cluster_size = fi->i_log_cluster_size;
|
||||
}
|
||||
}
|
||||
|
||||
@ -813,8 +796,9 @@ void f2fs_evict_inode(struct inode *inode)
|
||||
|
||||
f2fs_abort_atomic_write(inode, true);
|
||||
|
||||
if (fi->cow_inode) {
|
||||
if (fi->cow_inode && f2fs_is_cow_file(fi->cow_inode)) {
|
||||
clear_inode_flag(fi->cow_inode, FI_COW_FILE);
|
||||
F2FS_I(fi->cow_inode)->atomic_inode = NULL;
|
||||
iput(fi->cow_inode);
|
||||
fi->cow_inode = NULL;
|
||||
}
|
||||
|
@ -221,6 +221,7 @@ static struct inode *f2fs_new_inode(struct mnt_idmap *idmap,
|
||||
const char *name)
|
||||
{
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
|
||||
struct f2fs_inode_info *fi;
|
||||
nid_t ino;
|
||||
struct inode *inode;
|
||||
bool nid_free = false;
|
||||
@ -241,14 +242,15 @@ static struct inode *f2fs_new_inode(struct mnt_idmap *idmap,
|
||||
|
||||
inode_init_owner(idmap, inode, dir, mode);
|
||||
|
||||
fi = F2FS_I(inode);
|
||||
inode->i_ino = ino;
|
||||
inode->i_blocks = 0;
|
||||
simple_inode_init_ts(inode);
|
||||
F2FS_I(inode)->i_crtime = inode_get_mtime(inode);
|
||||
fi->i_crtime = inode_get_mtime(inode);
|
||||
inode->i_generation = get_random_u32();
|
||||
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
F2FS_I(inode)->i_current_depth = 1;
|
||||
fi->i_current_depth = 1;
|
||||
|
||||
err = insert_inode_locked(inode);
|
||||
if (err) {
|
||||
@ -258,9 +260,9 @@ static struct inode *f2fs_new_inode(struct mnt_idmap *idmap,
|
||||
|
||||
if (f2fs_sb_has_project_quota(sbi) &&
|
||||
(F2FS_I(dir)->i_flags & F2FS_PROJINHERIT_FL))
|
||||
F2FS_I(inode)->i_projid = F2FS_I(dir)->i_projid;
|
||||
fi->i_projid = F2FS_I(dir)->i_projid;
|
||||
else
|
||||
F2FS_I(inode)->i_projid = make_kprojid(&init_user_ns,
|
||||
fi->i_projid = make_kprojid(&init_user_ns,
|
||||
F2FS_DEF_PROJID);
|
||||
|
||||
err = fscrypt_prepare_new_inode(dir, inode, &encrypt);
|
||||
@ -278,7 +280,7 @@ static struct inode *f2fs_new_inode(struct mnt_idmap *idmap,
|
||||
|
||||
if (f2fs_sb_has_extra_attr(sbi)) {
|
||||
set_inode_flag(inode, FI_EXTRA_ATTR);
|
||||
F2FS_I(inode)->i_extra_isize = F2FS_TOTAL_EXTRA_ATTR_SIZE;
|
||||
fi->i_extra_isize = F2FS_TOTAL_EXTRA_ATTR_SIZE;
|
||||
}
|
||||
|
||||
if (test_opt(sbi, INLINE_XATTR))
|
||||
@ -296,15 +298,15 @@ static struct inode *f2fs_new_inode(struct mnt_idmap *idmap,
|
||||
f2fs_has_inline_dentry(inode)) {
|
||||
xattr_size = DEFAULT_INLINE_XATTR_ADDRS;
|
||||
}
|
||||
F2FS_I(inode)->i_inline_xattr_size = xattr_size;
|
||||
fi->i_inline_xattr_size = xattr_size;
|
||||
|
||||
F2FS_I(inode)->i_flags =
|
||||
fi->i_flags =
|
||||
f2fs_mask_flags(mode, F2FS_I(dir)->i_flags & F2FS_FL_INHERITED);
|
||||
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
F2FS_I(inode)->i_flags |= F2FS_INDEX_FL;
|
||||
fi->i_flags |= F2FS_INDEX_FL;
|
||||
|
||||
if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL)
|
||||
if (fi->i_flags & F2FS_PROJINHERIT_FL)
|
||||
set_inode_flag(inode, FI_PROJ_INHERIT);
|
||||
|
||||
/* Check compression first. */
|
||||
|
@ -280,6 +280,7 @@ static void recover_inline_flags(struct inode *inode, struct f2fs_inode *ri)
|
||||
static int recover_inode(struct inode *inode, struct page *page)
|
||||
{
|
||||
struct f2fs_inode *raw = F2FS_INODE(page);
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
char *name;
|
||||
int err;
|
||||
|
||||
@ -302,12 +303,12 @@ static int recover_inode(struct inode *inode, struct page *page)
|
||||
i_projid = (projid_t)le32_to_cpu(raw->i_projid);
|
||||
kprojid = make_kprojid(&init_user_ns, i_projid);
|
||||
|
||||
if (!projid_eq(kprojid, F2FS_I(inode)->i_projid)) {
|
||||
if (!projid_eq(kprojid, fi->i_projid)) {
|
||||
err = f2fs_transfer_project_quota(inode,
|
||||
kprojid);
|
||||
if (err)
|
||||
return err;
|
||||
F2FS_I(inode)->i_projid = kprojid;
|
||||
fi->i_projid = kprojid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -320,10 +321,10 @@ static int recover_inode(struct inode *inode, struct page *page)
|
||||
inode_set_mtime(inode, le64_to_cpu(raw->i_mtime),
|
||||
le32_to_cpu(raw->i_mtime_nsec));
|
||||
|
||||
F2FS_I(inode)->i_advise = raw->i_advise;
|
||||
F2FS_I(inode)->i_flags = le32_to_cpu(raw->i_flags);
|
||||
fi->i_advise = raw->i_advise;
|
||||
fi->i_flags = le32_to_cpu(raw->i_flags);
|
||||
f2fs_set_inode_flags(inode);
|
||||
F2FS_I(inode)->i_gc_failures = le16_to_cpu(raw->i_gc_failures);
|
||||
fi->i_gc_failures = le16_to_cpu(raw->i_gc_failures);
|
||||
|
||||
recover_inline_flags(inode, raw);
|
||||
|
||||
|
@ -2784,11 +2784,19 @@ static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type)
|
||||
unsigned short seg_type = curseg->seg_type;
|
||||
|
||||
sanity_check_seg_type(sbi, seg_type);
|
||||
if (f2fs_need_rand_seg(sbi))
|
||||
return get_random_u32_below(MAIN_SECS(sbi) * SEGS_PER_SEC(sbi));
|
||||
if (__is_large_section(sbi)) {
|
||||
if (f2fs_need_rand_seg(sbi)) {
|
||||
unsigned int hint = GET_SEC_FROM_SEG(sbi, curseg->segno);
|
||||
|
||||
if (__is_large_section(sbi))
|
||||
if (GET_SEC_FROM_SEG(sbi, curseg->segno + 1) != hint)
|
||||
return curseg->segno;
|
||||
return get_random_u32_inclusive(curseg->segno + 1,
|
||||
GET_SEG_FROM_SEC(sbi, hint + 1) - 1);
|
||||
}
|
||||
return curseg->segno;
|
||||
} else if (f2fs_need_rand_seg(sbi)) {
|
||||
return get_random_u32_below(MAIN_SECS(sbi) * SEGS_PER_SEC(sbi));
|
||||
}
|
||||
|
||||
/* inmem log may not locate on any segment after mount */
|
||||
if (!curseg->inited)
|
||||
@ -2931,12 +2939,12 @@ static int get_atssr_segment(struct f2fs_sb_info *sbi, int type,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __f2fs_init_atgc_curseg(struct f2fs_sb_info *sbi)
|
||||
static int __f2fs_init_atgc_curseg(struct f2fs_sb_info *sbi, bool force)
|
||||
{
|
||||
struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_ALL_DATA_ATGC);
|
||||
int ret = 0;
|
||||
|
||||
if (!sbi->am.atgc_enabled)
|
||||
if (!sbi->am.atgc_enabled && !force)
|
||||
return 0;
|
||||
|
||||
f2fs_down_read(&SM_I(sbi)->curseg_lock);
|
||||
@ -2953,9 +2961,30 @@ static int __f2fs_init_atgc_curseg(struct f2fs_sb_info *sbi)
|
||||
f2fs_up_read(&SM_I(sbi)->curseg_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi)
|
||||
{
|
||||
return __f2fs_init_atgc_curseg(sbi);
|
||||
return __f2fs_init_atgc_curseg(sbi, false);
|
||||
}
|
||||
|
||||
int f2fs_reinit_atgc_curseg(struct f2fs_sb_info *sbi)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!test_opt(sbi, ATGC))
|
||||
return 0;
|
||||
if (sbi->am.atgc_enabled)
|
||||
return 0;
|
||||
if (le64_to_cpu(F2FS_CKPT(sbi)->elapsed_time) <
|
||||
sbi->am.age_threshold)
|
||||
return 0;
|
||||
|
||||
ret = __f2fs_init_atgc_curseg(sbi, true);
|
||||
if (!ret) {
|
||||
sbi->am.atgc_enabled = true;
|
||||
f2fs_info(sbi, "reenabled age threshold GC");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi, int type)
|
||||
@ -3483,7 +3512,9 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
|
||||
if (page_private_gcing(fio->page)) {
|
||||
if (fio->sbi->am.atgc_enabled &&
|
||||
(fio->io_type == FS_DATA_IO) &&
|
||||
(fio->sbi->gc_mode != GC_URGENT_HIGH))
|
||||
(fio->sbi->gc_mode != GC_URGENT_HIGH) &&
|
||||
__is_valid_data_blkaddr(fio->old_blkaddr) &&
|
||||
!is_inode_flag_set(inode, FI_OPU_WRITE))
|
||||
return CURSEG_ALL_DATA_ATGC;
|
||||
else
|
||||
return CURSEG_COLD_DATA;
|
||||
@ -3828,7 +3859,7 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio)
|
||||
goto drop_bio;
|
||||
}
|
||||
|
||||
if (fio->post_read)
|
||||
if (fio->meta_gc)
|
||||
f2fs_truncate_meta_inode_pages(sbi, fio->new_blkaddr, 1);
|
||||
|
||||
stat_inc_inplace_blocks(fio->sbi);
|
||||
@ -3998,7 +4029,7 @@ void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr)
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
struct page *cpage;
|
||||
|
||||
if (!f2fs_post_read_required(inode))
|
||||
if (!f2fs_meta_inode_gc_required(inode))
|
||||
return;
|
||||
|
||||
if (!__is_valid_data_blkaddr(blkaddr))
|
||||
@ -4017,7 +4048,7 @@ void f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr,
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
block_t i;
|
||||
|
||||
if (!f2fs_post_read_required(inode))
|
||||
if (!f2fs_meta_inode_gc_required(inode))
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
@ -5187,7 +5218,8 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type)
|
||||
}
|
||||
|
||||
/* Allocate a new section if it's not new. */
|
||||
if (cs->next_blkoff) {
|
||||
if (cs->next_blkoff ||
|
||||
cs->segno != GET_SEG_FROM_SEC(sbi, GET_ZONE_FROM_SEC(sbi, cs_section))) {
|
||||
unsigned int old_segno = cs->segno, old_blkoff = cs->next_blkoff;
|
||||
|
||||
f2fs_allocate_new_section(sbi, type, true);
|
||||
|
@ -347,7 +347,8 @@ static inline unsigned int get_ckpt_valid_blocks(struct f2fs_sb_info *sbi,
|
||||
unsigned int segno, bool use_section)
|
||||
{
|
||||
if (use_section && __is_large_section(sbi)) {
|
||||
unsigned int start_segno = START_SEGNO(segno);
|
||||
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
|
||||
unsigned int start_segno = GET_SEG_FROM_SEC(sbi, secno);
|
||||
unsigned int blocks = 0;
|
||||
int i;
|
||||
|
||||
|
@ -151,8 +151,6 @@ enum {
|
||||
Opt_mode,
|
||||
Opt_fault_injection,
|
||||
Opt_fault_type,
|
||||
Opt_lazytime,
|
||||
Opt_nolazytime,
|
||||
Opt_quota,
|
||||
Opt_noquota,
|
||||
Opt_usrquota,
|
||||
@ -229,8 +227,6 @@ static match_table_t f2fs_tokens = {
|
||||
{Opt_mode, "mode=%s"},
|
||||
{Opt_fault_injection, "fault_injection=%u"},
|
||||
{Opt_fault_type, "fault_type=%u"},
|
||||
{Opt_lazytime, "lazytime"},
|
||||
{Opt_nolazytime, "nolazytime"},
|
||||
{Opt_quota, "quota"},
|
||||
{Opt_noquota, "noquota"},
|
||||
{Opt_usrquota, "usrquota"},
|
||||
@ -918,12 +914,6 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
|
||||
f2fs_info(sbi, "fault_type options not supported");
|
||||
break;
|
||||
#endif
|
||||
case Opt_lazytime:
|
||||
sb->s_flags |= SB_LAZYTIME;
|
||||
break;
|
||||
case Opt_nolazytime:
|
||||
sb->s_flags &= ~SB_LAZYTIME;
|
||||
break;
|
||||
#ifdef CONFIG_QUOTA
|
||||
case Opt_quota:
|
||||
case Opt_usrquota:
|
||||
@ -4481,6 +4471,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
sb->s_flags = (sb->s_flags & ~SB_POSIXACL) |
|
||||
(test_opt(sbi, POSIX_ACL) ? SB_POSIXACL : 0);
|
||||
super_set_uuid(sb, (void *) raw_super->uuid, sizeof(raw_super->uuid));
|
||||
super_set_sysfs_name_bdev(sb);
|
||||
sb->s_iflags |= SB_I_CGROUPWB;
|
||||
|
||||
/* init f2fs-specific super block info */
|
||||
|
@ -340,13 +340,13 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
|
||||
if (!strcmp(a->attr.name, "ckpt_thread_ioprio")) {
|
||||
struct ckpt_req_control *cprc = &sbi->cprc_info;
|
||||
int class = IOPRIO_PRIO_CLASS(cprc->ckpt_thread_ioprio);
|
||||
int data = IOPRIO_PRIO_DATA(cprc->ckpt_thread_ioprio);
|
||||
int level = IOPRIO_PRIO_LEVEL(cprc->ckpt_thread_ioprio);
|
||||
|
||||
if (class != IOPRIO_CLASS_RT && class != IOPRIO_CLASS_BE)
|
||||
return -EINVAL;
|
||||
|
||||
return sysfs_emit(buf, "%s,%d\n",
|
||||
class == IOPRIO_CLASS_RT ? "rt" : "be", data);
|
||||
class == IOPRIO_CLASS_RT ? "rt" : "be", level);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_F2FS_FS_COMPRESSION
|
||||
@ -450,7 +450,7 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
|
||||
const char *name = strim((char *)buf);
|
||||
struct ckpt_req_control *cprc = &sbi->cprc_info;
|
||||
int class;
|
||||
long data;
|
||||
long level;
|
||||
int ret;
|
||||
|
||||
if (!strncmp(name, "rt,", 3))
|
||||
@ -461,13 +461,13 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
|
||||
return -EINVAL;
|
||||
|
||||
name += 3;
|
||||
ret = kstrtol(name, 10, &data);
|
||||
ret = kstrtol(name, 10, &level);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (data >= IOPRIO_NR_LEVELS || data < 0)
|
||||
if (level >= IOPRIO_NR_LEVELS || level < 0)
|
||||
return -EINVAL;
|
||||
|
||||
cprc->ckpt_thread_ioprio = IOPRIO_PRIO_VALUE(class, data);
|
||||
cprc->ckpt_thread_ioprio = IOPRIO_PRIO_VALUE(class, level);
|
||||
if (test_opt(sbi, MERGE_CHECKPOINT)) {
|
||||
ret = set_task_ioprio(cprc->f2fs_issue_ckpt,
|
||||
cprc->ckpt_thread_ioprio);
|
||||
|
@ -259,15 +259,14 @@ struct node_footer {
|
||||
#define CUR_ADDRS_PER_INODE(inode) (DEF_ADDRS_PER_INODE - \
|
||||
get_extra_isize(inode))
|
||||
#define DEF_NIDS_PER_INODE 5 /* Node IDs in an Inode */
|
||||
#define ADDRS_PER_INODE(inode) addrs_per_inode(inode)
|
||||
#define ADDRS_PER_INODE(inode) addrs_per_page(inode, true)
|
||||
/* Address Pointers in a Direct Block */
|
||||
#define DEF_ADDRS_PER_BLOCK ((F2FS_BLKSIZE - sizeof(struct node_footer)) / sizeof(__le32))
|
||||
#define ADDRS_PER_BLOCK(inode) addrs_per_block(inode)
|
||||
#define ADDRS_PER_BLOCK(inode) addrs_per_page(inode, false)
|
||||
/* Node IDs in an Indirect Block */
|
||||
#define NIDS_PER_BLOCK ((F2FS_BLKSIZE - sizeof(struct node_footer)) / sizeof(__le32))
|
||||
|
||||
#define ADDRS_PER_PAGE(page, inode) \
|
||||
(IS_INODE(page) ? ADDRS_PER_INODE(inode) : ADDRS_PER_BLOCK(inode))
|
||||
#define ADDRS_PER_PAGE(page, inode) (addrs_per_page(inode, IS_INODE(page)))
|
||||
|
||||
#define NODE_DIR1_BLOCK (DEF_ADDRS_PER_INODE + 1)
|
||||
#define NODE_DIR2_BLOCK (DEF_ADDRS_PER_INODE + 2)
|
||||
|
Loading…
Reference in New Issue
Block a user