f2fs: readahead encrypted block during GC
Chao Yu
maintainerPATCH 1/1 f2fs: readahead encrypted block during GC
From: Chao Yu <[email protected]>
During GC, for each encrypted block, we will read block synchronously into meta page, and then submit it into current cold data log area.
So this block read model with 4k granularity can make poor performance, like migrating non-encrypted block, let's readahead encrypted block as well to improve migration performance.
To implement this, we choose meta page that its index is old block address of the encrypted block, and readahead ciphertext into this page, later, if readaheaded page is still updated, we will load its data into target meta page, and submit the write IO.
Note that for OPU, truncation, deletion, we need to invalid meta page after we invalid old block address, to make sure we won't load invalid data from target meta page during encrypted block migration.
for ((i = 0; i < 1000; i++))
do {
xfs_io -f /mnt/f2fs/dir/$i -c "pwrite 0 128k" -c "fsync";
} donefor ((i = 0; i < 1000; i+=2))
do {
rm /mnt/f2fs/dir/$i;
} doneret = ioctl(fd, F2FS_IOC_GARBAGE_COLLECT, 0);
Before:
gc-6549 [001] d..1 214682.212797: block_rq_insert: 8,32 RA 32768 () 786400 + 64 [gc]
gc-6549 [001] d..1 214682.212802: block_unplug: [gc] 1
gc-6549 [001] .... 214682.213892: block_bio_queue: 8,32 R 67494144 + 8 [gc]
gc-6549 [001] .... 214682.213899: block_getrq: 8,32 R 67494144 + 8 [gc]
gc-6549 [001] .... 214682.213902: block_plug: [gc]
gc-6549 [001] d..1 214682.213905: block_rq_insert: 8,32 R 4096 () 67494144 + 8 [gc]
gc-6549 [001] d..1 214682.213908: block_unplug: [gc] 1
gc-6549 [001] .... 214682.226405: block_bio_queue: 8,32 R 67494152 + 8 [gc]
gc-6549 [001] .... 214682.226412: block_getrq: 8,32 R 67494152 + 8 [gc]
gc-6549 [001] .... 214682.226414: block_plug: [gc]
gc-6549 [001] d..1 214682.226417: block_rq_insert: 8,32 R 4096 () 67494152 + 8 [gc]
gc-6549 [001] d..1 214682.226420: block_unplug: [gc] 1
gc-6549 [001] .... 214682.226904: block_bio_queue: 8,32 R 67494160 + 8 [gc]
gc-6549 [001] .... 214682.226910: block_getrq: 8,32 R 67494160 + 8 [gc]
gc-6549 [001] .... 214682.226911: block_plug: [gc]
gc-6549 [001] d..1 214682.226914: block_rq_insert: 8,32 R 4096 () 67494160 + 8 [gc]
gc-6549 [001] d..1 214682.226916: block_unplug: [gc] 1After:
gc-5678 [003] .... 214327.025906: block_bio_queue: 8,32 R 67493824 + 8 [gc]
gc-5678 [003] .... 214327.025908: block_bio_backmerge: 8,32 R 67493824 + 8 [gc]
gc-5678 [003] .... 214327.025915: block_bio_queue: 8,32 R 67493832 + 8 [gc]
gc-5678 [003] .... 214327.025917: block_bio_backmerge: 8,32 R 67493832 + 8 [gc]
gc-5678 [003] .... 214327.025923: block_bio_queue: 8,32 R 67493840 + 8 [gc]
gc-5678 [003] .... 214327.025925: block_bio_backmerge: 8,32 R 67493840 + 8 [gc]
gc-5678 [003] .... 214327.025932: block_bio_queue: 8,32 R 67493848 + 8 [gc]
gc-5678 [003] .... 214327.025934: block_bio_backmerge: 8,32 R 67493848 + 8 [gc]
gc-5678 [003] .... 214327.025941: block_bio_queue: 8,32 R 67493856 + 8 [gc]
gc-5678 [003] .... 214327.025943: block_bio_backmerge: 8,32 R 67493856 + 8 [gc]
gc-5678 [003] .... 214327.025953: block_bio_queue: 8,32 R 67493864 + 8 [gc]
gc-5678 [003] .... 214327.025955: block_bio_backmerge: 8,32 R 67493864 + 8 [gc]
gc-5678 [003] .... 214327.025962: block_bio_queue: 8,32 R 67493872 + 8 [gc]
gc-5678 [003] .... 214327.025964: block_bio_backmerge: 8,32 R 67493872 + 8 [gc]
gc-5678 [003] .... 214327.025970: block_bio_queue: 8,32 R 67493880 + 8 [gc]
gc-5678 [003] .... 214327.025972: block_bio_backmerge: 8,32 R 67493880 + 8 [gc]
gc-5678 [003] .... 214327.026000: block_bio_queue: 8,32 WS 34123776 + 2048 [gc]
gc-5678 [003] .... 214327.026019: block_getrq: 8,32 WS 34123776 + 2048 [gc]
gc-5678 [003] d..1 214327.026021: block_rq_insert: 8,32 R 131072 () 67493632 + 256 [gc]
gc-5678 [003] d..1 214327.026023: block_unplug: [gc] 1
gc-5678 [003] d..1 214327.026026: block_rq_issue: 8,32 R 131072 () 67493632 + 256 [gc]
gc-5678 [003] .... 214327.026046: block_plug: [gc]--- fs/f2fs/data.c | 35 ++++++++++----- fs/f2fs/gc.c | 111 +++++++++++++++++++++++++++++++++++++++++----- fs/f2fs/segment.c | 10 ++++- 3 files changed, 134 insertions(+), 22 deletions(-)
fs/f2fs/data.c +24 -11
@@ -877,6 +877,7 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)struct f2fs_sb_info *sbi =F2FS_I_SB (dn->inode);struct f2fs_summary sum;struct node_info ni; +block_t old_blkaddr;pgoff_t fofs;blkcnt_t count =1 ;int err;
@@ -898,9 +899,12 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type) alloc:set_summary (&sum, dn->nid, dn->ofs_in_node, ni.version); - -f2fs_allocate_data_block (sbi,NULL , dn->data_blkaddr, &dn->data_blkaddr, + old_blkaddr = dn->data_blkaddr; +f2fs_allocate_data_block (sbi,NULL , old_blkaddr, &dn->data_blkaddr, &sum, seg_type,NULL , false); +if (GET_SEGNO (sbi, old_blkaddr) !=NULL_SEGNO ) +invalidate_mapping_pages (META_MAPPING (sbi), + old_blkaddr, old_blkaddr);f2fs_set_data_blkaddr (dn);/* update i_size */
@@ -1616,6 +1620,7 @@ static int f2fs_read_data_pages(struct file *file,static int encrypt_one_page (struct f2fs_io_info *fio) {struct inode *inode = fio->page->mapping->host; +struct page *mpage;gfp_t gfp_flags =GFP_NOFS ;if (!f2fs_encrypted_file (inode))
@@ -1627,17 +1632,25 @@ static int encrypt_one_page(struct f2fs_io_info *fio) retry_encrypt: fio->encrypted_page =fscrypt_encrypt_page (inode, fio->page,PAGE_SIZE ,0 , fio->page->index, gfp_flags); -if (!IS_ERR (fio->encrypted_page)) -return 0 ; +if (IS_ERR (fio->encrypted_page)) { +/* flush pending IOs and wait for a while in the ENOMEM case */ +if (PTR_ERR (fio->encrypted_page) == -ENOMEM ) { +f2fs_flush_merged_writes (fio->sbi); +congestion_wait (BLK_RW_ASYNC ,HZ /50 ); + gfp_flags |= __GFP_NOFAIL; + goto retry_encrypt; + } +return PTR_ERR (fio->encrypted_page); + } -/* flush pending IOs and wait for a while in the ENOMEM case */ -if (PTR_ERR (fio->encrypted_page) == -ENOMEM ) { -f2fs_flush_merged_writes (fio->sbi); -congestion_wait (BLK_RW_ASYNC ,HZ /50 ); - gfp_flags |= __GFP_NOFAIL; - goto retry_encrypt; + mpage =find_lock_page (META_MAPPING (fio->sbi), fio->old_blkaddr); +if (mpage) { +if (PageUptodate (mpage)) +memcpy (page_address (mpage), +page_address (fio->encrypted_page),PAGE_SIZE ); +f2fs_put_page (mpage,1 ); } -return PTR_ERR (fio->encrypted_page); +return 0 ; } static inline bool check_inplace_update_policy(struct inode *inode,
fs/f2fs/gc.c +101 -10
148 lines not on this page · raw message
fs/f2fs/segment.c +9 -1
@@ -2152,6 +2152,8 @@ void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr)if (addr ==NEW_ADDR )return ; +invalidate_mapping_pages (META_MAPPING (sbi), addr, addr); +/* add it into sit main buffer */ down_write (&sit_i->sentry_lock);
@@ -3053,6 +3055,9 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio) reallocate:f2fs_allocate_data_block (fio->sbi, fio->page, fio->old_blkaddr, &fio->new_blkaddr, sum, type, fio, true); +if (GET_SEGNO (fio->sbi, fio->old_blkaddr) !=NULL_SEGNO ) +invalidate_mapping_pages (META_MAPPING (fio->sbi), + fio->old_blkaddr, fio->old_blkaddr);/* writeout dirty page into bdev */ f2fs_submit_page_write (fio);
@@ -3207,8 +3212,11 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,if (!recover_curseg || recover_newaddr)update_sit_entry (sbi, new_blkaddr,1 ); -if (GET_SEGNO (sbi, old_blkaddr) !=NULL_SEGNO ) +if (GET_SEGNO (sbi, old_blkaddr) !=NULL_SEGNO ) { +invalidate_mapping_pages (META_MAPPING (sbi), + old_blkaddr, old_blkaddr);update_sit_entry (sbi, old_blkaddr,-1 ); + }locate_dirty_segment (sbi,GET_SEGNO (sbi, old_blkaddr));locate_dirty_segment (sbi,GET_SEGNO (sbi, new_blkaddr));
Signature · 1 line
2.18.0