aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/f2fs/file.c')
-rw-r--r--fs/f2fs/file.c64
1 files changed, 58 insertions, 6 deletions
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index df6a0596eccf..a6f3f6186588 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -241,6 +241,8 @@ go_write:
241 * will be used only for fsynced inodes after checkpoint. 241 * will be used only for fsynced inodes after checkpoint.
242 */ 242 */
243 try_to_fix_pino(inode); 243 try_to_fix_pino(inode);
244 clear_inode_flag(fi, FI_APPEND_WRITE);
245 clear_inode_flag(fi, FI_UPDATE_WRITE);
244 goto out; 246 goto out;
245 } 247 }
246sync_nodes: 248sync_nodes:
@@ -433,8 +435,12 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count)
433 continue; 435 continue;
434 436
435 dn->data_blkaddr = NULL_ADDR; 437 dn->data_blkaddr = NULL_ADDR;
436 update_extent_cache(dn); 438 set_data_blkaddr(dn);
439 f2fs_update_extent_cache(dn);
437 invalidate_blocks(sbi, blkaddr); 440 invalidate_blocks(sbi, blkaddr);
441 if (dn->ofs_in_node == 0 && IS_INODE(dn->node_page))
442 clear_inode_flag(F2FS_I(dn->inode),
443 FI_FIRST_BLOCK_WRITTEN);
438 nr_free++; 444 nr_free++;
439 } 445 }
440 if (nr_free) { 446 if (nr_free) {
@@ -454,15 +460,16 @@ void truncate_data_blocks(struct dnode_of_data *dn)
454 truncate_data_blocks_range(dn, ADDRS_PER_BLOCK); 460 truncate_data_blocks_range(dn, ADDRS_PER_BLOCK);
455} 461}
456 462
457static int truncate_partial_data_page(struct inode *inode, u64 from) 463static int truncate_partial_data_page(struct inode *inode, u64 from,
464 bool force)
458{ 465{
459 unsigned offset = from & (PAGE_CACHE_SIZE - 1); 466 unsigned offset = from & (PAGE_CACHE_SIZE - 1);
460 struct page *page; 467 struct page *page;
461 468
462 if (!offset) 469 if (!offset && !force)
463 return 0; 470 return 0;
464 471
465 page = find_data_page(inode, from >> PAGE_CACHE_SHIFT, false); 472 page = find_data_page(inode, from >> PAGE_CACHE_SHIFT, force);
466 if (IS_ERR(page)) 473 if (IS_ERR(page))
467 return 0; 474 return 0;
468 475
@@ -473,7 +480,8 @@ static int truncate_partial_data_page(struct inode *inode, u64 from)
473 480
474 f2fs_wait_on_page_writeback(page, DATA); 481 f2fs_wait_on_page_writeback(page, DATA);
475 zero_user(page, offset, PAGE_CACHE_SIZE - offset); 482 zero_user(page, offset, PAGE_CACHE_SIZE - offset);
476 set_page_dirty(page); 483 if (!force)
484 set_page_dirty(page);
477out: 485out:
478 f2fs_put_page(page, 1); 486 f2fs_put_page(page, 1);
479 return 0; 487 return 0;
@@ -487,6 +495,7 @@ int truncate_blocks(struct inode *inode, u64 from, bool lock)
487 pgoff_t free_from; 495 pgoff_t free_from;
488 int count = 0, err = 0; 496 int count = 0, err = 0;
489 struct page *ipage; 497 struct page *ipage;
498 bool truncate_page = false;
490 499
491 trace_f2fs_truncate_blocks_enter(inode, from); 500 trace_f2fs_truncate_blocks_enter(inode, from);
492 501
@@ -502,7 +511,10 @@ int truncate_blocks(struct inode *inode, u64 from, bool lock)
502 } 511 }
503 512
504 if (f2fs_has_inline_data(inode)) { 513 if (f2fs_has_inline_data(inode)) {
514 if (truncate_inline_inode(ipage, from))
515 set_page_dirty(ipage);
505 f2fs_put_page(ipage, 1); 516 f2fs_put_page(ipage, 1);
517 truncate_page = true;
506 goto out; 518 goto out;
507 } 519 }
508 520
@@ -533,7 +545,7 @@ out:
533 545
534 /* lastly zero out the first data page */ 546 /* lastly zero out the first data page */
535 if (!err) 547 if (!err)
536 err = truncate_partial_data_page(inode, from); 548 err = truncate_partial_data_page(inode, from, truncate_page);
537 549
538 trace_f2fs_truncate_blocks_exit(inode, err); 550 trace_f2fs_truncate_blocks_exit(inode, err);
539 return err; 551 return err;
@@ -997,6 +1009,9 @@ static int f2fs_ioc_release_volatile_write(struct file *filp)
997 if (!f2fs_is_volatile_file(inode)) 1009 if (!f2fs_is_volatile_file(inode))
998 return 0; 1010 return 0;
999 1011
1012 if (!f2fs_is_first_block_written(inode))
1013 return truncate_partial_data_page(inode, 0, true);
1014
1000 punch_hole(inode, 0, F2FS_BLKSIZE); 1015 punch_hole(inode, 0, F2FS_BLKSIZE);
1001 return 0; 1016 return 0;
1002} 1017}
@@ -1029,6 +1044,41 @@ static int f2fs_ioc_abort_volatile_write(struct file *filp)
1029 return ret; 1044 return ret;
1030} 1045}
1031 1046
1047static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
1048{
1049 struct inode *inode = file_inode(filp);
1050 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
1051 struct super_block *sb = sbi->sb;
1052 __u32 in;
1053
1054 if (!capable(CAP_SYS_ADMIN))
1055 return -EPERM;
1056
1057 if (get_user(in, (__u32 __user *)arg))
1058 return -EFAULT;
1059
1060 switch (in) {
1061 case F2FS_GOING_DOWN_FULLSYNC:
1062 sb = freeze_bdev(sb->s_bdev);
1063 if (sb && !IS_ERR(sb)) {
1064 f2fs_stop_checkpoint(sbi);
1065 thaw_bdev(sb->s_bdev, sb);
1066 }
1067 break;
1068 case F2FS_GOING_DOWN_METASYNC:
1069 /* do checkpoint only */
1070 f2fs_sync_fs(sb, 1);
1071 f2fs_stop_checkpoint(sbi);
1072 break;
1073 case F2FS_GOING_DOWN_NOSYNC:
1074 f2fs_stop_checkpoint(sbi);
1075 break;
1076 default:
1077 return -EINVAL;
1078 }
1079 return 0;
1080}
1081
1032static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg) 1082static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg)
1033{ 1083{
1034 struct inode *inode = file_inode(filp); 1084 struct inode *inode = file_inode(filp);
@@ -1078,6 +1128,8 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1078 return f2fs_ioc_release_volatile_write(filp); 1128 return f2fs_ioc_release_volatile_write(filp);
1079 case F2FS_IOC_ABORT_VOLATILE_WRITE: 1129 case F2FS_IOC_ABORT_VOLATILE_WRITE:
1080 return f2fs_ioc_abort_volatile_write(filp); 1130 return f2fs_ioc_abort_volatile_write(filp);
1131 case F2FS_IOC_SHUTDOWN:
1132 return f2fs_ioc_shutdown(filp, arg);
1081 case FITRIM: 1133 case FITRIM:
1082 return f2fs_ioc_fitrim(filp, arg); 1134 return f2fs_ioc_fitrim(filp, arg);
1083 default: 1135 default: