diff --git a/[refs] b/[refs] index f1bb041c10d3..dbe5c95fdf7c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 54e7ff9d6249ba88e393d7fbc8008da9279723be +refs/heads/master: 9b46333406b9cb3397ab538485a4d57c316af0ff diff --git a/trunk/drivers/firmware/dmi_scan.c b/trunk/drivers/firmware/dmi_scan.c index 8daf4793ac32..3e526b6d00cb 100644 --- a/trunk/drivers/firmware/dmi_scan.c +++ b/trunk/drivers/firmware/dmi_scan.c @@ -81,9 +81,9 @@ static void dmi_table(u8 *buf, int len, int num, const struct dmi_header *dm = (const struct dmi_header *)data; /* - * We want to know the total length (formatted area and - * strings) before decoding to make sure we won't run off the - * table in dmi_decode or dmi_string + * We want to know the total length (formated area and strings) + * before decoding to make sure we won't run off the table in + * dmi_decode or dmi_string */ data += dm->length; while ((data - buf < len - 1) && (data[0] || data[1])) diff --git a/trunk/drivers/message/fusion/mptlan.c b/trunk/drivers/message/fusion/mptlan.c index 603ffd008c73..a1abf95cf751 100644 --- a/trunk/drivers/message/fusion/mptlan.c +++ b/trunk/drivers/message/fusion/mptlan.c @@ -77,6 +77,12 @@ MODULE_VERSION(my_VERSION); * Fusion MPT LAN private structures */ +struct NAA_Hosed { + u16 NAA; + u8 ieee[FC_ALEN]; + struct NAA_Hosed *next; +}; + struct BufferControl { struct sk_buff *skb; dma_addr_t dma; @@ -153,6 +159,11 @@ static u8 LanCtx = MPT_MAX_PROTOCOL_DRIVERS; static u32 max_buckets_out = 127; static u32 tx_max_out_p = 127 - 16; +#ifdef QLOGIC_NAA_WORKAROUND +static struct NAA_Hosed *mpt_bad_naa = NULL; +DEFINE_RWLOCK(bad_naa_lock); +#endif + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * lan_reply - Handle all data sent from the hardware. @@ -769,6 +780,30 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) // ctx, skb, skb->data)); mac = skb_mac_header(skb); +#ifdef QLOGIC_NAA_WORKAROUND +{ + struct NAA_Hosed *nh; + + /* Munge the NAA for Tx packets to QLogic boards, which don't follow + RFC 2625. The longer I look at this, the more my opinion of Qlogic + drops. */ + read_lock_irq(&bad_naa_lock); + for (nh = mpt_bad_naa; nh != NULL; nh=nh->next) { + if ((nh->ieee[0] == mac[0]) && + (nh->ieee[1] == mac[1]) && + (nh->ieee[2] == mac[2]) && + (nh->ieee[3] == mac[3]) && + (nh->ieee[4] == mac[4]) && + (nh->ieee[5] == mac[5])) { + cur_naa = nh->NAA; + dlprintk ((KERN_INFO "mptlan/sdu_send: using NAA value " + "= %04x.\n", cur_naa)); + break; + } + } + read_unlock_irq(&bad_naa_lock); +} +#endif pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa << 16) | (mac[0] << 8) | @@ -1537,6 +1572,79 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) fcllc = (struct fcllc *)skb->data; +#ifdef QLOGIC_NAA_WORKAROUND +{ + u16 source_naa = fch->stype, found = 0; + + /* Workaround for QLogic not following RFC 2625 in regards to the NAA + value. */ + + if ((source_naa & 0xF000) == 0) + source_naa = swab16(source_naa); + + if (fcllc->ethertype == htons(ETH_P_ARP)) + dlprintk ((KERN_INFO "mptlan/type_trans: got arp req/rep w/ naa of " + "%04x.\n", source_naa)); + + if ((fcllc->ethertype == htons(ETH_P_ARP)) && + ((source_naa >> 12) != MPT_LAN_NAA_RFC2625)){ + struct NAA_Hosed *nh, *prevnh; + int i; + + dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep from " + "system with non-RFC 2625 NAA value (%04x).\n", + source_naa)); + + write_lock_irq(&bad_naa_lock); + for (prevnh = nh = mpt_bad_naa; nh != NULL; + prevnh=nh, nh=nh->next) { + if ((nh->ieee[0] == fch->saddr[0]) && + (nh->ieee[1] == fch->saddr[1]) && + (nh->ieee[2] == fch->saddr[2]) && + (nh->ieee[3] == fch->saddr[3]) && + (nh->ieee[4] == fch->saddr[4]) && + (nh->ieee[5] == fch->saddr[5])) { + found = 1; + dlprintk ((KERN_INFO "mptlan/type_trans: ARP Re" + "q/Rep w/ bad NAA from system already" + " in DB.\n")); + break; + } + } + + if ((!found) && (nh == NULL)) { + + nh = kmalloc(sizeof(struct NAA_Hosed), GFP_KERNEL); + dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep w/" + " bad NAA from system not yet in DB.\n")); + + if (nh != NULL) { + nh->next = NULL; + if (!mpt_bad_naa) + mpt_bad_naa = nh; + if (prevnh) + prevnh->next = nh; + + nh->NAA = source_naa; /* Set the S_NAA value. */ + for (i = 0; i < FC_ALEN; i++) + nh->ieee[i] = fch->saddr[i]; + dlprintk ((KERN_INFO "Got ARP from %02x:%02x:%02x:%02x:" + "%02x:%02x with non-compliant S_NAA value.\n", + fch->saddr[0], fch->saddr[1], fch->saddr[2], + fch->saddr[3], fch->saddr[4],fch->saddr[5])); + } else { + printk (KERN_ERR "mptlan/type_trans: Unable to" + " kmalloc a NAA_Hosed struct.\n"); + } + } else if (!found) { + printk (KERN_ERR "mptlan/type_trans: found not" + " set, but nh isn't null. Evil " + "funkiness abounds.\n"); + } + write_unlock_irq(&bad_naa_lock); + } +} +#endif /* Strip the SNAP header from ARP packets since we don't * pass them through to the 802.2/SNAP layers. diff --git a/trunk/fs/ext4/ialloc.c b/trunk/fs/ext4/ialloc.c index 2a117e286e54..fe34d74cfb19 100644 --- a/trunk/fs/ext4/ialloc.c +++ b/trunk/fs/ext4/ialloc.c @@ -718,8 +718,6 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); free = ext4_free_blocks_after_init(sb, group, gdp); gdp->bg_free_blocks_count = cpu_to_le16(free); - gdp->bg_checksum = ext4_group_desc_csum(sbi, group, - gdp); } spin_unlock(sb_bgl_lock(sbi, group)); diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c index be21a5ae33cb..8dbf6953845b 100644 --- a/trunk/fs/ext4/inode.c +++ b/trunk/fs/ext4/inode.c @@ -2329,8 +2329,6 @@ static int ext4_da_writepage(struct page *page, unlock_page(page); return 0; } - /* now mark the buffer_heads as dirty and uptodate */ - block_commit_write(page, 0, PAGE_CACHE_SIZE); } if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) @@ -4582,10 +4580,9 @@ static int ext4_indirect_trans_blocks(struct inode *inode, int nrblocks, static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) { if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)) - return ext4_indirect_trans_blocks(inode, nrblocks, chunk); - return ext4_ext_index_trans_blocks(inode, nrblocks, chunk); + return ext4_indirect_trans_blocks(inode, nrblocks, 0); + return ext4_ext_index_trans_blocks(inode, nrblocks, 0); } - /* * Account for index blocks, block groups bitmaps and block group * descriptor blocks if modify datablocks and index blocks diff --git a/trunk/fs/ext4/mballoc.c b/trunk/fs/ext4/mballoc.c index 444ad998f72e..dfe17a134052 100644 --- a/trunk/fs/ext4/mballoc.c +++ b/trunk/fs/ext4/mballoc.c @@ -4441,7 +4441,6 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b, else if (block >= (entry->start_blk + entry->count)) n = &(*n)->rb_right; else { - ext4_unlock_group(sb, group); ext4_error(sb, __func__, "Double free of blocks %d (%d %d)\n", block, entry->start_blk, entry->count); diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index e4a241c65dbe..994859df010e 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -1458,8 +1458,9 @@ static int ext4_fill_flex_info(struct super_block *sb) /* We allocate both existing and potentially added groups */ flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + - ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) << - EXT4_DESC_PER_BLOCK_BITS(sb))) / groups_per_flex; + ((sbi->s_es->s_reserved_gdt_blocks +1 ) << + EXT4_DESC_PER_BLOCK_BITS(sb))) / + groups_per_flex; sbi->s_flex_groups = kzalloc(flex_group_count * sizeof(struct flex_groups), GFP_KERNEL); if (sbi->s_flex_groups == NULL) { @@ -2884,9 +2885,12 @@ int ext4_force_commit(struct super_block *sb) /* * Ext4 always journals updates to the superblock itself, so we don't * have to propagate any other updates to the superblock on disk at this - * point. (We can probably nuke this function altogether, and remove - * any mention to sb->s_dirt in all of fs/ext4; eventual cleanup...) + * point. Just start an async writeback to get the buffers on their way + * to the disk. + * + * This implicitly triggers the writebehind on sync(). */ + static void ext4_write_super(struct super_block *sb) { if (mutex_trylock(&sb->s_lock) != 0) @@ -2896,15 +2900,15 @@ static void ext4_write_super(struct super_block *sb) static int ext4_sync_fs(struct super_block *sb, int wait) { - int ret = 0; + tid_t target; trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); sb->s_dirt = 0; - if (wait) - ret = ext4_force_commit(sb); - else - jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL); - return ret; + if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) { + if (wait) + jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target); + } + return 0; } /* diff --git a/trunk/fs/jbd/checkpoint.c b/trunk/fs/jbd/checkpoint.c index 61f32f3868cd..1bd8d4acc6f2 100644 --- a/trunk/fs/jbd/checkpoint.c +++ b/trunk/fs/jbd/checkpoint.c @@ -115,7 +115,7 @@ static int __try_to_free_cp_buf(struct journal_head *jh) */ void __log_wait_for_space(journal_t *journal) { - int nblocks, space_left; + int nblocks; assert_spin_locked(&journal->j_state_lock); nblocks = jbd_space_needed(journal); @@ -128,42 +128,25 @@ void __log_wait_for_space(journal_t *journal) /* * Test again, another process may have checkpointed while we * were waiting for the checkpoint lock. If there are no - * transactions ready to be checkpointed, try to recover - * journal space by calling cleanup_journal_tail(), and if - * that doesn't work, by waiting for the currently committing - * transaction to complete. If there is absolutely no way - * to make progress, this is either a BUG or corrupted - * filesystem, so abort the journal and leave a stack - * trace for forensic evidence. + * outstanding transactions there is nothing to checkpoint and + * we can't make progress. Abort the journal in this case. */ spin_lock(&journal->j_state_lock); spin_lock(&journal->j_list_lock); nblocks = jbd_space_needed(journal); - space_left = __log_space_left(journal); - if (space_left < nblocks) { + if (__log_space_left(journal) < nblocks) { int chkpt = journal->j_checkpoint_transactions != NULL; - tid_t tid = 0; - if (journal->j_committing_transaction) - tid = journal->j_committing_transaction->t_tid; spin_unlock(&journal->j_list_lock); spin_unlock(&journal->j_state_lock); if (chkpt) { log_do_checkpoint(journal); - } else if (cleanup_journal_tail(journal) == 0) { - /* We were able to recover space; yay! */ - ; - } else if (tid) { - log_wait_commit(journal, tid); } else { - printk(KERN_ERR "%s: needed %d blocks and " - "only had %d space available\n", - __func__, nblocks, space_left); - printk(KERN_ERR "%s: no way to get more " - "journal space\n", __func__); - WARN_ON(1); + printk(KERN_ERR "%s: no transactions\n", + __func__); journal_abort(journal, 0); } + spin_lock(&journal->j_state_lock); } else { spin_unlock(&journal->j_list_lock); diff --git a/trunk/fs/jbd2/checkpoint.c b/trunk/fs/jbd2/checkpoint.c index 9497718fe920..9203c3332f17 100644 --- a/trunk/fs/jbd2/checkpoint.c +++ b/trunk/fs/jbd2/checkpoint.c @@ -116,7 +116,7 @@ static int __try_to_free_cp_buf(struct journal_head *jh) */ void __jbd2_log_wait_for_space(journal_t *journal) { - int nblocks, space_left; + int nblocks; assert_spin_locked(&journal->j_state_lock); nblocks = jbd_space_needed(journal); @@ -129,43 +129,25 @@ void __jbd2_log_wait_for_space(journal_t *journal) /* * Test again, another process may have checkpointed while we * were waiting for the checkpoint lock. If there are no - * transactions ready to be checkpointed, try to recover - * journal space by calling cleanup_journal_tail(), and if - * that doesn't work, by waiting for the currently committing - * transaction to complete. If there is absolutely no way - * to make progress, this is either a BUG or corrupted - * filesystem, so abort the journal and leave a stack - * trace for forensic evidence. + * outstanding transactions there is nothing to checkpoint and + * we can't make progress. Abort the journal in this case. */ spin_lock(&journal->j_state_lock); spin_lock(&journal->j_list_lock); nblocks = jbd_space_needed(journal); - space_left = __jbd2_log_space_left(journal); - if (space_left < nblocks) { + if (__jbd2_log_space_left(journal) < nblocks) { int chkpt = journal->j_checkpoint_transactions != NULL; - tid_t tid = 0; - if (journal->j_committing_transaction) - tid = journal->j_committing_transaction->t_tid; spin_unlock(&journal->j_list_lock); spin_unlock(&journal->j_state_lock); if (chkpt) { jbd2_log_do_checkpoint(journal); - } else if (jbd2_cleanup_journal_tail(journal) == 0) { - /* We were able to recover space; yay! */ - ; - } else if (tid) { - jbd2_log_wait_commit(journal, tid); } else { - printk(KERN_ERR "%s: needed %d blocks and " - "only had %d space available\n", - __func__, nblocks, space_left); - printk(KERN_ERR "%s: no way to get more " - "journal space in %s\n", __func__, - journal->j_devname); - WARN_ON(1); + printk(KERN_ERR "%s: no transactions\n", + __func__); jbd2_journal_abort(journal, 0); } + spin_lock(&journal->j_state_lock); } else { spin_unlock(&journal->j_list_lock); diff --git a/trunk/fs/jbd2/journal.c b/trunk/fs/jbd2/journal.c index e70d657a19f8..783de118de92 100644 --- a/trunk/fs/jbd2/journal.c +++ b/trunk/fs/jbd2/journal.c @@ -1089,7 +1089,6 @@ journal_t * jbd2_journal_init_inode (struct inode *inode) if (!journal->j_wbuf) { printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", __func__); - jbd2_stats_proc_exit(journal); kfree(journal); return NULL; } @@ -1099,7 +1098,6 @@ journal_t * jbd2_journal_init_inode (struct inode *inode) if (err) { printk(KERN_ERR "%s: Cannnot locate journal superblock\n", __func__); - jbd2_stats_proc_exit(journal); kfree(journal); return NULL; } diff --git a/trunk/mm/vmalloc.c b/trunk/mm/vmalloc.c index 66fad3fc02b1..ba6b0f5f7fac 100644 --- a/trunk/mm/vmalloc.c +++ b/trunk/mm/vmalloc.c @@ -592,6 +592,8 @@ static void free_unmap_vmap_area_addr(unsigned long addr) #define VMAP_BLOCK_SIZE (VMAP_BBMAP_BITS * PAGE_SIZE) +static bool vmap_initialized __read_mostly = false; + struct vmap_block_queue { spinlock_t lock; struct list_head free; @@ -828,6 +830,9 @@ void vm_unmap_aliases(void) int cpu; int flush = 0; + if (unlikely(!vmap_initialized)) + return; + for_each_possible_cpu(cpu) { struct vmap_block_queue *vbq = &per_cpu(vmap_block_queue, cpu); struct vmap_block *vb; @@ -942,6 +947,8 @@ void __init vmalloc_init(void) INIT_LIST_HEAD(&vbq->dirty); vbq->nr_dirty = 0; } + + vmap_initialized = true; } void unmap_kernel_range(unsigned long addr, unsigned long size)