Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
[pandora-kernel.git] / fs / ext4 / super.c
index d49e3b1..29c80f6 100644 (file)
@@ -406,28 +406,31 @@ void ext4_error_inode(struct inode *inode, const char *function,
                      const char *fmt, ...)
 {
        va_list args;
+       struct va_format vaf;
        struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
 
        es->s_last_error_ino = cpu_to_le32(inode->i_ino);
        es->s_last_error_block = cpu_to_le64(block);
        save_error_info(inode->i_sb, function, line);
        va_start(args, fmt);
+       vaf.fmt = fmt;
+       vaf.va = &args;
        printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: inode #%lu: ",
               inode->i_sb->s_id, function, line, inode->i_ino);
        if (block)
-               printk("block %llu: ", block);
-       printk("comm %s: ", current->comm);
-       vprintk(fmt, args);
-       printk("\n");
+               printk(KERN_CONT "block %llu: ", block);
+       printk(KERN_CONT "comm %s: %pV\n", current->comm, &vaf);
        va_end(args);
 
        ext4_handle_error(inode->i_sb);
 }
 
 void ext4_error_file(struct file *file, const char *function,
-                    unsigned int line, const char *fmt, ...)
+                    unsigned int line, ext4_fsblk_t block,
+                    const char *fmt, ...)
 {
        va_list args;
+       struct va_format vaf;
        struct ext4_super_block *es;
        struct inode *inode = file->f_dentry->d_inode;
        char pathname[80], *path;
@@ -435,17 +438,18 @@ void ext4_error_file(struct file *file, const char *function,
        es = EXT4_SB(inode->i_sb)->s_es;
        es->s_last_error_ino = cpu_to_le32(inode->i_ino);
        save_error_info(inode->i_sb, function, line);
-       va_start(args, fmt);
        path = d_path(&(file->f_path), pathname, sizeof(pathname));
        if (IS_ERR(path))
                path = "(unknown)";
        printk(KERN_CRIT
-              "EXT4-fs error (device %s): %s:%d: inode #%lu "
-              "(comm %s path %s): ",
-              inode->i_sb->s_id, function, line, inode->i_ino,
-              current->comm, path);
-       vprintk(fmt, args);
-       printk("\n");
+              "EXT4-fs error (device %s): %s:%d: inode #%lu: ",
+              inode->i_sb->s_id, function, line, inode->i_ino);
+       if (block)
+               printk(KERN_CONT "block %llu: ", block);
+       va_start(args, fmt);
+       vaf.fmt = fmt;
+       vaf.va = &args;
+       printk(KERN_CONT "comm %s: path %s: %pV\n", current->comm, path, &vaf);
        va_end(args);
 
        ext4_handle_error(inode->i_sb);
@@ -814,21 +818,15 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
        memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
        INIT_LIST_HEAD(&ei->i_prealloc_list);
        spin_lock_init(&ei->i_prealloc_lock);
-       /*
-        * Note:  We can be called before EXT4_SB(sb)->s_journal is set,
-        * therefore it can be null here.  Don't check it, just initialize
-        * jinode.
-        */
-       jbd2_journal_init_jbd_inode(&ei->jinode, &ei->vfs_inode);
        ei->i_reserved_data_blocks = 0;
        ei->i_reserved_meta_blocks = 0;
        ei->i_allocated_meta_blocks = 0;
        ei->i_da_metadata_calc_len = 0;
-       ei->i_delalloc_reserved_flag = 0;
        spin_lock_init(&(ei->i_block_reservation_lock));
 #ifdef CONFIG_QUOTA
        ei->i_reserved_quota = 0;
 #endif
+       ei->jinode = NULL;
        INIT_LIST_HEAD(&ei->i_completed_io_list);
        spin_lock_init(&ei->i_completed_io_lock);
        ei->cur_aio_dio = NULL;
@@ -847,6 +845,13 @@ static int ext4_drop_inode(struct inode *inode)
        return drop;
 }
 
+static void ext4_i_callback(struct rcu_head *head)
+{
+       struct inode *inode = container_of(head, struct inode, i_rcu);
+       INIT_LIST_HEAD(&inode->i_dentry);
+       kmem_cache_free(ext4_inode_cachep, EXT4_I(inode));
+}
+
 static void ext4_destroy_inode(struct inode *inode)
 {
        ext4_ioend_wait(inode);
@@ -859,7 +864,7 @@ static void ext4_destroy_inode(struct inode *inode)
                                true);
                dump_stack();
        }
-       kmem_cache_free(ext4_inode_cachep, EXT4_I(inode));
+       call_rcu(&inode->i_rcu, ext4_i_callback);
 }
 
 static void init_once(void *foo)
@@ -897,9 +902,12 @@ void ext4_clear_inode(struct inode *inode)
        end_writeback(inode);
        dquot_drop(inode);
        ext4_discard_preallocations(inode);
-       if (EXT4_JOURNAL(inode))
-               jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal,
-                                      &EXT4_I(inode)->jinode);
+       if (EXT4_I(inode)->jinode) {
+               jbd2_journal_release_jbd_inode(EXT4_JOURNAL(inode),
+                                              EXT4_I(inode)->jinode);
+               jbd2_free_inode(EXT4_I(inode)->jinode);
+               EXT4_I(inode)->jinode = NULL;
+       }
 }
 
 static inline void ext4_show_quota_options(struct seq_file *seq,
@@ -2921,7 +2929,7 @@ static int ext4_register_li_request(struct super_block *sb,
        struct ext4_sb_info *sbi = EXT4_SB(sb);
        struct ext4_li_request *elr;
        ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
-       int ret;
+       int ret = 0;
 
        if (sbi->s_li_request != NULL)
                return 0;