diff options
| -rw-r--r-- | fs/f2fs/data.c | 20 | ||||
| -rw-r--r-- | fs/f2fs/f2fs.h | 1 | ||||
| -rw-r--r-- | fs/f2fs/file.c | 5 | ||||
| -rw-r--r-- | fs/f2fs/gc.c | 12 | ||||
| -rw-r--r-- | fs/f2fs/segment.c | 17 | 
5 files changed, 44 insertions, 11 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 228537657723..77dfc9eee380 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -956,21 +956,14 @@ submit_and_realloc:  			if (f2fs_encrypted_inode(inode) &&  					S_ISREG(inode->i_mode)) { -				struct page *cpage;  				ctx = f2fs_get_crypto_ctx(inode);  				if (IS_ERR(ctx))  					goto set_error_page;  				/* wait the page to be moved by cleaning */ -				cpage = find_lock_page( -						META_MAPPING(F2FS_I_SB(inode)), -						block_nr); -				if (cpage) { -					f2fs_wait_on_page_writeback(cpage, -									DATA); -					f2fs_put_page(cpage, 1); -				} +				f2fs_wait_on_encrypted_page_writeback( +						F2FS_I_SB(inode), block_nr);  			}  			bio = bio_alloc(GFP_KERNEL, @@ -1064,6 +1057,11 @@ int do_write_data_page(struct f2fs_io_info *fio)  	}  	if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) { + +		/* wait for GCed encrypted page writeback */ +		f2fs_wait_on_encrypted_page_writeback(F2FS_I_SB(inode), +							fio->blk_addr); +  		fio->encrypted_page = f2fs_encrypt(inode, fio->page);  		if (IS_ERR(fio->encrypted_page)) {  			err = PTR_ERR(fio->encrypted_page); @@ -1452,6 +1450,10 @@ put_next:  	f2fs_wait_on_page_writeback(page, DATA); +	/* wait for GCed encrypted page writeback */ +	if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) +		f2fs_wait_on_encrypted_page_writeback(sbi, dn.data_blkaddr); +  	if (len == PAGE_CACHE_SIZE)  		goto out_update;  	if (PageUptodate(page)) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 94cf6bc1303f..c3443da2f991 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1792,6 +1792,7 @@ void f2fs_replace_block(struct f2fs_sb_info *, struct dnode_of_data *,  void allocate_data_block(struct f2fs_sb_info *, struct page *,  		block_t, block_t *, struct f2fs_summary *, int);  void f2fs_wait_on_page_writeback(struct page *, enum page_type); +void f2fs_wait_on_encrypted_page_writeback(struct f2fs_sb_info *, block_t);  void write_data_summaries(struct f2fs_sb_info *, block_t);  void write_node_summaries(struct f2fs_sb_info *, block_t);  int lookup_journal_in_cursum(struct f2fs_summary_block *, diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 5d2a2ee35742..91c51a6d42dd 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -87,6 +87,11 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,  mapped:  	/* fill the page */  	f2fs_wait_on_page_writeback(page, DATA); + +	/* wait for GCed encrypted page writeback */ +	if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) +		f2fs_wait_on_encrypted_page_writeback(sbi, dn.data_blkaddr); +  	/* if gced page is attached, don't write to cold segment */  	clear_cold_data(page);  out: diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 3f19634e2aa5..af7c24caeef9 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -559,8 +559,16 @@ static void move_encrypted_block(struct inode *inode, block_t bidx)  	if (err)  		goto out; -	if (unlikely(dn.data_blkaddr == NULL_ADDR)) +	if (unlikely(dn.data_blkaddr == NULL_ADDR)) { +		ClearPageUptodate(page);  		goto put_out; +	} + +	/* +	 * don't cache encrypted data into meta inode until previous dirty +	 * data were writebacked to avoid racing between GC and flush. +	 */ +	f2fs_wait_on_page_writeback(page, DATA);  	get_node_info(fio.sbi, dn.nid, &ni);  	set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version); @@ -589,7 +597,7 @@ static void move_encrypted_block(struct inode *inode, block_t bidx)  		goto put_page_out;  	set_page_dirty(fio.encrypted_page); -	f2fs_wait_on_page_writeback(fio.encrypted_page, META); +	f2fs_wait_on_page_writeback(fio.encrypted_page, DATA);  	if (clear_page_dirty_for_io(fio.encrypted_page))  		dec_page_count(fio.sbi, F2FS_DIRTY_META); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 5337fd6fdc32..f37c21233b5c 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1484,6 +1484,23 @@ void f2fs_wait_on_page_writeback(struct page *page,  	}  } +void f2fs_wait_on_encrypted_page_writeback(struct f2fs_sb_info *sbi, +							block_t blkaddr) +{ +	struct page *cpage; + +	if (blkaddr == NEW_ADDR) +		return; + +	f2fs_bug_on(sbi, blkaddr == NULL_ADDR); + +	cpage = find_lock_page(META_MAPPING(sbi), blkaddr); +	if (cpage) { +		f2fs_wait_on_page_writeback(cpage, DATA); +		f2fs_put_page(cpage, 1); +	} +} +  static int read_compacted_summaries(struct f2fs_sb_info *sbi)  {  	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);  | 
