summaryrefslogtreecommitdiffstats
path: root/fs/f2fs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/f2fs/super.c')
-rw-r--r--fs/f2fs/super.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 4031f8ed9d24..6dfe0d32ad88 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -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);