summaryrefslogtreecommitdiffstats
path: root/fs/f2fs/super.c
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2016-03-23 20:05:27 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2016-04-15 11:49:47 -0400
commitdf728b0f6954c38545f4bf12dedeeb9e07469a94 (patch)
treef7cbf73658f73afd742e80866e266e852a5293ef /fs/f2fs/super.c
parentf2353d7bd4221dfe0e230c5be49038d4a57d97e9 (diff)
f2fs: recover superblock at RW remounts
This patch adds a sbi flag, SBI_NEED_SB_WRITE, which indicates it needs to recover superblock when (re)mounting as RW. This is set only when f2fs is mounted as RO. Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/super.c')
-rw-r--r--fs/f2fs/super.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index ffe4616376ca..f5fbbfdb3d93 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -796,6 +796,15 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
796 set_sbi_flag(sbi, SBI_IS_DIRTY); 796 set_sbi_flag(sbi, SBI_IS_DIRTY);
797 } 797 }
798 798
799 /* recover superblocks we couldn't write due to previous RO mount */
800 if (!(*flags & MS_RDONLY) && is_sbi_flag_set(sbi, SBI_NEED_SB_WRITE)) {
801 err = f2fs_commit_super(sbi, false);
802 f2fs_msg(sb, KERN_INFO,
803 "Try to recover all the superblocks, ret: %d", err);
804 if (!err)
805 clear_sbi_flag(sbi, SBI_NEED_SB_WRITE);
806 }
807
799 sync_filesystem(sb); 808 sync_filesystem(sb);
800 809
801 sbi->mount_opt.opt = 0; 810 sbi->mount_opt.opt = 0;
@@ -852,8 +861,9 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
852 } 861 }
853skip: 862skip:
854 /* Update the POSIXACL Flag */ 863 /* Update the POSIXACL Flag */
855 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | 864 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
856 (test_opt(sbi, POSIX_ACL) ? MS_POSIXACL : 0); 865 (test_opt(sbi, POSIX_ACL) ? MS_POSIXACL : 0);
866
857 return 0; 867 return 0;
858restore_gc: 868restore_gc:
859 if (need_restart_gc) { 869 if (need_restart_gc) {
@@ -998,11 +1008,12 @@ static int __f2fs_commit_super(struct buffer_head *bh,
998 return __sync_dirty_buffer(bh, WRITE_FLUSH_FUA); 1008 return __sync_dirty_buffer(bh, WRITE_FLUSH_FUA);
999} 1009}
1000 1010
1001static inline bool sanity_check_area_boundary(struct super_block *sb, 1011static inline bool sanity_check_area_boundary(struct f2fs_sb_info *sbi,
1002 struct buffer_head *bh) 1012 struct buffer_head *bh)
1003{ 1013{
1004 struct f2fs_super_block *raw_super = (struct f2fs_super_block *) 1014 struct f2fs_super_block *raw_super = (struct f2fs_super_block *)
1005 (bh->b_data + F2FS_SUPER_OFFSET); 1015 (bh->b_data + F2FS_SUPER_OFFSET);
1016 struct super_block *sb = sbi->sb;
1006 u32 segment0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr); 1017 u32 segment0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr);
1007 u32 cp_blkaddr = le32_to_cpu(raw_super->cp_blkaddr); 1018 u32 cp_blkaddr = le32_to_cpu(raw_super->cp_blkaddr);
1008 u32 sit_blkaddr = le32_to_cpu(raw_super->sit_blkaddr); 1019 u32 sit_blkaddr = le32_to_cpu(raw_super->sit_blkaddr);
@@ -1081,6 +1092,7 @@ static inline bool sanity_check_area_boundary(struct super_block *sb,
1081 segment0_blkaddr) >> log_blocks_per_seg); 1092 segment0_blkaddr) >> log_blocks_per_seg);
1082 1093
1083 if (f2fs_readonly(sb) || bdev_read_only(sb->s_bdev)) { 1094 if (f2fs_readonly(sb) || bdev_read_only(sb->s_bdev)) {
1095 set_sbi_flag(sbi, SBI_NEED_SB_WRITE);
1084 res = "internally"; 1096 res = "internally";
1085 } else { 1097 } else {
1086 err = __f2fs_commit_super(bh, NULL); 1098 err = __f2fs_commit_super(bh, NULL);
@@ -1098,11 +1110,12 @@ static inline bool sanity_check_area_boundary(struct super_block *sb,
1098 return false; 1110 return false;
1099} 1111}
1100 1112
1101static int sanity_check_raw_super(struct super_block *sb, 1113static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
1102 struct buffer_head *bh) 1114 struct buffer_head *bh)
1103{ 1115{
1104 struct f2fs_super_block *raw_super = (struct f2fs_super_block *) 1116 struct f2fs_super_block *raw_super = (struct f2fs_super_block *)
1105 (bh->b_data + F2FS_SUPER_OFFSET); 1117 (bh->b_data + F2FS_SUPER_OFFSET);
1118 struct super_block *sb = sbi->sb;
1106 unsigned int blocksize; 1119 unsigned int blocksize;
1107 1120
1108 if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) { 1121 if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) {
@@ -1169,7 +1182,7 @@ static int sanity_check_raw_super(struct super_block *sb,
1169 } 1182 }
1170 1183
1171 /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */ 1184 /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */
1172 if (sanity_check_area_boundary(sb, bh)) 1185 if (sanity_check_area_boundary(sbi, bh))
1173 return 1; 1186 return 1;
1174 1187
1175 return 0; 1188 return 0;
@@ -1239,10 +1252,11 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
1239 * to get the first valid one. If any one of them is broken, we pass 1252 * to get the first valid one. If any one of them is broken, we pass
1240 * them recovery flag back to the caller. 1253 * them recovery flag back to the caller.
1241 */ 1254 */
1242static int read_raw_super_block(struct super_block *sb, 1255static int read_raw_super_block(struct f2fs_sb_info *sbi,
1243 struct f2fs_super_block **raw_super, 1256 struct f2fs_super_block **raw_super,
1244 int *valid_super_block, int *recovery) 1257 int *valid_super_block, int *recovery)
1245{ 1258{
1259 struct super_block *sb = sbi->sb;
1246 int block; 1260 int block;
1247 struct buffer_head *bh; 1261 struct buffer_head *bh;
1248 struct f2fs_super_block *super; 1262 struct f2fs_super_block *super;
@@ -1262,7 +1276,7 @@ static int read_raw_super_block(struct super_block *sb,
1262 } 1276 }
1263 1277
1264 /* sanity checking of raw super */ 1278 /* sanity checking of raw super */
1265 if (sanity_check_raw_super(sb, bh)) { 1279 if (sanity_check_raw_super(sbi, bh)) {
1266 f2fs_msg(sb, KERN_ERR, 1280 f2fs_msg(sb, KERN_ERR,
1267 "Can't find valid F2FS filesystem in %dth superblock", 1281 "Can't find valid F2FS filesystem in %dth superblock",
1268 block + 1); 1282 block + 1);
@@ -1298,8 +1312,11 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover)
1298 struct buffer_head *bh; 1312 struct buffer_head *bh;
1299 int err; 1313 int err;
1300 1314
1301 if (f2fs_readonly(sbi->sb) || bdev_read_only(sbi->sb->s_bdev)) 1315 if ((recover && f2fs_readonly(sbi->sb)) ||
1316 bdev_read_only(sbi->sb->s_bdev)) {
1317 set_sbi_flag(sbi, SBI_NEED_SB_WRITE);
1302 return -EROFS; 1318 return -EROFS;
1319 }
1303 1320
1304 /* write back-up superblock first */ 1321 /* write back-up superblock first */
1305 bh = sb_getblk(sbi->sb, sbi->valid_super_block ? 0: 1); 1322 bh = sb_getblk(sbi->sb, sbi->valid_super_block ? 0: 1);
@@ -1343,6 +1360,8 @@ try_onemore:
1343 if (!sbi) 1360 if (!sbi)
1344 return -ENOMEM; 1361 return -ENOMEM;
1345 1362
1363 sbi->sb = sb;
1364
1346 /* Load the checksum driver */ 1365 /* Load the checksum driver */
1347 sbi->s_chksum_driver = crypto_alloc_shash("crc32", 0, 0); 1366 sbi->s_chksum_driver = crypto_alloc_shash("crc32", 0, 0);
1348 if (IS_ERR(sbi->s_chksum_driver)) { 1367 if (IS_ERR(sbi->s_chksum_driver)) {
@@ -1358,7 +1377,7 @@ try_onemore:
1358 goto free_sbi; 1377 goto free_sbi;
1359 } 1378 }
1360 1379
1361 err = read_raw_super_block(sb, &raw_super, &valid_super_block, 1380 err = read_raw_super_block(sbi, &raw_super, &valid_super_block,
1362 &recovery); 1381 &recovery);
1363 if (err) 1382 if (err)
1364 goto free_sbi; 1383 goto free_sbi;
@@ -1393,7 +1412,6 @@ try_onemore:
1393 memcpy(sb->s_uuid, raw_super->uuid, sizeof(raw_super->uuid)); 1412 memcpy(sb->s_uuid, raw_super->uuid, sizeof(raw_super->uuid));
1394 1413
1395 /* init f2fs-specific super block info */ 1414 /* init f2fs-specific super block info */
1396 sbi->sb = sb;
1397 sbi->raw_super = raw_super; 1415 sbi->raw_super = raw_super;
1398 sbi->valid_super_block = valid_super_block; 1416 sbi->valid_super_block = valid_super_block;
1399 mutex_init(&sbi->gc_mutex); 1417 mutex_init(&sbi->gc_mutex);