aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-07-09 12:46:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-07-09 12:46:58 -0400
commit191d385f253a317ed905b06137b48e5990e700cf (patch)
treee988e626a987b3b06f46b380d5484637138bafec /fs
parent163e40743f730e0982b0df28e57e0bed71442a77 (diff)
parent50e1f8d22199b557337b3d1ec8520e4c5aa5c76e (diff)
Merge tag 'f2fs-fixes-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs bugfixes from Jaegeuk Kim: "This includes a couple of bug fixes found by xfstests. In addition, one critical bug was reported by Brian Chadwick, which is falling into the infinite loop in balance_dirty_pages. And it turned out due to the IO merging policy in f2fs, which was newly merged in 3.16. - fix normal and recovery path for fallocated regions - fix error case mishandling - recover renamed fsync inodes correctly - fix to get out of infinite loops in balance_dirty_pages - fix kernel NULL pointer error" * tag 'f2fs-fixes-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: f2fs: avoid to access NULL pointer in issue_flush_thread f2fs: check bdi->dirty_exceeded when trying to skip data writes f2fs: do checkpoint for the renamed inode f2fs: release new entry page correctly in error path of f2fs_rename f2fs: fix error path in init_inode_metadata f2fs: check lower bound nid value in check_nid_range f2fs: remove unused variables in f2fs_sm_info f2fs: fix not to allocate unnecessary blocks during fallocate f2fs: recover fallocated data and its i_size together f2fs: fix to report newly allocate region as extent
Diffstat (limited to 'fs')
-rw-r--r--fs/f2fs/data.c23
-rw-r--r--fs/f2fs/dir.c2
-rw-r--r--fs/f2fs/f2fs.h6
-rw-r--r--fs/f2fs/file.c12
-rw-r--r--fs/f2fs/inode.c1
-rw-r--r--fs/f2fs/namei.c13
-rw-r--r--fs/f2fs/node.c2
-rw-r--r--fs/f2fs/segment.c5
-rw-r--r--fs/f2fs/super.c4
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 */
611static int get_data_block(struct inode *inode, sector_t iblock, 611static 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
711static 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
717static 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
711int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, 723int 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
717static int f2fs_read_data_page(struct file *file, struct page *page) 730static 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
377put_error: 377put_error:
378 f2fs_put_page(page, 1); 378 f2fs_put_page(page, 1);
379error:
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);
383error:
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 */
645static inline int check_nid_range(struct f2fs_sb_info *sbi, nid_t nid) 642static 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 674noalloc:
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
476put_out_dir: 474put_out_dir:
477 f2fs_put_page(new_page, 1); 475 kunmap(new_page);
476 f2fs_put_page(new_page, 0);
478out_dir: 477out_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 /*