diff options
68 files changed, 455 insertions, 320 deletions
diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c index f444a94eb965..425928769c1d 100644 --- a/arch/alpha/kernel/module.c +++ b/arch/alpha/kernel/module.c @@ -300,3 +300,8 @@ module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, { return 0; } + +void +module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index c79822e3bb88..6d1f4a8d1426 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -159,3 +159,8 @@ module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, { return 0; } + +void +module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c index d0be4bd9c72b..2e4656b50335 100644 --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c @@ -104,18 +104,20 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) } rdmsr(MSR_IA32_THERM_STATUS, l, h); +#if 0 if (l & 0x01) -// printk(KERN_DEBUG PFX "CPU#%d currently thermal throttled\n", cpu); - + printk(KERN_DEBUG PFX "CPU#%d currently thermal throttled\n", cpu); +#endif if (has_N44_O17_errata[cpu] && (newstate == DC_25PT || newstate == DC_DFLT)) newstate = DC_38PT; rdmsr(MSR_IA32_THERM_CONTROL, l, h); if (newstate == DC_DISABLE) { -// printk(KERN_INFO PFX "CPU#%d disabling modulation\n", cpu); + /* printk(KERN_INFO PFX "CPU#%d disabling modulation\n", cpu); */ wrmsr(MSR_IA32_THERM_CONTROL, l & ~(1<<4), h); } else { -// printk(KERN_INFO PFX "CPU#%d setting duty cycle to %d%%\n", cpu, ((125 * newstate) / 10)); + /* printk(KERN_INFO PFX "CPU#%d setting duty cycle to %d%%\n", + cpu, ((125 * newstate) / 10)); */ /* bits 63 - 5 : reserved * bit 4 : enable/disable * bits 3-1 : duty cycle diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c index 8de1c6dd2d5a..f4c757e2d9ba 100644 --- a/arch/i386/kernel/dmi_scan.c +++ b/arch/i386/kernel/dmi_scan.c @@ -841,7 +841,7 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={ { acer_cpufreq_pst, "Acer Aspire", { MATCH(DMI_SYS_VENDOR, "Insyde Software"), MATCH(DMI_BIOS_VERSION, "3A71"), - NO_MATCH, NO_MATCH, NO_MATCH + NO_MATCH, NO_MATCH, } }, { NULL, } diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index c300e0569741..ad9e9446002d 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -73,9 +73,6 @@ EXPORT_SYMBOL(physnode_map); #ifdef CONFIG_X86_NUMAQ EXPORT_SYMBOL(xquad_portio); #endif -#ifndef CONFIG_X86_WP_WORKS_OK -EXPORT_SYMBOL(__verify_write); -#endif EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(dump_extended_fpu); diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index d6729a396b63..b5b275e96a8d 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -240,22 +240,22 @@ static void clear_IO_APIC (void) clear_IO_APIC_pin(apic, pin); } -static void set_ioapic_affinity (unsigned int irq, unsigned long mask) +static void set_ioapic_affinity (unsigned int irq, unsigned long cpu_mask) { unsigned long flags; int pin; struct irq_pin_list *entry = irq_2_pin + irq; - - /* - * Only the first 8 bits are valid. - */ - mask = mask << 24; + unsigned int apicid_value; + + apicid_value = cpu_mask_to_apicid(cpu_mask); + /* Prepare to do the io_apic_write */ + apicid_value = apicid_value << 24; spin_lock_irqsave(&ioapic_lock, flags); for (;;) { pin = entry->pin; if (pin == -1) break; - io_apic_write(entry->apic, 0x10 + 1 + pin*2, mask); + io_apic_write(entry->apic, 0x10 + 1 + pin*2, apicid_value); if (!entry->next) break; entry = irq_2_pin + entry->next; @@ -279,7 +279,7 @@ static void set_ioapic_affinity (unsigned int irq, unsigned long mask) extern unsigned long irq_affinity[NR_IRQS]; -static int __cacheline_aligned pending_irq_balance_apicid[NR_IRQS]; +static int __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS]; #define IRQBALANCE_CHECK_ARCH -999 static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; @@ -356,7 +356,7 @@ static inline void balance_irq(int cpu, int irq) unsigned long flags; spin_lock_irqsave(&desc->lock, flags); - pending_irq_balance_apicid[irq]=cpu_to_logical_apicid(new_cpu); + pending_irq_balance_cpumask[irq] = 1 << new_cpu; spin_unlock_irqrestore(&desc->lock, flags); } } @@ -553,8 +553,7 @@ tryanotherirq: selected_irq, min_loaded); /* mark for change destination */ spin_lock_irqsave(&desc->lock, flags); - pending_irq_balance_apicid[selected_irq] = - cpu_to_logical_apicid(min_loaded); + pending_irq_balance_cpumask[selected_irq] = 1 << min_loaded; spin_unlock_irqrestore(&desc->lock, flags); /* Since we made a change, come back sooner to * check for more variation. @@ -586,7 +585,7 @@ int balanced_irq(void *unused) /* push everything to CPU 0 to give us a starting point. */ for (i = 0 ; i < NR_IRQS ; i++) - pending_irq_balance_apicid[i] = cpu_to_logical_apicid(0); + pending_irq_balance_cpumask[i] = 1; repeat: set_current_state(TASK_INTERRUPTIBLE); @@ -663,9 +662,9 @@ static void set_ioapic_affinity (unsigned int irq, unsigned long mask); static inline void move_irq(int irq) { /* note - we hold the desc->lock */ - if (unlikely(pending_irq_balance_apicid[irq])) { - set_ioapic_affinity(irq, pending_irq_balance_apicid[irq]); - pending_irq_balance_apicid[irq] = 0; + if (unlikely(pending_irq_balance_cpumask[irq])) { + set_ioapic_affinity(irq, pending_irq_balance_cpumask[irq]); + pending_irq_balance_cpumask[irq] = 0; } } diff --git a/arch/i386/kernel/module.c b/arch/i386/kernel/module.c index 463a2c7e0acc..e8258ad35860 100644 --- a/arch/i386/kernel/module.c +++ b/arch/i386/kernel/module.c @@ -123,3 +123,7 @@ int module_finalize(const Elf_Ehdr *hdr, } return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index 335410b56423..ec4e16996b09 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c @@ -222,7 +222,6 @@ void iounmap(void *addr) return; } - unmap_vm_area(p); if (p->flags && p->phys_addr < virt_to_phys(high_memory)) { change_page_attr(virt_to_page(__va(p->phys_addr)), p->size >> PAGE_SHIFT, diff --git a/arch/i386/oprofile/init.c b/arch/i386/oprofile/init.c index d5ebbb600cf7..b87e0f2e3ebd 100644 --- a/arch/i386/oprofile/init.c +++ b/arch/i386/oprofile/init.c @@ -9,6 +9,7 @@ #include <linux/oprofile.h> #include <linux/init.h> +#include <linux/errno.h> /* We support CPUs that have performance counters like the Pentium Pro * with the NMI mode driver. diff --git a/arch/parisc/hpux/wrappers.S b/arch/parisc/hpux/wrappers.S index c9322351a85c..6f26159bed61 100644 --- a/arch/parisc/hpux/wrappers.S +++ b/arch/parisc/hpux/wrappers.S @@ -129,7 +129,7 @@ fork_exit: /* Set the return value for the child */ hpux_child_return: -#if CONFIG_SMP || CONFIG_PREEMPT +#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) bl schedule_tail, %r2 nop #endif diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 703991db6276..936eba6c6b99 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -568,3 +568,7 @@ int module_finalize(const Elf_Ehdr *hdr, #endif return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/ppc/kernel/module.c b/arch/ppc/kernel/module.c index e9e586cb0718..d263eacc0625 100644 --- a/arch/ppc/kernel/module.c +++ b/arch/ppc/kernel/module.c @@ -269,3 +269,7 @@ int module_finalize(const Elf_Ehdr *hdr, { return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/ppc64/kernel/module.c b/arch/ppc64/kernel/module.c index 7b27cdd29fa0..8847feb93b1a 100644 --- a/arch/ppc64/kernel/module.c +++ b/arch/ppc64/kernel/module.c @@ -384,3 +384,7 @@ int module_finalize(const Elf_Ehdr *hdr, me->num_exentries); return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index d79e7345264e..913a21691c2f 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -386,3 +386,7 @@ int module_finalize(const Elf_Ehdr *hdr, kfree(me->arch.syminfo); return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index 99183d7f24bf..1bde20c52683 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c @@ -145,3 +145,7 @@ int module_finalize(const Elf_Ehdr *hdr, { return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/sparc64/kernel/module.c b/arch/sparc64/kernel/module.c index 9918b76c6280..caf8eebcd34f 100644 --- a/arch/sparc64/kernel/module.c +++ b/arch/sparc64/kernel/module.c @@ -138,7 +138,9 @@ void *module_alloc(unsigned long size) /* Free memory returned from module_core_alloc/module_init_alloc */ void module_free(struct module *mod, void *module_region) { + write_lock(&vmlist_lock); module_unmap(module_region); + write_unlock(&vmlist_lock); /* FIXME: If module_region == mod->init_region, trim exception table entries. */ } @@ -273,3 +275,7 @@ int module_finalize(const Elf_Ehdr *hdr, { return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/v850/kernel/module.c b/arch/v850/kernel/module.c index eedced8ddb19..64aeb3e37c52 100644 --- a/arch/v850/kernel/module.c +++ b/arch/v850/kernel/module.c @@ -230,3 +230,8 @@ int apply_relocate_add (Elf32_Shdr *sechdrs, const char *strtab, return 0; } + +void +module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c index 9236b4b59c26..93b2801b524b 100644 --- a/arch/x86_64/kernel/module.c +++ b/arch/x86_64/kernel/module.c @@ -48,7 +48,6 @@ void module_free(struct module *mod, void *module_region) for (prevp = &mod_vmlist ; (map = *prevp) ; prevp = &map->next) { if ((unsigned long)map->addr == addr) { *prevp = map->next; - write_unlock(&vmlist_lock); goto found; } } @@ -57,6 +56,7 @@ void module_free(struct module *mod, void *module_region) return; found: unmap_vm_area(map); + write_unlock(&vmlist_lock); if (map->pages) { for (i = 0; i < map->nr_pages; i++) if (map->pages[i]) @@ -231,3 +231,7 @@ int module_finalize(const Elf_Ehdr *hdr, { return 0; } + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c index ed7cc711392a..331f57596a24 100644 --- a/arch/x86_64/mm/ioremap.c +++ b/arch/x86_64/mm/ioremap.c @@ -222,7 +222,6 @@ void iounmap(void *addr) return; } - unmap_vm_area(p); if (p->flags && p->phys_addr < virt_to_phys(high_memory)) { change_page_attr(virt_to_page(__va(p->phys_addr)), p->size >> PAGE_SHIFT, diff --git a/drivers/cpufreq/proc_intf.c b/drivers/cpufreq/proc_intf.c index 5845e3404085..253dab930b06 100644 --- a/drivers/cpufreq/proc_intf.c +++ b/drivers/cpufreq/proc_intf.c @@ -209,6 +209,9 @@ static int __init cpufreq_proc_init (void) { struct proc_dir_entry *entry = NULL; + if (!cpufreq_driver) + return -ENODEV; + /* are these acceptable values? */ entry = create_proc_entry("cpufreq", S_IFREG|S_IRUGO|S_IWUSR, &proc_root); diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 7d1ba24e716a..c5294afc125b 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -422,7 +422,7 @@ struct pnp_dev * pnp_check_irq_conflicts(struct pnp_dev * dev, int idx, int mode static irqreturn_t pnp_test_handler(int irq, void *dev_id, struct pt_regs *regs) { - return IRQ_NONE; + return IRQ_HANDLED; } int pnp_check_irq(struct pnp_dev * dev, int idx) diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 41014e98f56c..93a099010bcd 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -396,9 +396,6 @@ static uint32_t aic7xxx_pci_parity = ~0; * would result in never finding any devices :) */ #ifndef CONFIG_AIC7XXX_PROBE_EISA_VL -#define CONFIG_AIC7XXX_PROBE_EISA_VL n -#endif -#if CONFIG_AIC7XXX_PROBE_EISA_VL == n static uint32_t aic7xxx_probe_eisa_vl; #else static uint32_t aic7xxx_probe_eisa_vl = ~0; diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c index 3039664df313..fc9796848209 100644 --- a/drivers/video/logo/logo.c +++ b/drivers/video/logo/logo.c @@ -79,8 +79,10 @@ const struct linux_logo *fb_find_logo(int depth) logo = &logo_parisc_clut224; #endif #ifdef CONFIG_LOGO_SGI_CLUT224 - /* SGI Linux logo on MIPS/MIPS64 */ + /* SGI Linux logo on MIPS/MIPS64 and VISWS */ +#ifndef CONFIG_X86_VISWS if (mips_machgroup == MACH_GROUP_SGI) +#endif logo = &logo_sgi_clut224; #endif #ifdef CONFIG_LOGO_SUN_CLUT224 diff --git a/fs/buffer.c b/fs/buffer.c index f380aa531352..abb476e7679e 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -253,6 +253,8 @@ static void do_sync(unsigned long wait) sync_filesystems(0); /* Start syncing the filesystems */ sync_filesystems(wait); /* Waitingly sync the filesystems */ sync_inodes(wait); /* Mappings, inodes and blockdevs, again. */ + if (!wait) + printk("Emergency Sync complete\n"); } asmlinkage long sys_sync(void) diff --git a/fs/devfs/base.c b/fs/devfs/base.c index fa63dc1820a5..6ca2544a5322 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -752,6 +752,7 @@ # define DPRINTK(flag, format, args...) #endif +typedef struct devfs_entry *devfs_handle_t; struct directory_type { @@ -1424,98 +1425,6 @@ static void devfsd_notify (struct devfs_entry *de,unsigned short type) current->egid, &fs_info); } - -/** - * devfs_register - Register a device entry. - * @dir: The handle to the parent devfs directory entry. If this is %NULL the - * new name is relative to the root of the devfs. - * @name: The name of the entry. - * @flags: Must be 0 - * @major: The major number. Not needed for regular files. - * @minor: The minor number. Not needed for regular files. - * @mode: The default file mode. - * @ops: The &file_operations or &block_device_operations structure. - * This must not be externally deallocated. - * @info: An arbitrary pointer which will be written to the @private_data - * field of the &file structure passed to the device driver. You can set - * this to whatever you like, and change it once the file is opened (the next - * file opened will not see this change). - * - * On failure %NULL is returned. - */ - -devfs_handle_t devfs_register (devfs_handle_t dir, const char *name, - unsigned int flags, - unsigned int major, unsigned int minor, - umode_t mode, void *ops, void *info) -{ - int err; - dev_t devnum = 0, dev = MKDEV(major, minor); - struct devfs_entry *de; - - /* we don't accept any flags anymore. prototype will change soon. */ - WARN_ON(flags); - WARN_ON(dir); - WARN_ON(!S_ISCHR(mode)); - - if (name == NULL) - { - PRINTK ("(): NULL name pointer\n"); - return NULL; - } - if (ops == NULL) - { - PRINTK ("(%s): NULL ops pointer\n", name); - return NULL; - } - if ( S_ISDIR (mode) ) - { - PRINTK ("(%s): creating directories is not allowed\n", name); - return NULL; - } - if ( S_ISLNK (mode) ) - { - PRINTK ("(%s): creating symlinks is not allowed\n", name); - return NULL; - } - if ( ( de = _devfs_prepare_leaf (&dir, name, mode) ) == NULL ) - { - PRINTK ("(%s): could not prepare leaf\n", name); - if (devnum) devfs_dealloc_devnum (mode, devnum); - return NULL; - } - if (S_ISCHR (mode)) { - de->u.cdev.dev = dev; - de->u.cdev.autogen = devnum != 0; - de->u.cdev.ops = ops; - } else if (S_ISBLK (mode)) { - de->u.bdev.dev = dev; - de->u.cdev.autogen = devnum != 0; - } else { - PRINTK ("(%s): illegal mode: %x\n", name, mode); - devfs_put (de); - devfs_put (dir); - return (NULL); - } - de->info = info; - de->inode.uid = 0; - de->inode.gid = 0; - err = _devfs_append_entry(dir, de, NULL); - if (err) - { - PRINTK ("(%s): could not append to parent, err: %d\n", name, err); - devfs_put (dir); - if (devnum) devfs_dealloc_devnum (mode, devnum); - return NULL; - } - DPRINTK (DEBUG_REGISTER, "(%s): de: %p dir: %p \"%s\" pp: %p\n", - name, de, dir, dir->name, dir->parent); - devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED); - devfs_put (dir); - return de; -} /* End Function devfs_register */ - - int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...) { struct devfs_entry *dir = NULL, *de; @@ -1935,7 +1844,6 @@ static int __init devfs_setup (char *str) __setup("devfs=", devfs_setup); EXPORT_SYMBOL(devfs_put); -EXPORT_SYMBOL(devfs_register); EXPORT_SYMBOL(devfs_mk_symlink); EXPORT_SYMBOL(devfs_mk_dir); EXPORT_SYMBOL(devfs_remove); diff --git a/fs/dquot.c b/fs/dquot.c index f3c0f63265c3..edda8c2009d6 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -1011,9 +1011,12 @@ warn_put_all: spin_unlock(&dq_data_lock); flush_warnings(transfer_to, warntype); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if (transfer_from[cnt] != NODQUOT) + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + if (ret == QUOTA_OK && transfer_from[cnt] != NODQUOT) dqput(transfer_from[cnt]); + if (ret == NO_QUOTA && transfer_to[cnt] != NODQUOT) + dqput(transfer_to[cnt]); + } up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); return ret; } diff --git a/fs/ext2/xattr.h b/fs/ext2/xattr.h index a57b9da2306d..a113ead4adf9 100644 --- a/fs/ext2/xattr.h +++ b/fs/ext2/xattr.h @@ -22,6 +22,7 @@ #define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS 2 #define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT 3 #define EXT2_XATTR_INDEX_TRUSTED 4 +#define EXT2_XATTR_INDEX_LUSTRE 5 #define EXT2_XATTR_INDEX_SECURITY 6 struct ext2_xattr_header { diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index 1b5fae0032f2..b00bec6fe0ce 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c @@ -103,7 +103,11 @@ static int ext3_readdir(struct file * filp, sb = inode->i_sb; - if (is_dx(inode)) { +#ifdef CONFIG_EXT3_INDEX + if (EXT3_HAS_COMPAT_FEATURE(inode->i_sb, + EXT3_FEATURE_COMPAT_DIR_INDEX) && + ((EXT3_I(inode)->i_flags & EXT3_INDEX_FL) || + ((inode->i_size >> sb->s_blocksize_bits) == 1))) { err = ext3_dx_readdir(filp, dirent, filldir); if (err != ERR_BAD_DX_DIR) { ret = err; @@ -115,6 +119,7 @@ static int ext3_readdir(struct file * filp, */ EXT3_I(filp->f_dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL; } +#endif stored = 0; bh = NULL; offset = filp->f_pos & (sb->s_blocksize - 1); @@ -434,6 +439,9 @@ static int ext3_dx_readdir(struct file * filp, filp->private_data = info; } + if (filp->f_pos == EXT3_HTREE_EOF) + return 0; /* EOF */ + /* Some one has messed with f_pos; reset the world */ if (info->last_pos != filp->f_pos) { free_rb_tree_fname(&info->root); @@ -470,8 +478,10 @@ static int ext3_dx_readdir(struct file * filp, &info->next_hash); if (ret < 0) return ret; - if (ret == 0) + if (ret == 0) { + filp->f_pos = EXT3_HTREE_EOF; break; + } info->curr_node = rb_first(&info->root); } @@ -483,6 +493,10 @@ static int ext3_dx_readdir(struct file * filp, info->curr_node = rb_next(info->curr_node); if (!info->curr_node) { + if (info->next_hash == ~0) { + filp->f_pos = EXT3_HTREE_EOF; + break; + } info->curr_hash = info->next_hash; info->curr_minor_hash = 0; } @@ -495,7 +509,7 @@ finished: static int ext3_release_dir (struct inode * inode, struct file * filp) { - if (is_dx(inode) && filp->private_data) + if (filp->private_data) ext3_htree_free_dir_info(filp->private_data); return 0; diff --git a/fs/ext3/hash.c b/fs/ext3/hash.c index 2025354b85de..d00d658b1cfb 100644 --- a/fs/ext3/hash.c +++ b/fs/ext3/hash.c @@ -209,7 +209,10 @@ int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo) hinfo->hash = 0; return -1; } - hinfo->hash = hash & ~1; + hash = hash & ~1; + if (hash == (EXT3_HTREE_EOF << 1)) + hash = (EXT3_HTREE_EOF-1) << 1; + hinfo->hash = hash; hinfo->minor_hash = minor_hash; return 0; } diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 34218818c69d..ea83d3cb7bec 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -170,7 +170,7 @@ static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size); static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); static int ext3_htree_next_block(struct inode *dir, __u32 hash, struct dx_frame *frame, - struct dx_frame *frames, int *err, + struct dx_frame *frames, __u32 *start_hash); static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry, struct ext3_dir_entry_2 **res_dir, int *err); @@ -239,6 +239,17 @@ static inline unsigned dx_node_limit (struct inode *dir) * Debug */ #ifdef DX_DEBUG +static void dx_show_index (char * label, struct dx_entry *entries) +{ + int i, n = dx_get_count (entries); + printk("%s index ", label); + for (i = 0; i < n; i++) + { + printk("%x->%u ", i? dx_get_hash(entries + i): 0, dx_get_block(entries + i)); + } + printk("\n"); +} + struct stats { unsigned names; @@ -447,22 +458,21 @@ static void dx_release (struct dx_frame *frames) * * This function returns 1 if the caller should continue to search, * or 0 if it should not. If there is an error reading one of the - * index blocks, it will return -1. + * index blocks, it will a negative error code. * * If start_hash is non-null, it will be filled in with the starting * hash of the next page. */ static int ext3_htree_next_block(struct inode *dir, __u32 hash, struct dx_frame *frame, - struct dx_frame *frames, int *err, + struct dx_frame *frames, __u32 *start_hash) { struct dx_frame *p; struct buffer_head *bh; - int num_frames = 0; + int err, num_frames = 0; __u32 bhash; - *err = ENOENT; p = frame; /* * Find the next leaf page by incrementing the frame pointer. @@ -500,8 +510,8 @@ static int ext3_htree_next_block(struct inode *dir, __u32 hash, */ while (num_frames--) { if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at), - 0, err))) - return -1; /* Failure */ + 0, &err))) + return err; /* Failure */ p++; brelse (p->bh); p->bh = bh; @@ -521,6 +531,46 @@ static inline struct ext3_dir_entry_2 *ext3_next_entry(struct ext3_dir_entry_2 * /* * This function fills a red-black tree with information from a + * directory block. It returns the number directory entries loaded + * into the tree. If there is an error it is returned in err. + */ +static int htree_dirblock_to_tree(struct file *dir_file, + struct inode *dir, int block, + struct dx_hash_info *hinfo, + __u32 start_hash, __u32 start_minor_hash) +{ + struct buffer_head *bh; + struct ext3_dir_entry_2 *de, *top; + int err, count = 0; + + dxtrace(printk("In htree dirblock_to_tree: block %d\n", block)); + if (!(bh = ext3_bread (NULL, dir, block, 0, &err))) + return err; + + de = (struct ext3_dir_entry_2 *) bh->b_data; + top = (struct ext3_dir_entry_2 *) ((char *) de + + dir->i_sb->s_blocksize - + EXT3_DIR_REC_LEN(0)); + for (; de < top; de = ext3_next_entry(de)) { + ext3fs_dirhash(de->name, de->name_len, hinfo); + if ((hinfo->hash < start_hash) || + ((hinfo->hash == start_hash) && + (hinfo->minor_hash < start_minor_hash))) + continue; + if ((err = ext3_htree_store_dirent(dir_file, + hinfo->hash, hinfo->minor_hash, de)) != 0) { + brelse(bh); + return err; + } + count++; + } + brelse(bh); + return count; +} + + +/* + * This function fills a red-black tree with information from a * directory. We start scanning the directory in hash order, starting * at start_hash and start_minor_hash. * @@ -531,8 +581,7 @@ int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, __u32 start_minor_hash, __u32 *next_hash) { struct dx_hash_info hinfo; - struct buffer_head *bh; - struct ext3_dir_entry_2 *de, *top; + struct ext3_dir_entry_2 *de; struct dx_frame frames[2], *frame; struct inode *dir; int block, err; @@ -543,6 +592,14 @@ int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash, start_minor_hash)); dir = dir_file->f_dentry->d_inode; + if (!(EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) { + hinfo.hash_version = EXT3_SB(dir->i_sb)->s_def_hash_version; + hinfo.seed = EXT3_SB(dir->i_sb)->s_hash_seed; + count = htree_dirblock_to_tree(dir_file, dir, 0, &hinfo, + start_hash, start_minor_hash); + *next_hash = ~0; + return count; + } hinfo.hash = start_hash; hinfo.minor_hash = 0; frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err); @@ -562,34 +619,21 @@ int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, while (1) { block = dx_get_block(frame->at); - dxtrace(printk("Reading block %d\n", block)); - if (!(bh = ext3_bread (NULL, dir, block, 0, &err))) + ret = htree_dirblock_to_tree(dir_file, dir, block, &hinfo, + start_hash, start_minor_hash); + if (ret < 0) { + err = ret; goto errout; - - de = (struct ext3_dir_entry_2 *) bh->b_data; - top = (struct ext3_dir_entry_2 *) ((char *) de + dir->i_sb->s_blocksize - - EXT3_DIR_REC_LEN(0)); - for (; de < top; de = ext3_next_entry(de)) { - ext3fs_dirhash(de->name, de->name_len, &hinfo); - if ((hinfo.hash < start_hash) || - ((hinfo.hash == start_hash) && - (hinfo.minor_hash < start_minor_hash))) - continue; - if ((err = ext3_htree_store_dirent(dir_file, - hinfo.hash, hinfo.minor_hash, de)) != 0) { - brelse(bh); - goto errout; - } - count++; } - brelse (bh); - hashval = ~1; + count += ret; + hashval = ~0; ret = ext3_htree_next_block(dir, HASH_NB_ALWAYS, - frame, frames, &err, &hashval); - if (next_hash) - *next_hash = hashval; - if (ret == -1) + frame, frames, &hashval); + *next_hash = hashval; + if (ret < 0) { + err = ret; goto errout; + } /* * Stop if: (a) there are no more entries, or * (b) we have inserted at least one entry and the @@ -600,7 +644,8 @@ int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, break; } dx_release(frames); - dxtrace(printk("Fill tree: returned %d entries\n", count)); + dxtrace(printk("Fill tree: returned %d entries, next hash: %x\n", + count, *next_hash)); return count; errout: dx_release(frames); @@ -909,11 +954,12 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry, brelse (bh); /* Check to see if we should continue to search */ retval = ext3_htree_next_block(dir, hash, frame, - frames, err, 0); - if (retval == -1) { + frames, 0); + if (retval < 0) { ext3_warning(sb, __FUNCTION__, "error reading index page in directory #%lu", dir->i_ino); + *err = retval; goto errout; } } while (retval == 1); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 532c501e7396..8c72318360b7 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -1988,8 +1988,10 @@ int ext3_statfs (struct super_block * sb, struct statfs * buf) #ifdef CONFIG_QUOTA -#define EXT3_OLD_QFMT_BLOCKS 2 -#define EXT3_V0_QFMT_BLOCKS 6 +/* Blocks: (2 data blocks) * (3 indirect + 1 descriptor + 1 bitmap) + superblock */ +#define EXT3_OLD_QFMT_BLOCKS 11 +/* Blocks: quota info + (4 pointer blocks + 1 entry block) * (3 indirect + 1 descriptor + 1 bitmap) + superblock */ +#define EXT3_V0_QFMT_BLOCKS 27 static int (*old_sync_dquot)(struct dquot *dquot); diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h index 8de7046ed175..9c71433c6a90 100644 --- a/fs/ext3/xattr.h +++ b/fs/ext3/xattr.h @@ -21,6 +21,7 @@ #define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS 2 #define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT 3 #define EXT3_XATTR_INDEX_TRUSTED 4 +#define EXT3_XATTR_INDEX_LUSTRE 5 #define EXT3_XATTR_INDEX_SECURITY 6 struct ext3_xattr_header { diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 866edb62fad5..282c0c22db6f 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -897,6 +897,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, sbi->fsinfo_sector); } else { sbi->free_clusters = CF_LE_L(fsinfo->free_clusters); + sbi->prev_free = CF_LE_L(fsinfo->next_cluster); } brelse(fsinfo_bh); diff --git a/fs/fat/misc.c b/fs/fat/misc.c index f7043d09f086..6e3e86c8899b 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -74,6 +74,7 @@ void fat_clusters_flush(struct super_block *sb) MSDOS_SB(sb)->fsinfo_sector); } else { fsinfo->free_clusters = CF_LE_L(MSDOS_SB(sb)->free_clusters); + fsinfo->next_cluster = CF_LE_L(MSDOS_SB(sb)->prev_free); mark_buffer_dirty(bh); } brelse(bh); @@ -130,19 +131,23 @@ int fat_add_cluster(struct inode *inode) unlock_fat(sb); return -ENOSPC; } - limit = MSDOS_SB(sb)->clusters; - for (count = 0; count < limit; count++) { - nr = ((count + MSDOS_SB(sb)->prev_free) % limit) + 2; + + limit = MSDOS_SB(sb)->clusters + 2; + nr = MSDOS_SB(sb)->prev_free + 1; + for (count = 0; count < MSDOS_SB(sb)->clusters; count++, nr++) { + nr = nr % limit; + if (nr < 2) + nr = 2; if (fat_access(sb, nr, -1) == FAT_ENT_FREE) break; } - if (count >= limit) { + if (count >= MSDOS_SB(sb)->clusters) { MSDOS_SB(sb)->free_clusters = 0; unlock_fat(sb); return -ENOSPC; } - - MSDOS_SB(sb)->prev_free = (count + MSDOS_SB(sb)->prev_free + 1) % limit; + MSDOS_SB(sb)->prev_free = nr; + fat_access(sb, nr, FAT_ENT_EOF); if (MSDOS_SB(sb)->free_clusters != -1) MSDOS_SB(sb)->free_clusters--; diff --git a/fs/super.c b/fs/super.c index 58f90ef3a2b9..eba1a860a141 100644 --- a/fs/super.c +++ b/fs/super.c @@ -497,6 +497,7 @@ static void do_emergency_remount(unsigned long foo) spin_lock(&sb_lock); } spin_unlock(&sb_lock); + printk("Emergency Remount complete\n"); } void emergency_remount(void) diff --git a/include/asm-i386/mach-bigsmp/mach_apic.h b/include/asm-i386/mach-bigsmp/mach_apic.h index 93972fcd768f..7b6435b052f3 100644 --- a/include/asm-i386/mach-bigsmp/mach_apic.h +++ b/include/asm-i386/mach-bigsmp/mach_apic.h @@ -34,10 +34,12 @@ static inline unsigned long check_apicid_used(unsigned long bitmap, int apicid) return 0; } static inline unsigned long check_apicid_present(int bit) -{ +{ return (phys_cpu_present_map & (1 << bit)); } +#define apicid_cluster(apicid) (apicid & 0xF0) + static inline unsigned long calculate_ldr(unsigned long old) { unsigned long id; @@ -134,4 +136,37 @@ static inline unsigned get_apic_id(unsigned long x) #define GET_APIC_ID(x) get_apic_id(x) +static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +{ + int num_bits_set; + int cpus_found = 0; + int cpu; + int apicid; + + num_bits_set = hweight32(cpumask); + /* Return id to all */ + if (num_bits_set == 32) + return (int) 0xFF; + /* + * The cpus in the mask must all be on the apic cluster. If are not + * on the same apicid cluster return default value of TARGET_CPUS. + */ + cpu = ffs(cpumask)-1; + apicid = cpu_to_logical_apicid(cpu); + while (cpus_found < num_bits_set) { + if (cpumask & (1 << cpu)) { + int new_apicid = cpu_to_logical_apicid(cpu); + if (apicid_cluster(apicid) != + apicid_cluster(new_apicid)){ + printk ("%s: Not a valid mask!\n",__FUNCTION__); + return TARGET_CPUS; + } + apicid = apicid | new_apicid; + cpus_found++; + } + cpu++; + } + return apicid; +} + #endif /* __ASM_MACH_APIC_H */ diff --git a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h index e865f01f5167..ad40d96b3824 100644 --- a/include/asm-i386/mach-default/mach_apic.h +++ b/include/asm-i386/mach-default/mach_apic.h @@ -120,4 +120,9 @@ static inline int apic_id_registered(void) &phys_cpu_present_map)); } +static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +{ + return cpumask; +} + #endif /* __ASM_MACH_APIC_H */ diff --git a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h index 54a7c97fe8d1..d5160168908a 100644 --- a/include/asm-i386/mach-numaq/mach_apic.h +++ b/include/asm-i386/mach-numaq/mach_apic.h @@ -17,6 +17,7 @@ #define APIC_BROADCAST_ID 0x0F #define check_apicid_used(bitmap, apicid) ((bitmap) & (1 << (apicid))) #define check_apicid_present(bit) (phys_cpu_present_map & (1 << bit)) +#define apicid_cluster(apicid) (apicid & 0xF0) static inline int apic_id_registered(void) { @@ -115,4 +116,37 @@ static inline unsigned get_apic_id(unsigned long x) #define GET_APIC_ID(x) get_apic_id(x) +static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +{ + int num_bits_set; + int cpus_found = 0; + int cpu; + int apicid; + + num_bits_set = hweight32(cpumask); + /* Return id to all */ + if (num_bits_set == 32) + return (int) 0xFF; + /* + * The cpus in the mask must all be on the apic cluster. If are not + * on the same apicid cluster return default value of TARGET_CPUS. + */ + cpu = ffs(cpumask)-1; + apicid = cpu_to_logical_apicid(cpu); + while (cpus_found < num_bits_set) { + if (cpumask & (1 << cpu)) { + int new_apicid = cpu_to_logical_apicid(cpu); + if (apicid_cluster(apicid) != + apicid_cluster(new_apicid)){ + printk ("%s: Not a valid mask!\n",__FUNCTION__); + return TARGET_CPUS; + } + apicid = apicid | new_apicid; + cpus_found++; + } + cpu++; + } + return apicid; +} + #endif /* __ASM_MACH_APIC_H */ diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h index ae58d629c9ba..93207f09d43b 100644 --- a/include/asm-i386/mach-summit/mach_apic.h +++ b/include/asm-i386/mach-summit/mach_apic.h @@ -34,7 +34,7 @@ static inline unsigned long target_cpus(void) #define APIC_BROADCAST_ID (0x0F) static inline unsigned long check_apicid_used(unsigned long bitmap, int apicid) -{ +{ return (x86_summit ? 0 : (bitmap & (1 << apicid))); } @@ -44,6 +44,8 @@ static inline unsigned long check_apicid_present(int bit) return (x86_summit ? 1 : (phys_cpu_present_map & (1 << bit))); } +#define apicid_cluster(apicid) (apicid & 0xF0) + extern u8 bios_cpu_apicid[]; static inline void init_apic_ldr(void) @@ -142,4 +144,37 @@ static inline unsigned get_apic_id(unsigned long x) #define GET_APIC_ID(x) get_apic_id(x) +static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +{ + int num_bits_set; + int cpus_found = 0; + int cpu; + int apicid; + + num_bits_set = hweight32(cpumask); + /* Return id to all */ + if (num_bits_set == 32) + return (int) 0xFF; + /* + * The cpus in the mask must all be on the apic cluster. If are not + * on the same apicid cluster return default value of TARGET_CPUS. + */ + cpu = ffs(cpumask)-1; + apicid = cpu_to_logical_apicid(cpu); + while (cpus_found < num_bits_set) { + if (cpumask & (1 << cpu)) { + int new_apicid = cpu_to_logical_apicid(cpu); + if (apicid_cluster(apicid) != + apicid_cluster(new_apicid)){ + printk ("%s: Not a valid mask!\n",__FUNCTION__); + return TARGET_CPUS; + } + apicid = apicid | new_apicid; + cpus_found++; + } + cpu++; + } + return apicid; +} + #endif /* __ASM_MACH_APIC_H */ diff --git a/include/asm-i386/mach-visws/mach_apic.h b/include/asm-i386/mach-visws/mach_apic.h index 84047e09ce2b..641c173d4f76 100644 --- a/include/asm-i386/mach-visws/mach_apic.h +++ b/include/asm-i386/mach-visws/mach_apic.h @@ -77,4 +77,8 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) return test_bit(boot_cpu_physical_apicid, &phys_cpu_present_map); } +static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +{ + return cpumask; +} #endif /* __ASM_MACH_APIC_H */ diff --git a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h index 15aa2e7ef765..07caa21a978c 100644 --- a/include/asm-i386/uaccess.h +++ b/include/asm-i386/uaccess.h @@ -42,8 +42,6 @@ extern struct movsl_mask { } ____cacheline_aligned_in_smp movsl_mask; #endif -int __verify_write(const void *, unsigned long); - #define __addr_ok(addr) ((unsigned long)(addr) < (current_thread_info()->addr_limit.seg)) /* diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index e99b9c3c1d01..3dc9062bd414 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -311,4 +311,7 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu); #endif /* CONFIG_CPU_FREQ_TABLE */ +/* Currently exported only for the proc interface, remove when that goes */ +extern struct cpufreq_driver *cpufreq_driver; + #endif /* _LINUX_CPUFREQ_H */ diff --git a/include/linux/devfs_fs_kernel.h b/include/linux/devfs_fs_kernel.h index 34ebe93c6194..f12addd1daeb 100644 --- a/include/linux/devfs_fs_kernel.h +++ b/include/linux/devfs_fs_kernel.h @@ -11,20 +11,7 @@ #define DEVFS_SUPER_MAGIC 0x1373 -#define DEVFS_FL_NONE 0x000 /* This helps to make code more readable - no, it doesn't --hch */ -#define DEVFS_FL_DEFAULT DEVFS_FL_NONE - - -typedef struct devfs_entry * devfs_handle_t; - -struct gendisk; - #ifdef CONFIG_DEVFS_FS -extern devfs_handle_t devfs_register (devfs_handle_t dir, const char *name, - unsigned int flags, - unsigned int major, unsigned int minor, - umode_t mode, void *ops, void *info); extern int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...) __attribute__((format (printf, 3, 4))); extern int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...) @@ -36,19 +23,8 @@ extern void devfs_remove(const char *fmt, ...) __attribute__((format (printf, 1, 2))); extern int devfs_register_tape(const char *name); extern void devfs_unregister_tape(int num); -extern void devfs_register_partition(struct gendisk *dev, int part); extern void mount_devfs_fs(void); #else /* CONFIG_DEVFS_FS */ -static inline devfs_handle_t devfs_register (devfs_handle_t dir, - const char *name, - unsigned int flags, - unsigned int major, - unsigned int minor, - umode_t mode, - void *ops, void *info) -{ - return NULL; -} static inline int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...) { return 0; @@ -75,9 +51,6 @@ static inline int devfs_register_tape (const char *name) static inline void devfs_unregister_tape(int num) { } -static inline void devfs_register_partition(struct gendisk *dev, int part) -{ -} static inline void mount_devfs_fs (void) { return; diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index b3da32479e13..c2f36c9d8022 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h @@ -625,6 +625,8 @@ struct dx_hash_info u32 *seed; }; +#define EXT3_HTREE_EOF 0x7fffffff + #ifdef __KERNEL__ /* * Control parameters used by ext3_htree_next_block diff --git a/include/linux/mm.h b/include/linux/mm.h index 6aa89d73f65b..51f5377ec8fc 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -23,8 +23,13 @@ extern int page_cluster; #include <asm/page.h> #include <asm/pgtable.h> +#include <asm/processor.h> #include <asm/atomic.h> +#ifndef MM_VM_SIZE +#define MM_VM_SIZE(mm) TASK_SIZE +#endif + /* * Linux kernel virtual memory manager primitives. * The idea being to have a "virtual" mm in the same way diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h index 0c9e9a69f8ba..eb1033957486 100644 --- a/include/linux/moduleloader.h +++ b/include/linux/moduleloader.h @@ -41,4 +41,7 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod); +/* Any cleanup needed when module leaves. */ +void module_arch_cleanup(struct module *mod); + #endif diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h index 2945cb406b64..bd09a8135e79 100644 --- a/include/linux/msdos_fs.h +++ b/include/linux/msdos_fs.h @@ -146,8 +146,7 @@ struct fat_boot_fsinfo { __u32 reserved1[120]; /* Nothing as far as I can tell */ __u32 signature2; /* 0x61417272L */ __u32 free_clusters; /* Free cluster count. -1 if unknown */ - __u32 next_cluster; /* Most recently allocated cluster. - * Unused under Linux. */ + __u32 next_cluster; /* Most recently allocated cluster */ __u32 reserved2[4]; }; diff --git a/include/linux/smp_lock.h b/include/linux/smp_lock.h index 5a0b83a677d9..80fbd56eb3e4 100644 --- a/include/linux/smp_lock.h +++ b/include/linux/smp_lock.h @@ -5,7 +5,7 @@ #include <linux/sched.h> #include <linux/spinlock.h> -#if CONFIG_SMP || CONFIG_PREEMPT +#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) extern spinlock_t kernel_flag; diff --git a/include/linux/tpqic02.h b/include/linux/tpqic02.h index 2972cb2f827c..f980d4ff01fe 100644 --- a/include/linux/tpqic02.h +++ b/include/linux/tpqic02.h @@ -12,7 +12,7 @@ #include <linux/config.h> -#if CONFIG_QIC02_TAPE || CONFIG_QIC02_TAPE_MODULE +#if defined(CONFIG_QIC02_TAPE) || defined(CONFIG_QIC02_TAPE_MODULE) /* need to have QIC02_TAPE_DRIVE and QIC02_TAPE_IFC expand to something */ #include <linux/mtio.h> diff --git a/include/net/ip.h b/include/net/ip.h index 25e95ec9b4fb..b17e641f537d 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -230,6 +230,23 @@ static inline void ip_eth_mc_map(u32 addr, char *buf) buf[3]=addr&0x7F; } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +#include <linux/ipv6.h> +#endif + +static __inline__ void inet_reset_saddr(struct sock *sk) +{ + inet_sk(sk)->rcv_saddr = inet_sk(sk)->saddr = 0; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + if (sk->family == PF_INET6) { + struct ipv6_pinfo *np = inet6_sk(sk); + + memset(&np->saddr, 0, sizeof(np->saddr)); + memset(&np->rcv_saddr, 0, sizeof(np->rcv_saddr)); + } +#endif +} + #endif extern int ip_call_ra_chain(struct sk_buff *skb); diff --git a/ipc/msg.c b/ipc/msg.c index 015ff8da13ae..c1e6bb646990 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -74,7 +74,7 @@ static struct ipc_ids msg_ids; #define msg_buildid(id, seq) \ ipc_buildid(&msg_ids, id, seq) -static void freeque (int id); +static void freeque (struct msg_queue *msq, int id); static int newque (key_t key, int msgflg); #ifdef CONFIG_PROC_FS static int sysvipc_msg_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data); @@ -272,16 +272,21 @@ static void expunge_all(struct msg_queue* msq, int res) wake_up_process(msr->r_tsk); } } - -static void freeque (int id) +/* + * freeque() wakes up waiters on the sender and receiver waiting queue, + * removes the message queue from message queue ID + * array, and cleans up all the messages associated with this queue. + * + * msg_ids.sem and the spinlock for this message queue is hold + * before freeque() is called. msg_ids.sem remains locked on exit. + */ +static void freeque (struct msg_queue *msq, int id) { - struct msg_queue *msq; struct list_head *tmp; - msq = msg_rmid(id); - expunge_all(msq,-EIDRM); ss_wakeup(&msq->q_senders,1); + msq = msg_rmid(id); msg_unlock(msq); tmp = msq->q_messages.next; @@ -574,7 +579,7 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds *buf) break; } case IPC_RMID: - freeque (msqid); + freeque (msq, msqid); break; } err = 0; diff --git a/ipc/sem.c b/ipc/sem.c index d965818ea0ee..411e07803760 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -79,7 +79,7 @@ static struct ipc_ids sem_ids; static int newary (key_t, int, int); -static void freeary (int id); +static void freeary (struct sem_array *sma, int id); #ifdef CONFIG_PROC_FS static int sysvipc_sem_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data); #endif @@ -405,16 +405,16 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum) return semzcnt; } -/* Free a semaphore set. */ -static void freeary (int id) +/* Free a semaphore set. freeary() is called with sem_ids.sem down and + * the spinlock for this semaphore set hold. sem_ids.sem remains locked + * on exit. + */ +static void freeary (struct sem_array *sma, int id) { - struct sem_array *sma; struct sem_undo *un; struct sem_queue *q; int size; - sma = sem_rmid(id); - /* Invalidate the existing undo structures for this semaphore set. * (They will be freed without any further action in sem_exit() * or during the next semop.) @@ -428,6 +428,9 @@ static void freeary (int id) q->prev = NULL; wake_up_process(q->sleeper); /* doesn't sleep */ } + + /* Remove the semaphore set from the ID array*/ + sma = sem_rmid(id); sem_unlock(sma); used_sems -= sma->sem_nsems; @@ -764,7 +767,7 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun switch(cmd){ case IPC_RMID: - freeary(semid); + freeary(sma, semid); err = 0; break; case IPC_SET: diff --git a/kernel/cpufreq.c b/kernel/cpufreq.c index 913e6b0f56fb..589bf0bf2093 100644 --- a/kernel/cpufreq.c +++ b/kernel/cpufreq.c @@ -29,9 +29,11 @@ * level driver of CPUFreq support, and its locking mutex. * cpu_max_freq is in kHz. */ -static struct cpufreq_driver *cpufreq_driver; +struct cpufreq_driver *cpufreq_driver; static DECLARE_MUTEX (cpufreq_driver_sem); +/* required for the proc interface, remove when that goes away */ +EXPORT_SYMBOL_GPL(cpufreq_driver); /** * Two notifier lists: the "policy" list is involved in the diff --git a/kernel/fork.c b/kernel/fork.c index 1cc3801fbd29..2d74b5cf05e2 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -379,7 +379,6 @@ static struct mm_struct * mm_init(struct mm_struct * mm) free_mm(mm); return NULL; } - /* * Allocate and initialize an mm_struct. @@ -543,7 +542,7 @@ static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old) } else { fs->altrootmnt = NULL; fs->altroot = NULL; - } + } read_unlock(&old->lock); } return fs; @@ -562,14 +561,14 @@ static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk) } tsk->fs = __copy_fs_struct(current->fs); if (!tsk->fs) - return -1; + return -ENOMEM; return 0; } static int count_open_files(struct files_struct *files, int size) { int i; - + /* Find the last open fd */ for (i = size/(8*sizeof(long)); i > 0; ) { if (files->open_fds->fds_bits[--i]) @@ -669,7 +668,7 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk) if (newf->max_fdset > open_files) { int left = (newf->max_fdset-open_files)/8; int start = open_files / (8 * sizeof(unsigned long)); - + memset(&newf->open_fds->fds_bits[start], 0, left); memset(&newf->close_on_exec->fds_bits[start], 0, left); } @@ -697,7 +696,7 @@ static inline int copy_sighand(unsigned long clone_flags, struct task_struct * t sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL); tsk->sighand = sig; if (!sig) - return -1; + return -ENOMEM; spin_lock_init(&sig->siglock); atomic_set(&sig->count, 1); memcpy(sig->action, current->sighand->action, sizeof(sig->action)); @@ -715,7 +714,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); tsk->signal = sig; if (!sig) - return -1; + return -ENOMEM; atomic_set(&sig->count, 1); sig->group_exit = 0; sig->group_exit_code = 0; @@ -800,7 +799,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, */ if (nr_threads >= max_threads) goto bad_fork_cleanup_count; - + if (!try_module_get(p->thread_info->exec_domain->module)) goto bad_fork_cleanup_count; @@ -860,23 +859,22 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->security = NULL; retval = -ENOMEM; - if (security_task_alloc(p)) + if ((retval = security_task_alloc(p))) goto bad_fork_cleanup; /* copy all the process information */ - if (copy_semundo(clone_flags, p)) + if ((retval = copy_semundo(clone_flags, p))) goto bad_fork_cleanup_security; - if (copy_files(clone_flags, p)) + if ((retval = copy_files(clone_flags, p))) goto bad_fork_cleanup_semundo; - if (copy_fs(clone_flags, p)) + if ((retval = copy_fs(clone_flags, p))) goto bad_fork_cleanup_files; - if (copy_sighand(clone_flags, p)) + if ((retval = copy_sighand(clone_flags, p))) goto bad_fork_cleanup_fs; - if (copy_signal(clone_flags, p)) + if ((retval = copy_signal(clone_flags, p))) goto bad_fork_cleanup_sighand; - if (copy_mm(clone_flags, p)) + if ((retval = copy_mm(clone_flags, p))) goto bad_fork_cleanup_signal; - retval = copy_namespace(clone_flags, p); - if (retval) + if ((retval = copy_namespace(clone_flags, p))) goto bad_fork_cleanup_mm; retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); if (retval) diff --git a/kernel/module.c b/kernel/module.c index 06ff9328b30b..62568f702dfc 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -214,6 +214,8 @@ static void module_unload_init(struct module *mod) INIT_LIST_HEAD(&mod->modules_which_use_me); for (i = 0; i < NR_CPUS; i++) atomic_set(&mod->ref[i].count, 0); + /* Hold reference count during initialization. */ + atomic_set(&mod->ref[smp_processor_id()].count, 1); /* Backwards compatibility macros put refcount during init. */ mod->waiter = current; } @@ -462,6 +464,21 @@ void cleanup_module(void) } EXPORT_SYMBOL(cleanup_module); +static void wait_for_zero_refcount(struct module *mod) +{ + /* Since we might sleep for some time, drop the semaphore first */ + up(&module_mutex); + for (;;) { + DEBUGP("Looking at refcount...\n"); + set_current_state(TASK_UNINTERRUPTIBLE); + if (module_refcount(mod) == 0) + break; + schedule(); + } + current->state = TASK_RUNNING; + down(&module_mutex); +} + asmlinkage long sys_delete_module(const char __user *name_user, unsigned int flags) { @@ -500,16 +517,6 @@ sys_delete_module(const char __user *name_user, unsigned int flags) goto out; } - /* Coming up? Allow force on stuck modules. */ - if (mod->state == MODULE_STATE_COMING) { - forced = try_force(flags); - if (!forced) { - /* This module can't be removed */ - ret = -EBUSY; - goto out; - } - } - /* If it has an init func, it must have an exit func to unload */ if ((mod->init != init_module && mod->exit == cleanup_module) || mod->unsafe) { @@ -529,35 +536,22 @@ sys_delete_module(const char __user *name_user, unsigned int flags) /* If it's not unused, quit unless we are told to block. */ if ((flags & O_NONBLOCK) && module_refcount(mod) != 0) { forced = try_force(flags); - if (!forced) + if (!forced) { ret = -EWOULDBLOCK; - } else { - mod->waiter = current; - mod->state = MODULE_STATE_GOING; + restart_refcounts(); + goto out; + } } - restart_refcounts(); - - if (ret != 0) - goto out; - - if (forced) - goto destroy; - /* Since we might sleep for some time, drop the semaphore first */ - up(&module_mutex); - for (;;) { - DEBUGP("Looking at refcount...\n"); - set_current_state(TASK_UNINTERRUPTIBLE); - if (module_refcount(mod) == 0) - break; - schedule(); - } - current->state = TASK_RUNNING; + /* Mark it as dying. */ + mod->waiter = current; + mod->state = MODULE_STATE_GOING; + restart_refcounts(); - DEBUGP("Regrabbing mutex...\n"); - down(&module_mutex); + /* Never wait if forced. */ + if (!forced && module_refcount(mod) != 0) + wait_for_zero_refcount(mod); - destroy: /* Final destruction now noone is using it. */ mod->exit(); free_module(mod); @@ -910,6 +904,9 @@ static void free_module(struct module *mod) list_del(&mod->list); spin_unlock_irq(&modlist_lock); + /* Arch-specific cleanup. */ + module_arch_cleanup(mod); + /* Module unload stuff */ module_unload_free(mod); @@ -1276,6 +1273,7 @@ static struct module *load_module(void __user *umod, mod->module_init = ptr; /* Transfer each section which specifies SHF_ALLOC */ + DEBUGP("final section addresses:\n"); for (i = 0; i < hdr->e_shnum; i++) { void *dest; @@ -1293,6 +1291,7 @@ static struct module *load_module(void __user *umod, sechdrs[i].sh_size); /* Update sh_addr to point to copy in image. */ sechdrs[i].sh_addr = (unsigned long)dest; + DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name); } /* Module has been moved. */ mod = (void *)sechdrs[modindex].sh_addr; @@ -1448,6 +1447,7 @@ sys_init_module(void __user *umod, printk(KERN_ERR "%s: module is now stuck!\n", mod->name); else { + module_put(mod); down(&module_mutex); free_module(mod); up(&module_mutex); @@ -1458,6 +1458,8 @@ sys_init_module(void __user *umod, /* Now it's a first class citizen! */ down(&module_mutex); mod->state = MODULE_STATE_LIVE; + /* Drop initial reference. */ + module_put(mod); module_free(mod, mod->module_init); mod->module_init = NULL; mod->init_size = 0; diff --git a/kernel/pid.c b/kernel/pid.c index f5afb3137e74..00413e3967b9 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -252,6 +252,7 @@ void switch_exec_pids(task_t *leader, task_t *thread) attach_pid(thread, PIDTYPE_TGID, thread->tgid); attach_pid(thread, PIDTYPE_PGID, thread->pgrp); attach_pid(thread, PIDTYPE_SID, thread->session); + list_add_tail(&thread->tasks, &init_task.tasks); attach_pid(leader, PIDTYPE_PID, leader->pid); attach_pid(leader, PIDTYPE_TGID, leader->tgid); diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index bca12ba294e4..25757200b34d 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -357,13 +357,10 @@ static inline struct task_struct * good_sigevent(sigevent_t * event) rtn->tgid != current->tgid)) return NULL; - if ((event->sigev_notify & SIGEV_SIGNAL & MIPS_SIGEV) && + if ((event->sigev_notify & ~SIGEV_NONE & MIPS_SIGEV) && ((unsigned) (event->sigev_signo > SIGRTMAX))) return NULL; - if (event->sigev_notify & ~(SIGEV_SIGNAL | SIGEV_THREAD_ID)) - return NULL; - return rtn; } diff --git a/mm/mmap.c b/mm/mmap.c index cb35e2d7f1e2..f773d3d429b1 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -471,6 +471,8 @@ static int vma_merge(struct mm_struct *mm, struct vm_area_struct *prev, spin_unlock(lock); if (need_up) up(&inode->i_mapping->i_shared_sem); + if (file) + fput(file); mm->map_count--; kmem_cache_free(vm_area_cachep, next); @@ -1440,7 +1442,7 @@ void exit_mmap(struct mm_struct *mm) vm_unacct_memory(nr_accounted); BUG_ON(mm->map_count); /* This is just debugging */ clear_page_tables(tlb, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD); - tlb_finish_mmu(tlb, 0, TASK_SIZE); + tlb_finish_mmu(tlb, 0, MM_VM_SIZE(mm)); vma = mm->mmap; mm->mmap = mm->mmap_cache = NULL; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 9bc83d70425b..45b3d6bcd30f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -336,21 +336,17 @@ static void prep_new_page(struct page *page, int order) static struct page *__rmqueue(struct zone *zone, unsigned int order) { struct free_area * area; - unsigned int current_order = order; - struct list_head *head, *curr; + unsigned int current_order; struct page *page; unsigned int index; - for (current_order=order; current_order < MAX_ORDER; ++current_order) { + for (current_order = order; current_order < MAX_ORDER; ++current_order) { area = zone->free_area + current_order; - head = &area->free_list; - curr = head->next; - if (list_empty(&area->free_list)) continue; - page = list_entry(curr, struct page, list); - list_del(curr); + page = list_entry(area->free_list.next, struct page, list); + list_del(&page->list); index = page - zone->zone_mem_map; if (current_order != MAX_ORDER-1) MARK_USED(index, current_order, area); diff --git a/mm/slab.c b/mm/slab.c index 548585420afc..55ddd968cae2 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -949,7 +949,7 @@ kmem_cache_create (const char *name, size_t size, size_t offset, * with object sizes just above a power of two have a significant * amount of internal fragmentation */ - if ((size < (PAGE_SIZE>>3) || fls(size-1) == fls(size-1+3*BYTES_PER_WORD)) + if ((size < 4096 || fls(size-1) == fls(size-1+3*BYTES_PER_WORD)) && !(flags & SLAB_MUST_HWCACHE_ALIGN)) { flags |= SLAB_RED_ZONE|SLAB_STORE_USER; } diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 962850e3f4be..d746a85391ff 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -260,6 +260,7 @@ struct vm_struct *remove_vm_area(void *addr) return NULL; found: + unmap_vm_area(tmp); *p = tmp->next; write_unlock(&vmlist_lock); return tmp; @@ -283,8 +284,6 @@ void __vunmap(void *addr, int deallocate_pages) addr); return; } - - unmap_vm_area(area); if (deallocate_pages) { int i; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 0b2ebc5ef73f..332f46fadd80 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2140,17 +2140,8 @@ int tcp_disconnect(struct sock *sk, int flags) inet->dport = 0; - if (!(sk->userlocks & SOCK_BINDADDR_LOCK)) { - inet->rcv_saddr = inet->saddr = 0; -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - if (sk->family == PF_INET6) { - struct ipv6_pinfo *np = inet6_sk(sk); - - memset(&np->saddr, 0, 16); - memset(&np->rcv_saddr, 0, 16); - } -#endif - } + if (!(sk->userlocks & SOCK_BINDADDR_LOCK)) + inet_reset_saddr(sk); sk->shutdown = 0; __clear_bit(SOCK_DONE, &sk->flags); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 6f8f76e0ddf8..530187fb2aa4 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -920,17 +920,9 @@ int udp_disconnect(struct sock *sk, int flags) inet->daddr = 0; inet->dport = 0; sk->bound_dev_if = 0; - if (!(sk->userlocks&SOCK_BINDADDR_LOCK)) { - inet->rcv_saddr = inet->saddr = 0; -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - if (sk->family == PF_INET6) { - struct ipv6_pinfo *np = inet6_sk(sk); - - memset(&np->saddr, 0, 16); - memset(&np->rcv_saddr, 0, 16); - } -#endif - } + if (!(sk->userlocks & SOCK_BINDADDR_LOCK)) + inet_reset_saddr(sk); + if (!(sk->userlocks&SOCK_BINDPORT_LOCK)) { sk->prot->unhash(sk); inet->sport = 0; diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index 8db59d854c9b..5d51b9daa0d5 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c @@ -101,7 +101,7 @@ __xfrm4_find_acq(u8 mode, u16 reqid, u8 proto, x0->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES; xfrm_state_hold(x0); mod_timer(&x0->timer, jiffies + XFRM_ACQ_EXPIRES*HZ); - xfrm_state_hold(0); + xfrm_state_hold(x0); list_add_tail(&x0->bydst, xfrm4_state_afinfo.state_bydst+h); wake_up(&km_waitq); } diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index ee0e31af4cc8..88ba4d5f5c5a 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -355,10 +355,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) /* Make sure we are allowed to bind here. */ if (sk->prot->get_port(sk, snum) != 0) { - inet->rcv_saddr = inet->saddr = 0; - memset(&np->rcv_saddr, 0, sizeof(struct in6_addr)); - memset(&np->saddr, 0, sizeof(struct in6_addr)); - + inet_reset_saddr(sk); release_sock(sk); return -EADDRINUSE; } diff --git a/net/nonet.c b/net/nonet.c index 997b0e138485..e5241dceaa57 100644 --- a/net/nonet.c +++ b/net/nonet.c @@ -8,6 +8,7 @@ * Copyright (c) Matthew Wilcox 2003 */ +#include <linux/module.h> #include <linux/errno.h> #include <linux/fs.h> #include <linux/init.h> diff --git a/net/rxrpc/proc.c b/net/rxrpc/proc.c index 81ca4224c9fc..e9d979fc4eb0 100644 --- a/net/rxrpc/proc.c +++ b/net/rxrpc/proc.c @@ -52,7 +52,6 @@ static void rxrpc_proc_peers_stop(struct seq_file *p, void *v); static int rxrpc_proc_peers_show(struct seq_file *m, void *v); static struct seq_operations rxrpc_proc_peers_ops = { - .owner = THIS_MODULE, .start = rxrpc_proc_peers_start, .next = rxrpc_proc_peers_next, .stop = rxrpc_proc_peers_stop, @@ -102,6 +101,7 @@ static struct seq_operations rxrpc_proc_calls_ops = { }; static struct file_operations rxrpc_proc_calls_fops = { + .owner = THIS_MODULE, .open = rxrpc_proc_calls_open, .read = seq_read, .llseek = seq_lseek, diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c index 1500be8de8e1..72633a62431e 100644 --- a/net/wanrouter/wanproc.c +++ b/net/wanrouter/wanproc.c @@ -25,6 +25,7 @@ #include <linux/stddef.h> /* offsetof(), etc. */ #include <linux/errno.h> /* return codes */ #include <linux/kernel.h> +#include <linux/module.h> #include <linux/slab.h> /* kmalloc(), kfree() */ #include <linux/mm.h> /* verify_area(), etc. */ #include <linux/string.h> /* inline mem*, str* functions */ |
