Skip to content

Commit

Permalink
ext2: Implement freezing
Browse files Browse the repository at this point in the history
The only missing piece to make freezing work reliably with ext2 is to
stop iput() of unlinked inode from deleting the inode on frozen filesystem.
So add a necessary protection to ext2_evict_inode().

We also provide appropriate ->freeze_fs and ->unfreeze_fs functions.

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
Jan Kara authored and Al Viro committed Jul 31, 2012
1 parent b2b5ef5 commit 1e8b212
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
5 changes: 4 additions & 1 deletion fs/ext2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ void ext2_evict_inode(struct inode * inode)
truncate_inode_pages(&inode->i_data, 0);

if (want_delete) {
sb_start_intwrite(inode->i_sb);
/* set dtime */
EXT2_I(inode)->i_dtime = get_seconds();
mark_inode_dirty(inode);
Expand All @@ -98,8 +99,10 @@ void ext2_evict_inode(struct inode * inode)
if (unlikely(rsv))
kfree(rsv);

if (want_delete)
if (want_delete) {
ext2_free_inode(inode);
sb_end_intwrite(inode->i_sb);
}
}

typedef struct {
Expand Down
33 changes: 33 additions & 0 deletions fs/ext2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ static void ext2_sync_super(struct super_block *sb,
static int ext2_remount (struct super_block * sb, int * flags, char * data);
static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf);
static int ext2_sync_fs(struct super_block *sb, int wait);
static int ext2_freeze(struct super_block *sb);
static int ext2_unfreeze(struct super_block *sb);

void ext2_error(struct super_block *sb, const char *function,
const char *fmt, ...)
Expand Down Expand Up @@ -305,6 +307,8 @@ static const struct super_operations ext2_sops = {
.evict_inode = ext2_evict_inode,
.put_super = ext2_put_super,
.sync_fs = ext2_sync_fs,
.freeze_fs = ext2_freeze,
.unfreeze_fs = ext2_unfreeze,
.statfs = ext2_statfs,
.remount_fs = ext2_remount,
.show_options = ext2_show_options,
Expand Down Expand Up @@ -1200,6 +1204,35 @@ static int ext2_sync_fs(struct super_block *sb, int wait)
return 0;
}

static int ext2_freeze(struct super_block *sb)
{
struct ext2_sb_info *sbi = EXT2_SB(sb);

/*
* Open but unlinked files present? Keep EXT2_VALID_FS flag cleared
* because we have unattached inodes and thus filesystem is not fully
* consistent.
*/
if (atomic_long_read(&sb->s_remove_count)) {
ext2_sync_fs(sb, 1);
return 0;
}
/* Set EXT2_FS_VALID flag */
spin_lock(&sbi->s_lock);
sbi->s_es->s_state = cpu_to_le16(sbi->s_mount_state);
spin_unlock(&sbi->s_lock);
ext2_sync_super(sb, sbi->s_es, 1);

return 0;
}

static int ext2_unfreeze(struct super_block *sb)
{
/* Just write sb to clear EXT2_VALID_FS flag */
ext2_write_super(sb);

return 0;
}

void ext2_write_super(struct super_block *sb)
{
Expand Down

0 comments on commit 1e8b212

Please sign in to comment.