|
@@ -568,6 +568,7 @@ static void f2fs_put_super(struct super_block *sb)
|
|
|
|
|
|
sb->s_fs_info = NULL;
|
|
|
brelse(sbi->raw_super_buf);
|
|
|
+ kfree(sbi->raw_super);
|
|
|
kfree(sbi);
|
|
|
}
|
|
|
|
|
@@ -1139,6 +1140,9 @@ static int read_raw_super_block(struct super_block *sb,
|
|
|
struct f2fs_super_block *super;
|
|
|
int err = 0;
|
|
|
|
|
|
+ super = kzalloc(sizeof(struct f2fs_super_block), GFP_KERNEL);
|
|
|
+ if (!super)
|
|
|
+ return -ENOMEM;
|
|
|
retry:
|
|
|
buffer = sb_bread(sb, block);
|
|
|
if (!buffer) {
|
|
@@ -1154,8 +1158,7 @@ retry:
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- super = (struct f2fs_super_block *)
|
|
|
- ((char *)(buffer)->b_data + F2FS_SUPER_OFFSET);
|
|
|
+ memcpy(super, buffer->b_data + F2FS_SUPER_OFFSET, sizeof(*super));
|
|
|
|
|
|
/* sanity checking of raw super */
|
|
|
if (sanity_check_raw_super(sb, super)) {
|
|
@@ -1189,14 +1192,17 @@ retry:
|
|
|
|
|
|
out:
|
|
|
/* No valid superblock */
|
|
|
- if (!*raw_super)
|
|
|
+ if (!*raw_super) {
|
|
|
+ kfree(super);
|
|
|
return err;
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover)
|
|
|
{
|
|
|
+ struct f2fs_super_block *super = F2FS_RAW_SUPER(sbi);
|
|
|
struct buffer_head *sbh = sbi->raw_super_buf;
|
|
|
struct buffer_head *bh;
|
|
|
int err;
|
|
@@ -1207,7 +1213,7 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover)
|
|
|
return -EIO;
|
|
|
|
|
|
lock_buffer(bh);
|
|
|
- memcpy(bh->b_data, sbh->b_data, sbh->b_size);
|
|
|
+ memcpy(bh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super));
|
|
|
WARN_ON(sbh->b_size != F2FS_BLKSIZE);
|
|
|
set_buffer_uptodate(bh);
|
|
|
set_buffer_dirty(bh);
|
|
@@ -1223,6 +1229,10 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover)
|
|
|
|
|
|
/* write current valid superblock */
|
|
|
lock_buffer(sbh);
|
|
|
+ if (memcmp(sbh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super))) {
|
|
|
+ f2fs_msg(sbi->sb, KERN_INFO, "Write modified valid superblock");
|
|
|
+ memcpy(sbh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super));
|
|
|
+ }
|
|
|
set_buffer_dirty(sbh);
|
|
|
unlock_buffer(sbh);
|
|
|
|
|
@@ -1497,6 +1507,7 @@ free_options:
|
|
|
kfree(options);
|
|
|
free_sb_buf:
|
|
|
brelse(raw_super_buf);
|
|
|
+ kfree(raw_super);
|
|
|
free_sbi:
|
|
|
kfree(sbi);
|
|
|
|