Skip to content

Commit

Permalink
Merge tag 'f2fs-for-6.8-rc1' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/jaegeuk/f2fs

Pull f2fs update from Jaegeuk Kim:
 "In this series, we've some progress to support Zoned block device
  regarding to the power-cut recovery flow and enabling
  checkpoint=disable feature which is essential for Android OTA.

  Other than that, some patches touched sysfs entries and tracepoints
  which are minor, while several bug fixes on error handlers and
  compression flows are good to improve the overall stability.

  Enhancements:
   - enable checkpoint=disable for zoned block device
   - sysfs entries such as discard status, discard_io_aware, dir_level
   - tracepoints such as f2fs_vm_page_mkwrite(), f2fs_rename(),
     f2fs_new_inode()
   - use shared inode lock during f2fs_fiemap() and f2fs_seek_block()

  Bug fixes:
   - address some power-cut recovery issues on zoned block device
   - handle errors and logics on do_garbage_collect(),
     f2fs_reserve_new_block(), f2fs_move_file_range(),
     f2fs_recover_xattr_data()
   - don't set FI_PREALLOCATED_ALL for partial write
   - fix to update iostat correctly in f2fs_filemap_fault()
   - fix to wait on block writeback for post_read case
   - fix to tag gcing flag on page during block migration
   - restrict max filesize for 16K f2fs
   - fix to avoid dirent corruption
   - explicitly null-terminate the xattr list

  There are also several clean-up patches to remove dead codes and
  better readability"

* tag 'f2fs-for-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (33 commits)
  f2fs: show more discard status by sysfs
  f2fs: Add error handling for negative returns from do_garbage_collect
  f2fs: Constrain the modification range of dir_level in the sysfs
  f2fs: Use wait_event_freezable_timeout() for freezable kthread
  f2fs: fix to check return value of f2fs_recover_xattr_data
  f2fs: don't set FI_PREALLOCATED_ALL for partial write
  f2fs: fix to update iostat correctly in f2fs_filemap_fault()
  f2fs: fix to check compress file in f2fs_move_file_range()
  f2fs: fix to wait on block writeback for post_read case
  f2fs: fix to tag gcing flag on page during block migration
  f2fs: add tracepoint for f2fs_vm_page_mkwrite()
  f2fs: introduce f2fs_invalidate_internal_cache() for cleanup
  f2fs: update blkaddr in __set_data_blkaddr() for cleanup
  f2fs: introduce get_dnode_addr() to clean up codes
  f2fs: delete obsolete FI_DROP_CACHE
  f2fs: delete obsolete FI_FIRST_BLOCK_WRITTEN
  f2fs: Restrict max filesize for 16K f2fs
  f2fs: let's finish or reset zones all the time
  f2fs: check write pointers when checkpoint=disable
  f2fs: fix write pointers on zoned device after roll forward
  ...
  • Loading branch information
torvalds committed Jan 12, 2024
2 parents 6a31658 + c3c2d45 commit 70d201a
Show file tree
Hide file tree
Showing 16 changed files with 395 additions and 269 deletions.
21 changes: 21 additions & 0 deletions Documentation/ABI/testing/sysfs-fs-f2fs
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,21 @@ Description: Show status of f2fs checkpoint in real time.
CP_RESIZEFS_FLAG 0x00004000
=============================== ==============================

What: /sys/fs/f2fs/<disk>/stat/issued_discard
Date: December 2023
Contact: "Zhiguo Niu" <[email protected]>
Description: Shows the number of issued discard.

What: /sys/fs/f2fs/<disk>/stat/queued_discard
Date: December 2023
Contact: "Zhiguo Niu" <[email protected]>
Description: Shows the number of queued discard.

What: /sys/fs/f2fs/<disk>/stat/undiscard_blks
Date: December 2023
Contact: "Zhiguo Niu" <[email protected]>
Description: Shows the total number of undiscard blocks.

What: /sys/fs/f2fs/<disk>/ckpt_thread_ioprio
Date: January 2021
Contact: "Daeho Jeong" <[email protected]>
Expand Down Expand Up @@ -740,3 +755,9 @@ Description: When compress cache is on, it controls cached page
If cached page percent exceed threshold, then deny caching compress page.
The value should be in range of (0, 100], by default it was initialized
as 20(%).

What: /sys/fs/f2fs/<disk>/discard_io_aware
Date: November 2023
Contact: "Chao Yu" <[email protected]>
Description: It controls to enable/disable IO aware feature for background discard.
By default, the value is 1 which indicates IO aware is on.
6 changes: 3 additions & 3 deletions fs/f2fs/compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -1036,8 +1036,10 @@ static void set_cluster_dirty(struct compress_ctx *cc)
int i;

for (i = 0; i < cc->cluster_size; i++)
if (cc->rpages[i])
if (cc->rpages[i]) {
set_page_dirty(cc->rpages[i]);
set_page_private_gcing(cc->rpages[i]);
}
}

static int prepare_compress_overwrite(struct compress_ctx *cc,
Expand Down Expand Up @@ -1369,8 +1371,6 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
add_compr_block_stat(inode, cc->valid_nr_cpages);

set_inode_flag(cc->inode, FI_APPEND_WRITE);
if (cc->cluster_idx == 0)
set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);

f2fs_put_dnode(&dn);
if (quota_inode)
Expand Down
48 changes: 17 additions & 31 deletions fs/f2fs/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -1179,18 +1179,12 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,
return 0;
}

static void __set_data_blkaddr(struct dnode_of_data *dn)
static void __set_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr)
{
struct f2fs_node *rn = F2FS_NODE(dn->node_page);
__le32 *addr_array;
int base = 0;
__le32 *addr = get_dnode_addr(dn->inode, dn->node_page);

if (IS_INODE(dn->node_page) && f2fs_has_extra_attr(dn->inode))
base = get_extra_isize(dn->inode);

/* Get physical address of data block */
addr_array = blkaddr_in_node(rn);
addr_array[base + dn->ofs_in_node] = cpu_to_le32(dn->data_blkaddr);
dn->data_blkaddr = blkaddr;
addr[dn->ofs_in_node] = cpu_to_le32(dn->data_blkaddr);
}

/*
Expand All @@ -1199,18 +1193,17 @@ static void __set_data_blkaddr(struct dnode_of_data *dn)
* ->node_page
* update block addresses in the node page
*/
void f2fs_set_data_blkaddr(struct dnode_of_data *dn)
void f2fs_set_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr)
{
f2fs_wait_on_page_writeback(dn->node_page, NODE, true, true);
__set_data_blkaddr(dn);
__set_data_blkaddr(dn, blkaddr);
if (set_page_dirty(dn->node_page))
dn->node_changed = true;
}

void f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr)
{
dn->data_blkaddr = blkaddr;
f2fs_set_data_blkaddr(dn);
f2fs_set_data_blkaddr(dn, blkaddr);
f2fs_update_read_extent_cache(dn);
}

Expand All @@ -1237,8 +1230,7 @@ int f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count)
block_t blkaddr = f2fs_data_blkaddr(dn);

if (blkaddr == NULL_ADDR) {
dn->data_blkaddr = NEW_ADDR;
__set_data_blkaddr(dn);
__set_data_blkaddr(dn, NEW_ADDR);
count--;
}
}
Expand Down Expand Up @@ -1492,11 +1484,9 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
old_blkaddr = dn->data_blkaddr;
f2fs_allocate_data_block(sbi, NULL, old_blkaddr, &dn->data_blkaddr,
&sum, seg_type, NULL);
if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) {
invalidate_mapping_pages(META_MAPPING(sbi),
old_blkaddr, old_blkaddr);
f2fs_invalidate_compress_page(sbi, old_blkaddr);
}
if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
f2fs_invalidate_internal_cache(sbi, old_blkaddr);

f2fs_update_data_blkaddr(dn, dn->data_blkaddr);
return 0;
}
Expand Down Expand Up @@ -1992,7 +1982,7 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
if (ret)
return ret;

inode_lock(inode);
inode_lock_shared(inode);

maxbytes = max_file_blocks(inode) << F2FS_BLKSIZE_BITS;
if (start > maxbytes) {
Expand Down Expand Up @@ -2112,7 +2102,7 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
if (ret == 1)
ret = 0;

inode_unlock(inode);
inode_unlock_shared(inode);
return ret;
}

Expand Down Expand Up @@ -2566,9 +2556,6 @@ int f2fs_encrypt_one_page(struct f2fs_io_info *fio)

page = fio->compressed_page ? fio->compressed_page : fio->page;

/* wait for GCed page writeback via META_MAPPING */
f2fs_wait_on_block_writeback(inode, fio->old_blkaddr);

if (fscrypt_inode_uses_inline_crypto(inode))
return 0;

Expand Down Expand Up @@ -2755,6 +2742,10 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
goto out_writepage;
}

/* wait for GCed page writeback via META_MAPPING */
if (fio->post_read)
f2fs_wait_on_block_writeback(inode, fio->old_blkaddr);

/*
* If current allocation needs SSR,
* it had better in-place writes for updated data.
Expand Down Expand Up @@ -2810,8 +2801,6 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
f2fs_outplace_write_data(&dn, fio);
trace_f2fs_do_write_data_page(page, OPU);
set_inode_flag(inode, FI_APPEND_WRITE);
if (page->index == 0)
set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);
out_writepage:
f2fs_put_dnode(&dn);
out:
Expand Down Expand Up @@ -2894,9 +2883,6 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,

zero_user_segment(page, offset, PAGE_SIZE);
write:
if (f2fs_is_drop_cache(inode))
goto out;

/* Dentry/quota blocks are controlled by checkpoint */
if (S_ISDIR(inode->i_mode) || quota_inode) {
/*
Expand Down
46 changes: 30 additions & 16 deletions fs/f2fs/f2fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,12 @@ enum {
MAX_DPOLICY,
};

enum {
DPOLICY_IO_AWARE_DISABLE, /* force to not be aware of IO */
DPOLICY_IO_AWARE_ENABLE, /* force to be aware of IO */
DPOLICY_IO_AWARE_MAX,
};

struct discard_policy {
int type; /* type of discard */
unsigned int min_interval; /* used for candidates exist */
Expand Down Expand Up @@ -406,6 +412,7 @@ struct discard_cmd_control {
unsigned int discard_urgent_util; /* utilization which issue discard proactively */
unsigned int discard_granularity; /* discard granularity */
unsigned int max_ordered_discard; /* maximum discard granularity issued by lba order */
unsigned int discard_io_aware; /* io_aware policy */
unsigned int undiscard_blks; /* # of undiscard blocks */
unsigned int next_pos; /* next discard position */
atomic_t issued_discard; /* # of issued discard */
Expand Down Expand Up @@ -774,8 +781,6 @@ enum {
FI_UPDATE_WRITE, /* inode has in-place-update data */
FI_NEED_IPU, /* used for ipu per file */
FI_ATOMIC_FILE, /* indicate atomic file */
FI_FIRST_BLOCK_WRITTEN, /* indicate #0 data block was written */
FI_DROP_CACHE, /* drop dirty page cache */
FI_DATA_EXIST, /* indicate data exists */
FI_INLINE_DOTS, /* indicate inline dot dentries */
FI_SKIP_WRITES, /* should skip data page writeback */
Expand Down Expand Up @@ -3272,22 +3277,13 @@ static inline bool f2fs_is_cow_file(struct inode *inode)
return is_inode_flag_set(inode, FI_COW_FILE);
}

static inline bool f2fs_is_first_block_written(struct inode *inode)
{
return is_inode_flag_set(inode, FI_FIRST_BLOCK_WRITTEN);
}

static inline bool f2fs_is_drop_cache(struct inode *inode)
{
return is_inode_flag_set(inode, FI_DROP_CACHE);
}

static inline __le32 *get_dnode_addr(struct inode *inode,
struct page *node_page);
static inline void *inline_data_addr(struct inode *inode, struct page *page)
{
struct f2fs_inode *ri = F2FS_INODE(page);
int extra_size = get_extra_isize(inode);
__le32 *addr = get_dnode_addr(inode, page);

return (void *)&(ri->i_addr[extra_size + DEF_INLINE_RESERVED_SIZE]);
return (void *)(addr + DEF_INLINE_RESERVED_SIZE);
}

static inline int f2fs_has_inline_dentry(struct inode *inode)
Expand Down Expand Up @@ -3432,6 +3428,17 @@ static inline int get_inline_xattr_addrs(struct inode *inode)
return F2FS_I(inode)->i_inline_xattr_size;
}

static inline __le32 *get_dnode_addr(struct inode *inode,
struct page *node_page)
{
int base = 0;

if (IS_INODE(node_page) && f2fs_has_extra_attr(inode))
base = get_extra_isize(inode);

return blkaddr_in_node(F2FS_NODE(node_page)) + base;
}

#define f2fs_get_inode_mode(i) \
((is_inode_flag_set(i, FI_ACL_MODE)) ? \
(F2FS_I(i)->i_acl_mode) : ((i)->i_mode))
Expand Down Expand Up @@ -3815,7 +3822,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio);
struct block_device *f2fs_target_device(struct f2fs_sb_info *sbi,
block_t blk_addr, sector_t *sector);
int f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr);
void f2fs_set_data_blkaddr(struct dnode_of_data *dn);
void f2fs_set_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr);
void f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr);
int f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count);
int f2fs_reserve_new_block(struct dnode_of_data *dn);
Expand Down Expand Up @@ -4606,6 +4613,13 @@ static inline bool f2fs_is_readonly(struct f2fs_sb_info *sbi)
return f2fs_sb_has_readonly(sbi) || f2fs_readonly(sbi->sb);
}

static inline void f2fs_invalidate_internal_cache(struct f2fs_sb_info *sbi,
block_t blkaddr)
{
invalidate_mapping_pages(META_MAPPING(sbi), blkaddr, blkaddr);
f2fs_invalidate_compress_page(sbi, blkaddr);
}

#define EFSBADCRC EBADMSG /* Bad CRC detected */
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */

Expand Down
Loading

0 comments on commit 70d201a

Please sign in to comment.