diff options
| -rw-r--r-- | fs/f2fs/acl.c | 4 | ||||
| -rw-r--r-- | fs/f2fs/checkpoint.c | 108 | ||||
| -rw-r--r-- | fs/f2fs/data.c | 285 | ||||
| -rw-r--r-- | fs/f2fs/f2fs.h | 127 | ||||
| -rw-r--r-- | fs/f2fs/file.c | 76 | ||||
| -rw-r--r-- | fs/f2fs/gc.c | 16 | ||||
| -rw-r--r-- | fs/f2fs/inline.c | 17 | ||||
| -rw-r--r-- | fs/f2fs/inode.c | 12 | ||||
| -rw-r--r-- | fs/f2fs/namei.c | 2 | ||||
| -rw-r--r-- | fs/f2fs/node.c | 43 | ||||
| -rw-r--r-- | fs/f2fs/recovery.c | 37 | ||||
| -rw-r--r-- | fs/f2fs/segment.c | 71 | ||||
| -rw-r--r-- | fs/f2fs/segment.h | 16 | ||||
| -rw-r--r-- | fs/f2fs/super.c | 70 | ||||
| -rw-r--r-- | fs/f2fs/xattr.c | 36 | ||||
| -rw-r--r-- | fs/f2fs/xattr.h | 2 | ||||
| -rw-r--r-- | include/linux/f2fs_fs.h | 11 | ||||
| -rw-r--r-- | include/trace/events/f2fs.h | 57 |
18 files changed, 688 insertions, 302 deletions
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index 63e599524085..217b290ae3a5 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c | |||
| @@ -285,7 +285,7 @@ static int f2fs_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) | |||
| 285 | /* assert(atomic_read(acl->a_refcount) == 1); */ | 285 | /* assert(atomic_read(acl->a_refcount) == 1); */ |
| 286 | 286 | ||
| 287 | FOREACH_ACL_ENTRY(pa, acl, pe) { | 287 | FOREACH_ACL_ENTRY(pa, acl, pe) { |
| 288 | switch(pa->e_tag) { | 288 | switch (pa->e_tag) { |
| 289 | case ACL_USER_OBJ: | 289 | case ACL_USER_OBJ: |
| 290 | pa->e_perm &= (mode >> 6) | ~S_IRWXO; | 290 | pa->e_perm &= (mode >> 6) | ~S_IRWXO; |
| 291 | mode &= (pa->e_perm << 6) | ~S_IRWXU; | 291 | mode &= (pa->e_perm << 6) | ~S_IRWXU; |
| @@ -326,7 +326,7 @@ static int f2fs_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) | |||
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | *mode_p = (*mode_p & ~S_IRWXUGO) | mode; | 328 | *mode_p = (*mode_p & ~S_IRWXUGO) | mode; |
| 329 | return not_equiv; | 329 | return not_equiv; |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | static int f2fs_acl_create(struct inode *dir, umode_t *mode, | 332 | static int f2fs_acl_create(struct inode *dir, umode_t *mode, |
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index a98e1b02279e..ed70b68b2b38 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
| @@ -66,7 +66,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, | |||
| 66 | .old_blkaddr = index, | 66 | .old_blkaddr = index, |
| 67 | .new_blkaddr = index, | 67 | .new_blkaddr = index, |
| 68 | .encrypted_page = NULL, | 68 | .encrypted_page = NULL, |
| 69 | .is_meta = is_meta, | 69 | .is_por = !is_meta, |
| 70 | }; | 70 | }; |
| 71 | int err; | 71 | int err; |
| 72 | 72 | ||
| @@ -130,6 +130,30 @@ struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index) | |||
| 130 | return __get_meta_page(sbi, index, false); | 130 | return __get_meta_page(sbi, index, false); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr, | ||
| 134 | int type) | ||
| 135 | { | ||
| 136 | struct seg_entry *se; | ||
| 137 | unsigned int segno, offset; | ||
| 138 | bool exist; | ||
| 139 | |||
| 140 | if (type != DATA_GENERIC_ENHANCE && type != DATA_GENERIC_ENHANCE_READ) | ||
| 141 | return true; | ||
| 142 | |||
| 143 | segno = GET_SEGNO(sbi, blkaddr); | ||
| 144 | offset = GET_BLKOFF_FROM_SEG0(sbi, blkaddr); | ||
| 145 | se = get_seg_entry(sbi, segno); | ||
| 146 | |||
| 147 | exist = f2fs_test_bit(offset, se->cur_valid_map); | ||
| 148 | if (!exist && type == DATA_GENERIC_ENHANCE) { | ||
| 149 | f2fs_msg(sbi->sb, KERN_ERR, "Inconsistent error " | ||
| 150 | "blkaddr:%u, sit bitmap:%d", blkaddr, exist); | ||
| 151 | set_sbi_flag(sbi, SBI_NEED_FSCK); | ||
| 152 | WARN_ON(1); | ||
| 153 | } | ||
| 154 | return exist; | ||
| 155 | } | ||
| 156 | |||
| 133 | bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, | 157 | bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, |
| 134 | block_t blkaddr, int type) | 158 | block_t blkaddr, int type) |
| 135 | { | 159 | { |
| @@ -151,15 +175,22 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, | |||
| 151 | return false; | 175 | return false; |
| 152 | break; | 176 | break; |
| 153 | case META_POR: | 177 | case META_POR: |
| 178 | if (unlikely(blkaddr >= MAX_BLKADDR(sbi) || | ||
| 179 | blkaddr < MAIN_BLKADDR(sbi))) | ||
| 180 | return false; | ||
| 181 | break; | ||
| 154 | case DATA_GENERIC: | 182 | case DATA_GENERIC: |
| 183 | case DATA_GENERIC_ENHANCE: | ||
| 184 | case DATA_GENERIC_ENHANCE_READ: | ||
| 155 | if (unlikely(blkaddr >= MAX_BLKADDR(sbi) || | 185 | if (unlikely(blkaddr >= MAX_BLKADDR(sbi) || |
| 156 | blkaddr < MAIN_BLKADDR(sbi))) { | 186 | blkaddr < MAIN_BLKADDR(sbi))) { |
| 157 | if (type == DATA_GENERIC) { | 187 | f2fs_msg(sbi->sb, KERN_WARNING, |
| 158 | f2fs_msg(sbi->sb, KERN_WARNING, | 188 | "access invalid blkaddr:%u", blkaddr); |
| 159 | "access invalid blkaddr:%u", blkaddr); | 189 | set_sbi_flag(sbi, SBI_NEED_FSCK); |
| 160 | WARN_ON(1); | 190 | WARN_ON(1); |
| 161 | } | ||
| 162 | return false; | 191 | return false; |
| 192 | } else { | ||
| 193 | return __is_bitmap_valid(sbi, blkaddr, type); | ||
| 163 | } | 194 | } |
| 164 | break; | 195 | break; |
| 165 | case META_GENERIC: | 196 | case META_GENERIC: |
| @@ -189,7 +220,7 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, | |||
| 189 | .op_flags = sync ? (REQ_META | REQ_PRIO) : REQ_RAHEAD, | 220 | .op_flags = sync ? (REQ_META | REQ_PRIO) : REQ_RAHEAD, |
| 190 | .encrypted_page = NULL, | 221 | .encrypted_page = NULL, |
| 191 | .in_list = false, | 222 | .in_list = false, |
| 192 | .is_meta = (type != META_POR), | 223 | .is_por = (type == META_POR), |
| 193 | }; | 224 | }; |
| 194 | struct blk_plug plug; | 225 | struct blk_plug plug; |
| 195 | 226 | ||
| @@ -644,6 +675,12 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi) | |||
| 644 | if (!is_set_ckpt_flags(sbi, CP_ORPHAN_PRESENT_FLAG)) | 675 | if (!is_set_ckpt_flags(sbi, CP_ORPHAN_PRESENT_FLAG)) |
| 645 | return 0; | 676 | return 0; |
| 646 | 677 | ||
| 678 | if (bdev_read_only(sbi->sb->s_bdev)) { | ||
| 679 | f2fs_msg(sbi->sb, KERN_INFO, "write access " | ||
| 680 | "unavailable, skipping orphan cleanup"); | ||
| 681 | return 0; | ||
| 682 | } | ||
| 683 | |||
| 647 | if (s_flags & SB_RDONLY) { | 684 | if (s_flags & SB_RDONLY) { |
| 648 | f2fs_msg(sbi->sb, KERN_INFO, "orphan cleanup on readonly fs"); | 685 | f2fs_msg(sbi->sb, KERN_INFO, "orphan cleanup on readonly fs"); |
| 649 | sbi->sb->s_flags &= ~SB_RDONLY; | 686 | sbi->sb->s_flags &= ~SB_RDONLY; |
| @@ -758,13 +795,27 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk) | |||
| 758 | } | 795 | } |
| 759 | } | 796 | } |
| 760 | 797 | ||
| 798 | static __u32 f2fs_checkpoint_chksum(struct f2fs_sb_info *sbi, | ||
| 799 | struct f2fs_checkpoint *ckpt) | ||
| 800 | { | ||
| 801 | unsigned int chksum_ofs = le32_to_cpu(ckpt->checksum_offset); | ||
| 802 | __u32 chksum; | ||
| 803 | |||
| 804 | chksum = f2fs_crc32(sbi, ckpt, chksum_ofs); | ||
| 805 | if (chksum_ofs < CP_CHKSUM_OFFSET) { | ||
| 806 | chksum_ofs += sizeof(chksum); | ||
| 807 | chksum = f2fs_chksum(sbi, chksum, (__u8 *)ckpt + chksum_ofs, | ||
| 808 | F2FS_BLKSIZE - chksum_ofs); | ||
| 809 | } | ||
| 810 | return chksum; | ||
| 811 | } | ||
| 812 | |||
| 761 | static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr, | 813 | static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr, |
| 762 | struct f2fs_checkpoint **cp_block, struct page **cp_page, | 814 | struct f2fs_checkpoint **cp_block, struct page **cp_page, |
| 763 | unsigned long long *version) | 815 | unsigned long long *version) |
| 764 | { | 816 | { |
| 765 | unsigned long blk_size = sbi->blocksize; | ||
| 766 | size_t crc_offset = 0; | 817 | size_t crc_offset = 0; |
| 767 | __u32 crc = 0; | 818 | __u32 crc; |
| 768 | 819 | ||
| 769 | *cp_page = f2fs_get_meta_page(sbi, cp_addr); | 820 | *cp_page = f2fs_get_meta_page(sbi, cp_addr); |
| 770 | if (IS_ERR(*cp_page)) | 821 | if (IS_ERR(*cp_page)) |
| @@ -773,15 +824,27 @@ static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr, | |||
| 773 | *cp_block = (struct f2fs_checkpoint *)page_address(*cp_page); | 824 | *cp_block = (struct f2fs_checkpoint *)page_address(*cp_page); |
| 774 | 825 | ||
| 775 | crc_offset = le32_to_cpu((*cp_block)->checksum_offset); | 826 | crc_offset = le32_to_cpu((*cp_block)->checksum_offset); |
| 776 | if (crc_offset > (blk_size - sizeof(__le32))) { | 827 | if (crc_offset < CP_MIN_CHKSUM_OFFSET || |
| 828 | crc_offset > CP_CHKSUM_OFFSET) { | ||
| 777 | f2fs_put_page(*cp_page, 1); | 829 | f2fs_put_page(*cp_page, 1); |
| 778 | f2fs_msg(sbi->sb, KERN_WARNING, | 830 | f2fs_msg(sbi->sb, KERN_WARNING, |
| 779 | "invalid crc_offset: %zu", crc_offset); | 831 | "invalid crc_offset: %zu", crc_offset); |
| 780 | return -EINVAL; | 832 | return -EINVAL; |
| 781 | } | 833 | } |
| 782 | 834 | ||
| 783 | crc = cur_cp_crc(*cp_block); | 835 | if (__is_set_ckpt_flags(*cp_block, CP_LARGE_NAT_BITMAP_FLAG)) { |
| 784 | if (!f2fs_crc_valid(sbi, crc, *cp_block, crc_offset)) { | 836 | if (crc_offset != CP_MIN_CHKSUM_OFFSET) { |
| 837 | f2fs_put_page(*cp_page, 1); | ||
| 838 | f2fs_msg(sbi->sb, KERN_WARNING, | ||
| 839 | "layout of large_nat_bitmap is deprecated, " | ||
| 840 | "run fsck to repair, chksum_offset: %zu", | ||
| 841 | crc_offset); | ||
| 842 | return -EINVAL; | ||
| 843 | } | ||
| 844 | } | ||
| 845 | |||
| 846 | crc = f2fs_checkpoint_chksum(sbi, *cp_block); | ||
| 847 | if (crc != cur_cp_crc(*cp_block)) { | ||
| 785 | f2fs_put_page(*cp_page, 1); | 848 | f2fs_put_page(*cp_page, 1); |
| 786 | f2fs_msg(sbi->sb, KERN_WARNING, "invalid crc value"); | 849 | f2fs_msg(sbi->sb, KERN_WARNING, "invalid crc value"); |
| 787 | return -EINVAL; | 850 | return -EINVAL; |
| @@ -1009,13 +1072,11 @@ retry: | |||
| 1009 | if (inode) { | 1072 | if (inode) { |
| 1010 | unsigned long cur_ino = inode->i_ino; | 1073 | unsigned long cur_ino = inode->i_ino; |
| 1011 | 1074 | ||
| 1012 | if (is_dir) | 1075 | F2FS_I(inode)->cp_task = current; |
| 1013 | F2FS_I(inode)->cp_task = current; | ||
| 1014 | 1076 | ||
| 1015 | filemap_fdatawrite(inode->i_mapping); | 1077 | filemap_fdatawrite(inode->i_mapping); |
| 1016 | 1078 | ||
| 1017 | if (is_dir) | 1079 | F2FS_I(inode)->cp_task = NULL; |
| 1018 | F2FS_I(inode)->cp_task = NULL; | ||
| 1019 | 1080 | ||
| 1020 | iput(inode); | 1081 | iput(inode); |
| 1021 | /* We need to give cpu to another writers. */ | 1082 | /* We need to give cpu to another writers. */ |
| @@ -1391,7 +1452,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
| 1391 | get_sit_bitmap(sbi, __bitmap_ptr(sbi, SIT_BITMAP)); | 1452 | get_sit_bitmap(sbi, __bitmap_ptr(sbi, SIT_BITMAP)); |
| 1392 | get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP)); | 1453 | get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP)); |
| 1393 | 1454 | ||
| 1394 | crc32 = f2fs_crc32(sbi, ckpt, le32_to_cpu(ckpt->checksum_offset)); | 1455 | crc32 = f2fs_checkpoint_chksum(sbi, ckpt); |
| 1395 | *((__le32 *)((unsigned char *)ckpt + | 1456 | *((__le32 *)((unsigned char *)ckpt + |
| 1396 | le32_to_cpu(ckpt->checksum_offset))) | 1457 | le32_to_cpu(ckpt->checksum_offset))) |
| 1397 | = cpu_to_le32(crc32); | 1458 | = cpu_to_le32(crc32); |
| @@ -1475,7 +1536,11 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
| 1475 | clear_sbi_flag(sbi, SBI_IS_DIRTY); | 1536 | clear_sbi_flag(sbi, SBI_IS_DIRTY); |
| 1476 | clear_sbi_flag(sbi, SBI_NEED_CP); | 1537 | clear_sbi_flag(sbi, SBI_NEED_CP); |
| 1477 | clear_sbi_flag(sbi, SBI_QUOTA_SKIP_FLUSH); | 1538 | clear_sbi_flag(sbi, SBI_QUOTA_SKIP_FLUSH); |
| 1539 | |||
| 1540 | spin_lock(&sbi->stat_lock); | ||
| 1478 | sbi->unusable_block_count = 0; | 1541 | sbi->unusable_block_count = 0; |
| 1542 | spin_unlock(&sbi->stat_lock); | ||
| 1543 | |||
| 1479 | __set_cp_next_pack(sbi); | 1544 | __set_cp_next_pack(sbi); |
| 1480 | 1545 | ||
| 1481 | /* | 1546 | /* |
| @@ -1500,6 +1565,9 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
| 1500 | unsigned long long ckpt_ver; | 1565 | unsigned long long ckpt_ver; |
| 1501 | int err = 0; | 1566 | int err = 0; |
| 1502 | 1567 | ||
| 1568 | if (f2fs_readonly(sbi->sb) || f2fs_hw_is_readonly(sbi)) | ||
| 1569 | return -EROFS; | ||
| 1570 | |||
| 1503 | if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { | 1571 | if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { |
| 1504 | if (cpc->reason != CP_PAUSE) | 1572 | if (cpc->reason != CP_PAUSE) |
| 1505 | return 0; | 1573 | return 0; |
| @@ -1516,10 +1584,6 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
| 1516 | err = -EIO; | 1584 | err = -EIO; |
| 1517 | goto out; | 1585 | goto out; |
| 1518 | } | 1586 | } |
| 1519 | if (f2fs_readonly(sbi->sb)) { | ||
| 1520 | err = -EROFS; | ||
| 1521 | goto out; | ||
| 1522 | } | ||
| 1523 | 1587 | ||
| 1524 | trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "start block_ops"); | 1588 | trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "start block_ops"); |
| 1525 | 1589 | ||
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 64040e998439..eda4181d2092 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
| @@ -218,12 +218,14 @@ struct block_device *f2fs_target_device(struct f2fs_sb_info *sbi, | |||
| 218 | struct block_device *bdev = sbi->sb->s_bdev; | 218 | struct block_device *bdev = sbi->sb->s_bdev; |
| 219 | int i; | 219 | int i; |
| 220 | 220 | ||
| 221 | for (i = 0; i < sbi->s_ndevs; i++) { | 221 | if (f2fs_is_multi_device(sbi)) { |
| 222 | if (FDEV(i).start_blk <= blk_addr && | 222 | for (i = 0; i < sbi->s_ndevs; i++) { |
| 223 | FDEV(i).end_blk >= blk_addr) { | 223 | if (FDEV(i).start_blk <= blk_addr && |
| 224 | blk_addr -= FDEV(i).start_blk; | 224 | FDEV(i).end_blk >= blk_addr) { |
| 225 | bdev = FDEV(i).bdev; | 225 | blk_addr -= FDEV(i).start_blk; |
| 226 | break; | 226 | bdev = FDEV(i).bdev; |
| 227 | break; | ||
| 228 | } | ||
| 227 | } | 229 | } |
| 228 | } | 230 | } |
| 229 | if (bio) { | 231 | if (bio) { |
| @@ -237,6 +239,9 @@ int f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr) | |||
| 237 | { | 239 | { |
| 238 | int i; | 240 | int i; |
| 239 | 241 | ||
| 242 | if (!f2fs_is_multi_device(sbi)) | ||
| 243 | return 0; | ||
| 244 | |||
| 240 | for (i = 0; i < sbi->s_ndevs; i++) | 245 | for (i = 0; i < sbi->s_ndevs; i++) |
| 241 | if (FDEV(i).start_blk <= blkaddr && FDEV(i).end_blk >= blkaddr) | 246 | if (FDEV(i).start_blk <= blkaddr && FDEV(i).end_blk >= blkaddr) |
| 242 | return i; | 247 | return i; |
| @@ -420,7 +425,7 @@ static void __submit_merged_write_cond(struct f2fs_sb_info *sbi, | |||
| 420 | 425 | ||
| 421 | void f2fs_submit_merged_write(struct f2fs_sb_info *sbi, enum page_type type) | 426 | void f2fs_submit_merged_write(struct f2fs_sb_info *sbi, enum page_type type) |
| 422 | { | 427 | { |
| 423 | __submit_merged_write_cond(sbi, NULL, 0, 0, type, true); | 428 | __submit_merged_write_cond(sbi, NULL, NULL, 0, type, true); |
| 424 | } | 429 | } |
| 425 | 430 | ||
| 426 | void f2fs_submit_merged_write_cond(struct f2fs_sb_info *sbi, | 431 | void f2fs_submit_merged_write_cond(struct f2fs_sb_info *sbi, |
| @@ -448,7 +453,8 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio) | |||
| 448 | fio->encrypted_page : fio->page; | 453 | fio->encrypted_page : fio->page; |
| 449 | 454 | ||
| 450 | if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr, | 455 | if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr, |
| 451 | __is_meta_io(fio) ? META_GENERIC : DATA_GENERIC)) | 456 | fio->is_por ? META_POR : (__is_meta_io(fio) ? |
| 457 | META_GENERIC : DATA_GENERIC_ENHANCE))) | ||
| 452 | return -EFAULT; | 458 | return -EFAULT; |
| 453 | 459 | ||
| 454 | trace_f2fs_submit_page_bio(page, fio); | 460 | trace_f2fs_submit_page_bio(page, fio); |
| @@ -498,9 +504,7 @@ next: | |||
| 498 | spin_unlock(&io->io_lock); | 504 | spin_unlock(&io->io_lock); |
| 499 | } | 505 | } |
| 500 | 506 | ||
| 501 | if (__is_valid_data_blkaddr(fio->old_blkaddr)) | 507 | verify_fio_blkaddr(fio); |
| 502 | verify_block_addr(fio, fio->old_blkaddr); | ||
| 503 | verify_block_addr(fio, fio->new_blkaddr); | ||
| 504 | 508 | ||
| 505 | bio_page = fio->encrypted_page ? fio->encrypted_page : fio->page; | 509 | bio_page = fio->encrypted_page ? fio->encrypted_page : fio->page; |
| 506 | 510 | ||
| @@ -557,9 +561,6 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr, | |||
| 557 | struct bio_post_read_ctx *ctx; | 561 | struct bio_post_read_ctx *ctx; |
| 558 | unsigned int post_read_steps = 0; | 562 | unsigned int post_read_steps = 0; |
| 559 | 563 | ||
| 560 | if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) | ||
| 561 | return ERR_PTR(-EFAULT); | ||
| 562 | |||
| 563 | bio = f2fs_bio_alloc(sbi, min_t(int, nr_pages, BIO_MAX_PAGES), false); | 564 | bio = f2fs_bio_alloc(sbi, min_t(int, nr_pages, BIO_MAX_PAGES), false); |
| 564 | if (!bio) | 565 | if (!bio) |
| 565 | return ERR_PTR(-ENOMEM); | 566 | return ERR_PTR(-ENOMEM); |
| @@ -587,8 +588,10 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr, | |||
| 587 | static int f2fs_submit_page_read(struct inode *inode, struct page *page, | 588 | static int f2fs_submit_page_read(struct inode *inode, struct page *page, |
| 588 | block_t blkaddr) | 589 | block_t blkaddr) |
| 589 | { | 590 | { |
| 590 | struct bio *bio = f2fs_grab_read_bio(inode, blkaddr, 1, 0); | 591 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
| 592 | struct bio *bio; | ||
| 591 | 593 | ||
| 594 | bio = f2fs_grab_read_bio(inode, blkaddr, 1, 0); | ||
| 592 | if (IS_ERR(bio)) | 595 | if (IS_ERR(bio)) |
| 593 | return PTR_ERR(bio); | 596 | return PTR_ERR(bio); |
| 594 | 597 | ||
| @@ -600,8 +603,8 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page, | |||
| 600 | return -EFAULT; | 603 | return -EFAULT; |
| 601 | } | 604 | } |
| 602 | ClearPageError(page); | 605 | ClearPageError(page); |
| 603 | inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA); | 606 | inc_page_count(sbi, F2FS_RD_DATA); |
| 604 | __submit_bio(F2FS_I_SB(inode), bio, DATA); | 607 | __submit_bio(sbi, bio, DATA); |
| 605 | return 0; | 608 | return 0; |
| 606 | } | 609 | } |
| 607 | 610 | ||
| @@ -729,6 +732,11 @@ struct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index, | |||
| 729 | 732 | ||
| 730 | if (f2fs_lookup_extent_cache(inode, index, &ei)) { | 733 | if (f2fs_lookup_extent_cache(inode, index, &ei)) { |
| 731 | dn.data_blkaddr = ei.blk + index - ei.fofs; | 734 | dn.data_blkaddr = ei.blk + index - ei.fofs; |
| 735 | if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), dn.data_blkaddr, | ||
| 736 | DATA_GENERIC_ENHANCE_READ)) { | ||
| 737 | err = -EFAULT; | ||
| 738 | goto put_err; | ||
| 739 | } | ||
| 732 | goto got_it; | 740 | goto got_it; |
| 733 | } | 741 | } |
| 734 | 742 | ||
| @@ -742,6 +750,13 @@ struct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index, | |||
| 742 | err = -ENOENT; | 750 | err = -ENOENT; |
| 743 | goto put_err; | 751 | goto put_err; |
| 744 | } | 752 | } |
| 753 | if (dn.data_blkaddr != NEW_ADDR && | ||
| 754 | !f2fs_is_valid_blkaddr(F2FS_I_SB(inode), | ||
| 755 | dn.data_blkaddr, | ||
| 756 | DATA_GENERIC_ENHANCE)) { | ||
| 757 | err = -EFAULT; | ||
| 758 | goto put_err; | ||
| 759 | } | ||
| 745 | got_it: | 760 | got_it: |
| 746 | if (PageUptodate(page)) { | 761 | if (PageUptodate(page)) { |
| 747 | unlock_page(page); | 762 | unlock_page(page); |
| @@ -1084,12 +1099,12 @@ next_block: | |||
| 1084 | blkaddr = datablock_addr(dn.inode, dn.node_page, dn.ofs_in_node); | 1099 | blkaddr = datablock_addr(dn.inode, dn.node_page, dn.ofs_in_node); |
| 1085 | 1100 | ||
| 1086 | if (__is_valid_data_blkaddr(blkaddr) && | 1101 | if (__is_valid_data_blkaddr(blkaddr) && |
| 1087 | !f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) { | 1102 | !f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE)) { |
| 1088 | err = -EFAULT; | 1103 | err = -EFAULT; |
| 1089 | goto sync_out; | 1104 | goto sync_out; |
| 1090 | } | 1105 | } |
| 1091 | 1106 | ||
| 1092 | if (is_valid_data_blkaddr(sbi, blkaddr)) { | 1107 | if (__is_valid_data_blkaddr(blkaddr)) { |
| 1093 | /* use out-place-update for driect IO under LFS mode */ | 1108 | /* use out-place-update for driect IO under LFS mode */ |
| 1094 | if (test_opt(sbi, LFS) && flag == F2FS_GET_BLOCK_DIO && | 1109 | if (test_opt(sbi, LFS) && flag == F2FS_GET_BLOCK_DIO && |
| 1095 | map->m_may_create) { | 1110 | map->m_may_create) { |
| @@ -1499,6 +1514,118 @@ out: | |||
| 1499 | return ret; | 1514 | return ret; |
| 1500 | } | 1515 | } |
| 1501 | 1516 | ||
| 1517 | static int f2fs_read_single_page(struct inode *inode, struct page *page, | ||
| 1518 | unsigned nr_pages, | ||
| 1519 | struct f2fs_map_blocks *map, | ||
| 1520 | struct bio **bio_ret, | ||
| 1521 | sector_t *last_block_in_bio, | ||
| 1522 | bool is_readahead) | ||
| 1523 | { | ||
| 1524 | struct bio *bio = *bio_ret; | ||
| 1525 | const unsigned blkbits = inode->i_blkbits; | ||
| 1526 | const unsigned blocksize = 1 << blkbits; | ||
| 1527 | sector_t block_in_file; | ||
| 1528 | sector_t last_block; | ||
| 1529 | sector_t last_block_in_file; | ||
| 1530 | sector_t block_nr; | ||
| 1531 | int ret = 0; | ||
| 1532 | |||
| 1533 | block_in_file = (sector_t)page->index; | ||
| 1534 | last_block = block_in_file + nr_pages; | ||
| 1535 | last_block_in_file = (i_size_read(inode) + blocksize - 1) >> | ||
| 1536 | blkbits; | ||
| 1537 | if (last_block > last_block_in_file) | ||
| 1538 | last_block = last_block_in_file; | ||
| 1539 | |||
| 1540 | /* just zeroing out page which is beyond EOF */ | ||
| 1541 | if (block_in_file >= last_block) | ||
| 1542 | goto zero_out; | ||
| 1543 | /* | ||
| 1544 | * Map blocks using the previous result first. | ||
| 1545 | */ | ||
| 1546 | if ((map->m_flags & F2FS_MAP_MAPPED) && | ||
| 1547 | block_in_file > map->m_lblk && | ||
| 1548 | block_in_file < (map->m_lblk + map->m_len)) | ||
| 1549 | goto got_it; | ||
| 1550 | |||
| 1551 | /* | ||
| 1552 | * Then do more f2fs_map_blocks() calls until we are | ||
| 1553 | * done with this page. | ||
| 1554 | */ | ||
| 1555 | map->m_lblk = block_in_file; | ||
| 1556 | map->m_len = last_block - block_in_file; | ||
| 1557 | |||
| 1558 | ret = f2fs_map_blocks(inode, map, 0, F2FS_GET_BLOCK_DEFAULT); | ||
| 1559 | if (ret) | ||
| 1560 | goto out; | ||
| 1561 | got_it: | ||
| 1562 | if ((map->m_flags & F2FS_MAP_MAPPED)) { | ||
| 1563 | block_nr = map->m_pblk + block_in_file - map->m_lblk; | ||
| 1564 | SetPageMappedToDisk(page); | ||
| 1565 | |||
| 1566 | if (!PageUptodate(page) && !cleancache_get_page(page)) { | ||
| 1567 | SetPageUptodate(page); | ||
| 1568 | goto confused; | ||
| 1569 | } | ||
| 1570 | |||
| 1571 | if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), block_nr, | ||
| 1572 | DATA_GENERIC_ENHANCE_READ)) { | ||
| 1573 | ret = -EFAULT; | ||
| 1574 | goto out; | ||
| 1575 | } | ||
| 1576 | } else { | ||
| 1577 | zero_out: | ||
| 1578 | zero_user_segment(page, 0, PAGE_SIZE); | ||
| 1579 | if (!PageUptodate(page)) | ||
| 1580 | SetPageUptodate(page); | ||
| 1581 | unlock_page(page); | ||
| 1582 | goto out; | ||
| 1583 | } | ||
| 1584 | |||
| 1585 | /* | ||
| 1586 | * This page will go to BIO. Do we need to send this | ||
| 1587 | * BIO off first? | ||
| 1588 | */ | ||
| 1589 | if (bio && (*last_block_in_bio != block_nr - 1 || | ||
| 1590 | !__same_bdev(F2FS_I_SB(inode), block_nr, bio))) { | ||
| 1591 | submit_and_realloc: | ||
| 1592 | __submit_bio(F2FS_I_SB(inode), bio, DATA); | ||
| 1593 | bio = NULL; | ||
| 1594 | } | ||
| 1595 | if (bio == NULL) { | ||
| 1596 | bio = f2fs_grab_read_bio(inode, block_nr, nr_pages, | ||
| 1597 | is_readahead ? REQ_RAHEAD : 0); | ||
| 1598 | if (IS_ERR(bio)) { | ||
| 1599 | ret = PTR_ERR(bio); | ||
| 1600 | bio = NULL; | ||
| 1601 | goto out; | ||
| 1602 | } | ||
| 1603 | } | ||
| 1604 | |||
| 1605 | /* | ||
| 1606 | * If the page is under writeback, we need to wait for | ||
| 1607 | * its completion to see the correct decrypted data. | ||
| 1608 | */ | ||
| 1609 | f2fs_wait_on_block_writeback(inode, block_nr); | ||
| 1610 | |||
| 1611 | if (bio_add_page(bio, page, blocksize, 0) < blocksize) | ||
| 1612 | goto submit_and_realloc; | ||
| 1613 | |||
| 1614 | inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA); | ||
| 1615 | ClearPageError(page); | ||
| 1616 | *last_block_in_bio = block_nr; | ||
| 1617 | goto out; | ||
| 1618 | confused: | ||
| 1619 | if (bio) { | ||
| 1620 | __submit_bio(F2FS_I_SB(inode), bio, DATA); | ||
| 1621 | bio = NULL; | ||
| 1622 | } | ||
| 1623 | unlock_page(page); | ||
| 1624 | out: | ||
| 1625 | *bio_ret = bio; | ||
| 1626 | return ret; | ||
| 1627 | } | ||
| 1628 | |||
| 1502 | /* | 1629 | /* |
| 1503 | * This function was originally taken from fs/mpage.c, and customized for f2fs. | 1630 | * This function was originally taken from fs/mpage.c, and customized for f2fs. |
| 1504 | * Major change was from block_size == page_size in f2fs by default. | 1631 | * Major change was from block_size == page_size in f2fs by default. |
| @@ -1515,13 +1642,8 @@ static int f2fs_mpage_readpages(struct address_space *mapping, | |||
| 1515 | struct bio *bio = NULL; | 1642 | struct bio *bio = NULL; |
| 1516 | sector_t last_block_in_bio = 0; | 1643 | sector_t last_block_in_bio = 0; |
| 1517 | struct inode *inode = mapping->host; | 1644 | struct inode *inode = mapping->host; |
| 1518 | const unsigned blkbits = inode->i_blkbits; | ||
| 1519 | const unsigned blocksize = 1 << blkbits; | ||
| 1520 | sector_t block_in_file; | ||
| 1521 | sector_t last_block; | ||
| 1522 | sector_t last_block_in_file; | ||
| 1523 | sector_t block_nr; | ||
| 1524 | struct f2fs_map_blocks map; | 1645 | struct f2fs_map_blocks map; |
| 1646 | int ret = 0; | ||
| 1525 | 1647 | ||
| 1526 | map.m_pblk = 0; | 1648 | map.m_pblk = 0; |
| 1527 | map.m_lblk = 0; | 1649 | map.m_lblk = 0; |
| @@ -1544,98 +1666,13 @@ static int f2fs_mpage_readpages(struct address_space *mapping, | |||
| 1544 | goto next_page; | 1666 | goto next_page; |
| 1545 | } | 1667 | } |
| 1546 | 1668 | ||
| 1547 | block_in_file = (sector_t)page->index; | 1669 | ret = f2fs_read_single_page(inode, page, nr_pages, &map, &bio, |
| 1548 | last_block = block_in_file + nr_pages; | 1670 | &last_block_in_bio, is_readahead); |
| 1549 | last_block_in_file = (i_size_read(inode) + blocksize - 1) >> | 1671 | if (ret) { |
| 1550 | blkbits; | 1672 | SetPageError(page); |
| 1551 | if (last_block > last_block_in_file) | ||
| 1552 | last_block = last_block_in_file; | ||
| 1553 | |||
| 1554 | /* just zeroing out page which is beyond EOF */ | ||
| 1555 | if (block_in_file >= last_block) | ||
| 1556 | goto zero_out; | ||
| 1557 | /* | ||
| 1558 | * Map blocks using the previous result first. | ||
| 1559 | */ | ||
| 1560 | if ((map.m_flags & F2FS_MAP_MAPPED) && | ||
| 1561 | block_in_file > map.m_lblk && | ||
| 1562 | block_in_file < (map.m_lblk + map.m_len)) | ||
| 1563 | goto got_it; | ||
| 1564 | |||
| 1565 | /* | ||
| 1566 | * Then do more f2fs_map_blocks() calls until we are | ||
| 1567 | * done with this page. | ||
| 1568 | */ | ||
| 1569 | map.m_lblk = block_in_file; | ||
| 1570 | map.m_len = last_block - block_in_file; | ||
| 1571 | |||
| 1572 | if (f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_DEFAULT)) | ||
| 1573 | goto set_error_page; | ||
| 1574 | got_it: | ||
| 1575 | if ((map.m_flags & F2FS_MAP_MAPPED)) { | ||
| 1576 | block_nr = map.m_pblk + block_in_file - map.m_lblk; | ||
| 1577 | SetPageMappedToDisk(page); | ||
| 1578 | |||
| 1579 | if (!PageUptodate(page) && !cleancache_get_page(page)) { | ||
| 1580 | SetPageUptodate(page); | ||
| 1581 | goto confused; | ||
| 1582 | } | ||
| 1583 | |||
| 1584 | if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), block_nr, | ||
| 1585 | DATA_GENERIC)) | ||
| 1586 | goto set_error_page; | ||
| 1587 | } else { | ||
| 1588 | zero_out: | ||
| 1589 | zero_user_segment(page, 0, PAGE_SIZE); | 1673 | zero_user_segment(page, 0, PAGE_SIZE); |
| 1590 | if (!PageUptodate(page)) | ||
| 1591 | SetPageUptodate(page); | ||
| 1592 | unlock_page(page); | 1674 | unlock_page(page); |
| 1593 | goto next_page; | ||
| 1594 | } | 1675 | } |
| 1595 | |||
| 1596 | /* | ||
| 1597 | * This page will go to BIO. Do we need to send this | ||
| 1598 | * BIO off first? | ||
| 1599 | */ | ||
| 1600 | if (bio && (last_block_in_bio != block_nr - 1 || | ||
| 1601 | !__same_bdev(F2FS_I_SB(inode), block_nr, bio))) { | ||
| 1602 | submit_and_realloc: | ||
| 1603 | __submit_bio(F2FS_I_SB(inode), bio, DATA); | ||
| 1604 | bio = NULL; | ||
| 1605 | } | ||
| 1606 | if (bio == NULL) { | ||
| 1607 | bio = f2fs_grab_read_bio(inode, block_nr, nr_pages, | ||
| 1608 | is_readahead ? REQ_RAHEAD : 0); | ||
| 1609 | if (IS_ERR(bio)) { | ||
| 1610 | bio = NULL; | ||
| 1611 | goto set_error_page; | ||
| 1612 | } | ||
| 1613 | } | ||
| 1614 | |||
| 1615 | /* | ||
| 1616 | * If the page is under writeback, we need to wait for | ||
| 1617 | * its completion to see the correct decrypted data. | ||
| 1618 | */ | ||
| 1619 | f2fs_wait_on_block_writeback(inode, block_nr); | ||
| 1620 | |||
| 1621 | if (bio_add_page(bio, page, blocksize, 0) < blocksize) | ||
| 1622 | goto submit_and_realloc; | ||
| 1623 | |||
| 1624 | inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA); | ||
| 1625 | ClearPageError(page); | ||
| 1626 | last_block_in_bio = block_nr; | ||
| 1627 | goto next_page; | ||
| 1628 | set_error_page: | ||
| 1629 | SetPageError(page); | ||
| 1630 | zero_user_segment(page, 0, PAGE_SIZE); | ||
| 1631 | unlock_page(page); | ||
| 1632 | goto next_page; | ||
| 1633 | confused: | ||
| 1634 | if (bio) { | ||
| 1635 | __submit_bio(F2FS_I_SB(inode), bio, DATA); | ||
| 1636 | bio = NULL; | ||
| 1637 | } | ||
| 1638 | unlock_page(page); | ||
| 1639 | next_page: | 1676 | next_page: |
| 1640 | if (pages) | 1677 | if (pages) |
| 1641 | put_page(page); | 1678 | put_page(page); |
| @@ -1643,7 +1680,7 @@ next_page: | |||
| 1643 | BUG_ON(pages && !list_empty(pages)); | 1680 | BUG_ON(pages && !list_empty(pages)); |
| 1644 | if (bio) | 1681 | if (bio) |
| 1645 | __submit_bio(F2FS_I_SB(inode), bio, DATA); | 1682 | __submit_bio(F2FS_I_SB(inode), bio, DATA); |
| 1646 | return 0; | 1683 | return pages ? 0 : ret; |
| 1647 | } | 1684 | } |
| 1648 | 1685 | ||
| 1649 | static int f2fs_read_data_page(struct file *file, struct page *page) | 1686 | static int f2fs_read_data_page(struct file *file, struct page *page) |
| @@ -1813,7 +1850,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) | |||
| 1813 | fio->old_blkaddr = ei.blk + page->index - ei.fofs; | 1850 | fio->old_blkaddr = ei.blk + page->index - ei.fofs; |
| 1814 | 1851 | ||
| 1815 | if (!f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr, | 1852 | if (!f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr, |
| 1816 | DATA_GENERIC)) | 1853 | DATA_GENERIC_ENHANCE)) |
| 1817 | return -EFAULT; | 1854 | return -EFAULT; |
| 1818 | 1855 | ||
| 1819 | ipu_force = true; | 1856 | ipu_force = true; |
| @@ -1840,7 +1877,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) | |||
| 1840 | got_it: | 1877 | got_it: |
| 1841 | if (__is_valid_data_blkaddr(fio->old_blkaddr) && | 1878 | if (__is_valid_data_blkaddr(fio->old_blkaddr) && |
| 1842 | !f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr, | 1879 | !f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr, |
| 1843 | DATA_GENERIC)) { | 1880 | DATA_GENERIC_ENHANCE)) { |
| 1844 | err = -EFAULT; | 1881 | err = -EFAULT; |
| 1845 | goto out_writepage; | 1882 | goto out_writepage; |
| 1846 | } | 1883 | } |
| @@ -1848,7 +1885,8 @@ got_it: | |||
| 1848 | * If current allocation needs SSR, | 1885 | * If current allocation needs SSR, |
| 1849 | * it had better in-place writes for updated data. | 1886 | * it had better in-place writes for updated data. |
| 1850 | */ | 1887 | */ |
| 1851 | if (ipu_force || (is_valid_data_blkaddr(fio->sbi, fio->old_blkaddr) && | 1888 | if (ipu_force || |
| 1889 | (__is_valid_data_blkaddr(fio->old_blkaddr) && | ||
| 1852 | need_inplace_update(fio))) { | 1890 | need_inplace_update(fio))) { |
| 1853 | err = encrypt_one_page(fio); | 1891 | err = encrypt_one_page(fio); |
| 1854 | if (err) | 1892 | if (err) |
| @@ -1866,9 +1904,10 @@ got_it: | |||
| 1866 | true); | 1904 | true); |
| 1867 | if (PageWriteback(page)) | 1905 | if (PageWriteback(page)) |
| 1868 | end_page_writeback(page); | 1906 | end_page_writeback(page); |
| 1907 | } else { | ||
| 1908 | set_inode_flag(inode, FI_UPDATE_WRITE); | ||
| 1869 | } | 1909 | } |
| 1870 | trace_f2fs_do_write_data_page(fio->page, IPU); | 1910 | trace_f2fs_do_write_data_page(fio->page, IPU); |
| 1871 | set_inode_flag(inode, FI_UPDATE_WRITE); | ||
| 1872 | return err; | 1911 | return err; |
| 1873 | } | 1912 | } |
| 1874 | 1913 | ||
| @@ -2030,7 +2069,8 @@ out: | |||
| 2030 | } | 2069 | } |
| 2031 | 2070 | ||
| 2032 | unlock_page(page); | 2071 | unlock_page(page); |
| 2033 | if (!S_ISDIR(inode->i_mode) && !IS_NOQUOTA(inode)) | 2072 | if (!S_ISDIR(inode->i_mode) && !IS_NOQUOTA(inode) && |
| 2073 | !F2FS_I(inode)->cp_task) | ||
| 2034 | f2fs_balance_fs(sbi, need_balance_fs); | 2074 | f2fs_balance_fs(sbi, need_balance_fs); |
| 2035 | 2075 | ||
| 2036 | if (unlikely(f2fs_cp_error(sbi))) { | 2076 | if (unlikely(f2fs_cp_error(sbi))) { |
| @@ -2491,6 +2531,11 @@ repeat: | |||
| 2491 | zero_user_segment(page, 0, PAGE_SIZE); | 2531 | zero_user_segment(page, 0, PAGE_SIZE); |
| 2492 | SetPageUptodate(page); | 2532 | SetPageUptodate(page); |
| 2493 | } else { | 2533 | } else { |
| 2534 | if (!f2fs_is_valid_blkaddr(sbi, blkaddr, | ||
| 2535 | DATA_GENERIC_ENHANCE_READ)) { | ||
| 2536 | err = -EFAULT; | ||
| 2537 | goto fail; | ||
| 2538 | } | ||
| 2494 | err = f2fs_submit_page_read(inode, page, blkaddr); | 2539 | err = f2fs_submit_page_read(inode, page, blkaddr); |
| 2495 | if (err) | 2540 | if (err) |
| 2496 | goto fail; | 2541 | goto fail; |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index bacf5c2a8850..06b89a9862ab 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
| @@ -210,7 +210,14 @@ enum { | |||
| 210 | META_SSA, | 210 | META_SSA, |
| 211 | META_MAX, | 211 | META_MAX, |
| 212 | META_POR, | 212 | META_POR, |
| 213 | DATA_GENERIC, | 213 | DATA_GENERIC, /* check range only */ |
| 214 | DATA_GENERIC_ENHANCE, /* strong check on range and segment bitmap */ | ||
| 215 | DATA_GENERIC_ENHANCE_READ, /* | ||
| 216 | * strong check on range and segment | ||
| 217 | * bitmap but no warning due to race | ||
| 218 | * condition of read on truncated area | ||
| 219 | * by extent_cache | ||
| 220 | */ | ||
| 214 | META_GENERIC, | 221 | META_GENERIC, |
| 215 | }; | 222 | }; |
| 216 | 223 | ||
| @@ -1041,7 +1048,7 @@ struct f2fs_io_info { | |||
| 1041 | bool submitted; /* indicate IO submission */ | 1048 | bool submitted; /* indicate IO submission */ |
| 1042 | int need_lock; /* indicate we need to lock cp_rwsem */ | 1049 | int need_lock; /* indicate we need to lock cp_rwsem */ |
| 1043 | bool in_list; /* indicate fio is in io_list */ | 1050 | bool in_list; /* indicate fio is in io_list */ |
| 1044 | bool is_meta; /* indicate borrow meta inode mapping or not */ | 1051 | bool is_por; /* indicate IO is from recovery or not */ |
| 1045 | bool retry; /* need to reallocate block address */ | 1052 | bool retry; /* need to reallocate block address */ |
| 1046 | enum iostat_type io_type; /* io type */ | 1053 | enum iostat_type io_type; /* io type */ |
| 1047 | struct writeback_control *io_wbc; /* writeback control */ | 1054 | struct writeback_control *io_wbc; /* writeback control */ |
| @@ -1068,8 +1075,8 @@ struct f2fs_dev_info { | |||
| 1068 | block_t start_blk; | 1075 | block_t start_blk; |
| 1069 | block_t end_blk; | 1076 | block_t end_blk; |
| 1070 | #ifdef CONFIG_BLK_DEV_ZONED | 1077 | #ifdef CONFIG_BLK_DEV_ZONED |
| 1071 | unsigned int nr_blkz; /* Total number of zones */ | 1078 | unsigned int nr_blkz; /* Total number of zones */ |
| 1072 | u8 *blkz_type; /* Array of zones type */ | 1079 | unsigned long *blkz_seq; /* Bitmap indicating sequential zones */ |
| 1073 | #endif | 1080 | #endif |
| 1074 | }; | 1081 | }; |
| 1075 | 1082 | ||
| @@ -1366,6 +1373,17 @@ static inline bool time_to_inject(struct f2fs_sb_info *sbi, int type) | |||
| 1366 | } | 1373 | } |
| 1367 | #endif | 1374 | #endif |
| 1368 | 1375 | ||
| 1376 | /* | ||
| 1377 | * Test if the mounted volume is a multi-device volume. | ||
| 1378 | * - For a single regular disk volume, sbi->s_ndevs is 0. | ||
| 1379 | * - For a single zoned disk volume, sbi->s_ndevs is 1. | ||
| 1380 | * - For a multi-device volume, sbi->s_ndevs is always 2 or more. | ||
| 1381 | */ | ||
| 1382 | static inline bool f2fs_is_multi_device(struct f2fs_sb_info *sbi) | ||
| 1383 | { | ||
| 1384 | return sbi->s_ndevs > 1; | ||
| 1385 | } | ||
| 1386 | |||
| 1369 | /* For write statistics. Suppose sector size is 512 bytes, | 1387 | /* For write statistics. Suppose sector size is 512 bytes, |
| 1370 | * and the return value is in kbytes. s is of struct f2fs_sb_info. | 1388 | * and the return value is in kbytes. s is of struct f2fs_sb_info. |
| 1371 | */ | 1389 | */ |
| @@ -1777,6 +1795,7 @@ enospc: | |||
| 1777 | return -ENOSPC; | 1795 | return -ENOSPC; |
| 1778 | } | 1796 | } |
| 1779 | 1797 | ||
| 1798 | void f2fs_msg(struct super_block *sb, const char *level, const char *fmt, ...); | ||
| 1780 | static inline void dec_valid_block_count(struct f2fs_sb_info *sbi, | 1799 | static inline void dec_valid_block_count(struct f2fs_sb_info *sbi, |
| 1781 | struct inode *inode, | 1800 | struct inode *inode, |
| 1782 | block_t count) | 1801 | block_t count) |
| @@ -1785,13 +1804,21 @@ static inline void dec_valid_block_count(struct f2fs_sb_info *sbi, | |||
| 1785 | 1804 | ||
| 1786 | spin_lock(&sbi->stat_lock); | 1805 | spin_lock(&sbi->stat_lock); |
| 1787 | f2fs_bug_on(sbi, sbi->total_valid_block_count < (block_t) count); | 1806 | f2fs_bug_on(sbi, sbi->total_valid_block_count < (block_t) count); |
| 1788 | f2fs_bug_on(sbi, inode->i_blocks < sectors); | ||
| 1789 | sbi->total_valid_block_count -= (block_t)count; | 1807 | sbi->total_valid_block_count -= (block_t)count; |
| 1790 | if (sbi->reserved_blocks && | 1808 | if (sbi->reserved_blocks && |
| 1791 | sbi->current_reserved_blocks < sbi->reserved_blocks) | 1809 | sbi->current_reserved_blocks < sbi->reserved_blocks) |
| 1792 | sbi->current_reserved_blocks = min(sbi->reserved_blocks, | 1810 | sbi->current_reserved_blocks = min(sbi->reserved_blocks, |
| 1793 | sbi->current_reserved_blocks + count); | 1811 | sbi->current_reserved_blocks + count); |
| 1794 | spin_unlock(&sbi->stat_lock); | 1812 | spin_unlock(&sbi->stat_lock); |
| 1813 | if (unlikely(inode->i_blocks < sectors)) { | ||
| 1814 | f2fs_msg(sbi->sb, KERN_WARNING, | ||
| 1815 | "Inconsistent i_blocks, ino:%lu, iblocks:%llu, sectors:%llu", | ||
| 1816 | inode->i_ino, | ||
| 1817 | (unsigned long long)inode->i_blocks, | ||
| 1818 | (unsigned long long)sectors); | ||
| 1819 | set_sbi_flag(sbi, SBI_NEED_FSCK); | ||
| 1820 | return; | ||
| 1821 | } | ||
| 1795 | f2fs_i_blocks_write(inode, count, false, true); | 1822 | f2fs_i_blocks_write(inode, count, false, true); |
| 1796 | } | 1823 | } |
| 1797 | 1824 | ||
| @@ -1889,7 +1916,11 @@ static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag) | |||
| 1889 | if (is_set_ckpt_flags(sbi, CP_LARGE_NAT_BITMAP_FLAG)) { | 1916 | if (is_set_ckpt_flags(sbi, CP_LARGE_NAT_BITMAP_FLAG)) { |
| 1890 | offset = (flag == SIT_BITMAP) ? | 1917 | offset = (flag == SIT_BITMAP) ? |
| 1891 | le32_to_cpu(ckpt->nat_ver_bitmap_bytesize) : 0; | 1918 | le32_to_cpu(ckpt->nat_ver_bitmap_bytesize) : 0; |
| 1892 | return &ckpt->sit_nat_version_bitmap + offset; | 1919 | /* |
| 1920 | * if large_nat_bitmap feature is enabled, leave checksum | ||
| 1921 | * protection for all nat/sit bitmaps. | ||
| 1922 | */ | ||
| 1923 | return &ckpt->sit_nat_version_bitmap + offset + sizeof(__le32); | ||
| 1893 | } | 1924 | } |
| 1894 | 1925 | ||
| 1895 | if (__cp_payload(sbi) > 0) { | 1926 | if (__cp_payload(sbi) > 0) { |
| @@ -2008,7 +2039,6 @@ static inline void dec_valid_node_count(struct f2fs_sb_info *sbi, | |||
| 2008 | 2039 | ||
| 2009 | f2fs_bug_on(sbi, !sbi->total_valid_block_count); | 2040 | f2fs_bug_on(sbi, !sbi->total_valid_block_count); |
| 2010 | f2fs_bug_on(sbi, !sbi->total_valid_node_count); | 2041 | f2fs_bug_on(sbi, !sbi->total_valid_node_count); |
| 2011 | f2fs_bug_on(sbi, !is_inode && !inode->i_blocks); | ||
| 2012 | 2042 | ||
| 2013 | sbi->total_valid_node_count--; | 2043 | sbi->total_valid_node_count--; |
| 2014 | sbi->total_valid_block_count--; | 2044 | sbi->total_valid_block_count--; |
| @@ -2018,10 +2048,19 @@ static inline void dec_valid_node_count(struct f2fs_sb_info *sbi, | |||
| 2018 | 2048 | ||
| 2019 | spin_unlock(&sbi->stat_lock); | 2049 | spin_unlock(&sbi->stat_lock); |
| 2020 | 2050 | ||
| 2021 | if (is_inode) | 2051 | if (is_inode) { |
| 2022 | dquot_free_inode(inode); | 2052 | dquot_free_inode(inode); |
| 2023 | else | 2053 | } else { |
| 2054 | if (unlikely(inode->i_blocks == 0)) { | ||
| 2055 | f2fs_msg(sbi->sb, KERN_WARNING, | ||
| 2056 | "Inconsistent i_blocks, ino:%lu, iblocks:%llu", | ||
| 2057 | inode->i_ino, | ||
| 2058 | (unsigned long long)inode->i_blocks); | ||
| 2059 | set_sbi_flag(sbi, SBI_NEED_FSCK); | ||
| 2060 | return; | ||
| 2061 | } | ||
| 2024 | f2fs_i_blocks_write(inode, 1, false, true); | 2062 | f2fs_i_blocks_write(inode, 1, false, true); |
| 2063 | } | ||
| 2025 | } | 2064 | } |
| 2026 | 2065 | ||
| 2027 | static inline unsigned int valid_node_count(struct f2fs_sb_info *sbi) | 2066 | static inline unsigned int valid_node_count(struct f2fs_sb_info *sbi) |
| @@ -2545,7 +2584,14 @@ static inline int f2fs_has_inline_xattr(struct inode *inode) | |||
| 2545 | 2584 | ||
| 2546 | static inline unsigned int addrs_per_inode(struct inode *inode) | 2585 | static inline unsigned int addrs_per_inode(struct inode *inode) |
| 2547 | { | 2586 | { |
| 2548 | return CUR_ADDRS_PER_INODE(inode) - get_inline_xattr_addrs(inode); | 2587 | unsigned int addrs = CUR_ADDRS_PER_INODE(inode) - |
| 2588 | get_inline_xattr_addrs(inode); | ||
| 2589 | return ALIGN_DOWN(addrs, 1); | ||
| 2590 | } | ||
| 2591 | |||
| 2592 | static inline unsigned int addrs_per_block(struct inode *inode) | ||
| 2593 | { | ||
| 2594 | return ALIGN_DOWN(DEF_ADDRS_PER_BLOCK, 1); | ||
| 2549 | } | 2595 | } |
| 2550 | 2596 | ||
| 2551 | static inline void *inline_xattr_addr(struct inode *inode, struct page *page) | 2597 | static inline void *inline_xattr_addr(struct inode *inode, struct page *page) |
| @@ -2558,7 +2604,9 @@ static inline void *inline_xattr_addr(struct inode *inode, struct page *page) | |||
| 2558 | 2604 | ||
| 2559 | static inline int inline_xattr_size(struct inode *inode) | 2605 | static inline int inline_xattr_size(struct inode *inode) |
| 2560 | { | 2606 | { |
| 2561 | return get_inline_xattr_addrs(inode) * sizeof(__le32); | 2607 | if (f2fs_has_inline_xattr(inode)) |
| 2608 | return get_inline_xattr_addrs(inode) * sizeof(__le32); | ||
| 2609 | return 0; | ||
| 2562 | } | 2610 | } |
| 2563 | 2611 | ||
| 2564 | static inline int f2fs_has_inline_data(struct inode *inode) | 2612 | static inline int f2fs_has_inline_data(struct inode *inode) |
| @@ -2800,12 +2848,10 @@ static inline void f2fs_update_iostat(struct f2fs_sb_info *sbi, | |||
| 2800 | 2848 | ||
| 2801 | #define __is_large_section(sbi) ((sbi)->segs_per_sec > 1) | 2849 | #define __is_large_section(sbi) ((sbi)->segs_per_sec > 1) |
| 2802 | 2850 | ||
| 2803 | #define __is_meta_io(fio) (PAGE_TYPE_OF_BIO((fio)->type) == META && \ | 2851 | #define __is_meta_io(fio) (PAGE_TYPE_OF_BIO((fio)->type) == META) |
| 2804 | (!is_read_io((fio)->op) || (fio)->is_meta)) | ||
| 2805 | 2852 | ||
| 2806 | bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, | 2853 | bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, |
| 2807 | block_t blkaddr, int type); | 2854 | block_t blkaddr, int type); |
| 2808 | void f2fs_msg(struct super_block *sb, const char *level, const char *fmt, ...); | ||
| 2809 | static inline void verify_blkaddr(struct f2fs_sb_info *sbi, | 2855 | static inline void verify_blkaddr(struct f2fs_sb_info *sbi, |
| 2810 | block_t blkaddr, int type) | 2856 | block_t blkaddr, int type) |
| 2811 | { | 2857 | { |
| @@ -2824,15 +2870,6 @@ static inline bool __is_valid_data_blkaddr(block_t blkaddr) | |||
| 2824 | return true; | 2870 | return true; |
| 2825 | } | 2871 | } |
| 2826 | 2872 | ||
| 2827 | static inline bool is_valid_data_blkaddr(struct f2fs_sb_info *sbi, | ||
| 2828 | block_t blkaddr) | ||
| 2829 | { | ||
| 2830 | if (!__is_valid_data_blkaddr(blkaddr)) | ||
| 2831 | return false; | ||
| 2832 | verify_blkaddr(sbi, blkaddr, DATA_GENERIC); | ||
| 2833 | return true; | ||
| 2834 | } | ||
| 2835 | |||
| 2836 | static inline void f2fs_set_page_private(struct page *page, | 2873 | static inline void f2fs_set_page_private(struct page *page, |
| 2837 | unsigned long data) | 2874 | unsigned long data) |
| 2838 | { | 2875 | { |
| @@ -3530,16 +3567,12 @@ F2FS_FEATURE_FUNCS(lost_found, LOST_FOUND); | |||
| 3530 | F2FS_FEATURE_FUNCS(sb_chksum, SB_CHKSUM); | 3567 | F2FS_FEATURE_FUNCS(sb_chksum, SB_CHKSUM); |
| 3531 | 3568 | ||
| 3532 | #ifdef CONFIG_BLK_DEV_ZONED | 3569 | #ifdef CONFIG_BLK_DEV_ZONED |
| 3533 | static inline int get_blkz_type(struct f2fs_sb_info *sbi, | 3570 | static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi, |
| 3534 | struct block_device *bdev, block_t blkaddr) | 3571 | block_t blkaddr) |
| 3535 | { | 3572 | { |
| 3536 | unsigned int zno = blkaddr >> sbi->log_blocks_per_blkz; | 3573 | unsigned int zno = blkaddr >> sbi->log_blocks_per_blkz; |
| 3537 | int i; | ||
| 3538 | 3574 | ||
| 3539 | for (i = 0; i < sbi->s_ndevs; i++) | 3575 | return test_bit(zno, FDEV(devi).blkz_seq); |
| 3540 | if (FDEV(i).bdev == bdev) | ||
| 3541 | return FDEV(i).blkz_type[zno]; | ||
| 3542 | return -EINVAL; | ||
| 3543 | } | 3576 | } |
| 3544 | #endif | 3577 | #endif |
| 3545 | 3578 | ||
| @@ -3548,9 +3581,23 @@ static inline bool f2fs_hw_should_discard(struct f2fs_sb_info *sbi) | |||
| 3548 | return f2fs_sb_has_blkzoned(sbi); | 3581 | return f2fs_sb_has_blkzoned(sbi); |
| 3549 | } | 3582 | } |
| 3550 | 3583 | ||
| 3584 | static inline bool f2fs_bdev_support_discard(struct block_device *bdev) | ||
| 3585 | { | ||
| 3586 | return blk_queue_discard(bdev_get_queue(bdev)) || | ||
| 3587 | bdev_is_zoned(bdev); | ||
| 3588 | } | ||
| 3589 | |||
| 3551 | static inline bool f2fs_hw_support_discard(struct f2fs_sb_info *sbi) | 3590 | static inline bool f2fs_hw_support_discard(struct f2fs_sb_info *sbi) |
| 3552 | { | 3591 | { |
| 3553 | return blk_queue_discard(bdev_get_queue(sbi->sb->s_bdev)); | 3592 | int i; |
| 3593 | |||
| 3594 | if (!f2fs_is_multi_device(sbi)) | ||
| 3595 | return f2fs_bdev_support_discard(sbi->sb->s_bdev); | ||
| 3596 | |||
| 3597 | for (i = 0; i < sbi->s_ndevs; i++) | ||
| 3598 | if (f2fs_bdev_support_discard(FDEV(i).bdev)) | ||
| 3599 | return true; | ||
| 3600 | return false; | ||
| 3554 | } | 3601 | } |
| 3555 | 3602 | ||
| 3556 | static inline bool f2fs_realtime_discard_enable(struct f2fs_sb_info *sbi) | 3603 | static inline bool f2fs_realtime_discard_enable(struct f2fs_sb_info *sbi) |
| @@ -3559,6 +3606,20 @@ static inline bool f2fs_realtime_discard_enable(struct f2fs_sb_info *sbi) | |||
| 3559 | f2fs_hw_should_discard(sbi); | 3606 | f2fs_hw_should_discard(sbi); |
| 3560 | } | 3607 | } |
| 3561 | 3608 | ||
| 3609 | static inline bool f2fs_hw_is_readonly(struct f2fs_sb_info *sbi) | ||
| 3610 | { | ||
| 3611 | int i; | ||
| 3612 | |||
| 3613 | if (!f2fs_is_multi_device(sbi)) | ||
| 3614 | return bdev_read_only(sbi->sb->s_bdev); | ||
| 3615 | |||
| 3616 | for (i = 0; i < sbi->s_ndevs; i++) | ||
| 3617 | if (bdev_read_only(FDEV(i).bdev)) | ||
| 3618 | return true; | ||
| 3619 | return false; | ||
| 3620 | } | ||
| 3621 | |||
| 3622 | |||
| 3562 | static inline void set_opt_mode(struct f2fs_sb_info *sbi, unsigned int mt) | 3623 | static inline void set_opt_mode(struct f2fs_sb_info *sbi, unsigned int mt) |
| 3563 | { | 3624 | { |
| 3564 | clear_opt(sbi, ADAPTIVE); | 3625 | clear_opt(sbi, ADAPTIVE); |
| @@ -3614,7 +3675,7 @@ static inline bool f2fs_force_buffered_io(struct inode *inode, | |||
| 3614 | 3675 | ||
| 3615 | if (f2fs_post_read_required(inode)) | 3676 | if (f2fs_post_read_required(inode)) |
| 3616 | return true; | 3677 | return true; |
| 3617 | if (sbi->s_ndevs) | 3678 | if (f2fs_is_multi_device(sbi)) |
| 3618 | return true; | 3679 | return true; |
| 3619 | /* | 3680 | /* |
| 3620 | * for blkzoned device, fallback direct IO to buffered IO, so | 3681 | * for blkzoned device, fallback direct IO to buffered IO, so |
| @@ -3651,4 +3712,4 @@ static inline bool is_journalled_quota(struct f2fs_sb_info *sbi) | |||
| 3651 | return false; | 3712 | return false; |
| 3652 | } | 3713 | } |
| 3653 | 3714 | ||
| 3654 | #endif | 3715 | #endif /* _LINUX_F2FS_H */ |
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 5742ab8b57dc..45b45f37d347 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
| @@ -39,6 +39,8 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf) | |||
| 39 | ret = filemap_fault(vmf); | 39 | ret = filemap_fault(vmf); |
| 40 | up_read(&F2FS_I(inode)->i_mmap_sem); | 40 | up_read(&F2FS_I(inode)->i_mmap_sem); |
| 41 | 41 | ||
| 42 | trace_f2fs_filemap_fault(inode, vmf->pgoff, (unsigned long)ret); | ||
| 43 | |||
| 42 | return ret; | 44 | return ret; |
| 43 | } | 45 | } |
| 44 | 46 | ||
| @@ -356,7 +358,7 @@ static bool __found_offset(struct f2fs_sb_info *sbi, block_t blkaddr, | |||
| 356 | switch (whence) { | 358 | switch (whence) { |
| 357 | case SEEK_DATA: | 359 | case SEEK_DATA: |
| 358 | if ((blkaddr == NEW_ADDR && dirty == pgofs) || | 360 | if ((blkaddr == NEW_ADDR && dirty == pgofs) || |
| 359 | is_valid_data_blkaddr(sbi, blkaddr)) | 361 | __is_valid_data_blkaddr(blkaddr)) |
| 360 | return true; | 362 | return true; |
| 361 | break; | 363 | break; |
| 362 | case SEEK_HOLE: | 364 | case SEEK_HOLE: |
| @@ -422,7 +424,7 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence) | |||
| 422 | 424 | ||
| 423 | if (__is_valid_data_blkaddr(blkaddr) && | 425 | if (__is_valid_data_blkaddr(blkaddr) && |
| 424 | !f2fs_is_valid_blkaddr(F2FS_I_SB(inode), | 426 | !f2fs_is_valid_blkaddr(F2FS_I_SB(inode), |
| 425 | blkaddr, DATA_GENERIC)) { | 427 | blkaddr, DATA_GENERIC_ENHANCE)) { |
| 426 | f2fs_put_dnode(&dn); | 428 | f2fs_put_dnode(&dn); |
| 427 | goto fail; | 429 | goto fail; |
| 428 | } | 430 | } |
| @@ -523,7 +525,8 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count) | |||
| 523 | f2fs_set_data_blkaddr(dn); | 525 | f2fs_set_data_blkaddr(dn); |
| 524 | 526 | ||
| 525 | if (__is_valid_data_blkaddr(blkaddr) && | 527 | if (__is_valid_data_blkaddr(blkaddr) && |
| 526 | !f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) | 528 | !f2fs_is_valid_blkaddr(sbi, blkaddr, |
| 529 | DATA_GENERIC_ENHANCE)) | ||
| 527 | continue; | 530 | continue; |
| 528 | 531 | ||
| 529 | f2fs_invalidate_blocks(sbi, blkaddr); | 532 | f2fs_invalidate_blocks(sbi, blkaddr); |
| @@ -552,7 +555,7 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count) | |||
| 552 | 555 | ||
| 553 | void f2fs_truncate_data_blocks(struct dnode_of_data *dn) | 556 | void f2fs_truncate_data_blocks(struct dnode_of_data *dn) |
| 554 | { | 557 | { |
| 555 | f2fs_truncate_data_blocks_range(dn, ADDRS_PER_BLOCK); | 558 | f2fs_truncate_data_blocks_range(dn, ADDRS_PER_BLOCK(dn->inode)); |
| 556 | } | 559 | } |
| 557 | 560 | ||
| 558 | static int truncate_partial_data_page(struct inode *inode, u64 from, | 561 | static int truncate_partial_data_page(struct inode *inode, u64 from, |
| @@ -1006,7 +1009,8 @@ next_dnode: | |||
| 1006 | } else if (ret == -ENOENT) { | 1009 | } else if (ret == -ENOENT) { |
| 1007 | if (dn.max_level == 0) | 1010 | if (dn.max_level == 0) |
| 1008 | return -ENOENT; | 1011 | return -ENOENT; |
| 1009 | done = min((pgoff_t)ADDRS_PER_BLOCK - dn.ofs_in_node, len); | 1012 | done = min((pgoff_t)ADDRS_PER_BLOCK(inode) - dn.ofs_in_node, |
| 1013 | len); | ||
| 1010 | blkaddr += done; | 1014 | blkaddr += done; |
| 1011 | do_replace += done; | 1015 | do_replace += done; |
| 1012 | goto next; | 1016 | goto next; |
| @@ -1017,6 +1021,14 @@ next_dnode: | |||
| 1017 | for (i = 0; i < done; i++, blkaddr++, do_replace++, dn.ofs_in_node++) { | 1021 | for (i = 0; i < done; i++, blkaddr++, do_replace++, dn.ofs_in_node++) { |
| 1018 | *blkaddr = datablock_addr(dn.inode, | 1022 | *blkaddr = datablock_addr(dn.inode, |
| 1019 | dn.node_page, dn.ofs_in_node); | 1023 | dn.node_page, dn.ofs_in_node); |
| 1024 | |||
| 1025 | if (__is_valid_data_blkaddr(*blkaddr) && | ||
| 1026 | !f2fs_is_valid_blkaddr(sbi, *blkaddr, | ||
| 1027 | DATA_GENERIC_ENHANCE)) { | ||
| 1028 | f2fs_put_dnode(&dn); | ||
| 1029 | return -EFAULT; | ||
| 1030 | } | ||
| 1031 | |||
| 1020 | if (!f2fs_is_checkpointed_data(sbi, *blkaddr)) { | 1032 | if (!f2fs_is_checkpointed_data(sbi, *blkaddr)) { |
| 1021 | 1033 | ||
| 1022 | if (test_opt(sbi, LFS)) { | 1034 | if (test_opt(sbi, LFS)) { |
| @@ -1157,7 +1169,7 @@ static int __exchange_data_block(struct inode *src_inode, | |||
| 1157 | int ret; | 1169 | int ret; |
| 1158 | 1170 | ||
| 1159 | while (len) { | 1171 | while (len) { |
| 1160 | olen = min((pgoff_t)4 * ADDRS_PER_BLOCK, len); | 1172 | olen = min((pgoff_t)4 * ADDRS_PER_BLOCK(src_inode), len); |
| 1161 | 1173 | ||
| 1162 | src_blkaddr = f2fs_kvzalloc(F2FS_I_SB(src_inode), | 1174 | src_blkaddr = f2fs_kvzalloc(F2FS_I_SB(src_inode), |
| 1163 | array_size(olen, sizeof(block_t)), | 1175 | array_size(olen, sizeof(block_t)), |
| @@ -2573,10 +2585,10 @@ static int f2fs_ioc_flush_device(struct file *filp, unsigned long arg) | |||
| 2573 | sizeof(range))) | 2585 | sizeof(range))) |
| 2574 | return -EFAULT; | 2586 | return -EFAULT; |
| 2575 | 2587 | ||
| 2576 | if (sbi->s_ndevs <= 1 || sbi->s_ndevs - 1 <= range.dev_num || | 2588 | if (!f2fs_is_multi_device(sbi) || sbi->s_ndevs - 1 <= range.dev_num || |
| 2577 | __is_large_section(sbi)) { | 2589 | __is_large_section(sbi)) { |
| 2578 | f2fs_msg(sbi->sb, KERN_WARNING, | 2590 | f2fs_msg(sbi->sb, KERN_WARNING, |
| 2579 | "Can't flush %u in %d for segs_per_sec %u != 1\n", | 2591 | "Can't flush %u in %d for segs_per_sec %u != 1", |
| 2580 | range.dev_num, sbi->s_ndevs, | 2592 | range.dev_num, sbi->s_ndevs, |
| 2581 | sbi->segs_per_sec); | 2593 | sbi->segs_per_sec); |
| 2582 | return -EINVAL; | 2594 | return -EINVAL; |
| @@ -2858,7 +2870,7 @@ int f2fs_pin_file_control(struct inode *inode, bool inc) | |||
| 2858 | 2870 | ||
| 2859 | if (fi->i_gc_failures[GC_FAILURE_PIN] > sbi->gc_pin_file_threshold) { | 2871 | if (fi->i_gc_failures[GC_FAILURE_PIN] > sbi->gc_pin_file_threshold) { |
| 2860 | f2fs_msg(sbi->sb, KERN_WARNING, | 2872 | f2fs_msg(sbi->sb, KERN_WARNING, |
| 2861 | "%s: Enable GC = ino %lx after %x GC trials\n", | 2873 | "%s: Enable GC = ino %lx after %x GC trials", |
| 2862 | __func__, inode->i_ino, | 2874 | __func__, inode->i_ino, |
| 2863 | fi->i_gc_failures[GC_FAILURE_PIN]); | 2875 | fi->i_gc_failures[GC_FAILURE_PIN]); |
| 2864 | clear_inode_flag(inode, FI_PIN_FILE); | 2876 | clear_inode_flag(inode, FI_PIN_FILE); |
| @@ -3035,15 +3047,21 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
| 3035 | struct inode *inode = file_inode(file); | 3047 | struct inode *inode = file_inode(file); |
| 3036 | ssize_t ret; | 3048 | ssize_t ret; |
| 3037 | 3049 | ||
| 3038 | if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) | 3050 | if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) { |
| 3039 | return -EIO; | 3051 | ret = -EIO; |
| 3052 | goto out; | ||
| 3053 | } | ||
| 3040 | 3054 | ||
| 3041 | if ((iocb->ki_flags & IOCB_NOWAIT) && !(iocb->ki_flags & IOCB_DIRECT)) | 3055 | if ((iocb->ki_flags & IOCB_NOWAIT) && !(iocb->ki_flags & IOCB_DIRECT)) { |
| 3042 | return -EINVAL; | 3056 | ret = -EINVAL; |
| 3057 | goto out; | ||
| 3058 | } | ||
| 3043 | 3059 | ||
| 3044 | if (!inode_trylock(inode)) { | 3060 | if (!inode_trylock(inode)) { |
| 3045 | if (iocb->ki_flags & IOCB_NOWAIT) | 3061 | if (iocb->ki_flags & IOCB_NOWAIT) { |
| 3046 | return -EAGAIN; | 3062 | ret = -EAGAIN; |
| 3063 | goto out; | ||
| 3064 | } | ||
| 3047 | inode_lock(inode); | 3065 | inode_lock(inode); |
| 3048 | } | 3066 | } |
| 3049 | 3067 | ||
| @@ -3056,19 +3074,16 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
| 3056 | if (iov_iter_fault_in_readable(from, iov_iter_count(from))) | 3074 | if (iov_iter_fault_in_readable(from, iov_iter_count(from))) |
| 3057 | set_inode_flag(inode, FI_NO_PREALLOC); | 3075 | set_inode_flag(inode, FI_NO_PREALLOC); |
| 3058 | 3076 | ||
| 3059 | if ((iocb->ki_flags & IOCB_NOWAIT) && | 3077 | if ((iocb->ki_flags & IOCB_NOWAIT)) { |
| 3060 | (iocb->ki_flags & IOCB_DIRECT)) { | 3078 | if (!f2fs_overwrite_io(inode, iocb->ki_pos, |
| 3061 | if (!f2fs_overwrite_io(inode, iocb->ki_pos, | ||
| 3062 | iov_iter_count(from)) || | 3079 | iov_iter_count(from)) || |
| 3063 | f2fs_has_inline_data(inode) || | 3080 | f2fs_has_inline_data(inode) || |
| 3064 | f2fs_force_buffered_io(inode, | 3081 | f2fs_force_buffered_io(inode, iocb, from)) { |
| 3065 | iocb, from)) { | 3082 | clear_inode_flag(inode, FI_NO_PREALLOC); |
| 3066 | clear_inode_flag(inode, | 3083 | inode_unlock(inode); |
| 3067 | FI_NO_PREALLOC); | 3084 | ret = -EAGAIN; |
| 3068 | inode_unlock(inode); | 3085 | goto out; |
| 3069 | return -EAGAIN; | 3086 | } |
| 3070 | } | ||
| 3071 | |||
| 3072 | } else { | 3087 | } else { |
| 3073 | preallocated = true; | 3088 | preallocated = true; |
| 3074 | target_size = iocb->ki_pos + iov_iter_count(from); | 3089 | target_size = iocb->ki_pos + iov_iter_count(from); |
| @@ -3077,7 +3092,8 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
| 3077 | if (err) { | 3092 | if (err) { |
| 3078 | clear_inode_flag(inode, FI_NO_PREALLOC); | 3093 | clear_inode_flag(inode, FI_NO_PREALLOC); |
| 3079 | inode_unlock(inode); | 3094 | inode_unlock(inode); |
| 3080 | return err; | 3095 | ret = err; |
| 3096 | goto out; | ||
| 3081 | } | 3097 | } |
| 3082 | } | 3098 | } |
| 3083 | ret = __generic_file_write_iter(iocb, from); | 3099 | ret = __generic_file_write_iter(iocb, from); |
| @@ -3091,7 +3107,9 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
| 3091 | f2fs_update_iostat(F2FS_I_SB(inode), APP_WRITE_IO, ret); | 3107 | f2fs_update_iostat(F2FS_I_SB(inode), APP_WRITE_IO, ret); |
| 3092 | } | 3108 | } |
| 3093 | inode_unlock(inode); | 3109 | inode_unlock(inode); |
| 3094 | 3110 | out: | |
| 3111 | trace_f2fs_file_write_iter(inode, iocb->ki_pos, | ||
| 3112 | iov_iter_count(from), ret); | ||
| 3095 | if (ret > 0) | 3113 | if (ret > 0) |
| 3096 | ret = generic_write_sync(iocb, ret); | 3114 | ret = generic_write_sync(iocb, ret); |
| 3097 | return ret; | 3115 | return ret; |
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 195cf0f9d9ef..963fb4571fd9 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c | |||
| @@ -591,7 +591,7 @@ block_t f2fs_start_bidx_of_node(unsigned int node_ofs, struct inode *inode) | |||
| 591 | int dec = (node_ofs - indirect_blks - 3) / (NIDS_PER_BLOCK + 1); | 591 | int dec = (node_ofs - indirect_blks - 3) / (NIDS_PER_BLOCK + 1); |
| 592 | bidx = node_ofs - 5 - dec; | 592 | bidx = node_ofs - 5 - dec; |
| 593 | } | 593 | } |
| 594 | return bidx * ADDRS_PER_BLOCK + ADDRS_PER_INODE(inode); | 594 | return bidx * ADDRS_PER_BLOCK(inode) + ADDRS_PER_INODE(inode); |
| 595 | } | 595 | } |
| 596 | 596 | ||
| 597 | static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, | 597 | static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, |
| @@ -656,6 +656,11 @@ static int ra_data_block(struct inode *inode, pgoff_t index) | |||
| 656 | 656 | ||
| 657 | if (f2fs_lookup_extent_cache(inode, index, &ei)) { | 657 | if (f2fs_lookup_extent_cache(inode, index, &ei)) { |
| 658 | dn.data_blkaddr = ei.blk + index - ei.fofs; | 658 | dn.data_blkaddr = ei.blk + index - ei.fofs; |
| 659 | if (unlikely(!f2fs_is_valid_blkaddr(sbi, dn.data_blkaddr, | ||
| 660 | DATA_GENERIC_ENHANCE_READ))) { | ||
| 661 | err = -EFAULT; | ||
| 662 | goto put_page; | ||
| 663 | } | ||
| 659 | goto got_it; | 664 | goto got_it; |
| 660 | } | 665 | } |
| 661 | 666 | ||
| @@ -665,8 +670,12 @@ static int ra_data_block(struct inode *inode, pgoff_t index) | |||
| 665 | goto put_page; | 670 | goto put_page; |
| 666 | f2fs_put_dnode(&dn); | 671 | f2fs_put_dnode(&dn); |
| 667 | 672 | ||
| 673 | if (!__is_valid_data_blkaddr(dn.data_blkaddr)) { | ||
| 674 | err = -ENOENT; | ||
| 675 | goto put_page; | ||
| 676 | } | ||
| 668 | if (unlikely(!f2fs_is_valid_blkaddr(sbi, dn.data_blkaddr, | 677 | if (unlikely(!f2fs_is_valid_blkaddr(sbi, dn.data_blkaddr, |
| 669 | DATA_GENERIC))) { | 678 | DATA_GENERIC_ENHANCE))) { |
| 670 | err = -EFAULT; | 679 | err = -EFAULT; |
| 671 | goto put_page; | 680 | goto put_page; |
| 672 | } | 681 | } |
| @@ -1175,6 +1184,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, | |||
| 1175 | "type [%d, %d] in SSA and SIT", | 1184 | "type [%d, %d] in SSA and SIT", |
| 1176 | segno, type, GET_SUM_TYPE((&sum->footer))); | 1185 | segno, type, GET_SUM_TYPE((&sum->footer))); |
| 1177 | set_sbi_flag(sbi, SBI_NEED_FSCK); | 1186 | set_sbi_flag(sbi, SBI_NEED_FSCK); |
| 1187 | f2fs_stop_checkpoint(sbi, false); | ||
| 1178 | goto skip; | 1188 | goto skip; |
| 1179 | } | 1189 | } |
| 1180 | 1190 | ||
| @@ -1346,7 +1356,7 @@ void f2fs_build_gc_manager(struct f2fs_sb_info *sbi) | |||
| 1346 | sbi->gc_pin_file_threshold = DEF_GC_FAILED_PINNED_FILES; | 1356 | sbi->gc_pin_file_threshold = DEF_GC_FAILED_PINNED_FILES; |
| 1347 | 1357 | ||
| 1348 | /* give warm/cold data area from slower device */ | 1358 | /* give warm/cold data area from slower device */ |
| 1349 | if (sbi->s_ndevs && !__is_large_section(sbi)) | 1359 | if (f2fs_is_multi_device(sbi) && !__is_large_section(sbi)) |
| 1350 | SIT_I(sbi)->last_victim[ALLOC_NEXT] = | 1360 | SIT_I(sbi)->last_victim[ALLOC_NEXT] = |
| 1351 | GET_SEGNO(sbi, FDEV(0).end_blk) + 1; | 1361 | GET_SEGNO(sbi, FDEV(0).end_blk) + 1; |
| 1352 | } | 1362 | } |
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index bb6a152310ef..404d2462a0fe 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c | |||
| @@ -420,6 +420,14 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage, | |||
| 420 | stat_dec_inline_dir(dir); | 420 | stat_dec_inline_dir(dir); |
| 421 | clear_inode_flag(dir, FI_INLINE_DENTRY); | 421 | clear_inode_flag(dir, FI_INLINE_DENTRY); |
| 422 | 422 | ||
| 423 | /* | ||
| 424 | * should retrieve reserved space which was used to keep | ||
| 425 | * inline_dentry's structure for backward compatibility. | ||
| 426 | */ | ||
| 427 | if (!f2fs_sb_has_flexible_inline_xattr(F2FS_I_SB(dir)) && | ||
| 428 | !f2fs_has_inline_xattr(dir)) | ||
| 429 | F2FS_I(dir)->i_inline_xattr_size = 0; | ||
| 430 | |||
| 423 | f2fs_i_depth_write(dir, 1); | 431 | f2fs_i_depth_write(dir, 1); |
| 424 | if (i_size_read(dir) < PAGE_SIZE) | 432 | if (i_size_read(dir) < PAGE_SIZE) |
| 425 | f2fs_i_size_write(dir, PAGE_SIZE); | 433 | f2fs_i_size_write(dir, PAGE_SIZE); |
| @@ -501,6 +509,15 @@ static int f2fs_move_rehashed_dirents(struct inode *dir, struct page *ipage, | |||
| 501 | 509 | ||
| 502 | stat_dec_inline_dir(dir); | 510 | stat_dec_inline_dir(dir); |
| 503 | clear_inode_flag(dir, FI_INLINE_DENTRY); | 511 | clear_inode_flag(dir, FI_INLINE_DENTRY); |
| 512 | |||
| 513 | /* | ||
| 514 | * should retrieve reserved space which was used to keep | ||
| 515 | * inline_dentry's structure for backward compatibility. | ||
| 516 | */ | ||
| 517 | if (!f2fs_sb_has_flexible_inline_xattr(F2FS_I_SB(dir)) && | ||
| 518 | !f2fs_has_inline_xattr(dir)) | ||
| 519 | F2FS_I(dir)->i_inline_xattr_size = 0; | ||
| 520 | |||
| 504 | kvfree(backup_dentry); | 521 | kvfree(backup_dentry); |
| 505 | return 0; | 522 | return 0; |
| 506 | recover: | 523 | recover: |
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index e7f2e8759315..ccb02226dd2c 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c | |||
| @@ -73,7 +73,7 @@ static int __written_first_block(struct f2fs_sb_info *sbi, | |||
| 73 | 73 | ||
| 74 | if (!__is_valid_data_blkaddr(addr)) | 74 | if (!__is_valid_data_blkaddr(addr)) |
| 75 | return 1; | 75 | return 1; |
| 76 | if (!f2fs_is_valid_blkaddr(sbi, addr, DATA_GENERIC)) | 76 | if (!f2fs_is_valid_blkaddr(sbi, addr, DATA_GENERIC_ENHANCE)) |
| 77 | return -EFAULT; | 77 | return -EFAULT; |
| 78 | return 0; | 78 | return 0; |
| 79 | } | 79 | } |
| @@ -177,8 +177,8 @@ bool f2fs_inode_chksum_verify(struct f2fs_sb_info *sbi, struct page *page) | |||
| 177 | 177 | ||
| 178 | if (provided != calculated) | 178 | if (provided != calculated) |
| 179 | f2fs_msg(sbi->sb, KERN_WARNING, | 179 | f2fs_msg(sbi->sb, KERN_WARNING, |
| 180 | "checksum invalid, ino = %x, %x vs. %x", | 180 | "checksum invalid, nid = %lu, ino_of_node = %x, %x vs. %x", |
| 181 | ino_of_node(page), provided, calculated); | 181 | page->index, ino_of_node(page), provided, calculated); |
| 182 | 182 | ||
| 183 | return provided == calculated; | 183 | return provided == calculated; |
| 184 | } | 184 | } |
| @@ -267,9 +267,10 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page) | |||
| 267 | struct extent_info *ei = &F2FS_I(inode)->extent_tree->largest; | 267 | struct extent_info *ei = &F2FS_I(inode)->extent_tree->largest; |
| 268 | 268 | ||
| 269 | if (ei->len && | 269 | if (ei->len && |
| 270 | (!f2fs_is_valid_blkaddr(sbi, ei->blk, DATA_GENERIC) || | 270 | (!f2fs_is_valid_blkaddr(sbi, ei->blk, |
| 271 | DATA_GENERIC_ENHANCE) || | ||
| 271 | !f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1, | 272 | !f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1, |
| 272 | DATA_GENERIC))) { | 273 | DATA_GENERIC_ENHANCE))) { |
| 273 | set_sbi_flag(sbi, SBI_NEED_FSCK); | 274 | set_sbi_flag(sbi, SBI_NEED_FSCK); |
| 274 | f2fs_msg(sbi->sb, KERN_WARNING, | 275 | f2fs_msg(sbi->sb, KERN_WARNING, |
| 275 | "%s: inode (ino=%lx) extent info [%u, %u, %u] " | 276 | "%s: inode (ino=%lx) extent info [%u, %u, %u] " |
| @@ -488,6 +489,7 @@ make_now: | |||
| 488 | return inode; | 489 | return inode; |
| 489 | 490 | ||
| 490 | bad_inode: | 491 | bad_inode: |
| 492 | f2fs_inode_synced(inode); | ||
| 491 | iget_failed(inode); | 493 | iget_failed(inode); |
| 492 | trace_f2fs_iget_exit(inode, ret); | 494 | trace_f2fs_iget_exit(inode, ret); |
| 493 | return ERR_PTR(ret); | 495 | return ERR_PTR(ret); |
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index c3e8a901d47a..0f77f9242751 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
| @@ -143,7 +143,7 @@ fail_drop: | |||
| 143 | return ERR_PTR(err); | 143 | return ERR_PTR(err); |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | static int is_extension_exist(const unsigned char *s, const char *sub) | 146 | static inline int is_extension_exist(const unsigned char *s, const char *sub) |
| 147 | { | 147 | { |
| 148 | size_t slen = strlen(s); | 148 | size_t slen = strlen(s); |
| 149 | size_t sublen = strlen(sub); | 149 | size_t sublen = strlen(sub); |
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index d6e48a6487d5..18a038a2a9fa 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c | |||
| @@ -454,7 +454,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, | |||
| 454 | new_blkaddr == NULL_ADDR); | 454 | new_blkaddr == NULL_ADDR); |
| 455 | f2fs_bug_on(sbi, nat_get_blkaddr(e) == NEW_ADDR && | 455 | f2fs_bug_on(sbi, nat_get_blkaddr(e) == NEW_ADDR && |
| 456 | new_blkaddr == NEW_ADDR); | 456 | new_blkaddr == NEW_ADDR); |
| 457 | f2fs_bug_on(sbi, is_valid_data_blkaddr(sbi, nat_get_blkaddr(e)) && | 457 | f2fs_bug_on(sbi, __is_valid_data_blkaddr(nat_get_blkaddr(e)) && |
| 458 | new_blkaddr == NEW_ADDR); | 458 | new_blkaddr == NEW_ADDR); |
| 459 | 459 | ||
| 460 | /* increment version no as node is removed */ | 460 | /* increment version no as node is removed */ |
| @@ -465,7 +465,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, | |||
| 465 | 465 | ||
| 466 | /* change address */ | 466 | /* change address */ |
| 467 | nat_set_blkaddr(e, new_blkaddr); | 467 | nat_set_blkaddr(e, new_blkaddr); |
| 468 | if (!is_valid_data_blkaddr(sbi, new_blkaddr)) | 468 | if (!__is_valid_data_blkaddr(new_blkaddr)) |
| 469 | set_nat_flag(e, IS_CHECKPOINTED, false); | 469 | set_nat_flag(e, IS_CHECKPOINTED, false); |
| 470 | __set_nat_cache_dirty(nm_i, e); | 470 | __set_nat_cache_dirty(nm_i, e); |
| 471 | 471 | ||
| @@ -526,6 +526,7 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, | |||
| 526 | struct f2fs_nat_entry ne; | 526 | struct f2fs_nat_entry ne; |
| 527 | struct nat_entry *e; | 527 | struct nat_entry *e; |
| 528 | pgoff_t index; | 528 | pgoff_t index; |
| 529 | block_t blkaddr; | ||
| 529 | int i; | 530 | int i; |
| 530 | 531 | ||
| 531 | ni->nid = nid; | 532 | ni->nid = nid; |
| @@ -569,6 +570,11 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, | |||
| 569 | node_info_from_raw_nat(ni, &ne); | 570 | node_info_from_raw_nat(ni, &ne); |
| 570 | f2fs_put_page(page, 1); | 571 | f2fs_put_page(page, 1); |
| 571 | cache: | 572 | cache: |
| 573 | blkaddr = le32_to_cpu(ne.block_addr); | ||
| 574 | if (__is_valid_data_blkaddr(blkaddr) && | ||
| 575 | !f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE)) | ||
| 576 | return -EFAULT; | ||
| 577 | |||
| 572 | /* cache nat entry */ | 578 | /* cache nat entry */ |
| 573 | cache_nat_entry(sbi, nid, &ne); | 579 | cache_nat_entry(sbi, nid, &ne); |
| 574 | return 0; | 580 | return 0; |
| @@ -600,9 +606,9 @@ static void f2fs_ra_node_pages(struct page *parent, int start, int n) | |||
| 600 | pgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs) | 606 | pgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs) |
| 601 | { | 607 | { |
| 602 | const long direct_index = ADDRS_PER_INODE(dn->inode); | 608 | const long direct_index = ADDRS_PER_INODE(dn->inode); |
| 603 | const long direct_blks = ADDRS_PER_BLOCK; | 609 | const long direct_blks = ADDRS_PER_BLOCK(dn->inode); |
| 604 | const long indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK; | 610 | const long indirect_blks = ADDRS_PER_BLOCK(dn->inode) * NIDS_PER_BLOCK; |
| 605 | unsigned int skipped_unit = ADDRS_PER_BLOCK; | 611 | unsigned int skipped_unit = ADDRS_PER_BLOCK(dn->inode); |
| 606 | int cur_level = dn->cur_level; | 612 | int cur_level = dn->cur_level; |
| 607 | int max_level = dn->max_level; | 613 | int max_level = dn->max_level; |
| 608 | pgoff_t base = 0; | 614 | pgoff_t base = 0; |
| @@ -638,9 +644,9 @@ static int get_node_path(struct inode *inode, long block, | |||
| 638 | int offset[4], unsigned int noffset[4]) | 644 | int offset[4], unsigned int noffset[4]) |
| 639 | { | 645 | { |
| 640 | const long direct_index = ADDRS_PER_INODE(inode); | 646 | const long direct_index = ADDRS_PER_INODE(inode); |
| 641 | const long direct_blks = ADDRS_PER_BLOCK; | 647 | const long direct_blks = ADDRS_PER_BLOCK(inode); |
| 642 | const long dptrs_per_blk = NIDS_PER_BLOCK; | 648 | const long dptrs_per_blk = NIDS_PER_BLOCK; |
| 643 | const long indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK; | 649 | const long indirect_blks = ADDRS_PER_BLOCK(inode) * NIDS_PER_BLOCK; |
| 644 | const long dindirect_blks = indirect_blks * NIDS_PER_BLOCK; | 650 | const long dindirect_blks = indirect_blks * NIDS_PER_BLOCK; |
| 645 | int n = 0; | 651 | int n = 0; |
| 646 | int level = 0; | 652 | int level = 0; |
| @@ -1181,8 +1187,14 @@ int f2fs_remove_inode_page(struct inode *inode) | |||
| 1181 | f2fs_put_dnode(&dn); | 1187 | f2fs_put_dnode(&dn); |
| 1182 | return -EIO; | 1188 | return -EIO; |
| 1183 | } | 1189 | } |
| 1184 | f2fs_bug_on(F2FS_I_SB(inode), | 1190 | |
| 1185 | inode->i_blocks != 0 && inode->i_blocks != 8); | 1191 | if (unlikely(inode->i_blocks != 0 && inode->i_blocks != 8)) { |
| 1192 | f2fs_msg(F2FS_I_SB(inode)->sb, KERN_WARNING, | ||
| 1193 | "Inconsistent i_blocks, ino:%lu, iblocks:%llu", | ||
| 1194 | inode->i_ino, | ||
| 1195 | (unsigned long long)inode->i_blocks); | ||
| 1196 | set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK); | ||
| 1197 | } | ||
| 1186 | 1198 | ||
| 1187 | /* will put inode & node pages */ | 1199 | /* will put inode & node pages */ |
| 1188 | err = truncate_node(&dn); | 1200 | err = truncate_node(&dn); |
| @@ -1277,9 +1289,10 @@ static int read_node_page(struct page *page, int op_flags) | |||
| 1277 | int err; | 1289 | int err; |
| 1278 | 1290 | ||
| 1279 | if (PageUptodate(page)) { | 1291 | if (PageUptodate(page)) { |
| 1280 | #ifdef CONFIG_F2FS_CHECK_FS | 1292 | if (!f2fs_inode_chksum_verify(sbi, page)) { |
| 1281 | f2fs_bug_on(sbi, !f2fs_inode_chksum_verify(sbi, page)); | 1293 | ClearPageUptodate(page); |
| 1282 | #endif | 1294 | return -EBADMSG; |
| 1295 | } | ||
| 1283 | return LOCKED_PAGE; | 1296 | return LOCKED_PAGE; |
| 1284 | } | 1297 | } |
| 1285 | 1298 | ||
| @@ -1543,7 +1556,8 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, | |||
| 1543 | } | 1556 | } |
| 1544 | 1557 | ||
| 1545 | if (__is_valid_data_blkaddr(ni.blk_addr) && | 1558 | if (__is_valid_data_blkaddr(ni.blk_addr) && |
| 1546 | !f2fs_is_valid_blkaddr(sbi, ni.blk_addr, DATA_GENERIC)) { | 1559 | !f2fs_is_valid_blkaddr(sbi, ni.blk_addr, |
| 1560 | DATA_GENERIC_ENHANCE)) { | ||
| 1547 | up_read(&sbi->node_write); | 1561 | up_read(&sbi->node_write); |
| 1548 | goto redirty_out; | 1562 | goto redirty_out; |
| 1549 | } | 1563 | } |
| @@ -2078,6 +2092,9 @@ static bool add_free_nid(struct f2fs_sb_info *sbi, | |||
| 2078 | if (unlikely(nid == 0)) | 2092 | if (unlikely(nid == 0)) |
| 2079 | return false; | 2093 | return false; |
| 2080 | 2094 | ||
| 2095 | if (unlikely(f2fs_check_nid_range(sbi, nid))) | ||
| 2096 | return false; | ||
| 2097 | |||
| 2081 | i = f2fs_kmem_cache_alloc(free_nid_slab, GFP_NOFS); | 2098 | i = f2fs_kmem_cache_alloc(free_nid_slab, GFP_NOFS); |
| 2082 | i->nid = nid; | 2099 | i->nid = nid; |
| 2083 | i->state = FREE_NID; | 2100 | i->state = FREE_NID; |
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index e3883db868d8..e04f82b3f4fc 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c | |||
| @@ -325,8 +325,10 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head, | |||
| 325 | break; | 325 | break; |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | if (!is_recoverable_dnode(page)) | 328 | if (!is_recoverable_dnode(page)) { |
| 329 | f2fs_put_page(page, 1); | ||
| 329 | break; | 330 | break; |
| 331 | } | ||
| 330 | 332 | ||
| 331 | if (!is_fsync_dnode(page)) | 333 | if (!is_fsync_dnode(page)) |
| 332 | goto next; | 334 | goto next; |
| @@ -338,8 +340,10 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head, | |||
| 338 | if (!check_only && | 340 | if (!check_only && |
| 339 | IS_INODE(page) && is_dent_dnode(page)) { | 341 | IS_INODE(page) && is_dent_dnode(page)) { |
| 340 | err = f2fs_recover_inode_page(sbi, page); | 342 | err = f2fs_recover_inode_page(sbi, page); |
| 341 | if (err) | 343 | if (err) { |
| 344 | f2fs_put_page(page, 1); | ||
| 342 | break; | 345 | break; |
| 346 | } | ||
| 343 | quota_inode = true; | 347 | quota_inode = true; |
| 344 | } | 348 | } |
| 345 | 349 | ||
| @@ -355,6 +359,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head, | |||
| 355 | err = 0; | 359 | err = 0; |
| 356 | goto next; | 360 | goto next; |
| 357 | } | 361 | } |
| 362 | f2fs_put_page(page, 1); | ||
| 358 | break; | 363 | break; |
| 359 | } | 364 | } |
| 360 | } | 365 | } |
| @@ -370,6 +375,7 @@ next: | |||
| 370 | "%s: detect looped node chain, " | 375 | "%s: detect looped node chain, " |
| 371 | "blkaddr:%u, next:%u", | 376 | "blkaddr:%u, next:%u", |
| 372 | __func__, blkaddr, next_blkaddr_of_node(page)); | 377 | __func__, blkaddr, next_blkaddr_of_node(page)); |
| 378 | f2fs_put_page(page, 1); | ||
| 373 | err = -EINVAL; | 379 | err = -EINVAL; |
| 374 | break; | 380 | break; |
| 375 | } | 381 | } |
| @@ -380,7 +386,6 @@ next: | |||
| 380 | 386 | ||
| 381 | f2fs_ra_meta_pages_cond(sbi, blkaddr); | 387 | f2fs_ra_meta_pages_cond(sbi, blkaddr); |
| 382 | } | 388 | } |
| 383 | f2fs_put_page(page, 1); | ||
| 384 | return err; | 389 | return err; |
| 385 | } | 390 | } |
| 386 | 391 | ||
| @@ -546,7 +551,15 @@ retry_dn: | |||
| 546 | goto err; | 551 | goto err; |
| 547 | 552 | ||
| 548 | f2fs_bug_on(sbi, ni.ino != ino_of_node(page)); | 553 | f2fs_bug_on(sbi, ni.ino != ino_of_node(page)); |
| 549 | f2fs_bug_on(sbi, ofs_of_node(dn.node_page) != ofs_of_node(page)); | 554 | |
| 555 | if (ofs_of_node(dn.node_page) != ofs_of_node(page)) { | ||
| 556 | f2fs_msg(sbi->sb, KERN_WARNING, | ||
| 557 | "Inconsistent ofs_of_node, ino:%lu, ofs:%u, %u", | ||
| 558 | inode->i_ino, ofs_of_node(dn.node_page), | ||
| 559 | ofs_of_node(page)); | ||
| 560 | err = -EFAULT; | ||
| 561 | goto err; | ||
| 562 | } | ||
| 550 | 563 | ||
| 551 | for (; start < end; start++, dn.ofs_in_node++) { | 564 | for (; start < end; start++, dn.ofs_in_node++) { |
| 552 | block_t src, dest; | 565 | block_t src, dest; |
| @@ -554,6 +567,18 @@ retry_dn: | |||
| 554 | src = datablock_addr(dn.inode, dn.node_page, dn.ofs_in_node); | 567 | src = datablock_addr(dn.inode, dn.node_page, dn.ofs_in_node); |
| 555 | dest = datablock_addr(dn.inode, page, dn.ofs_in_node); | 568 | dest = datablock_addr(dn.inode, page, dn.ofs_in_node); |
| 556 | 569 | ||
| 570 | if (__is_valid_data_blkaddr(src) && | ||
| 571 | !f2fs_is_valid_blkaddr(sbi, src, META_POR)) { | ||
| 572 | err = -EFAULT; | ||
| 573 | goto err; | ||
| 574 | } | ||
| 575 | |||
| 576 | if (__is_valid_data_blkaddr(dest) && | ||
| 577 | !f2fs_is_valid_blkaddr(sbi, dest, META_POR)) { | ||
| 578 | err = -EFAULT; | ||
| 579 | goto err; | ||
| 580 | } | ||
| 581 | |||
| 557 | /* skip recovering if dest is the same as src */ | 582 | /* skip recovering if dest is the same as src */ |
| 558 | if (src == dest) | 583 | if (src == dest) |
| 559 | continue; | 584 | continue; |
| @@ -666,8 +691,10 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list, | |||
| 666 | */ | 691 | */ |
| 667 | if (IS_INODE(page)) { | 692 | if (IS_INODE(page)) { |
| 668 | err = recover_inode(entry->inode, page); | 693 | err = recover_inode(entry->inode, page); |
| 669 | if (err) | 694 | if (err) { |
| 695 | f2fs_put_page(page, 1); | ||
| 670 | break; | 696 | break; |
| 697 | } | ||
| 671 | } | 698 | } |
| 672 | if (entry->last_dentry == blkaddr) { | 699 | if (entry->last_dentry == blkaddr) { |
| 673 | err = recover_dentry(entry->inode, page, dir_list); | 700 | err = recover_dentry(entry->inode, page, dir_list); |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index aa7fe79b62b2..8dee063c833f 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
| @@ -580,7 +580,7 @@ static int submit_flush_wait(struct f2fs_sb_info *sbi, nid_t ino) | |||
| 580 | int ret = 0; | 580 | int ret = 0; |
| 581 | int i; | 581 | int i; |
| 582 | 582 | ||
| 583 | if (!sbi->s_ndevs) | 583 | if (!f2fs_is_multi_device(sbi)) |
| 584 | return __submit_flush_wait(sbi, sbi->sb->s_bdev); | 584 | return __submit_flush_wait(sbi, sbi->sb->s_bdev); |
| 585 | 585 | ||
| 586 | for (i = 0; i < sbi->s_ndevs; i++) { | 586 | for (i = 0; i < sbi->s_ndevs; i++) { |
| @@ -648,7 +648,8 @@ int f2fs_issue_flush(struct f2fs_sb_info *sbi, nid_t ino) | |||
| 648 | return ret; | 648 | return ret; |
| 649 | } | 649 | } |
| 650 | 650 | ||
| 651 | if (atomic_inc_return(&fcc->queued_flush) == 1 || sbi->s_ndevs > 1) { | 651 | if (atomic_inc_return(&fcc->queued_flush) == 1 || |
| 652 | f2fs_is_multi_device(sbi)) { | ||
| 652 | ret = submit_flush_wait(sbi, ino); | 653 | ret = submit_flush_wait(sbi, ino); |
| 653 | atomic_dec(&fcc->queued_flush); | 654 | atomic_dec(&fcc->queued_flush); |
| 654 | 655 | ||
| @@ -754,7 +755,7 @@ int f2fs_flush_device_cache(struct f2fs_sb_info *sbi) | |||
| 754 | { | 755 | { |
| 755 | int ret = 0, i; | 756 | int ret = 0, i; |
| 756 | 757 | ||
| 757 | if (!sbi->s_ndevs) | 758 | if (!f2fs_is_multi_device(sbi)) |
| 758 | return 0; | 759 | return 0; |
| 759 | 760 | ||
| 760 | for (i = 1; i < sbi->s_ndevs; i++) { | 761 | for (i = 1; i < sbi->s_ndevs; i++) { |
| @@ -1367,9 +1368,12 @@ static int __queue_discard_cmd(struct f2fs_sb_info *sbi, | |||
| 1367 | { | 1368 | { |
| 1368 | block_t lblkstart = blkstart; | 1369 | block_t lblkstart = blkstart; |
| 1369 | 1370 | ||
| 1371 | if (!f2fs_bdev_support_discard(bdev)) | ||
| 1372 | return 0; | ||
| 1373 | |||
| 1370 | trace_f2fs_queue_discard(bdev, blkstart, blklen); | 1374 | trace_f2fs_queue_discard(bdev, blkstart, blklen); |
| 1371 | 1375 | ||
| 1372 | if (sbi->s_ndevs) { | 1376 | if (f2fs_is_multi_device(sbi)) { |
| 1373 | int devi = f2fs_target_device_index(sbi, blkstart); | 1377 | int devi = f2fs_target_device_index(sbi, blkstart); |
| 1374 | 1378 | ||
| 1375 | blkstart -= FDEV(devi).start_blk; | 1379 | blkstart -= FDEV(devi).start_blk; |
| @@ -1732,42 +1736,36 @@ static int __f2fs_issue_discard_zone(struct f2fs_sb_info *sbi, | |||
| 1732 | block_t lblkstart = blkstart; | 1736 | block_t lblkstart = blkstart; |
| 1733 | int devi = 0; | 1737 | int devi = 0; |
| 1734 | 1738 | ||
| 1735 | if (sbi->s_ndevs) { | 1739 | if (f2fs_is_multi_device(sbi)) { |
| 1736 | devi = f2fs_target_device_index(sbi, blkstart); | 1740 | devi = f2fs_target_device_index(sbi, blkstart); |
| 1741 | if (blkstart < FDEV(devi).start_blk || | ||
| 1742 | blkstart > FDEV(devi).end_blk) { | ||
| 1743 | f2fs_msg(sbi->sb, KERN_ERR, "Invalid block %x", | ||
| 1744 | blkstart); | ||
| 1745 | return -EIO; | ||
| 1746 | } | ||
| 1737 | blkstart -= FDEV(devi).start_blk; | 1747 | blkstart -= FDEV(devi).start_blk; |
| 1738 | } | 1748 | } |
| 1739 | 1749 | ||
| 1740 | /* | 1750 | /* For sequential zones, reset the zone write pointer */ |
| 1741 | * We need to know the type of the zone: for conventional zones, | 1751 | if (f2fs_blkz_is_seq(sbi, devi, blkstart)) { |
| 1742 | * use regular discard if the drive supports it. For sequential | ||
| 1743 | * zones, reset the zone write pointer. | ||
| 1744 | */ | ||
| 1745 | switch (get_blkz_type(sbi, bdev, blkstart)) { | ||
| 1746 | |||
| 1747 | case BLK_ZONE_TYPE_CONVENTIONAL: | ||
| 1748 | if (!blk_queue_discard(bdev_get_queue(bdev))) | ||
| 1749 | return 0; | ||
| 1750 | return __queue_discard_cmd(sbi, bdev, lblkstart, blklen); | ||
| 1751 | case BLK_ZONE_TYPE_SEQWRITE_REQ: | ||
| 1752 | case BLK_ZONE_TYPE_SEQWRITE_PREF: | ||
| 1753 | sector = SECTOR_FROM_BLOCK(blkstart); | 1752 | sector = SECTOR_FROM_BLOCK(blkstart); |
| 1754 | nr_sects = SECTOR_FROM_BLOCK(blklen); | 1753 | nr_sects = SECTOR_FROM_BLOCK(blklen); |
| 1755 | 1754 | ||
| 1756 | if (sector & (bdev_zone_sectors(bdev) - 1) || | 1755 | if (sector & (bdev_zone_sectors(bdev) - 1) || |
| 1757 | nr_sects != bdev_zone_sectors(bdev)) { | 1756 | nr_sects != bdev_zone_sectors(bdev)) { |
| 1758 | f2fs_msg(sbi->sb, KERN_INFO, | 1757 | f2fs_msg(sbi->sb, KERN_ERR, |
| 1759 | "(%d) %s: Unaligned discard attempted (block %x + %x)", | 1758 | "(%d) %s: Unaligned zone reset attempted (block %x + %x)", |
| 1760 | devi, sbi->s_ndevs ? FDEV(devi).path: "", | 1759 | devi, sbi->s_ndevs ? FDEV(devi).path: "", |
| 1761 | blkstart, blklen); | 1760 | blkstart, blklen); |
| 1762 | return -EIO; | 1761 | return -EIO; |
| 1763 | } | 1762 | } |
| 1764 | trace_f2fs_issue_reset_zone(bdev, blkstart); | 1763 | trace_f2fs_issue_reset_zone(bdev, blkstart); |
| 1765 | return blkdev_reset_zones(bdev, sector, | 1764 | return blkdev_reset_zones(bdev, sector, nr_sects, GFP_NOFS); |
| 1766 | nr_sects, GFP_NOFS); | ||
| 1767 | default: | ||
| 1768 | /* Unknown zone type: broken device ? */ | ||
| 1769 | return -EIO; | ||
| 1770 | } | 1765 | } |
| 1766 | |||
| 1767 | /* For conventional zones, use regular discard if supported */ | ||
| 1768 | return __queue_discard_cmd(sbi, bdev, lblkstart, blklen); | ||
| 1771 | } | 1769 | } |
| 1772 | #endif | 1770 | #endif |
| 1773 | 1771 | ||
| @@ -1775,8 +1773,7 @@ static int __issue_discard_async(struct f2fs_sb_info *sbi, | |||
| 1775 | struct block_device *bdev, block_t blkstart, block_t blklen) | 1773 | struct block_device *bdev, block_t blkstart, block_t blklen) |
| 1776 | { | 1774 | { |
| 1777 | #ifdef CONFIG_BLK_DEV_ZONED | 1775 | #ifdef CONFIG_BLK_DEV_ZONED |
| 1778 | if (f2fs_sb_has_blkzoned(sbi) && | 1776 | if (f2fs_sb_has_blkzoned(sbi) && bdev_is_zoned(bdev)) |
| 1779 | bdev_zoned_model(bdev) != BLK_ZONED_NONE) | ||
| 1780 | return __f2fs_issue_discard_zone(sbi, bdev, blkstart, blklen); | 1777 | return __f2fs_issue_discard_zone(sbi, bdev, blkstart, blklen); |
| 1781 | #endif | 1778 | #endif |
| 1782 | return __queue_discard_cmd(sbi, bdev, blkstart, blklen); | 1779 | return __queue_discard_cmd(sbi, bdev, blkstart, blklen); |
| @@ -2172,8 +2169,11 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) | |||
| 2172 | * before, we must track that to know how much space we | 2169 | * before, we must track that to know how much space we |
| 2173 | * really have. | 2170 | * really have. |
| 2174 | */ | 2171 | */ |
| 2175 | if (f2fs_test_bit(offset, se->ckpt_valid_map)) | 2172 | if (f2fs_test_bit(offset, se->ckpt_valid_map)) { |
| 2173 | spin_lock(&sbi->stat_lock); | ||
| 2176 | sbi->unusable_block_count++; | 2174 | sbi->unusable_block_count++; |
| 2175 | spin_unlock(&sbi->stat_lock); | ||
| 2176 | } | ||
| 2177 | } | 2177 | } |
| 2178 | 2178 | ||
| 2179 | if (f2fs_test_and_clear_bit(offset, se->discard_map)) | 2179 | if (f2fs_test_and_clear_bit(offset, se->discard_map)) |
| @@ -2220,7 +2220,7 @@ bool f2fs_is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr) | |||
| 2220 | struct seg_entry *se; | 2220 | struct seg_entry *se; |
| 2221 | bool is_cp = false; | 2221 | bool is_cp = false; |
| 2222 | 2222 | ||
| 2223 | if (!is_valid_data_blkaddr(sbi, blkaddr)) | 2223 | if (!__is_valid_data_blkaddr(blkaddr)) |
| 2224 | return true; | 2224 | return true; |
| 2225 | 2225 | ||
| 2226 | down_read(&sit_i->sentry_lock); | 2226 | down_read(&sit_i->sentry_lock); |
| @@ -3089,7 +3089,7 @@ static void update_device_state(struct f2fs_io_info *fio) | |||
| 3089 | struct f2fs_sb_info *sbi = fio->sbi; | 3089 | struct f2fs_sb_info *sbi = fio->sbi; |
| 3090 | unsigned int devidx; | 3090 | unsigned int devidx; |
| 3091 | 3091 | ||
| 3092 | if (!sbi->s_ndevs) | 3092 | if (!f2fs_is_multi_device(sbi)) |
| 3093 | return; | 3093 | return; |
| 3094 | 3094 | ||
| 3095 | devidx = f2fs_target_device_index(sbi, fio->new_blkaddr); | 3095 | devidx = f2fs_target_device_index(sbi, fio->new_blkaddr); |
| @@ -3187,13 +3187,18 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio) | |||
| 3187 | { | 3187 | { |
| 3188 | int err; | 3188 | int err; |
| 3189 | struct f2fs_sb_info *sbi = fio->sbi; | 3189 | struct f2fs_sb_info *sbi = fio->sbi; |
| 3190 | unsigned int segno; | ||
| 3190 | 3191 | ||
| 3191 | fio->new_blkaddr = fio->old_blkaddr; | 3192 | fio->new_blkaddr = fio->old_blkaddr; |
| 3192 | /* i/o temperature is needed for passing down write hints */ | 3193 | /* i/o temperature is needed for passing down write hints */ |
| 3193 | __get_segment_type(fio); | 3194 | __get_segment_type(fio); |
| 3194 | 3195 | ||
| 3195 | f2fs_bug_on(sbi, !IS_DATASEG(get_seg_entry(sbi, | 3196 | segno = GET_SEGNO(sbi, fio->new_blkaddr); |
| 3196 | GET_SEGNO(sbi, fio->new_blkaddr))->type)); | 3197 | |
| 3198 | if (!IS_DATASEG(get_seg_entry(sbi, segno)->type)) { | ||
| 3199 | set_sbi_flag(sbi, SBI_NEED_FSCK); | ||
| 3200 | return -EFAULT; | ||
| 3201 | } | ||
| 3197 | 3202 | ||
| 3198 | stat_inc_inplace_blocks(fio->sbi); | 3203 | stat_inc_inplace_blocks(fio->sbi); |
| 3199 | 3204 | ||
| @@ -3336,7 +3341,7 @@ void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr) | |||
| 3336 | if (!f2fs_post_read_required(inode)) | 3341 | if (!f2fs_post_read_required(inode)) |
| 3337 | return; | 3342 | return; |
| 3338 | 3343 | ||
| 3339 | if (!is_valid_data_blkaddr(sbi, blkaddr)) | 3344 | if (!__is_valid_data_blkaddr(blkaddr)) |
| 3340 | return; | 3345 | return; |
| 3341 | 3346 | ||
| 3342 | cpage = find_lock_page(META_MAPPING(sbi), blkaddr); | 3347 | cpage = find_lock_page(META_MAPPING(sbi), blkaddr); |
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 5c7ed0442d6e..429007b8036e 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h | |||
| @@ -82,7 +82,7 @@ | |||
| 82 | (GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & ((sbi)->blocks_per_seg - 1)) | 82 | (GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & ((sbi)->blocks_per_seg - 1)) |
| 83 | 83 | ||
| 84 | #define GET_SEGNO(sbi, blk_addr) \ | 84 | #define GET_SEGNO(sbi, blk_addr) \ |
| 85 | ((!is_valid_data_blkaddr(sbi, blk_addr)) ? \ | 85 | ((!__is_valid_data_blkaddr(blk_addr)) ? \ |
| 86 | NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi), \ | 86 | NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi), \ |
| 87 | GET_SEGNO_FROM_SEG0(sbi, blk_addr))) | 87 | GET_SEGNO_FROM_SEG0(sbi, blk_addr))) |
| 88 | #define BLKS_PER_SEC(sbi) \ | 88 | #define BLKS_PER_SEC(sbi) \ |
| @@ -656,14 +656,15 @@ static inline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno) | |||
| 656 | f2fs_bug_on(sbi, segno > TOTAL_SEGS(sbi) - 1); | 656 | f2fs_bug_on(sbi, segno > TOTAL_SEGS(sbi) - 1); |
| 657 | } | 657 | } |
| 658 | 658 | ||
| 659 | static inline void verify_block_addr(struct f2fs_io_info *fio, block_t blk_addr) | 659 | static inline void verify_fio_blkaddr(struct f2fs_io_info *fio) |
| 660 | { | 660 | { |
| 661 | struct f2fs_sb_info *sbi = fio->sbi; | 661 | struct f2fs_sb_info *sbi = fio->sbi; |
| 662 | 662 | ||
| 663 | if (__is_meta_io(fio)) | 663 | if (__is_valid_data_blkaddr(fio->old_blkaddr)) |
| 664 | verify_blkaddr(sbi, blk_addr, META_GENERIC); | 664 | verify_blkaddr(sbi, fio->old_blkaddr, __is_meta_io(fio) ? |
| 665 | else | 665 | META_GENERIC : DATA_GENERIC); |
| 666 | verify_blkaddr(sbi, blk_addr, DATA_GENERIC); | 666 | verify_blkaddr(sbi, fio->new_blkaddr, __is_meta_io(fio) ? |
| 667 | META_GENERIC : DATA_GENERIC_ENHANCE); | ||
| 667 | } | 668 | } |
| 668 | 669 | ||
| 669 | /* | 670 | /* |
| @@ -672,7 +673,6 @@ static inline void verify_block_addr(struct f2fs_io_info *fio, block_t blk_addr) | |||
| 672 | static inline int check_block_count(struct f2fs_sb_info *sbi, | 673 | static inline int check_block_count(struct f2fs_sb_info *sbi, |
| 673 | int segno, struct f2fs_sit_entry *raw_sit) | 674 | int segno, struct f2fs_sit_entry *raw_sit) |
| 674 | { | 675 | { |
| 675 | #ifdef CONFIG_F2FS_CHECK_FS | ||
| 676 | bool is_valid = test_bit_le(0, raw_sit->valid_map) ? true : false; | 676 | bool is_valid = test_bit_le(0, raw_sit->valid_map) ? true : false; |
| 677 | int valid_blocks = 0; | 677 | int valid_blocks = 0; |
| 678 | int cur_pos = 0, next_pos; | 678 | int cur_pos = 0, next_pos; |
| @@ -699,7 +699,7 @@ static inline int check_block_count(struct f2fs_sb_info *sbi, | |||
| 699 | set_sbi_flag(sbi, SBI_NEED_FSCK); | 699 | set_sbi_flag(sbi, SBI_NEED_FSCK); |
| 700 | return -EINVAL; | 700 | return -EINVAL; |
| 701 | } | 701 | } |
| 702 | #endif | 702 | |
| 703 | /* check segment usage, and check boundary of a given segment number */ | 703 | /* check segment usage, and check boundary of a given segment number */ |
| 704 | if (unlikely(GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg | 704 | if (unlikely(GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg |
| 705 | || segno > TOTAL_SEGS(sbi) - 1)) { | 705 | || segno > TOTAL_SEGS(sbi) - 1)) { |
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 4c55d2ea9df3..6b959bbb336a 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
| @@ -1019,7 +1019,7 @@ static void destroy_device_list(struct f2fs_sb_info *sbi) | |||
| 1019 | for (i = 0; i < sbi->s_ndevs; i++) { | 1019 | for (i = 0; i < sbi->s_ndevs; i++) { |
| 1020 | blkdev_put(FDEV(i).bdev, FMODE_EXCL); | 1020 | blkdev_put(FDEV(i).bdev, FMODE_EXCL); |
| 1021 | #ifdef CONFIG_BLK_DEV_ZONED | 1021 | #ifdef CONFIG_BLK_DEV_ZONED |
| 1022 | kvfree(FDEV(i).blkz_type); | 1022 | kvfree(FDEV(i).blkz_seq); |
| 1023 | #endif | 1023 | #endif |
| 1024 | } | 1024 | } |
| 1025 | kvfree(sbi->devs); | 1025 | kvfree(sbi->devs); |
| @@ -1221,10 +1221,13 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
| 1221 | buf->f_blocks = total_count - start_count; | 1221 | buf->f_blocks = total_count - start_count; |
| 1222 | buf->f_bfree = user_block_count - valid_user_blocks(sbi) - | 1222 | buf->f_bfree = user_block_count - valid_user_blocks(sbi) - |
| 1223 | sbi->current_reserved_blocks; | 1223 | sbi->current_reserved_blocks; |
| 1224 | |||
| 1225 | spin_lock(&sbi->stat_lock); | ||
| 1224 | if (unlikely(buf->f_bfree <= sbi->unusable_block_count)) | 1226 | if (unlikely(buf->f_bfree <= sbi->unusable_block_count)) |
| 1225 | buf->f_bfree = 0; | 1227 | buf->f_bfree = 0; |
| 1226 | else | 1228 | else |
| 1227 | buf->f_bfree -= sbi->unusable_block_count; | 1229 | buf->f_bfree -= sbi->unusable_block_count; |
| 1230 | spin_unlock(&sbi->stat_lock); | ||
| 1228 | 1231 | ||
| 1229 | if (buf->f_bfree > F2FS_OPTION(sbi).root_reserved_blocks) | 1232 | if (buf->f_bfree > F2FS_OPTION(sbi).root_reserved_blocks) |
| 1230 | buf->f_bavail = buf->f_bfree - | 1233 | buf->f_bavail = buf->f_bfree - |
| @@ -1499,9 +1502,15 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) | |||
| 1499 | mutex_lock(&sbi->gc_mutex); | 1502 | mutex_lock(&sbi->gc_mutex); |
| 1500 | cpc.reason = CP_PAUSE; | 1503 | cpc.reason = CP_PAUSE; |
| 1501 | set_sbi_flag(sbi, SBI_CP_DISABLED); | 1504 | set_sbi_flag(sbi, SBI_CP_DISABLED); |
| 1502 | f2fs_write_checkpoint(sbi, &cpc); | 1505 | err = f2fs_write_checkpoint(sbi, &cpc); |
| 1506 | if (err) | ||
| 1507 | goto out_unlock; | ||
| 1503 | 1508 | ||
| 1509 | spin_lock(&sbi->stat_lock); | ||
| 1504 | sbi->unusable_block_count = 0; | 1510 | sbi->unusable_block_count = 0; |
| 1511 | spin_unlock(&sbi->stat_lock); | ||
| 1512 | |||
| 1513 | out_unlock: | ||
| 1505 | mutex_unlock(&sbi->gc_mutex); | 1514 | mutex_unlock(&sbi->gc_mutex); |
| 1506 | restore_flag: | 1515 | restore_flag: |
| 1507 | sbi->sb->s_flags = s_flags; /* Restore MS_RDONLY status */ | 1516 | sbi->sb->s_flags = s_flags; /* Restore MS_RDONLY status */ |
| @@ -2271,7 +2280,7 @@ static const struct export_operations f2fs_export_ops = { | |||
| 2271 | static loff_t max_file_blocks(void) | 2280 | static loff_t max_file_blocks(void) |
| 2272 | { | 2281 | { |
| 2273 | loff_t result = 0; | 2282 | loff_t result = 0; |
| 2274 | loff_t leaf_count = ADDRS_PER_BLOCK; | 2283 | loff_t leaf_count = DEF_ADDRS_PER_BLOCK; |
| 2275 | 2284 | ||
| 2276 | /* | 2285 | /* |
| 2277 | * note: previously, result is equal to (DEF_ADDRS_PER_INODE - | 2286 | * note: previously, result is equal to (DEF_ADDRS_PER_INODE - |
| @@ -2449,7 +2458,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, | |||
| 2449 | /* Currently, support only 4KB page cache size */ | 2458 | /* Currently, support only 4KB page cache size */ |
| 2450 | if (F2FS_BLKSIZE != PAGE_SIZE) { | 2459 | if (F2FS_BLKSIZE != PAGE_SIZE) { |
| 2451 | f2fs_msg(sb, KERN_INFO, | 2460 | f2fs_msg(sb, KERN_INFO, |
| 2452 | "Invalid page_cache_size (%lu), supports only 4KB\n", | 2461 | "Invalid page_cache_size (%lu), supports only 4KB", |
| 2453 | PAGE_SIZE); | 2462 | PAGE_SIZE); |
| 2454 | return 1; | 2463 | return 1; |
| 2455 | } | 2464 | } |
| @@ -2458,7 +2467,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, | |||
| 2458 | blocksize = 1 << le32_to_cpu(raw_super->log_blocksize); | 2467 | blocksize = 1 << le32_to_cpu(raw_super->log_blocksize); |
| 2459 | if (blocksize != F2FS_BLKSIZE) { | 2468 | if (blocksize != F2FS_BLKSIZE) { |
| 2460 | f2fs_msg(sb, KERN_INFO, | 2469 | f2fs_msg(sb, KERN_INFO, |
| 2461 | "Invalid blocksize (%u), supports only 4KB\n", | 2470 | "Invalid blocksize (%u), supports only 4KB", |
| 2462 | blocksize); | 2471 | blocksize); |
| 2463 | return 1; | 2472 | return 1; |
| 2464 | } | 2473 | } |
| @@ -2466,7 +2475,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, | |||
| 2466 | /* check log blocks per segment */ | 2475 | /* check log blocks per segment */ |
| 2467 | if (le32_to_cpu(raw_super->log_blocks_per_seg) != 9) { | 2476 | if (le32_to_cpu(raw_super->log_blocks_per_seg) != 9) { |
| 2468 | f2fs_msg(sb, KERN_INFO, | 2477 | f2fs_msg(sb, KERN_INFO, |
| 2469 | "Invalid log blocks per segment (%u)\n", | 2478 | "Invalid log blocks per segment (%u)", |
| 2470 | le32_to_cpu(raw_super->log_blocks_per_seg)); | 2479 | le32_to_cpu(raw_super->log_blocks_per_seg)); |
| 2471 | return 1; | 2480 | return 1; |
| 2472 | } | 2481 | } |
| @@ -2587,7 +2596,8 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) | |||
| 2587 | unsigned int log_blocks_per_seg; | 2596 | unsigned int log_blocks_per_seg; |
| 2588 | unsigned int segment_count_main; | 2597 | unsigned int segment_count_main; |
| 2589 | unsigned int cp_pack_start_sum, cp_payload; | 2598 | unsigned int cp_pack_start_sum, cp_payload; |
| 2590 | block_t user_block_count; | 2599 | block_t user_block_count, valid_user_blocks; |
| 2600 | block_t avail_node_count, valid_node_count; | ||
| 2591 | int i, j; | 2601 | int i, j; |
| 2592 | 2602 | ||
| 2593 | total = le32_to_cpu(raw_super->segment_count); | 2603 | total = le32_to_cpu(raw_super->segment_count); |
| @@ -2622,6 +2632,24 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) | |||
| 2622 | return 1; | 2632 | return 1; |
| 2623 | } | 2633 | } |
| 2624 | 2634 | ||
| 2635 | valid_user_blocks = le64_to_cpu(ckpt->valid_block_count); | ||
| 2636 | if (valid_user_blocks > user_block_count) { | ||
| 2637 | f2fs_msg(sbi->sb, KERN_ERR, | ||
| 2638 | "Wrong valid_user_blocks: %u, user_block_count: %u", | ||
| 2639 | valid_user_blocks, user_block_count); | ||
| 2640 | return 1; | ||
| 2641 | } | ||
| 2642 | |||
| 2643 | valid_node_count = le32_to_cpu(ckpt->valid_node_count); | ||
| 2644 | avail_node_count = sbi->total_node_count - sbi->nquota_files - | ||
| 2645 | F2FS_RESERVED_NODE_NUM; | ||
| 2646 | if (valid_node_count > avail_node_count) { | ||
| 2647 | f2fs_msg(sbi->sb, KERN_ERR, | ||
| 2648 | "Wrong valid_node_count: %u, avail_node_count: %u", | ||
| 2649 | valid_node_count, avail_node_count); | ||
| 2650 | return 1; | ||
| 2651 | } | ||
| 2652 | |||
| 2625 | main_segs = le32_to_cpu(raw_super->segment_count_main); | 2653 | main_segs = le32_to_cpu(raw_super->segment_count_main); |
| 2626 | blocks_per_seg = sbi->blocks_per_seg; | 2654 | blocks_per_seg = sbi->blocks_per_seg; |
| 2627 | 2655 | ||
| @@ -2793,9 +2821,11 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi) | |||
| 2793 | if (nr_sectors & (bdev_zone_sectors(bdev) - 1)) | 2821 | if (nr_sectors & (bdev_zone_sectors(bdev) - 1)) |
| 2794 | FDEV(devi).nr_blkz++; | 2822 | FDEV(devi).nr_blkz++; |
| 2795 | 2823 | ||
| 2796 | FDEV(devi).blkz_type = f2fs_kmalloc(sbi, FDEV(devi).nr_blkz, | 2824 | FDEV(devi).blkz_seq = f2fs_kzalloc(sbi, |
| 2797 | GFP_KERNEL); | 2825 | BITS_TO_LONGS(FDEV(devi).nr_blkz) |
| 2798 | if (!FDEV(devi).blkz_type) | 2826 | * sizeof(unsigned long), |
| 2827 | GFP_KERNEL); | ||
| 2828 | if (!FDEV(devi).blkz_seq) | ||
| 2799 | return -ENOMEM; | 2829 | return -ENOMEM; |
| 2800 | 2830 | ||
| 2801 | #define F2FS_REPORT_NR_ZONES 4096 | 2831 | #define F2FS_REPORT_NR_ZONES 4096 |
| @@ -2822,7 +2852,8 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi) | |||
| 2822 | } | 2852 | } |
| 2823 | 2853 | ||
| 2824 | for (i = 0; i < nr_zones; i++) { | 2854 | for (i = 0; i < nr_zones; i++) { |
| 2825 | FDEV(devi).blkz_type[n] = zones[i].type; | 2855 | if (zones[i].type != BLK_ZONE_TYPE_CONVENTIONAL) |
| 2856 | set_bit(n, FDEV(devi).blkz_seq); | ||
| 2826 | sector += zones[i].len; | 2857 | sector += zones[i].len; |
| 2827 | n++; | 2858 | n++; |
| 2828 | } | 2859 | } |
| @@ -3105,7 +3136,7 @@ try_onemore: | |||
| 3105 | #ifndef CONFIG_BLK_DEV_ZONED | 3136 | #ifndef CONFIG_BLK_DEV_ZONED |
| 3106 | if (f2fs_sb_has_blkzoned(sbi)) { | 3137 | if (f2fs_sb_has_blkzoned(sbi)) { |
| 3107 | f2fs_msg(sb, KERN_ERR, | 3138 | f2fs_msg(sb, KERN_ERR, |
| 3108 | "Zoned block device support is not enabled\n"); | 3139 | "Zoned block device support is not enabled"); |
| 3109 | err = -EOPNOTSUPP; | 3140 | err = -EOPNOTSUPP; |
| 3110 | goto free_sb_buf; | 3141 | goto free_sb_buf; |
| 3111 | } | 3142 | } |
| @@ -3350,10 +3381,17 @@ try_onemore: | |||
| 3350 | * mount should be failed, when device has readonly mode, and | 3381 | * mount should be failed, when device has readonly mode, and |
| 3351 | * previous checkpoint was not done by clean system shutdown. | 3382 | * previous checkpoint was not done by clean system shutdown. |
| 3352 | */ | 3383 | */ |
| 3353 | if (bdev_read_only(sb->s_bdev) && | 3384 | if (f2fs_hw_is_readonly(sbi)) { |
| 3354 | !is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { | 3385 | if (!is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { |
| 3355 | err = -EROFS; | 3386 | err = -EROFS; |
| 3356 | goto free_meta; | 3387 | f2fs_msg(sb, KERN_ERR, |
| 3388 | "Need to recover fsync data, but " | ||
| 3389 | "write access unavailable"); | ||
| 3390 | goto free_meta; | ||
| 3391 | } | ||
| 3392 | f2fs_msg(sbi->sb, KERN_INFO, "write access " | ||
| 3393 | "unavailable, skipping recovery"); | ||
| 3394 | goto reset_checkpoint; | ||
| 3357 | } | 3395 | } |
| 3358 | 3396 | ||
| 3359 | if (need_fsck) | 3397 | if (need_fsck) |
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 848a785abe25..e791741d193b 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c | |||
| @@ -202,12 +202,17 @@ static inline const struct xattr_handler *f2fs_xattr_handler(int index) | |||
| 202 | return handler; | 202 | return handler; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | static struct f2fs_xattr_entry *__find_xattr(void *base_addr, int index, | 205 | static struct f2fs_xattr_entry *__find_xattr(void *base_addr, |
| 206 | size_t len, const char *name) | 206 | void *last_base_addr, int index, |
| 207 | size_t len, const char *name) | ||
| 207 | { | 208 | { |
| 208 | struct f2fs_xattr_entry *entry; | 209 | struct f2fs_xattr_entry *entry; |
| 209 | 210 | ||
| 210 | list_for_each_xattr(entry, base_addr) { | 211 | list_for_each_xattr(entry, base_addr) { |
| 212 | if ((void *)(entry) + sizeof(__u32) > last_base_addr || | ||
| 213 | (void *)XATTR_NEXT_ENTRY(entry) > last_base_addr) | ||
| 214 | return NULL; | ||
| 215 | |||
| 211 | if (entry->e_name_index != index) | 216 | if (entry->e_name_index != index) |
| 212 | continue; | 217 | continue; |
| 213 | if (entry->e_name_len != len) | 218 | if (entry->e_name_len != len) |
| @@ -297,20 +302,22 @@ static int lookup_all_xattrs(struct inode *inode, struct page *ipage, | |||
| 297 | const char *name, struct f2fs_xattr_entry **xe, | 302 | const char *name, struct f2fs_xattr_entry **xe, |
| 298 | void **base_addr, int *base_size) | 303 | void **base_addr, int *base_size) |
| 299 | { | 304 | { |
| 300 | void *cur_addr, *txattr_addr, *last_addr = NULL; | 305 | void *cur_addr, *txattr_addr, *last_txattr_addr; |
| 306 | void *last_addr = NULL; | ||
| 301 | nid_t xnid = F2FS_I(inode)->i_xattr_nid; | 307 | nid_t xnid = F2FS_I(inode)->i_xattr_nid; |
| 302 | unsigned int size = xnid ? VALID_XATTR_BLOCK_SIZE : 0; | ||
| 303 | unsigned int inline_size = inline_xattr_size(inode); | 308 | unsigned int inline_size = inline_xattr_size(inode); |
| 304 | int err = 0; | 309 | int err = 0; |
| 305 | 310 | ||
| 306 | if (!size && !inline_size) | 311 | if (!xnid && !inline_size) |
| 307 | return -ENODATA; | 312 | return -ENODATA; |
| 308 | 313 | ||
| 309 | *base_size = inline_size + size + XATTR_PADDING_SIZE; | 314 | *base_size = XATTR_SIZE(xnid, inode) + XATTR_PADDING_SIZE; |
| 310 | txattr_addr = f2fs_kzalloc(F2FS_I_SB(inode), *base_size, GFP_NOFS); | 315 | txattr_addr = f2fs_kzalloc(F2FS_I_SB(inode), *base_size, GFP_NOFS); |
| 311 | if (!txattr_addr) | 316 | if (!txattr_addr) |
| 312 | return -ENOMEM; | 317 | return -ENOMEM; |
| 313 | 318 | ||
| 319 | last_txattr_addr = (void *)txattr_addr + XATTR_SIZE(xnid, inode); | ||
| 320 | |||
| 314 | /* read from inline xattr */ | 321 | /* read from inline xattr */ |
| 315 | if (inline_size) { | 322 | if (inline_size) { |
| 316 | err = read_inline_xattr(inode, ipage, txattr_addr); | 323 | err = read_inline_xattr(inode, ipage, txattr_addr); |
| @@ -337,7 +344,11 @@ static int lookup_all_xattrs(struct inode *inode, struct page *ipage, | |||
| 337 | else | 344 | else |
| 338 | cur_addr = txattr_addr; | 345 | cur_addr = txattr_addr; |
| 339 | 346 | ||
| 340 | *xe = __find_xattr(cur_addr, index, len, name); | 347 | *xe = __find_xattr(cur_addr, last_txattr_addr, index, len, name); |
| 348 | if (!*xe) { | ||
| 349 | err = -EFAULT; | ||
| 350 | goto out; | ||
| 351 | } | ||
| 341 | check: | 352 | check: |
| 342 | if (IS_XATTR_LAST_ENTRY(*xe)) { | 353 | if (IS_XATTR_LAST_ENTRY(*xe)) { |
| 343 | err = -ENODATA; | 354 | err = -ENODATA; |
| @@ -581,7 +592,8 @@ static int __f2fs_setxattr(struct inode *inode, int index, | |||
| 581 | struct page *ipage, int flags) | 592 | struct page *ipage, int flags) |
| 582 | { | 593 | { |
| 583 | struct f2fs_xattr_entry *here, *last; | 594 | struct f2fs_xattr_entry *here, *last; |
| 584 | void *base_addr; | 595 | void *base_addr, *last_base_addr; |
| 596 | nid_t xnid = F2FS_I(inode)->i_xattr_nid; | ||
| 585 | int found, newsize; | 597 | int found, newsize; |
| 586 | size_t len; | 598 | size_t len; |
| 587 | __u32 new_hsize; | 599 | __u32 new_hsize; |
| @@ -605,8 +617,14 @@ static int __f2fs_setxattr(struct inode *inode, int index, | |||
| 605 | if (error) | 617 | if (error) |
| 606 | return error; | 618 | return error; |
| 607 | 619 | ||
| 620 | last_base_addr = (void *)base_addr + XATTR_SIZE(xnid, inode); | ||
| 621 | |||
| 608 | /* find entry with wanted name. */ | 622 | /* find entry with wanted name. */ |
| 609 | here = __find_xattr(base_addr, index, len, name); | 623 | here = __find_xattr(base_addr, last_base_addr, index, len, name); |
| 624 | if (!here) { | ||
| 625 | error = -EFAULT; | ||
| 626 | goto exit; | ||
| 627 | } | ||
| 610 | 628 | ||
| 611 | found = IS_XATTR_LAST_ENTRY(here) ? 0 : 1; | 629 | found = IS_XATTR_LAST_ENTRY(here) ? 0 : 1; |
| 612 | 630 | ||
diff --git a/fs/f2fs/xattr.h b/fs/f2fs/xattr.h index 9172ee082ca8..a90920e2f949 100644 --- a/fs/f2fs/xattr.h +++ b/fs/f2fs/xattr.h | |||
| @@ -71,6 +71,8 @@ struct f2fs_xattr_entry { | |||
| 71 | entry = XATTR_NEXT_ENTRY(entry)) | 71 | entry = XATTR_NEXT_ENTRY(entry)) |
| 72 | #define VALID_XATTR_BLOCK_SIZE (PAGE_SIZE - sizeof(struct node_footer)) | 72 | #define VALID_XATTR_BLOCK_SIZE (PAGE_SIZE - sizeof(struct node_footer)) |
| 73 | #define XATTR_PADDING_SIZE (sizeof(__u32)) | 73 | #define XATTR_PADDING_SIZE (sizeof(__u32)) |
| 74 | #define XATTR_SIZE(x,i) (((x) ? VALID_XATTR_BLOCK_SIZE : 0) + \ | ||
| 75 | (inline_xattr_size(i))) | ||
| 74 | #define MIN_OFFSET(i) XATTR_ALIGN(inline_xattr_size(i) + \ | 76 | #define MIN_OFFSET(i) XATTR_ALIGN(inline_xattr_size(i) + \ |
| 75 | VALID_XATTR_BLOCK_SIZE) | 77 | VALID_XATTR_BLOCK_SIZE) |
| 76 | 78 | ||
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index f5740423b002..65559900d4d7 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h | |||
| @@ -164,6 +164,10 @@ struct f2fs_checkpoint { | |||
| 164 | unsigned char sit_nat_version_bitmap[1]; | 164 | unsigned char sit_nat_version_bitmap[1]; |
| 165 | } __packed; | 165 | } __packed; |
| 166 | 166 | ||
| 167 | #define CP_CHKSUM_OFFSET 4092 /* default chksum offset in checkpoint */ | ||
| 168 | #define CP_MIN_CHKSUM_OFFSET \ | ||
| 169 | (offsetof(struct f2fs_checkpoint, sit_nat_version_bitmap)) | ||
| 170 | |||
| 167 | /* | 171 | /* |
| 168 | * For orphan inode management | 172 | * For orphan inode management |
| 169 | */ | 173 | */ |
| @@ -198,11 +202,12 @@ struct f2fs_extent { | |||
| 198 | get_extra_isize(inode)) | 202 | get_extra_isize(inode)) |
| 199 | #define DEF_NIDS_PER_INODE 5 /* Node IDs in an Inode */ | 203 | #define DEF_NIDS_PER_INODE 5 /* Node IDs in an Inode */ |
| 200 | #define ADDRS_PER_INODE(inode) addrs_per_inode(inode) | 204 | #define ADDRS_PER_INODE(inode) addrs_per_inode(inode) |
| 201 | #define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */ | 205 | #define DEF_ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */ |
| 206 | #define ADDRS_PER_BLOCK(inode) addrs_per_block(inode) | ||
| 202 | #define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block */ | 207 | #define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block */ |
| 203 | 208 | ||
| 204 | #define ADDRS_PER_PAGE(page, inode) \ | 209 | #define ADDRS_PER_PAGE(page, inode) \ |
| 205 | (IS_INODE(page) ? ADDRS_PER_INODE(inode) : ADDRS_PER_BLOCK) | 210 | (IS_INODE(page) ? ADDRS_PER_INODE(inode) : ADDRS_PER_BLOCK(inode)) |
| 206 | 211 | ||
| 207 | #define NODE_DIR1_BLOCK (DEF_ADDRS_PER_INODE + 1) | 212 | #define NODE_DIR1_BLOCK (DEF_ADDRS_PER_INODE + 1) |
| 208 | #define NODE_DIR2_BLOCK (DEF_ADDRS_PER_INODE + 2) | 213 | #define NODE_DIR2_BLOCK (DEF_ADDRS_PER_INODE + 2) |
| @@ -267,7 +272,7 @@ struct f2fs_inode { | |||
| 267 | } __packed; | 272 | } __packed; |
| 268 | 273 | ||
| 269 | struct direct_node { | 274 | struct direct_node { |
| 270 | __le32 addr[ADDRS_PER_BLOCK]; /* array of data block address */ | 275 | __le32 addr[DEF_ADDRS_PER_BLOCK]; /* array of data block address */ |
| 271 | } __packed; | 276 | } __packed; |
| 272 | 277 | ||
| 273 | struct indirect_node { | 278 | struct indirect_node { |
diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index a3916b4dd57e..53b96f12300c 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h | |||
| @@ -533,6 +533,37 @@ TRACE_EVENT(f2fs_truncate_partial_nodes, | |||
| 533 | __entry->err) | 533 | __entry->err) |
| 534 | ); | 534 | ); |
| 535 | 535 | ||
| 536 | TRACE_EVENT(f2fs_file_write_iter, | ||
| 537 | |||
| 538 | TP_PROTO(struct inode *inode, unsigned long offset, | ||
| 539 | unsigned long length, int ret), | ||
| 540 | |||
| 541 | TP_ARGS(inode, offset, length, ret), | ||
| 542 | |||
| 543 | TP_STRUCT__entry( | ||
| 544 | __field(dev_t, dev) | ||
| 545 | __field(ino_t, ino) | ||
| 546 | __field(unsigned long, offset) | ||
| 547 | __field(unsigned long, length) | ||
| 548 | __field(int, ret) | ||
| 549 | ), | ||
| 550 | |||
| 551 | TP_fast_assign( | ||
| 552 | __entry->dev = inode->i_sb->s_dev; | ||
| 553 | __entry->ino = inode->i_ino; | ||
| 554 | __entry->offset = offset; | ||
| 555 | __entry->length = length; | ||
| 556 | __entry->ret = ret; | ||
| 557 | ), | ||
| 558 | |||
| 559 | TP_printk("dev = (%d,%d), ino = %lu, " | ||
| 560 | "offset = %lu, length = %lu, written(err) = %d", | ||
| 561 | show_dev_ino(__entry), | ||
| 562 | __entry->offset, | ||
| 563 | __entry->length, | ||
| 564 | __entry->ret) | ||
| 565 | ); | ||
| 566 | |||
| 536 | TRACE_EVENT(f2fs_map_blocks, | 567 | TRACE_EVENT(f2fs_map_blocks, |
| 537 | TP_PROTO(struct inode *inode, struct f2fs_map_blocks *map, int ret), | 568 | TP_PROTO(struct inode *inode, struct f2fs_map_blocks *map, int ret), |
| 538 | 569 | ||
| @@ -1253,6 +1284,32 @@ DEFINE_EVENT(f2fs__page, f2fs_commit_inmem_page, | |||
| 1253 | TP_ARGS(page, type) | 1284 | TP_ARGS(page, type) |
| 1254 | ); | 1285 | ); |
| 1255 | 1286 | ||
| 1287 | TRACE_EVENT(f2fs_filemap_fault, | ||
| 1288 | |||
| 1289 | TP_PROTO(struct inode *inode, pgoff_t index, unsigned long ret), | ||
| 1290 | |||
| 1291 | TP_ARGS(inode, index, ret), | ||
| 1292 | |||
| 1293 | TP_STRUCT__entry( | ||
| 1294 | __field(dev_t, dev) | ||
| 1295 | __field(ino_t, ino) | ||
| 1296 | __field(pgoff_t, index) | ||
| 1297 | __field(unsigned long, ret) | ||
| 1298 | ), | ||
| 1299 | |||
| 1300 | TP_fast_assign( | ||
| 1301 | __entry->dev = inode->i_sb->s_dev; | ||
| 1302 | __entry->ino = inode->i_ino; | ||
| 1303 | __entry->index = index; | ||
| 1304 | __entry->ret = ret; | ||
| 1305 | ), | ||
| 1306 | |||
| 1307 | TP_printk("dev = (%d,%d), ino = %lu, index = %lu, ret = %lx", | ||
| 1308 | show_dev_ino(__entry), | ||
| 1309 | (unsigned long)__entry->index, | ||
| 1310 | __entry->ret) | ||
| 1311 | ); | ||
| 1312 | |||
| 1256 | TRACE_EVENT(f2fs_writepages, | 1313 | TRACE_EVENT(f2fs_writepages, |
| 1257 | 1314 | ||
| 1258 | TP_PROTO(struct inode *inode, struct writeback_control *wbc, int type), | 1315 | TP_PROTO(struct inode *inode, struct writeback_control *wbc, int type), |
