diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-14 00:01:44 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-14 00:01:44 -0500 |
| commit | f9a03ae123c92c1f45cd2ca88d0f6edd787be78c (patch) | |
| tree | c15c8b9b5732eb36b591bf570de63f3c30d252e1 /fs/f2fs/super.c | |
| parent | 1289ace5b4f70f1e68ce785735b82c7e483de863 (diff) | |
| parent | 447135a86659c646017b8e707c1243c186bf2dff (diff) | |
Merge tag 'for-f2fs-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs updates from Jaegeuk Kim:
"This series adds two ioctls to control cached data and fragmented
files. Most of the rest fixes missing error cases and bugs that we
have not covered so far. Summary:
Enhancements:
- support an ioctl to execute online file defragmentation
- support an ioctl to flush cached data
- speed up shrinking of extent_cache entries
- handle broken superblock
- refector dirty inode management infra
- revisit f2fs_map_blocks to handle more cases
- reduce global lock coverage
- add detecting user's idle time
Major bug fixes:
- fix data race condition on cached nat entries
- fix error cases of volatile and atomic writes"
* tag 'for-f2fs-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (87 commits)
f2fs: should unset atomic flag after successful commit
f2fs: fix wrong memory condition check
f2fs: monitor the number of background checkpoint
f2fs: detect idle time depending on user behavior
f2fs: introduce time and interval facility
f2fs: skip releasing nodes in chindless extent tree
f2fs: use atomic type for node count in extent tree
f2fs: recognize encrypted data in f2fs_fiemap
f2fs: clean up f2fs_balance_fs
f2fs: remove redundant calls
f2fs: avoid unnecessary f2fs_balance_fs calls
f2fs: check the page status filled from disk
f2fs: introduce __get_node_page to reuse common code
f2fs: check node id earily when readaheading node page
f2fs: read isize while holding i_mutex in fiemap
Revert "f2fs: check the node block address of newly allocated nid"
f2fs: cover more area with nat_tree_lock
f2fs: introduce max_file_blocks in sbi
f2fs crypto: check CONFIG_F2FS_FS_XATTR for encrypted symlink
f2fs: introduce zombie list for fast shrinking extent trees
...
Diffstat (limited to 'fs/f2fs/super.c')
| -rw-r--r-- | fs/f2fs/super.c | 253 |
1 files changed, 187 insertions, 66 deletions
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 3a65e0132352..3bf990b80026 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
| @@ -67,6 +67,7 @@ enum { | |||
| 67 | Opt_extent_cache, | 67 | Opt_extent_cache, |
| 68 | Opt_noextent_cache, | 68 | Opt_noextent_cache, |
| 69 | Opt_noinline_data, | 69 | Opt_noinline_data, |
| 70 | Opt_data_flush, | ||
| 70 | Opt_err, | 71 | Opt_err, |
| 71 | }; | 72 | }; |
| 72 | 73 | ||
| @@ -91,6 +92,7 @@ static match_table_t f2fs_tokens = { | |||
| 91 | {Opt_extent_cache, "extent_cache"}, | 92 | {Opt_extent_cache, "extent_cache"}, |
| 92 | {Opt_noextent_cache, "noextent_cache"}, | 93 | {Opt_noextent_cache, "noextent_cache"}, |
| 93 | {Opt_noinline_data, "noinline_data"}, | 94 | {Opt_noinline_data, "noinline_data"}, |
| 95 | {Opt_data_flush, "data_flush"}, | ||
| 94 | {Opt_err, NULL}, | 96 | {Opt_err, NULL}, |
| 95 | }; | 97 | }; |
| 96 | 98 | ||
| @@ -216,7 +218,8 @@ F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); | |||
| 216 | F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages); | 218 | F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages); |
| 217 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); | 219 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); |
| 218 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); | 220 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); |
| 219 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, cp_interval); | 221 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, interval_time[CP_TIME]); |
| 222 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]); | ||
| 220 | 223 | ||
| 221 | #define ATTR_LIST(name) (&f2fs_attr_##name.attr) | 224 | #define ATTR_LIST(name) (&f2fs_attr_##name.attr) |
| 222 | static struct attribute *f2fs_attrs[] = { | 225 | static struct attribute *f2fs_attrs[] = { |
| @@ -235,6 +238,7 @@ static struct attribute *f2fs_attrs[] = { | |||
| 235 | ATTR_LIST(ram_thresh), | 238 | ATTR_LIST(ram_thresh), |
| 236 | ATTR_LIST(ra_nid_pages), | 239 | ATTR_LIST(ra_nid_pages), |
| 237 | ATTR_LIST(cp_interval), | 240 | ATTR_LIST(cp_interval), |
| 241 | ATTR_LIST(idle_interval), | ||
| 238 | NULL, | 242 | NULL, |
| 239 | }; | 243 | }; |
| 240 | 244 | ||
| @@ -406,6 +410,9 @@ static int parse_options(struct super_block *sb, char *options) | |||
| 406 | case Opt_noinline_data: | 410 | case Opt_noinline_data: |
| 407 | clear_opt(sbi, INLINE_DATA); | 411 | clear_opt(sbi, INLINE_DATA); |
| 408 | break; | 412 | break; |
| 413 | case Opt_data_flush: | ||
| 414 | set_opt(sbi, DATA_FLUSH); | ||
| 415 | break; | ||
| 409 | default: | 416 | default: |
| 410 | f2fs_msg(sb, KERN_ERR, | 417 | f2fs_msg(sb, KERN_ERR, |
| 411 | "Unrecognized mount option \"%s\" or missing value", | 418 | "Unrecognized mount option \"%s\" or missing value", |
| @@ -432,6 +439,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) | |||
| 432 | fi->i_current_depth = 1; | 439 | fi->i_current_depth = 1; |
| 433 | fi->i_advise = 0; | 440 | fi->i_advise = 0; |
| 434 | init_rwsem(&fi->i_sem); | 441 | init_rwsem(&fi->i_sem); |
| 442 | INIT_LIST_HEAD(&fi->dirty_list); | ||
| 435 | INIT_LIST_HEAD(&fi->inmem_pages); | 443 | INIT_LIST_HEAD(&fi->inmem_pages); |
| 436 | mutex_init(&fi->inmem_lock); | 444 | mutex_init(&fi->inmem_lock); |
| 437 | 445 | ||
| @@ -548,7 +556,7 @@ static void f2fs_put_super(struct super_block *sb) | |||
| 548 | * normally superblock is clean, so we need to release this. | 556 | * normally superblock is clean, so we need to release this. |
| 549 | * In addition, EIO will skip do checkpoint, we need this as well. | 557 | * In addition, EIO will skip do checkpoint, we need this as well. |
| 550 | */ | 558 | */ |
| 551 | release_dirty_inode(sbi); | 559 | release_ino_entry(sbi); |
| 552 | release_discard_addrs(sbi); | 560 | release_discard_addrs(sbi); |
| 553 | 561 | ||
| 554 | f2fs_leave_shrinker(sbi); | 562 | f2fs_leave_shrinker(sbi); |
| @@ -566,13 +574,14 @@ static void f2fs_put_super(struct super_block *sb) | |||
| 566 | wait_for_completion(&sbi->s_kobj_unregister); | 574 | wait_for_completion(&sbi->s_kobj_unregister); |
| 567 | 575 | ||
| 568 | sb->s_fs_info = NULL; | 576 | sb->s_fs_info = NULL; |
| 569 | brelse(sbi->raw_super_buf); | 577 | kfree(sbi->raw_super); |
| 570 | kfree(sbi); | 578 | kfree(sbi); |
| 571 | } | 579 | } |
| 572 | 580 | ||
| 573 | int f2fs_sync_fs(struct super_block *sb, int sync) | 581 | int f2fs_sync_fs(struct super_block *sb, int sync) |
| 574 | { | 582 | { |
| 575 | struct f2fs_sb_info *sbi = F2FS_SB(sb); | 583 | struct f2fs_sb_info *sbi = F2FS_SB(sb); |
| 584 | int err = 0; | ||
| 576 | 585 | ||
| 577 | trace_f2fs_sync_fs(sb, sync); | 586 | trace_f2fs_sync_fs(sb, sync); |
| 578 | 587 | ||
| @@ -582,14 +591,12 @@ int f2fs_sync_fs(struct super_block *sb, int sync) | |||
| 582 | cpc.reason = __get_cp_reason(sbi); | 591 | cpc.reason = __get_cp_reason(sbi); |
| 583 | 592 | ||
| 584 | mutex_lock(&sbi->gc_mutex); | 593 | mutex_lock(&sbi->gc_mutex); |
| 585 | write_checkpoint(sbi, &cpc); | 594 | err = write_checkpoint(sbi, &cpc); |
| 586 | mutex_unlock(&sbi->gc_mutex); | 595 | mutex_unlock(&sbi->gc_mutex); |
| 587 | } else { | ||
| 588 | f2fs_balance_fs(sbi); | ||
| 589 | } | 596 | } |
| 590 | f2fs_trace_ios(NULL, 1); | 597 | f2fs_trace_ios(NULL, 1); |
| 591 | 598 | ||
| 592 | return 0; | 599 | return err; |
| 593 | } | 600 | } |
| 594 | 601 | ||
| 595 | static int f2fs_freeze(struct super_block *sb) | 602 | static int f2fs_freeze(struct super_block *sb) |
| @@ -686,6 +693,8 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) | |||
| 686 | seq_puts(seq, ",extent_cache"); | 693 | seq_puts(seq, ",extent_cache"); |
| 687 | else | 694 | else |
| 688 | seq_puts(seq, ",noextent_cache"); | 695 | seq_puts(seq, ",noextent_cache"); |
| 696 | if (test_opt(sbi, DATA_FLUSH)) | ||
| 697 | seq_puts(seq, ",data_flush"); | ||
| 689 | seq_printf(seq, ",active_logs=%u", sbi->active_logs); | 698 | seq_printf(seq, ",active_logs=%u", sbi->active_logs); |
| 690 | 699 | ||
| 691 | return 0; | 700 | return 0; |
| @@ -898,7 +907,7 @@ static const struct export_operations f2fs_export_ops = { | |||
| 898 | .get_parent = f2fs_get_parent, | 907 | .get_parent = f2fs_get_parent, |
| 899 | }; | 908 | }; |
| 900 | 909 | ||
| 901 | static loff_t max_file_size(unsigned bits) | 910 | static loff_t max_file_blocks(void) |
| 902 | { | 911 | { |
| 903 | loff_t result = (DEF_ADDRS_PER_INODE - F2FS_INLINE_XATTR_ADDRS); | 912 | loff_t result = (DEF_ADDRS_PER_INODE - F2FS_INLINE_XATTR_ADDRS); |
| 904 | loff_t leaf_count = ADDRS_PER_BLOCK; | 913 | loff_t leaf_count = ADDRS_PER_BLOCK; |
| @@ -914,10 +923,82 @@ static loff_t max_file_size(unsigned bits) | |||
| 914 | leaf_count *= NIDS_PER_BLOCK; | 923 | leaf_count *= NIDS_PER_BLOCK; |
| 915 | result += leaf_count; | 924 | result += leaf_count; |
| 916 | 925 | ||
| 917 | result <<= bits; | ||
| 918 | return result; | 926 | return result; |
| 919 | } | 927 | } |
| 920 | 928 | ||
| 929 | static inline bool sanity_check_area_boundary(struct super_block *sb, | ||
| 930 | struct f2fs_super_block *raw_super) | ||
| 931 | { | ||
| 932 | u32 segment0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr); | ||
| 933 | u32 cp_blkaddr = le32_to_cpu(raw_super->cp_blkaddr); | ||
| 934 | u32 sit_blkaddr = le32_to_cpu(raw_super->sit_blkaddr); | ||
| 935 | u32 nat_blkaddr = le32_to_cpu(raw_super->nat_blkaddr); | ||
| 936 | u32 ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr); | ||
| 937 | u32 main_blkaddr = le32_to_cpu(raw_super->main_blkaddr); | ||
| 938 | u32 segment_count_ckpt = le32_to_cpu(raw_super->segment_count_ckpt); | ||
| 939 | u32 segment_count_sit = le32_to_cpu(raw_super->segment_count_sit); | ||
| 940 | u32 segment_count_nat = le32_to_cpu(raw_super->segment_count_nat); | ||
| 941 | u32 segment_count_ssa = le32_to_cpu(raw_super->segment_count_ssa); | ||
| 942 | u32 segment_count_main = le32_to_cpu(raw_super->segment_count_main); | ||
| 943 | u32 segment_count = le32_to_cpu(raw_super->segment_count); | ||
| 944 | u32 log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg); | ||
| 945 | |||
| 946 | if (segment0_blkaddr != cp_blkaddr) { | ||
| 947 | f2fs_msg(sb, KERN_INFO, | ||
| 948 | "Mismatch start address, segment0(%u) cp_blkaddr(%u)", | ||
| 949 | segment0_blkaddr, cp_blkaddr); | ||
| 950 | return true; | ||
| 951 | } | ||
| 952 | |||
| 953 | if (cp_blkaddr + (segment_count_ckpt << log_blocks_per_seg) != | ||
| 954 | sit_blkaddr) { | ||
| 955 | f2fs_msg(sb, KERN_INFO, | ||
| 956 | "Wrong CP boundary, start(%u) end(%u) blocks(%u)", | ||
| 957 | cp_blkaddr, sit_blkaddr, | ||
| 958 | segment_count_ckpt << log_blocks_per_seg); | ||
| 959 | return true; | ||
| 960 | } | ||
| 961 | |||
| 962 | if (sit_blkaddr + (segment_count_sit << log_blocks_per_seg) != | ||
| 963 | nat_blkaddr) { | ||
| 964 | f2fs_msg(sb, KERN_INFO, | ||
| 965 | "Wrong SIT boundary, start(%u) end(%u) blocks(%u)", | ||
| 966 | sit_blkaddr, nat_blkaddr, | ||
| 967 | segment_count_sit << log_blocks_per_seg); | ||
| 968 | return true; | ||
| 969 | } | ||
| 970 | |||
| 971 | if (nat_blkaddr + (segment_count_nat << log_blocks_per_seg) != | ||
| 972 | ssa_blkaddr) { | ||
| 973 | f2fs_msg(sb, KERN_INFO, | ||
| 974 | "Wrong NAT boundary, start(%u) end(%u) blocks(%u)", | ||
| 975 | nat_blkaddr, ssa_blkaddr, | ||
| 976 | segment_count_nat << log_blocks_per_seg); | ||
| 977 | return true; | ||
| 978 | } | ||
| 979 | |||
| 980 | if (ssa_blkaddr + (segment_count_ssa << log_blocks_per_seg) != | ||
| 981 | main_blkaddr) { | ||
| 982 | f2fs_msg(sb, KERN_INFO, | ||
| 983 | "Wrong SSA boundary, start(%u) end(%u) blocks(%u)", | ||
| 984 | ssa_blkaddr, main_blkaddr, | ||
| 985 | segment_count_ssa << log_blocks_per_seg); | ||
| 986 | return true; | ||
| 987 | } | ||
| 988 | |||
| 989 | if (main_blkaddr + (segment_count_main << log_blocks_per_seg) != | ||
| 990 | segment0_blkaddr + (segment_count << log_blocks_per_seg)) { | ||
| 991 | f2fs_msg(sb, KERN_INFO, | ||
| 992 | "Wrong MAIN_AREA boundary, start(%u) end(%u) blocks(%u)", | ||
| 993 | main_blkaddr, | ||
| 994 | segment0_blkaddr + (segment_count << log_blocks_per_seg), | ||
| 995 | segment_count_main << log_blocks_per_seg); | ||
| 996 | return true; | ||
| 997 | } | ||
| 998 | |||
| 999 | return false; | ||
| 1000 | } | ||
| 1001 | |||
| 921 | static int sanity_check_raw_super(struct super_block *sb, | 1002 | static int sanity_check_raw_super(struct super_block *sb, |
| 922 | struct f2fs_super_block *raw_super) | 1003 | struct f2fs_super_block *raw_super) |
| 923 | { | 1004 | { |
| @@ -947,6 +1028,14 @@ static int sanity_check_raw_super(struct super_block *sb, | |||
| 947 | return 1; | 1028 | return 1; |
| 948 | } | 1029 | } |
| 949 | 1030 | ||
| 1031 | /* check log blocks per segment */ | ||
| 1032 | if (le32_to_cpu(raw_super->log_blocks_per_seg) != 9) { | ||
| 1033 | f2fs_msg(sb, KERN_INFO, | ||
| 1034 | "Invalid log blocks per segment (%u)\n", | ||
| 1035 | le32_to_cpu(raw_super->log_blocks_per_seg)); | ||
| 1036 | return 1; | ||
| 1037 | } | ||
| 1038 | |||
| 950 | /* Currently, support 512/1024/2048/4096 bytes sector size */ | 1039 | /* Currently, support 512/1024/2048/4096 bytes sector size */ |
| 951 | if (le32_to_cpu(raw_super->log_sectorsize) > | 1040 | if (le32_to_cpu(raw_super->log_sectorsize) > |
| 952 | F2FS_MAX_LOG_SECTOR_SIZE || | 1041 | F2FS_MAX_LOG_SECTOR_SIZE || |
| @@ -965,6 +1054,23 @@ static int sanity_check_raw_super(struct super_block *sb, | |||
| 965 | le32_to_cpu(raw_super->log_sectorsize)); | 1054 | le32_to_cpu(raw_super->log_sectorsize)); |
| 966 | return 1; | 1055 | return 1; |
| 967 | } | 1056 | } |
| 1057 | |||
| 1058 | /* check reserved ino info */ | ||
| 1059 | if (le32_to_cpu(raw_super->node_ino) != 1 || | ||
| 1060 | le32_to_cpu(raw_super->meta_ino) != 2 || | ||
| 1061 | le32_to_cpu(raw_super->root_ino) != 3) { | ||
| 1062 | f2fs_msg(sb, KERN_INFO, | ||
| 1063 | "Invalid Fs Meta Ino: node(%u) meta(%u) root(%u)", | ||
| 1064 | le32_to_cpu(raw_super->node_ino), | ||
| 1065 | le32_to_cpu(raw_super->meta_ino), | ||
| 1066 | le32_to_cpu(raw_super->root_ino)); | ||
| 1067 | return 1; | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */ | ||
| 1071 | if (sanity_check_area_boundary(sb, raw_super)) | ||
| 1072 | return 1; | ||
| 1073 | |||
| 968 | return 0; | 1074 | return 0; |
| 969 | } | 1075 | } |
| 970 | 1076 | ||
| @@ -1018,7 +1124,8 @@ static void init_sb_info(struct f2fs_sb_info *sbi) | |||
| 1018 | atomic_set(&sbi->nr_pages[i], 0); | 1124 | atomic_set(&sbi->nr_pages[i], 0); |
| 1019 | 1125 | ||
| 1020 | sbi->dir_level = DEF_DIR_LEVEL; | 1126 | sbi->dir_level = DEF_DIR_LEVEL; |
| 1021 | sbi->cp_interval = DEF_CP_INTERVAL; | 1127 | sbi->interval_time[CP_TIME] = DEF_CP_INTERVAL; |
| 1128 | sbi->interval_time[REQ_TIME] = DEF_IDLE_INTERVAL; | ||
| 1022 | clear_sbi_flag(sbi, SBI_NEED_FSCK); | 1129 | clear_sbi_flag(sbi, SBI_NEED_FSCK); |
| 1023 | 1130 | ||
| 1024 | INIT_LIST_HEAD(&sbi->s_list); | 1131 | INIT_LIST_HEAD(&sbi->s_list); |
| @@ -1032,111 +1139,114 @@ static void init_sb_info(struct f2fs_sb_info *sbi) | |||
| 1032 | */ | 1139 | */ |
| 1033 | static int read_raw_super_block(struct super_block *sb, | 1140 | static int read_raw_super_block(struct super_block *sb, |
| 1034 | struct f2fs_super_block **raw_super, | 1141 | struct f2fs_super_block **raw_super, |
| 1035 | struct buffer_head **raw_super_buf, | 1142 | int *valid_super_block, int *recovery) |
| 1036 | int *recovery) | ||
| 1037 | { | 1143 | { |
| 1038 | int block = 0; | 1144 | int block = 0; |
| 1039 | struct buffer_head *buffer; | 1145 | struct buffer_head *bh; |
| 1040 | struct f2fs_super_block *super; | 1146 | struct f2fs_super_block *super, *buf; |
| 1041 | int err = 0; | 1147 | int err = 0; |
| 1042 | 1148 | ||
| 1149 | super = kzalloc(sizeof(struct f2fs_super_block), GFP_KERNEL); | ||
| 1150 | if (!super) | ||
| 1151 | return -ENOMEM; | ||
| 1043 | retry: | 1152 | retry: |
| 1044 | buffer = sb_bread(sb, block); | 1153 | bh = sb_bread(sb, block); |
| 1045 | if (!buffer) { | 1154 | if (!bh) { |
| 1046 | *recovery = 1; | 1155 | *recovery = 1; |
| 1047 | f2fs_msg(sb, KERN_ERR, "Unable to read %dth superblock", | 1156 | f2fs_msg(sb, KERN_ERR, "Unable to read %dth superblock", |
| 1048 | block + 1); | 1157 | block + 1); |
| 1049 | if (block == 0) { | 1158 | err = -EIO; |
| 1050 | block++; | 1159 | goto next; |
| 1051 | goto retry; | ||
| 1052 | } else { | ||
| 1053 | err = -EIO; | ||
| 1054 | goto out; | ||
| 1055 | } | ||
| 1056 | } | 1160 | } |
| 1057 | 1161 | ||
| 1058 | super = (struct f2fs_super_block *) | 1162 | buf = (struct f2fs_super_block *)(bh->b_data + F2FS_SUPER_OFFSET); |
| 1059 | ((char *)(buffer)->b_data + F2FS_SUPER_OFFSET); | ||
| 1060 | 1163 | ||
| 1061 | /* sanity checking of raw super */ | 1164 | /* sanity checking of raw super */ |
| 1062 | if (sanity_check_raw_super(sb, super)) { | 1165 | if (sanity_check_raw_super(sb, buf)) { |
| 1063 | brelse(buffer); | 1166 | brelse(bh); |
| 1064 | *recovery = 1; | 1167 | *recovery = 1; |
| 1065 | f2fs_msg(sb, KERN_ERR, | 1168 | f2fs_msg(sb, KERN_ERR, |
| 1066 | "Can't find valid F2FS filesystem in %dth superblock", | 1169 | "Can't find valid F2FS filesystem in %dth superblock", |
| 1067 | block + 1); | 1170 | block + 1); |
| 1068 | if (block == 0) { | 1171 | err = -EINVAL; |
| 1069 | block++; | 1172 | goto next; |
| 1070 | goto retry; | ||
| 1071 | } else { | ||
| 1072 | err = -EINVAL; | ||
| 1073 | goto out; | ||
| 1074 | } | ||
| 1075 | } | 1173 | } |
| 1076 | 1174 | ||
| 1077 | if (!*raw_super) { | 1175 | if (!*raw_super) { |
| 1078 | *raw_super_buf = buffer; | 1176 | memcpy(super, buf, sizeof(*super)); |
| 1177 | *valid_super_block = block; | ||
| 1079 | *raw_super = super; | 1178 | *raw_super = super; |
| 1080 | } else { | ||
| 1081 | /* already have a valid superblock */ | ||
| 1082 | brelse(buffer); | ||
| 1083 | } | 1179 | } |
| 1180 | brelse(bh); | ||
| 1084 | 1181 | ||
| 1182 | next: | ||
| 1085 | /* check the validity of the second superblock */ | 1183 | /* check the validity of the second superblock */ |
| 1086 | if (block == 0) { | 1184 | if (block == 0) { |
| 1087 | block++; | 1185 | block++; |
| 1088 | goto retry; | 1186 | goto retry; |
| 1089 | } | 1187 | } |
| 1090 | 1188 | ||
| 1091 | out: | ||
| 1092 | /* No valid superblock */ | 1189 | /* No valid superblock */ |
| 1093 | if (!*raw_super) | 1190 | if (!*raw_super) { |
| 1191 | kfree(super); | ||
| 1094 | return err; | 1192 | return err; |
| 1193 | } | ||
| 1095 | 1194 | ||
| 1096 | return 0; | 1195 | return 0; |
| 1097 | } | 1196 | } |
| 1098 | 1197 | ||
| 1198 | static int __f2fs_commit_super(struct f2fs_sb_info *sbi, int block) | ||
| 1199 | { | ||
| 1200 | struct f2fs_super_block *super = F2FS_RAW_SUPER(sbi); | ||
| 1201 | struct buffer_head *bh; | ||
| 1202 | int err; | ||
| 1203 | |||
| 1204 | bh = sb_getblk(sbi->sb, block); | ||
| 1205 | if (!bh) | ||
| 1206 | return -EIO; | ||
| 1207 | |||
| 1208 | lock_buffer(bh); | ||
| 1209 | memcpy(bh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super)); | ||
| 1210 | set_buffer_uptodate(bh); | ||
| 1211 | set_buffer_dirty(bh); | ||
| 1212 | unlock_buffer(bh); | ||
| 1213 | |||
| 1214 | /* it's rare case, we can do fua all the time */ | ||
| 1215 | err = __sync_dirty_buffer(bh, WRITE_FLUSH_FUA); | ||
| 1216 | brelse(bh); | ||
| 1217 | |||
| 1218 | return err; | ||
| 1219 | } | ||
| 1220 | |||
| 1099 | int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) | 1221 | int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) |
| 1100 | { | 1222 | { |
| 1101 | struct buffer_head *sbh = sbi->raw_super_buf; | ||
| 1102 | sector_t block = sbh->b_blocknr; | ||
| 1103 | int err; | 1223 | int err; |
| 1104 | 1224 | ||
| 1105 | /* write back-up superblock first */ | 1225 | /* write back-up superblock first */ |
| 1106 | sbh->b_blocknr = block ? 0 : 1; | 1226 | err = __f2fs_commit_super(sbi, sbi->valid_super_block ? 0 : 1); |
| 1107 | mark_buffer_dirty(sbh); | ||
| 1108 | err = sync_dirty_buffer(sbh); | ||
| 1109 | |||
| 1110 | sbh->b_blocknr = block; | ||
| 1111 | 1227 | ||
| 1112 | /* if we are in recovery path, skip writing valid superblock */ | 1228 | /* if we are in recovery path, skip writing valid superblock */ |
| 1113 | if (recover || err) | 1229 | if (recover || err) |
| 1114 | goto out; | 1230 | return err; |
| 1115 | 1231 | ||
| 1116 | /* write current valid superblock */ | 1232 | /* write current valid superblock */ |
| 1117 | mark_buffer_dirty(sbh); | 1233 | return __f2fs_commit_super(sbi, sbi->valid_super_block); |
| 1118 | err = sync_dirty_buffer(sbh); | ||
| 1119 | out: | ||
| 1120 | clear_buffer_write_io_error(sbh); | ||
| 1121 | set_buffer_uptodate(sbh); | ||
| 1122 | return err; | ||
| 1123 | } | 1234 | } |
| 1124 | 1235 | ||
| 1125 | static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | 1236 | static int f2fs_fill_super(struct super_block *sb, void *data, int silent) |
| 1126 | { | 1237 | { |
| 1127 | struct f2fs_sb_info *sbi; | 1238 | struct f2fs_sb_info *sbi; |
| 1128 | struct f2fs_super_block *raw_super; | 1239 | struct f2fs_super_block *raw_super; |
| 1129 | struct buffer_head *raw_super_buf; | ||
| 1130 | struct inode *root; | 1240 | struct inode *root; |
| 1131 | long err; | 1241 | long err; |
| 1132 | bool retry = true, need_fsck = false; | 1242 | bool retry = true, need_fsck = false; |
| 1133 | char *options = NULL; | 1243 | char *options = NULL; |
| 1134 | int recovery, i; | 1244 | int recovery, i, valid_super_block; |
| 1135 | 1245 | ||
| 1136 | try_onemore: | 1246 | try_onemore: |
| 1137 | err = -EINVAL; | 1247 | err = -EINVAL; |
| 1138 | raw_super = NULL; | 1248 | raw_super = NULL; |
| 1139 | raw_super_buf = NULL; | 1249 | valid_super_block = -1; |
| 1140 | recovery = 0; | 1250 | recovery = 0; |
| 1141 | 1251 | ||
| 1142 | /* allocate memory for f2fs-specific super block info */ | 1252 | /* allocate memory for f2fs-specific super block info */ |
| @@ -1150,7 +1260,8 @@ try_onemore: | |||
| 1150 | goto free_sbi; | 1260 | goto free_sbi; |
| 1151 | } | 1261 | } |
| 1152 | 1262 | ||
| 1153 | err = read_raw_super_block(sb, &raw_super, &raw_super_buf, &recovery); | 1263 | err = read_raw_super_block(sb, &raw_super, &valid_super_block, |
| 1264 | &recovery); | ||
| 1154 | if (err) | 1265 | if (err) |
| 1155 | goto free_sbi; | 1266 | goto free_sbi; |
| 1156 | 1267 | ||
| @@ -1167,7 +1278,9 @@ try_onemore: | |||
| 1167 | if (err) | 1278 | if (err) |
| 1168 | goto free_options; | 1279 | goto free_options; |
| 1169 | 1280 | ||
| 1170 | sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize)); | 1281 | sbi->max_file_blocks = max_file_blocks(); |
| 1282 | sb->s_maxbytes = sbi->max_file_blocks << | ||
| 1283 | le32_to_cpu(raw_super->log_blocksize); | ||
| 1171 | sb->s_max_links = F2FS_LINK_MAX; | 1284 | sb->s_max_links = F2FS_LINK_MAX; |
| 1172 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); | 1285 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); |
| 1173 | 1286 | ||
| @@ -1183,7 +1296,7 @@ try_onemore: | |||
| 1183 | /* init f2fs-specific super block info */ | 1296 | /* init f2fs-specific super block info */ |
| 1184 | sbi->sb = sb; | 1297 | sbi->sb = sb; |
| 1185 | sbi->raw_super = raw_super; | 1298 | sbi->raw_super = raw_super; |
| 1186 | sbi->raw_super_buf = raw_super_buf; | 1299 | sbi->valid_super_block = valid_super_block; |
| 1187 | mutex_init(&sbi->gc_mutex); | 1300 | mutex_init(&sbi->gc_mutex); |
| 1188 | mutex_init(&sbi->writepages); | 1301 | mutex_init(&sbi->writepages); |
| 1189 | mutex_init(&sbi->cp_mutex); | 1302 | mutex_init(&sbi->cp_mutex); |
| @@ -1236,8 +1349,10 @@ try_onemore: | |||
| 1236 | le64_to_cpu(sbi->ckpt->valid_block_count); | 1349 | le64_to_cpu(sbi->ckpt->valid_block_count); |
| 1237 | sbi->last_valid_block_count = sbi->total_valid_block_count; | 1350 | sbi->last_valid_block_count = sbi->total_valid_block_count; |
| 1238 | sbi->alloc_valid_block_count = 0; | 1351 | sbi->alloc_valid_block_count = 0; |
| 1239 | INIT_LIST_HEAD(&sbi->dir_inode_list); | 1352 | for (i = 0; i < NR_INODE_TYPE; i++) { |
| 1240 | spin_lock_init(&sbi->dir_inode_lock); | 1353 | INIT_LIST_HEAD(&sbi->inode_list[i]); |
| 1354 | spin_lock_init(&sbi->inode_lock[i]); | ||
| 1355 | } | ||
| 1241 | 1356 | ||
| 1242 | init_extent_cache_info(sbi); | 1357 | init_extent_cache_info(sbi); |
| 1243 | 1358 | ||
| @@ -1355,12 +1470,14 @@ try_onemore: | |||
| 1355 | f2fs_commit_super(sbi, true); | 1470 | f2fs_commit_super(sbi, true); |
| 1356 | } | 1471 | } |
| 1357 | 1472 | ||
| 1358 | sbi->cp_expires = round_jiffies_up(jiffies); | 1473 | f2fs_update_time(sbi, CP_TIME); |
| 1359 | 1474 | f2fs_update_time(sbi, REQ_TIME); | |
| 1360 | return 0; | 1475 | return 0; |
| 1361 | 1476 | ||
| 1362 | free_kobj: | 1477 | free_kobj: |
| 1363 | kobject_del(&sbi->s_kobj); | 1478 | kobject_del(&sbi->s_kobj); |
| 1479 | kobject_put(&sbi->s_kobj); | ||
| 1480 | wait_for_completion(&sbi->s_kobj_unregister); | ||
| 1364 | free_proc: | 1481 | free_proc: |
| 1365 | if (sbi->s_proc) { | 1482 | if (sbi->s_proc) { |
| 1366 | remove_proc_entry("segment_info", sbi->s_proc); | 1483 | remove_proc_entry("segment_info", sbi->s_proc); |
| @@ -1387,7 +1504,7 @@ free_meta_inode: | |||
| 1387 | free_options: | 1504 | free_options: |
| 1388 | kfree(options); | 1505 | kfree(options); |
| 1389 | free_sb_buf: | 1506 | free_sb_buf: |
| 1390 | brelse(raw_super_buf); | 1507 | kfree(raw_super); |
| 1391 | free_sbi: | 1508 | free_sbi: |
| 1392 | kfree(sbi); | 1509 | kfree(sbi); |
| 1393 | 1510 | ||
| @@ -1478,10 +1595,14 @@ static int __init init_f2fs_fs(void) | |||
| 1478 | err = register_filesystem(&f2fs_fs_type); | 1595 | err = register_filesystem(&f2fs_fs_type); |
| 1479 | if (err) | 1596 | if (err) |
| 1480 | goto free_shrinker; | 1597 | goto free_shrinker; |
| 1481 | f2fs_create_root_stats(); | 1598 | err = f2fs_create_root_stats(); |
| 1599 | if (err) | ||
| 1600 | goto free_filesystem; | ||
| 1482 | f2fs_proc_root = proc_mkdir("fs/f2fs", NULL); | 1601 | f2fs_proc_root = proc_mkdir("fs/f2fs", NULL); |
| 1483 | return 0; | 1602 | return 0; |
| 1484 | 1603 | ||
| 1604 | free_filesystem: | ||
| 1605 | unregister_filesystem(&f2fs_fs_type); | ||
| 1485 | free_shrinker: | 1606 | free_shrinker: |
| 1486 | unregister_shrinker(&f2fs_shrinker_info); | 1607 | unregister_shrinker(&f2fs_shrinker_info); |
| 1487 | free_crypto: | 1608 | free_crypto: |
