]> Pileus Git - ~andy/linux/blobdiff - fs/ext2/super.c
Merge branch 'perfcounters-fixes-for-linus' of git://git.kernel.org/pub/scm/linux...
[~andy/linux] / fs / ext2 / super.c
index 5c4afe652245a9d045825f26f3ad3dbe0a06e13a..1a9ffee47d56c545dcc9420680178fb32ea6c374 100644 (file)
@@ -42,6 +42,7 @@ static void ext2_sync_super(struct super_block *sb,
                            struct ext2_super_block *es);
 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);
 
 void ext2_error (struct super_block * sb, const char * function,
                 const char * fmt, ...)
@@ -114,6 +115,11 @@ static void ext2_put_super (struct super_block * sb)
        int i;
        struct ext2_sb_info *sbi = EXT2_SB(sb);
 
+       lock_kernel();
+
+       if (sb->s_dirt)
+               ext2_write_super(sb);
+
        ext2_xattr_put_super(sb);
        if (!(sb->s_flags & MS_RDONLY)) {
                struct ext2_super_block *es = sbi->s_es;
@@ -135,7 +141,7 @@ static void ext2_put_super (struct super_block * sb)
        kfree(sbi->s_blockgroup_lock);
        kfree(sbi);
 
-       return;
+       unlock_kernel();
 }
 
 static struct kmem_cache * ext2_inode_cachep;
@@ -146,10 +152,6 @@ static struct inode *ext2_alloc_inode(struct super_block *sb)
        ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, GFP_KERNEL);
        if (!ei)
                return NULL;
-#ifdef CONFIG_EXT2_FS_POSIX_ACL
-       ei->i_acl = EXT2_ACL_NOT_CACHED;
-       ei->i_default_acl = EXT2_ACL_NOT_CACHED;
-#endif
        ei->i_block_alloc_info = NULL;
        ei->vfs_inode.i_version = 1;
        return &ei->vfs_inode;
@@ -192,18 +194,6 @@ static void destroy_inodecache(void)
 static void ext2_clear_inode(struct inode *inode)
 {
        struct ext2_block_alloc_info *rsv = EXT2_I(inode)->i_block_alloc_info;
-#ifdef CONFIG_EXT2_FS_POSIX_ACL
-       struct ext2_inode_info *ei = EXT2_I(inode);
-
-       if (ei->i_acl && ei->i_acl != EXT2_ACL_NOT_CACHED) {
-               posix_acl_release(ei->i_acl);
-               ei->i_acl = EXT2_ACL_NOT_CACHED;
-       }
-       if (ei->i_default_acl && ei->i_default_acl != EXT2_ACL_NOT_CACHED) {
-               posix_acl_release(ei->i_default_acl);
-               ei->i_default_acl = EXT2_ACL_NOT_CACHED;
-       }
-#endif
        ext2_discard_reservation(inode);
        EXT2_I(inode)->i_block_alloc_info = NULL;
        if (unlikely(rsv))
@@ -304,6 +294,7 @@ static const struct super_operations ext2_sops = {
        .delete_inode   = ext2_delete_inode,
        .put_super      = ext2_put_super,
        .write_super    = ext2_write_super,
+       .sync_fs        = ext2_sync_fs,
        .statfs         = ext2_statfs,
        .remount_fs     = ext2_remount,
        .clear_inode    = ext2_clear_inode,
@@ -1093,6 +1084,7 @@ failed_mount:
        brelse(bh);
 failed_sbi:
        sb->s_fs_info = NULL;
+       kfree(sbi->s_blockgroup_lock);
        kfree(sbi);
        return ret;
 }
@@ -1126,25 +1118,36 @@ static void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es)
  * set s_state to EXT2_VALID_FS after some corrections.
  */
 
-void ext2_write_super (struct super_block * sb)
+static int ext2_sync_fs(struct super_block *sb, int wait)
 {
-       struct ext2_super_block * es;
+       struct ext2_super_block *es = EXT2_SB(sb)->s_es;
+
        lock_kernel();
-       if (!(sb->s_flags & MS_RDONLY)) {
-               es = EXT2_SB(sb)->s_es;
-
-               if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) {
-                       ext2_debug ("setting valid to 0\n");
-                       es->s_state &= cpu_to_le16(~EXT2_VALID_FS);
-                       es->s_free_blocks_count = cpu_to_le32(ext2_count_free_blocks(sb));
-                       es->s_free_inodes_count = cpu_to_le32(ext2_count_free_inodes(sb));
-                       es->s_mtime = cpu_to_le32(get_seconds());
-                       ext2_sync_super(sb, es);
-               } else
-                       ext2_commit_super (sb, es);
+       if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) {
+               ext2_debug("setting valid to 0\n");
+               es->s_state &= cpu_to_le16(~EXT2_VALID_FS);
+               es->s_free_blocks_count =
+                       cpu_to_le32(ext2_count_free_blocks(sb));
+               es->s_free_inodes_count =
+                       cpu_to_le32(ext2_count_free_inodes(sb));
+               es->s_mtime = cpu_to_le32(get_seconds());
+               ext2_sync_super(sb, es);
+       } else {
+               ext2_commit_super(sb, es);
        }
        sb->s_dirt = 0;
        unlock_kernel();
+
+       return 0;
+}
+
+
+void ext2_write_super(struct super_block *sb)
+{
+       if (!(sb->s_flags & MS_RDONLY))
+               ext2_sync_fs(sb, 1);
+       else
+               sb->s_dirt = 0;
 }
 
 static int ext2_remount (struct super_block * sb, int * flags, char * data)
@@ -1156,6 +1159,8 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
        unsigned long old_sb_flags;
        int err;
 
+       lock_kernel();
+
        /* Store the old options */
        old_sb_flags = sb->s_flags;
        old_opts.s_mount_opt = sbi->s_mount_opt;
@@ -1191,12 +1196,16 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
                sbi->s_mount_opt &= ~EXT2_MOUNT_XIP;
                sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP;
        }
-       if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
+       if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
+               unlock_kernel();
                return 0;
+       }
        if (*flags & MS_RDONLY) {
                if (le16_to_cpu(es->s_state) & EXT2_VALID_FS ||
-                   !(sbi->s_mount_state & EXT2_VALID_FS))
+                   !(sbi->s_mount_state & EXT2_VALID_FS)) {
+                       unlock_kernel();
                        return 0;
+               }
                /*
                 * OK, we are remounting a valid rw partition rdonly, so set
                 * the rdonly flag and then mark the partition as valid again.
@@ -1223,12 +1232,14 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
                        sb->s_flags &= ~MS_RDONLY;
        }
        ext2_sync_super(sb, es);
+       unlock_kernel();
        return 0;
 restore_opts:
        sbi->s_mount_opt = old_opts.s_mount_opt;
        sbi->s_resuid = old_opts.s_resuid;
        sbi->s_resgid = old_opts.s_resgid;
        sb->s_flags = old_sb_flags;
+       unlock_kernel();
        return err;
 }