diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/f2fs/data.c | 23 | ||||
-rw-r--r-- | fs/f2fs/dir.c | 2 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 6 | ||||
-rw-r--r-- | fs/f2fs/file.c | 12 | ||||
-rw-r--r-- | fs/f2fs/inode.c | 1 | ||||
-rw-r--r-- | fs/f2fs/namei.c | 13 | ||||
-rw-r--r-- | fs/f2fs/node.c | 2 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 5 | ||||
-rw-r--r-- | fs/f2fs/super.c | 4 |
9 files changed, 41 insertions, 27 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 0924521306b4..f8cf619edb5f 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -608,8 +608,8 @@ static int __allocate_data_block(struct dnode_of_data *dn) | |||
608 | * b. do not use extent cache for better performance | 608 | * b. do not use extent cache for better performance |
609 | * c. give the block addresses to blockdev | 609 | * c. give the block addresses to blockdev |
610 | */ | 610 | */ |
611 | static int get_data_block(struct inode *inode, sector_t iblock, | 611 | static int __get_data_block(struct inode *inode, sector_t iblock, |
612 | struct buffer_head *bh_result, int create) | 612 | struct buffer_head *bh_result, int create, bool fiemap) |
613 | { | 613 | { |
614 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); | 614 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); |
615 | unsigned int blkbits = inode->i_sb->s_blocksize_bits; | 615 | unsigned int blkbits = inode->i_sb->s_blocksize_bits; |
@@ -637,7 +637,7 @@ static int get_data_block(struct inode *inode, sector_t iblock, | |||
637 | err = 0; | 637 | err = 0; |
638 | goto unlock_out; | 638 | goto unlock_out; |
639 | } | 639 | } |
640 | if (dn.data_blkaddr == NEW_ADDR) | 640 | if (dn.data_blkaddr == NEW_ADDR && !fiemap) |
641 | goto put_out; | 641 | goto put_out; |
642 | 642 | ||
643 | if (dn.data_blkaddr != NULL_ADDR) { | 643 | if (dn.data_blkaddr != NULL_ADDR) { |
@@ -671,7 +671,7 @@ get_next: | |||
671 | err = 0; | 671 | err = 0; |
672 | goto unlock_out; | 672 | goto unlock_out; |
673 | } | 673 | } |
674 | if (dn.data_blkaddr == NEW_ADDR) | 674 | if (dn.data_blkaddr == NEW_ADDR && !fiemap) |
675 | goto put_out; | 675 | goto put_out; |
676 | 676 | ||
677 | end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); | 677 | end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); |
@@ -708,10 +708,23 @@ out: | |||
708 | return err; | 708 | return err; |
709 | } | 709 | } |
710 | 710 | ||
711 | static int get_data_block(struct inode *inode, sector_t iblock, | ||
712 | struct buffer_head *bh_result, int create) | ||
713 | { | ||
714 | return __get_data_block(inode, iblock, bh_result, create, false); | ||
715 | } | ||
716 | |||
717 | static int get_data_block_fiemap(struct inode *inode, sector_t iblock, | ||
718 | struct buffer_head *bh_result, int create) | ||
719 | { | ||
720 | return __get_data_block(inode, iblock, bh_result, create, true); | ||
721 | } | ||
722 | |||
711 | int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 723 | int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
712 | u64 start, u64 len) | 724 | u64 start, u64 len) |
713 | { | 725 | { |
714 | return generic_block_fiemap(inode, fieinfo, start, len, get_data_block); | 726 | return generic_block_fiemap(inode, fieinfo, |
727 | start, len, get_data_block_fiemap); | ||
715 | } | 728 | } |
716 | 729 | ||
717 | static int f2fs_read_data_page(struct file *file, struct page *page) | 730 | static int f2fs_read_data_page(struct file *file, struct page *page) |
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 966acb039e3b..a4addd72ebbd 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c | |||
@@ -376,11 +376,11 @@ static struct page *init_inode_metadata(struct inode *inode, | |||
376 | 376 | ||
377 | put_error: | 377 | put_error: |
378 | f2fs_put_page(page, 1); | 378 | f2fs_put_page(page, 1); |
379 | error: | ||
379 | /* once the failed inode becomes a bad inode, i_mode is S_IFREG */ | 380 | /* once the failed inode becomes a bad inode, i_mode is S_IFREG */ |
380 | truncate_inode_pages(&inode->i_data, 0); | 381 | truncate_inode_pages(&inode->i_data, 0); |
381 | truncate_blocks(inode, 0); | 382 | truncate_blocks(inode, 0); |
382 | remove_dirty_dir_inode(inode); | 383 | remove_dirty_dir_inode(inode); |
383 | error: | ||
384 | remove_inode_page(inode); | 384 | remove_inode_page(inode); |
385 | return ERR_PTR(err); | 385 | return ERR_PTR(err); |
386 | } | 386 | } |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index e51c732b0dd9..58df97e174d0 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -342,9 +342,6 @@ struct f2fs_sm_info { | |||
342 | struct dirty_seglist_info *dirty_info; /* dirty segment information */ | 342 | struct dirty_seglist_info *dirty_info; /* dirty segment information */ |
343 | struct curseg_info *curseg_array; /* active segment information */ | 343 | struct curseg_info *curseg_array; /* active segment information */ |
344 | 344 | ||
345 | struct list_head wblist_head; /* list of under-writeback pages */ | ||
346 | spinlock_t wblist_lock; /* lock for checkpoint */ | ||
347 | |||
348 | block_t seg0_blkaddr; /* block address of 0'th segment */ | 345 | block_t seg0_blkaddr; /* block address of 0'th segment */ |
349 | block_t main_blkaddr; /* start block address of main area */ | 346 | block_t main_blkaddr; /* start block address of main area */ |
350 | block_t ssa_blkaddr; /* start block address of SSA area */ | 347 | block_t ssa_blkaddr; /* start block address of SSA area */ |
@@ -644,7 +641,8 @@ static inline void f2fs_unlock_all(struct f2fs_sb_info *sbi) | |||
644 | */ | 641 | */ |
645 | static inline int check_nid_range(struct f2fs_sb_info *sbi, nid_t nid) | 642 | static inline int check_nid_range(struct f2fs_sb_info *sbi, nid_t nid) |
646 | { | 643 | { |
647 | WARN_ON((nid >= NM_I(sbi)->max_nid)); | 644 | if (unlikely(nid < F2FS_ROOT_INO(sbi))) |
645 | return -EINVAL; | ||
648 | if (unlikely(nid >= NM_I(sbi)->max_nid)) | 646 | if (unlikely(nid >= NM_I(sbi)->max_nid)) |
649 | return -EINVAL; | 647 | return -EINVAL; |
650 | return 0; | 648 | return 0; |
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index c58e33075719..7d8b96275092 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -659,16 +659,19 @@ static int expand_inode_data(struct inode *inode, loff_t offset, | |||
659 | off_start = offset & (PAGE_CACHE_SIZE - 1); | 659 | off_start = offset & (PAGE_CACHE_SIZE - 1); |
660 | off_end = (offset + len) & (PAGE_CACHE_SIZE - 1); | 660 | off_end = (offset + len) & (PAGE_CACHE_SIZE - 1); |
661 | 661 | ||
662 | f2fs_lock_op(sbi); | ||
663 | |||
662 | for (index = pg_start; index <= pg_end; index++) { | 664 | for (index = pg_start; index <= pg_end; index++) { |
663 | struct dnode_of_data dn; | 665 | struct dnode_of_data dn; |
664 | 666 | ||
665 | f2fs_lock_op(sbi); | 667 | if (index == pg_end && !off_end) |
668 | goto noalloc; | ||
669 | |||
666 | set_new_dnode(&dn, inode, NULL, NULL, 0); | 670 | set_new_dnode(&dn, inode, NULL, NULL, 0); |
667 | ret = f2fs_reserve_block(&dn, index); | 671 | ret = f2fs_reserve_block(&dn, index); |
668 | f2fs_unlock_op(sbi); | ||
669 | if (ret) | 672 | if (ret) |
670 | break; | 673 | break; |
671 | 674 | noalloc: | |
672 | if (pg_start == pg_end) | 675 | if (pg_start == pg_end) |
673 | new_size = offset + len; | 676 | new_size = offset + len; |
674 | else if (index == pg_start && off_start) | 677 | else if (index == pg_start && off_start) |
@@ -683,8 +686,9 @@ static int expand_inode_data(struct inode *inode, loff_t offset, | |||
683 | i_size_read(inode) < new_size) { | 686 | i_size_read(inode) < new_size) { |
684 | i_size_write(inode, new_size); | 687 | i_size_write(inode, new_size); |
685 | mark_inode_dirty(inode); | 688 | mark_inode_dirty(inode); |
686 | f2fs_write_inode(inode, NULL); | 689 | update_inode_page(inode); |
687 | } | 690 | } |
691 | f2fs_unlock_op(sbi); | ||
688 | 692 | ||
689 | return ret; | 693 | return ret; |
690 | } | 694 | } |
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index adc622c6bdce..2cf6962f6cc8 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c | |||
@@ -78,6 +78,7 @@ static int do_read_inode(struct inode *inode) | |||
78 | if (check_nid_range(sbi, inode->i_ino)) { | 78 | if (check_nid_range(sbi, inode->i_ino)) { |
79 | f2fs_msg(inode->i_sb, KERN_ERR, "bad inode number: %lu", | 79 | f2fs_msg(inode->i_sb, KERN_ERR, "bad inode number: %lu", |
80 | (unsigned long) inode->i_ino); | 80 | (unsigned long) inode->i_ino); |
81 | WARN_ON(1); | ||
81 | return -EINVAL; | 82 | return -EINVAL; |
82 | } | 83 | } |
83 | 84 | ||
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 9138c32aa698..a6bdddc33ce2 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
@@ -417,9 +417,6 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
417 | } | 417 | } |
418 | 418 | ||
419 | f2fs_set_link(new_dir, new_entry, new_page, old_inode); | 419 | f2fs_set_link(new_dir, new_entry, new_page, old_inode); |
420 | down_write(&F2FS_I(old_inode)->i_sem); | ||
421 | F2FS_I(old_inode)->i_pino = new_dir->i_ino; | ||
422 | up_write(&F2FS_I(old_inode)->i_sem); | ||
423 | 420 | ||
424 | new_inode->i_ctime = CURRENT_TIME; | 421 | new_inode->i_ctime = CURRENT_TIME; |
425 | down_write(&F2FS_I(new_inode)->i_sem); | 422 | down_write(&F2FS_I(new_inode)->i_sem); |
@@ -448,6 +445,10 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
448 | } | 445 | } |
449 | } | 446 | } |
450 | 447 | ||
448 | down_write(&F2FS_I(old_inode)->i_sem); | ||
449 | file_lost_pino(old_inode); | ||
450 | up_write(&F2FS_I(old_inode)->i_sem); | ||
451 | |||
451 | old_inode->i_ctime = CURRENT_TIME; | 452 | old_inode->i_ctime = CURRENT_TIME; |
452 | mark_inode_dirty(old_inode); | 453 | mark_inode_dirty(old_inode); |
453 | 454 | ||
@@ -457,9 +458,6 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
457 | if (old_dir != new_dir) { | 458 | if (old_dir != new_dir) { |
458 | f2fs_set_link(old_inode, old_dir_entry, | 459 | f2fs_set_link(old_inode, old_dir_entry, |
459 | old_dir_page, new_dir); | 460 | old_dir_page, new_dir); |
460 | down_write(&F2FS_I(old_inode)->i_sem); | ||
461 | F2FS_I(old_inode)->i_pino = new_dir->i_ino; | ||
462 | up_write(&F2FS_I(old_inode)->i_sem); | ||
463 | update_inode_page(old_inode); | 461 | update_inode_page(old_inode); |
464 | } else { | 462 | } else { |
465 | kunmap(old_dir_page); | 463 | kunmap(old_dir_page); |
@@ -474,7 +472,8 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
474 | return 0; | 472 | return 0; |
475 | 473 | ||
476 | put_out_dir: | 474 | put_out_dir: |
477 | f2fs_put_page(new_page, 1); | 475 | kunmap(new_page); |
476 | f2fs_put_page(new_page, 0); | ||
478 | out_dir: | 477 | out_dir: |
479 | if (old_dir_entry) { | 478 | if (old_dir_entry) { |
480 | kunmap(old_dir_page); | 479 | kunmap(old_dir_page); |
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 9dfb9a042fd2..4b697ccc9b0c 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c | |||
@@ -42,6 +42,8 @@ bool available_free_memory(struct f2fs_sb_info *sbi, int type) | |||
42 | mem_size = (nm_i->nat_cnt * sizeof(struct nat_entry)) >> 12; | 42 | mem_size = (nm_i->nat_cnt * sizeof(struct nat_entry)) >> 12; |
43 | res = mem_size < ((val.totalram * nm_i->ram_thresh / 100) >> 2); | 43 | res = mem_size < ((val.totalram * nm_i->ram_thresh / 100) >> 2); |
44 | } else if (type == DIRTY_DENTS) { | 44 | } else if (type == DIRTY_DENTS) { |
45 | if (sbi->sb->s_bdi->dirty_exceeded) | ||
46 | return false; | ||
45 | mem_size = get_pages(sbi, F2FS_DIRTY_DENTS); | 47 | mem_size = get_pages(sbi, F2FS_DIRTY_DENTS); |
46 | res = mem_size < ((val.totalram * nm_i->ram_thresh / 100) >> 1); | 48 | res = mem_size < ((val.totalram * nm_i->ram_thresh / 100) >> 1); |
47 | } | 49 | } |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index f25f0e07e26f..d04613df710a 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -272,14 +272,15 @@ int create_flush_cmd_control(struct f2fs_sb_info *sbi) | |||
272 | return -ENOMEM; | 272 | return -ENOMEM; |
273 | spin_lock_init(&fcc->issue_lock); | 273 | spin_lock_init(&fcc->issue_lock); |
274 | init_waitqueue_head(&fcc->flush_wait_queue); | 274 | init_waitqueue_head(&fcc->flush_wait_queue); |
275 | sbi->sm_info->cmd_control_info = fcc; | ||
275 | fcc->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi, | 276 | fcc->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi, |
276 | "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); | 277 | "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); |
277 | if (IS_ERR(fcc->f2fs_issue_flush)) { | 278 | if (IS_ERR(fcc->f2fs_issue_flush)) { |
278 | err = PTR_ERR(fcc->f2fs_issue_flush); | 279 | err = PTR_ERR(fcc->f2fs_issue_flush); |
279 | kfree(fcc); | 280 | kfree(fcc); |
281 | sbi->sm_info->cmd_control_info = NULL; | ||
280 | return err; | 282 | return err; |
281 | } | 283 | } |
282 | sbi->sm_info->cmd_control_info = fcc; | ||
283 | 284 | ||
284 | return err; | 285 | return err; |
285 | } | 286 | } |
@@ -1885,8 +1886,6 @@ int build_segment_manager(struct f2fs_sb_info *sbi) | |||
1885 | 1886 | ||
1886 | /* init sm info */ | 1887 | /* init sm info */ |
1887 | sbi->sm_info = sm_info; | 1888 | sbi->sm_info = sm_info; |
1888 | INIT_LIST_HEAD(&sm_info->wblist_head); | ||
1889 | spin_lock_init(&sm_info->wblist_lock); | ||
1890 | sm_info->seg0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr); | 1889 | sm_info->seg0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr); |
1891 | sm_info->main_blkaddr = le32_to_cpu(raw_super->main_blkaddr); | 1890 | sm_info->main_blkaddr = le32_to_cpu(raw_super->main_blkaddr); |
1892 | sm_info->segment_count = le32_to_cpu(raw_super->segment_count); | 1891 | sm_info->segment_count = le32_to_cpu(raw_super->segment_count); |
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index b2b18637cb9e..8f96d9372ade 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -689,9 +689,7 @@ static struct inode *f2fs_nfs_get_inode(struct super_block *sb, | |||
689 | struct f2fs_sb_info *sbi = F2FS_SB(sb); | 689 | struct f2fs_sb_info *sbi = F2FS_SB(sb); |
690 | struct inode *inode; | 690 | struct inode *inode; |
691 | 691 | ||
692 | if (unlikely(ino < F2FS_ROOT_INO(sbi))) | 692 | if (check_nid_range(sbi, ino)) |
693 | return ERR_PTR(-ESTALE); | ||
694 | if (unlikely(ino >= NM_I(sbi)->max_nid)) | ||
695 | return ERR_PTR(-ESTALE); | 693 | return ERR_PTR(-ESTALE); |
696 | 694 | ||
697 | /* | 695 | /* |