From e2996cc7c1815c9edd10f30d815853128c61fa72 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 24 Jan 2007 14:42:04 -0800 Subject: [PATCH] --- yaml --- r: 45871 b: refs/heads/master c: 6640e69731b42fd5e3d2b26201c8b34fc897a0ee h: refs/heads/master i: 45869: c5517f4a2f2fd2596c2c9616c5cc0660e7c4b550 45867: c02e5bbc4bb9b471625ebb036dbb553762aacd04 45863: 40e815680339b5f0b830981a330a139fe888d910 45855: 7a8d6c6f8b62b1924a98dbaab6b4bbe01f45e98d v: v3 --- [refs] | 2 +- trunk/Documentation/filesystems/9p.txt | 20 +- trunk/MAINTAINERS | 21 +-- trunk/Makefile | 2 +- trunk/arch/i386/kernel/entry.S | 4 - trunk/arch/i386/kernel/sysenter.c | 14 +- trunk/arch/powerpc/Kconfig | 1 - trunk/arch/powerpc/kernel/vdso.c | 7 - trunk/arch/um/Kconfig.i386 | 34 ++-- trunk/arch/x86_64/ia32/ia32_binfmt.c | 49 +++++ trunk/arch/x86_64/ia32/syscall32.c | 15 -- trunk/drivers/acpi/processor_perflib.c | 4 + trunk/drivers/ata/Kconfig | 4 - trunk/drivers/ata/ahci.c | 60 +----- trunk/drivers/ata/ata_generic.c | 6 +- trunk/drivers/ata/libata-core.c | 14 +- trunk/drivers/ata/libata-sff.c | 21 +-- trunk/drivers/ata/pata_cmd64x.c | 23 +-- trunk/drivers/ata/pata_hpt3x2n.c | 6 +- trunk/drivers/ata/pata_it821x.c | 4 +- trunk/drivers/ata/pata_ixp4xx_cf.c | 5 +- trunk/drivers/ata/pata_legacy.c | 4 +- trunk/drivers/ata/pata_rz1000.c | 6 +- trunk/drivers/ata/sata_uli.c | 3 +- trunk/drivers/ata/sata_via.c | 12 +- trunk/drivers/firmware/efivars.c | 29 +-- trunk/drivers/isdn/gigaset/common.c | 61 +++--- trunk/drivers/kvm/kvm.h | 1 - trunk/drivers/kvm/kvm_main.c | 17 +- trunk/drivers/kvm/mmu.c | 16 +- trunk/drivers/kvm/paging_tmpl.h | 77 +++----- trunk/drivers/kvm/svm.c | 23 +-- trunk/drivers/md/bitmap.c | 12 +- trunk/drivers/md/dm.c | 27 +-- trunk/drivers/md/md.c | 32 +--- trunk/drivers/md/raid1.c | 7 - trunk/drivers/md/raid5.c | 5 +- trunk/drivers/rtc/rtc-sysfs.c | 2 +- trunk/drivers/spi/pxa2xx_spi.c | 5 +- trunk/drivers/spi/spi.c | 23 +-- trunk/drivers/spi/spi_s3c24xx.c | 28 +-- trunk/fs/9p/error.c | 1 - trunk/fs/9p/fid.c | 69 +------ trunk/fs/9p/fid.h | 5 - trunk/fs/9p/mux.c | 4 +- trunk/fs/9p/v9fs.c | 11 +- trunk/fs/9p/vfs_file.c | 47 ++++- trunk/fs/9p/vfs_inode.c | 206 +++++++++------------ trunk/fs/binfmt_elf.c | 51 +---- trunk/fs/binfmt_elf_fdpic.c | 8 - trunk/fs/buffer.c | 15 +- trunk/fs/fs-writeback.c | 13 +- trunk/fs/nfsd/nfs3xdr.c | 9 +- trunk/fs/nfsd/nfs4xdr.c | 5 +- trunk/fs/nfsd/nfssvc.c | 8 +- trunk/fs/nfsd/nfsxdr.c | 5 +- trunk/fs/nfsd/vfs.c | 28 ++- trunk/fs/proc/base.c | 8 +- trunk/include/asm-generic/libata-portmap.h | 4 +- trunk/include/asm-i386/elf.h | 51 ++++- trunk/include/asm-i386/fixmap.h | 2 - trunk/include/asm-i386/page.h | 2 - trunk/include/asm-powerpc/libata-portmap.h | 12 -- trunk/include/asm-x86_64/uaccess.h | 2 +- trunk/include/linux/bitops.h | 6 +- trunk/include/linux/kvm.h | 1 - trunk/include/linux/libata.h | 5 +- trunk/include/linux/list.h | 10 +- trunk/include/linux/mm.h | 1 - trunk/include/linux/mutex.h | 2 +- trunk/include/linux/nfsd/nfsd.h | 4 +- trunk/include/linux/nfsd/nfsfh.h | 15 +- trunk/include/linux/nfsd/xdr.h | 4 +- trunk/include/linux/nfsd/xdr3.h | 8 +- trunk/include/linux/raid/md.h | 2 +- trunk/include/linux/rtmutex.h | 4 +- trunk/include/linux/sunrpc/svc.h | 5 +- trunk/include/linux/timer.h | 4 +- trunk/mm/memory.c | 11 +- trunk/mm/truncate.c | 22 +-- trunk/net/ipv4/fib_trie.c | 21 ++- trunk/net/sunrpc/svc.c | 3 +- trunk/net/sunrpc/svcsock.c | 2 - 83 files changed, 556 insertions(+), 846 deletions(-) delete mode 100644 trunk/include/asm-powerpc/libata-portmap.h diff --git a/[refs] b/[refs] index 801f7a68501d..d75490249a90 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 08eacc3157baf5d14c8e2c4ffc77c13a0ac8a85b +refs/heads/master: 6640e69731b42fd5e3d2b26201c8b34fc897a0ee diff --git a/trunk/Documentation/filesystems/9p.txt b/trunk/Documentation/filesystems/9p.txt index 4d075a4558f9..43b89c214d20 100644 --- a/trunk/Documentation/filesystems/9p.txt +++ b/trunk/Documentation/filesystems/9p.txt @@ -73,22 +73,8 @@ OPTIONS RESOURCES ========= -Our current recommendation is to use Inferno (http://www.vitanuova.com/inferno) -as the 9p server. You can start a 9p server under Inferno by issuing the -following command: - ; styxlisten -A tcp!*!564 export '#U*' - -The -A specifies an unauthenticated export. The 564 is the port # (you may -have to choose a higher port number if running as a normal user). The '#U*' -specifies exporting the root of the Linux name space. You may specify a -subset of the namespace by extending the path: '#U*'/tmp would just export -/tmp. For more information, see the Inferno manual pages covering styxlisten -and export. - -A Linux version of the 9p server is now maintained under the npfs project -on sourceforge (http://sourceforge.net/projects/npfs). There is also a -more stable single-threaded version of the server (named spfs) available from -the same CVS repository. +The Linux version of the 9p server is now maintained under the npfs project +on sourceforge (http://sourceforge.net/projects/npfs). There are user and developer mailing lists available through the v9fs project on sourceforge (http://sourceforge.net/projects/v9fs). @@ -110,5 +96,5 @@ STATUS The 2.6 kernel support is working on PPC and x86. -PLEASE USE THE KERNEL BUGZILLA TO REPORT PROBLEMS. (http://bugzilla.kernel.org) +PLEASE USE THE SOURCEFORGE BUG-TRACKER TO REPORT PROBLEMS. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index f0596e452c5c..d6f04a81f761 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1137,9 +1137,9 @@ T: git kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git S: Maintained DSCC4 DRIVER -P: Francois Romieu -M: romieu@fr.zoreil.com -L: netdev@vger.kernel.org +P: François Romieu +M: romieu@cogenit.fr +M: romieu@ensta.fr S: Maintained DVB SUBSYSTEM AND DRIVERS @@ -1928,10 +1928,11 @@ S: Maintained KERNEL NFSD P: Neil Brown -M: neilb@suse.de +M: neilb@cse.unsw.edu.au L: nfs@lists.sourceforge.net W: http://nfs.sourceforge.net/ -S: Supported +W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/ +S: Maintained KERNEL VIRTUAL MACHINE (KVM) P: Avi Kivity @@ -2992,9 +2993,9 @@ SOFTWARE RAID (Multiple Disks) SUPPORT P: Ingo Molnar M: mingo@redhat.com P: Neil Brown -M: neilb@suse.de +M: neilb@cse.unsw.edu.au L: linux-raid@vger.kernel.org -S: Supported +S: Maintained SOFTWARE SUSPEND: P: Pavel Machek @@ -3574,12 +3575,6 @@ M: khali@linux-fr.org L: i2c@lm-sensors.org S: Maintained -VIA VELOCITY NETWORK DRIVER -P: Francois Romieu -M: romieu@fr.zoreil.com -L: netdev@vger.kernel.org -S: Maintained - UCLINUX (AND M68KNOMMU) P: Greg Ungerer M: gerg@uclinux.org diff --git a/trunk/Makefile b/trunk/Makefile index 9e1adac8aa28..477f52e3c7f6 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 20 -EXTRAVERSION =-rc6 +EXTRAVERSION =-rc5 NAME = Homicidal Dwarf Hamster # *DOCUMENTATION* diff --git a/trunk/arch/i386/kernel/entry.S b/trunk/arch/i386/kernel/entry.S index 5e47683fc63a..06461b8b715d 100644 --- a/trunk/arch/i386/kernel/entry.S +++ b/trunk/arch/i386/kernel/entry.S @@ -302,16 +302,12 @@ sysenter_past_esp: pushl $(__USER_CS) CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET cs, 0*/ -#ifndef CONFIG_COMPAT_VDSO /* * Push current_thread_info()->sysenter_return to the stack. * A tiny bit of offset fixup is necessary - 4*4 means the 4 words * pushed above; +8 corresponds to copy_thread's esp0 setting. */ pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) -#else - pushl $SYSENTER_RETURN -#endif CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET eip, 0 diff --git a/trunk/arch/i386/kernel/sysenter.c b/trunk/arch/i386/kernel/sysenter.c index 5da744204d10..7de9117b5a3a 100644 --- a/trunk/arch/i386/kernel/sysenter.c +++ b/trunk/arch/i386/kernel/sysenter.c @@ -79,6 +79,11 @@ int __init sysenter_setup(void) #ifdef CONFIG_COMPAT_VDSO __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY); printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO)); +#else + /* + * In the non-compat case the ELF coredumping code needs the fixmap: + */ + __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_KERNEL_RO); #endif if (!boot_cpu_has(X86_FEATURE_SEP)) { @@ -95,7 +100,6 @@ int __init sysenter_setup(void) return 0; } -#ifndef CONFIG_COMPAT_VDSO static struct page *syscall_nopage(struct vm_area_struct *vma, unsigned long adr, int *type) { @@ -142,13 +146,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) vma->vm_end = addr + PAGE_SIZE; /* MAYWRITE to allow gdb to COW and set breakpoints */ vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; - /* - * Make sure the vDSO gets into every core dump. - * Dumping its contents makes post-mortem fully interpretable later - * without matching up the same kernel and hardware config to see - * what PC values meant. - */ - vma->vm_flags |= VM_ALWAYSDUMP; vma->vm_flags |= mm->def_flags; vma->vm_page_prot = protection_map[vma->vm_flags & 7]; vma->vm_ops = &syscall_vm_ops; @@ -190,4 +187,3 @@ int in_gate_area_no_task(unsigned long addr) { return 0; } -#endif diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index b268c417c0bf..0855d55c194d 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -484,7 +484,6 @@ config PPC_MAPLE select PPC_970_NAP select PPC_NATIVE select PPC_RTAS - select ATA_NONSTANDARD if ATA default n help This option enables support for the Maple 970FX Evaluation Board. diff --git a/trunk/arch/powerpc/kernel/vdso.c b/trunk/arch/powerpc/kernel/vdso.c index ae0ede19879d..a4b28c73bba0 100644 --- a/trunk/arch/powerpc/kernel/vdso.c +++ b/trunk/arch/powerpc/kernel/vdso.c @@ -284,13 +284,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, * pages though */ vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC; - /* - * Make sure the vDSO gets into every core dump. - * Dumping its contents makes post-mortem fully interpretable later - * without matching up the same kernel and hardware config to see - * what PC values meant. - */ - vma->vm_flags |= VM_ALWAYSDUMP; vma->vm_flags |= mm->def_flags; vma->vm_page_prot = protection_map[vma->vm_flags & 0x7]; vma->vm_ops = &vdso_vmops; diff --git a/trunk/arch/um/Kconfig.i386 b/trunk/arch/um/Kconfig.i386 index 77558a88a2fe..f191a550a079 100644 --- a/trunk/arch/um/Kconfig.i386 +++ b/trunk/arch/um/Kconfig.i386 @@ -19,22 +19,22 @@ config SEMAPHORE_SLEEPERS choice prompt "Host memory split" default HOST_VMSPLIT_3G - help - This is needed when the host kernel on which you run has a non-default - (like 2G/2G) memory split, instead of the customary 3G/1G. If you did - not recompile your own kernel but use the default distro's one, you can - safely accept the "Default split" option. + ---help--- + This is needed when the host kernel on which you run has a non-default + (like 2G/2G) memory split, instead of the customary 3G/1G. If you did + not recompile your own kernel but use the default distro's one, you can + safely accept the "Default split" option. - It can be enabled on recent (>=2.6.16-rc2) vanilla kernels via - CONFIG_VM_SPLIT_*, or on previous kernels with special patches (-ck - patchset by Con Kolivas, or other ones) - option names match closely the - host CONFIG_VM_SPLIT_* ones. + It can be enabled on recent (>=2.6.16-rc2) vanilla kernels via + CONFIG_VM_SPLIT_*, or on previous kernels with special patches (-ck + patchset by Con Kolivas, or other ones) - option names match closely the + host CONFIG_VM_SPLIT_* ones. - A lower setting (where 1G/3G is lowest and 3G/1G is higher) will - tolerate even more "normal" host kernels, but an higher setting will be - stricter. + A lower setting (where 1G/3G is lowest and 3G/1G is higher) will + tolerate even more "normal" host kernels, but an higher setting will be + stricter. - So, if you do not know what to do here, say 'Default split'. + So, if you do not know what to do here, say 'Default split'. config HOST_VMSPLIT_3G bool "Default split (3G/1G user/kernel host split)" @@ -67,13 +67,13 @@ config 3_LEVEL_PGTABLES config STUB_CODE hex - default 0xbfffe000 if !HOST_VMSPLIT_2G - default 0x7fffe000 if HOST_VMSPLIT_2G + default 0xbfffe000 if !HOST_2G_2G + default 0x7fffe000 if HOST_2G_2G config STUB_DATA hex - default 0xbffff000 if !HOST_VMSPLIT_2G - default 0x7ffff000 if HOST_VMSPLIT_2G + default 0xbffff000 if !HOST_2G_2G + default 0x7ffff000 if HOST_2G_2G config STUB_START hex diff --git a/trunk/arch/x86_64/ia32/ia32_binfmt.c b/trunk/arch/x86_64/ia32/ia32_binfmt.c index 5ce0bd486bbf..543ef4f405e9 100644 --- a/trunk/arch/x86_64/ia32/ia32_binfmt.c +++ b/trunk/arch/x86_64/ia32/ia32_binfmt.c @@ -64,6 +64,55 @@ typedef unsigned int elf_greg_t; #define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t)) typedef elf_greg_t elf_gregset_t[ELF_NGREG]; +/* + * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out + * extra segments containing the vsyscall DSO contents. Dumping its + * contents makes post-mortem fully interpretable later without matching up + * the same kernel and hardware config to see what PC values meant. + * Dumping its extra ELF program headers includes all the other information + * a debugger needs to easily find how the vsyscall DSO was being used. + */ +#define ELF_CORE_EXTRA_PHDRS (find_vma(current->mm, VSYSCALL32_BASE) ? \ + (VSYSCALL32_EHDR->e_phnum) : 0) +#define ELF_CORE_WRITE_EXTRA_PHDRS \ +do { \ + if (find_vma(current->mm, VSYSCALL32_BASE)) { \ + const struct elf32_phdr *const vsyscall_phdrs = \ + (const struct elf32_phdr *) (VSYSCALL32_BASE \ + + VSYSCALL32_EHDR->e_phoff);\ + int i; \ + Elf32_Off ofs = 0; \ + for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ + struct elf32_phdr phdr = vsyscall_phdrs[i]; \ + if (phdr.p_type == PT_LOAD) { \ + BUG_ON(ofs != 0); \ + ofs = phdr.p_offset = offset; \ + phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \ + phdr.p_filesz = phdr.p_memsz; \ + offset += phdr.p_filesz; \ + } \ + else \ + phdr.p_offset += ofs; \ + phdr.p_paddr = 0; /* match other core phdrs */ \ + DUMP_WRITE(&phdr, sizeof(phdr)); \ + } \ + } \ +} while (0) +#define ELF_CORE_WRITE_EXTRA_DATA \ +do { \ + if (find_vma(current->mm, VSYSCALL32_BASE)) { \ + const struct elf32_phdr *const vsyscall_phdrs = \ + (const struct elf32_phdr *) (VSYSCALL32_BASE \ + + VSYSCALL32_EHDR->e_phoff); \ + int i; \ + for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ + if (vsyscall_phdrs[i].p_type == PT_LOAD) \ + DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr,\ + PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ + } \ + } \ +} while (0) + struct elf_siginfo { int si_signo; /* signal number */ diff --git a/trunk/arch/x86_64/ia32/syscall32.c b/trunk/arch/x86_64/ia32/syscall32.c index 59f1fa155915..3e5ed20cba45 100644 --- a/trunk/arch/x86_64/ia32/syscall32.c +++ b/trunk/arch/x86_64/ia32/syscall32.c @@ -59,13 +59,6 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) vma->vm_end = VSYSCALL32_END; /* MAYWRITE to allow gdb to COW and set breakpoints */ vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; - /* - * Make sure the vDSO gets into every core dump. - * Dumping its contents makes post-mortem fully interpretable later - * without matching up the same kernel and hardware config to see - * what PC values meant. - */ - vma->vm_flags |= VM_ALWAYSDUMP; vma->vm_flags |= mm->def_flags; vma->vm_page_prot = protection_map[vma->vm_flags & 7]; vma->vm_ops = &syscall32_vm_ops; @@ -82,14 +75,6 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) return 0; } -const char *arch_vma_name(struct vm_area_struct *vma) -{ - if (vma->vm_start == VSYSCALL32_BASE && - vma->vm_mm && vma->vm_mm->task_size == IA32_PAGE_OFFSET) - return "[vdso]"; - return NULL; -} - static int __init init_syscall32(void) { syscall32_page = (void *)get_zeroed_page(GFP_KERNEL); diff --git a/trunk/drivers/acpi/processor_perflib.c b/trunk/drivers/acpi/processor_perflib.c index cbb6f0814ce2..5207f9e4b443 100644 --- a/trunk/drivers/acpi/processor_perflib.c +++ b/trunk/drivers/acpi/processor_perflib.c @@ -322,6 +322,10 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr) if (result) return result; + result = acpi_processor_get_platform_limit(pr); + if (result) + return result; + return 0; } diff --git a/trunk/drivers/ata/Kconfig b/trunk/drivers/ata/Kconfig index 1c94b43d2c9b..da21552d2b1c 100644 --- a/trunk/drivers/ata/Kconfig +++ b/trunk/drivers/ata/Kconfig @@ -19,10 +19,6 @@ config ATA if ATA -config ATA_NONSTANDARD - bool - default n - config SATA_AHCI tristate "AHCI SATA support" depends on PCI diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index 28a82e3403f1..e3c7b312287a 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -75,7 +75,6 @@ enum { AHCI_CMD_CLR_BUSY = (1 << 10), RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ - RX_FIS_SDB = 0x58, /* offset of SDB FIS data */ RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */ board_ahci = 0, @@ -203,10 +202,6 @@ struct ahci_port_priv { dma_addr_t cmd_tbl_dma; void *rx_fis; dma_addr_t rx_fis_dma; - /* for NCQ spurious interrupt analysis */ - int ncq_saw_spurious_sdb_cnt; - unsigned int ncq_saw_d2h:1; - unsigned int ncq_saw_dmas:1; }; static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); @@ -903,7 +898,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(ap->device, &tf); - tf.command = 0x80; + tf.command = 0xff; ata_tf_to_fis(&tf, d2h_fis, 0); rc = sata_std_hardreset(ap, class); @@ -1114,9 +1109,8 @@ static void ahci_host_intr(struct ata_port *ap) void __iomem *mmio = ap->host->mmio_base; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); struct ata_eh_info *ehi = &ap->eh_info; - struct ahci_port_priv *pp = ap->private_data; u32 status, qc_active; - int rc, known_irq = 0; + int rc; status = readl(port_mmio + PORT_IRQ_STAT); writel(status, port_mmio + PORT_IRQ_STAT); @@ -1143,53 +1137,17 @@ static void ahci_host_intr(struct ata_port *ap) /* hmmm... a spurious interupt */ - /* if !NCQ, ignore. No modern ATA device has broken HSM - * implementation for non-NCQ commands. - */ - if (!ap->sactive) + /* some devices send D2H reg with I bit set during NCQ command phase */ + if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS)) return; - if (status & PORT_IRQ_D2H_REG_FIS) { - if (!pp->ncq_saw_d2h) - ata_port_printk(ap, KERN_INFO, - "D2H reg with I during NCQ, " - "this message won't be printed again\n"); - pp->ncq_saw_d2h = 1; - known_irq = 1; - } - - if (status & PORT_IRQ_DMAS_FIS) { - if (!pp->ncq_saw_dmas) - ata_port_printk(ap, KERN_INFO, - "DMAS FIS during NCQ, " - "this message won't be printed again\n"); - pp->ncq_saw_dmas = 1; - known_irq = 1; - } - - if (status & PORT_IRQ_SDB_FIS && - pp->ncq_saw_spurious_sdb_cnt < 10) { - /* SDB FIS containing spurious completions might be - * dangerous, we need to know more about them. Print - * more of it. - */ - const u32 *f = pp->rx_fis + RX_FIS_SDB; - - ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ " - "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n", - readl(port_mmio + PORT_CMD_ISSUE), - readl(port_mmio + PORT_SCR_ACT), - le32_to_cpu(f[0]), le32_to_cpu(f[1]), - pp->ncq_saw_spurious_sdb_cnt < 10 ? - "" : ", shutting up"); - - pp->ncq_saw_spurious_sdb_cnt++; - known_irq = 1; - } + /* ignore interim PIO setup fis interrupts */ + if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS)) + return; - if (!known_irq) + if (ata_ratelimit()) ata_port_printk(ap, KERN_INFO, "spurious interrupt " - "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n", + "(irq_stat 0x%x active_tag %d sactive 0x%x)\n", status, ap->active_tag, ap->sactive); } diff --git a/trunk/drivers/ata/ata_generic.c b/trunk/drivers/ata/ata_generic.c index 24af56081b5d..908751d27e76 100644 --- a/trunk/drivers/ata/ata_generic.c +++ b/trunk/drivers/ata/ata_generic.c @@ -64,7 +64,6 @@ static void generic_error_handler(struct ata_port *ap) /** * generic_set_mode - mode setting * @ap: interface to set up - * @unused: returned device on error * * Use a non standard set_mode function. We don't want to be tuned. * The BIOS configured everything. Our job is not to fiddle. We @@ -72,7 +71,7 @@ static void generic_error_handler(struct ata_port *ap) * and respect them. */ -static int generic_set_mode(struct ata_port *ap, struct ata_device **unused) +static void generic_set_mode(struct ata_port *ap) { int dma_enabled = 0; int i; @@ -83,7 +82,7 @@ static int generic_set_mode(struct ata_port *ap, struct ata_device **unused) for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_ready(dev)) { + if (ata_dev_enabled(dev)) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; dev->dma_mode = XFER_MW_DMA_0; @@ -100,7 +99,6 @@ static int generic_set_mode(struct ata_port *ap, struct ata_device **unused) } } } - return 0; } static struct scsi_host_template generic_sht = { diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index a388a8df0043..0d51d13b16bf 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -2431,8 +2431,18 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) int i, rc = 0, used_dma = 0, found = 0; /* has private set_mode? */ - if (ap->ops->set_mode) - return ap->ops->set_mode(ap, r_failed_dev); + if (ap->ops->set_mode) { + /* FIXME: make ->set_mode handle no device case and + * return error code and failing device on failure. + */ + for (i = 0; i < ATA_MAX_DEVICES; i++) { + if (ata_dev_ready(&ap->device[i])) { + ap->ops->set_mode(ap); + break; + } + } + return 0; + } /* step 1: calculate xfer_mask */ for (i = 0; i < ATA_MAX_DEVICES; i++) { diff --git a/trunk/drivers/ata/libata-sff.c b/trunk/drivers/ata/libata-sff.c index 12c88c588039..623cec914c9b 100644 --- a/trunk/drivers/ata/libata-sff.c +++ b/trunk/drivers/ata/libata-sff.c @@ -827,8 +827,7 @@ void ata_bmdma_error_handler(struct ata_port *ap) */ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) { - if (qc->ap->ioaddr.bmdma_addr) - ata_bmdma_stop(qc); + ata_bmdma_stop(qc); } #ifdef CONFIG_PCI @@ -871,8 +870,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; bmdma = pci_resource_start(pdev, 4); if (bmdma) { - if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) && - (inb(bmdma + 2) & 0x80)) + if (inb(bmdma + 2) & 0x80) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; probe_ent->port[p].bmdma_addr = bmdma; } @@ -888,8 +886,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int bmdma = pci_resource_start(pdev, 4); if (bmdma) { bmdma += 8; - if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) && - (inb(bmdma + 2) & 0x80)) + if(inb(bmdma + 2) & 0x80) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; probe_ent->port[p].bmdma_addr = bmdma; } @@ -917,14 +914,13 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, probe_ent->irq_flags = IRQF_SHARED; if (port_mask & ATA_PORT_PRIMARY) { - probe_ent->irq = ATA_PRIMARY_IRQ(pdev); + probe_ent->irq = ATA_PRIMARY_IRQ; probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD; probe_ent->port[0].altstatus_addr = probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL; if (bmdma) { probe_ent->port[0].bmdma_addr = bmdma; - if ((!(port[0]->flags & ATA_FLAG_IGN_SIMPLEX)) && - (inb(bmdma + 2) & 0x80)) + if (inb(bmdma + 2) & 0x80) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; } ata_std_ports(&probe_ent->port[0]); @@ -933,16 +929,15 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, if (port_mask & ATA_PORT_SECONDARY) { if (probe_ent->irq) - probe_ent->irq2 = ATA_SECONDARY_IRQ(pdev); + probe_ent->irq2 = ATA_SECONDARY_IRQ; else - probe_ent->irq = ATA_SECONDARY_IRQ(pdev); + probe_ent->irq = ATA_SECONDARY_IRQ; probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD; probe_ent->port[1].altstatus_addr = probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL; if (bmdma) { probe_ent->port[1].bmdma_addr = bmdma + 8; - if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) && - (inb(bmdma + 10) & 0x80)) + if (inb(bmdma + 10) & 0x80) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; } ata_std_ports(&probe_ent->port[1]); diff --git a/trunk/drivers/ata/pata_cmd64x.c b/trunk/drivers/ata/pata_cmd64x.c index 449162cbf93e..15841a563694 100644 --- a/trunk/drivers/ata/pata_cmd64x.c +++ b/trunk/drivers/ata/pata_cmd64x.c @@ -197,7 +197,7 @@ static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev) static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) { static const u8 udma_data[] = { - 0x30, 0x20, 0x10, 0x20, 0x10, 0x00 + 0x31, 0x21, 0x11, 0x25, 0x15, 0x05 }; static const u8 mwdma_data[] = { 0x30, 0x20, 0x10 @@ -213,21 +213,12 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) pci_read_config_byte(pdev, pciD, ®D); pci_read_config_byte(pdev, pciU, ®U); - /* DMA bits off */ - regD &= ~(0x20 << adev->devno); - /* DMA control bits */ - regU &= ~(0x30 << shift); - /* DMA timing bits */ - regU &= ~(0x05 << adev->devno); + regD &= ~(0x20 << shift); + regU &= ~(0x35 << shift); - if (adev->dma_mode >= XFER_UDMA_0) { - /* Merge thge timing value */ + if (adev->dma_mode >= XFER_UDMA_0) regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift; - /* Merge the control bits */ - regU |= 1 << adev->devno; /* UDMA on */ - if (adev->dma_mode > 2) /* 15nS timing */ - regU |= 4 << adev->devno; - } else + else regD |= mwdma_data[adev->dma_mode - XFER_MW_DMA_0] << shift; regD |= 0x20 << adev->devno; @@ -248,8 +239,8 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 dma_intr; - int dma_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; - int dma_reg = ap->port_no ? ARTTIM2 : CFR; + int dma_reg = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; + int dma_mask = ap->port_no ? ARTTIM2 : CFR; ata_bmdma_stop(qc); diff --git a/trunk/drivers/ata/pata_hpt3x2n.c b/trunk/drivers/ata/pata_hpt3x2n.c index 886fab9aa62c..f6817b4093a4 100644 --- a/trunk/drivers/ata/pata_hpt3x2n.c +++ b/trunk/drivers/ata/pata_hpt3x2n.c @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.2" +#define DRV_VERSION "0.3" enum { HPT_PCI_FAST = (1 << 31), @@ -297,11 +297,11 @@ static int hpt3x2n_pair_idle(struct ata_port *ap) return 0; } -static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) +static int hpt3x2n_use_dpll(struct ata_port *ap, int reading) { long flags = (long)ap->host->private_data; /* See if we should use the DPLL */ - if (writing) + if (reading == 0) return USE_DPLL; /* Needed for write */ if (flags & PCI66) return USE_DPLL; /* Needed at 66Mhz */ diff --git a/trunk/drivers/ata/pata_it821x.c b/trunk/drivers/ata/pata_it821x.c index e8afd486434a..0b56ff3d1cfe 100644 --- a/trunk/drivers/ata/pata_it821x.c +++ b/trunk/drivers/ata/pata_it821x.c @@ -476,7 +476,6 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc) /** * it821x_smart_set_mode - mode setting * @ap: interface to set up - * @unused: device that failed (error only) * * Use a non standard set_mode function. We don't want to be tuned. * The BIOS configured everything. Our job is not to fiddle. We @@ -484,7 +483,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc) * and respect them. */ -static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused) +static void it821x_smart_set_mode(struct ata_port *ap) { int dma_enabled = 0; int i; @@ -513,7 +512,6 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused } } } - return 0; } /** diff --git a/trunk/drivers/ata/pata_ixp4xx_cf.c b/trunk/drivers/ata/pata_ixp4xx_cf.c index 23b8aab3ebd8..cb8924109f59 100644 --- a/trunk/drivers/ata/pata_ixp4xx_cf.c +++ b/trunk/drivers/ata/pata_ixp4xx_cf.c @@ -23,9 +23,9 @@ #include #define DRV_NAME "pata_ixp4xx_cf" -#define DRV_VERSION "0.1.1ac1" +#define DRV_VERSION "0.1.1" -static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device *adev) +static void ixp4xx_set_mode(struct ata_port *ap) { int i; @@ -38,7 +38,6 @@ static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device *adev) dev->flags |= ATA_DFLAG_PIO; } } - return 0; } static void ixp4xx_phy_reset(struct ata_port *ap) diff --git a/trunk/drivers/ata/pata_legacy.c b/trunk/drivers/ata/pata_legacy.c index 581cb33c6f45..e7bf9d89c8ee 100644 --- a/trunk/drivers/ata/pata_legacy.c +++ b/trunk/drivers/ata/pata_legacy.c @@ -96,7 +96,6 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */ /** * legacy_set_mode - mode setting * @ap: IDE interface - * @unused: Device that failed when error is returned * * Use a non standard set_mode function. We don't want to be tuned. * @@ -106,7 +105,7 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */ * expand on this as per hdparm in the base kernel. */ -static int legacy_set_mode(struct ata_port *ap, struct ata_device **unused) +static void legacy_set_mode(struct ata_port *ap) { int i; @@ -119,7 +118,6 @@ static int legacy_set_mode(struct ata_port *ap, struct ata_device **unused) dev->flags |= ATA_DFLAG_PIO; } } - return 0; } static struct scsi_host_template legacy_sht = { diff --git a/trunk/drivers/ata/pata_rz1000.c b/trunk/drivers/ata/pata_rz1000.c index cec0729225e1..adf4cc134f25 100644 --- a/trunk/drivers/ata/pata_rz1000.c +++ b/trunk/drivers/ata/pata_rz1000.c @@ -52,20 +52,19 @@ static void rz1000_error_handler(struct ata_port *ap) /** * rz1000_set_mode - mode setting function * @ap: ATA interface - * @unused: returned device on set_mode failure * * Use a non standard set_mode function. We don't want to be tuned. We * would prefer to be BIOS generic but for the fact our hardware is * whacked out. */ -static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused) +static void rz1000_set_mode(struct ata_port *ap) { int i; for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_ready(dev)) { + if (ata_dev_enabled(dev)) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; dev->xfer_mode = XFER_PIO_0; @@ -73,7 +72,6 @@ static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused) dev->flags |= ATA_DFLAG_PIO; } } - return 0; } diff --git a/trunk/drivers/ata/sata_uli.c b/trunk/drivers/ata/sata_uli.c index a43aec62d505..5c603ca3a50a 100644 --- a/trunk/drivers/ata/sata_uli.c +++ b/trunk/drivers/ata/sata_uli.c @@ -128,8 +128,7 @@ static const struct ata_port_operations uli_ops = { static struct ata_port_info uli_port_info = { .sht = &uli_sht, - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_IGN_SIMPLEX, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &uli_ops, diff --git a/trunk/drivers/ata/sata_via.c b/trunk/drivers/ata/sata_via.c index d3d5c0d57032..88f0565c8883 100644 --- a/trunk/drivers/ata/sata_via.c +++ b/trunk/drivers/ata/sata_via.c @@ -74,7 +74,6 @@ enum { static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); -static void svia_noop_freeze(struct ata_port *ap); static void vt6420_error_handler(struct ata_port *ap); static const struct pci_device_id svia_pci_tbl[] = { @@ -129,7 +128,7 @@ static const struct ata_port_operations vt6420_sata_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, - .freeze = svia_noop_freeze, + .freeze = ata_bmdma_freeze, .thaw = ata_bmdma_thaw, .error_handler = vt6420_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, @@ -205,15 +204,6 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) outl(val, ap->ioaddr.scr_addr + (4 * sc_reg)); } -static void svia_noop_freeze(struct ata_port *ap) -{ - /* Some VIA controllers choke if ATA_NIEN is manipulated in - * certain way. Leave it alone and just clear pending IRQ. - */ - ata_chk_status(ap); - ata_bmdma_irq_clear(ap); -} - /** * vt6420_prereset - prereset for vt6420 * @ap: target ATA port diff --git a/trunk/drivers/firmware/efivars.c b/trunk/drivers/firmware/efivars.c index c6281ccd4fe7..5ab5e393b882 100644 --- a/trunk/drivers/firmware/efivars.c +++ b/trunk/drivers/firmware/efivars.c @@ -122,6 +122,8 @@ struct efivar_entry { struct kobject kobj; }; +#define get_efivar_entry(n) list_entry(n, struct efivar_entry, list) + struct efivar_attribute { struct attribute attr; ssize_t (*show) (struct efivar_entry *entry, char *buf); @@ -384,6 +386,9 @@ static struct sysfs_ops efivar_attr_ops = { static void efivar_release(struct kobject *kobj) { struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj); + spin_lock(&efivars_lock); + list_del(&var->list); + spin_unlock(&efivars_lock); kfree(var); } @@ -425,8 +430,9 @@ static ssize_t efivar_create(struct subsystem *sub, const char *buf, size_t count) { struct efi_variable *new_var = (struct efi_variable *)buf; - struct efivar_entry *search_efivar, *n; + struct efivar_entry *search_efivar = NULL; unsigned long strsize1, strsize2; + struct list_head *pos, *n; efi_status_t status = EFI_NOT_FOUND; int found = 0; @@ -438,7 +444,8 @@ efivar_create(struct subsystem *sub, const char *buf, size_t count) /* * Does this variable already exist? */ - list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { + list_for_each_safe(pos, n, &efivar_list) { + search_efivar = get_efivar_entry(pos); strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); strsize2 = utf8_strsize(new_var->VariableName, 1024); if (strsize1 == strsize2 && @@ -483,8 +490,9 @@ static ssize_t efivar_delete(struct subsystem *sub, const char *buf, size_t count) { struct efi_variable *del_var = (struct efi_variable *)buf; - struct efivar_entry *search_efivar, *n; + struct efivar_entry *search_efivar = NULL; unsigned long strsize1, strsize2; + struct list_head *pos, *n; efi_status_t status = EFI_NOT_FOUND; int found = 0; @@ -496,7 +504,8 @@ efivar_delete(struct subsystem *sub, const char *buf, size_t count) /* * Does this variable already exist? */ - list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { + list_for_each_safe(pos, n, &efivar_list) { + search_efivar = get_efivar_entry(pos); strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); strsize2 = utf8_strsize(del_var->VariableName, 1024); if (strsize1 == strsize2 && @@ -528,9 +537,9 @@ efivar_delete(struct subsystem *sub, const char *buf, size_t count) spin_unlock(&efivars_lock); return -EIO; } - list_del(&search_efivar->list); /* We need to release this lock before unregistering. */ spin_unlock(&efivars_lock); + efivar_unregister(search_efivar); /* It's dead Jim.... */ @@ -759,14 +768,10 @@ efivars_init(void) static void __exit efivars_exit(void) { - struct efivar_entry *entry, *n; + struct list_head *pos, *n; - list_for_each_entry_safe(entry, n, &efivar_list, list) { - spin_lock(&efivars_lock); - list_del(&entry->list); - spin_unlock(&efivars_lock); - efivar_unregister(entry); - } + list_for_each_safe(pos, n, &efivar_list) + efivar_unregister(get_efivar_entry(pos)); subsystem_unregister(&vars_subsys); firmware_unregister(&efi_subsys); diff --git a/trunk/drivers/isdn/gigaset/common.c b/trunk/drivers/isdn/gigaset/common.c index 4f75cce6fdff..95eff3b2917a 100644 --- a/trunk/drivers/isdn/gigaset/common.c +++ b/trunk/drivers/isdn/gigaset/common.c @@ -356,17 +356,16 @@ static struct cardstate *alloc_cs(struct gigaset_driver *drv) { unsigned long flags; unsigned i; - struct cardstate *ret = NULL; + static struct cardstate *ret = NULL; spin_lock_irqsave(&drv->lock, flags); for (i = 0; i < drv->minors; ++i) { if (!(drv->flags[i] & VALID_MINOR)) { - if (try_module_get(drv->owner)) { - drv->flags[i] = VALID_MINOR; - ret = drv->cs + i; - } - break; + drv->flags[i] = VALID_MINOR; + ret = drv->cs + i; } + if (ret) + break; } spin_unlock_irqrestore(&drv->lock, flags); return ret; @@ -377,8 +376,6 @@ static void free_cs(struct cardstate *cs) unsigned long flags; struct gigaset_driver *drv = cs->driver; spin_lock_irqsave(&drv->lock, flags); - if (drv->flags[cs->minor_index] & VALID_MINOR) - module_put(drv->owner); drv->flags[cs->minor_index] = 0; spin_unlock_irqrestore(&drv->lock, flags); } @@ -582,7 +579,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) skb_reserve(bcs->skb, HW_HDR_LEN); else { - warn("could not allocate skb"); + warn("could not allocate skb\n"); bcs->inputstate |= INS_skip_frame; } @@ -635,25 +632,17 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, int i; gig_dbg(DEBUG_INIT, "allocating cs"); - if (!(cs = alloc_cs(drv))) { - err("maximum number of devices exceeded"); - return NULL; - } - mutex_init(&cs->mutex); - mutex_lock(&cs->mutex); - + cs = alloc_cs(drv); + if (!cs) + goto error; gig_dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1); cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); - if (!cs->bcs) { - err("out of memory"); + if (!cs->bcs) goto error; - } gig_dbg(DEBUG_INIT, "allocating inbuf"); cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL); - if (!cs->inbuf) { - err("out of memory"); + if (!cs->inbuf) goto error; - } cs->cs_init = 0; cs->channels = channels; @@ -665,6 +654,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, spin_lock_init(&cs->ev_lock); cs->ev_tail = 0; cs->ev_head = 0; + mutex_init(&cs->mutex); + mutex_lock(&cs->mutex); tasklet_init(&cs->event_tasklet, &gigaset_handle_event, (unsigned long) cs); @@ -693,10 +684,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, for (i = 0; i < channels; ++i) { gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i); - if (!gigaset_initbcs(cs->bcs + i, cs, i)) { - err("could not allocate channel %d data", i); + if (!gigaset_initbcs(cs->bcs + i, cs, i)) goto error; - } } ++cs->cs_init; @@ -731,10 +720,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, make_valid(cs, VALID_ID); ++cs->cs_init; gig_dbg(DEBUG_INIT, "setting up hw"); - if (!cs->ops->initcshw(cs)) { - err("could not allocate device specific data"); + if (!cs->ops->initcshw(cs)) goto error; - } ++cs->cs_init; @@ -756,8 +743,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, mutex_unlock(&cs->mutex); return cs; -error: - mutex_unlock(&cs->mutex); +error: if (cs) + mutex_unlock(&cs->mutex); gig_dbg(DEBUG_INIT, "failed"); gigaset_freecs(cs); return NULL; @@ -1053,6 +1040,7 @@ void gigaset_freedriver(struct gigaset_driver *drv) spin_unlock_irqrestore(&driver_lock, flags); gigaset_if_freedriver(drv); + module_put(drv->owner); kfree(drv->cs); kfree(drv->flags); @@ -1084,6 +1072,10 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, if (!drv) return NULL; + if (!try_module_get(owner)) + goto out1; + + drv->cs = NULL; drv->have_tty = 0; drv->minor = minor; drv->minors = minors; @@ -1095,11 +1087,11 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, drv->cs = kmalloc(minors * sizeof *drv->cs, GFP_KERNEL); if (!drv->cs) - goto error; + goto out2; drv->flags = kmalloc(minors * sizeof *drv->flags, GFP_KERNEL); if (!drv->flags) - goto error; + goto out3; for (i = 0; i < minors; ++i) { drv->flags[i] = 0; @@ -1116,8 +1108,11 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, return drv; -error: +out3: kfree(drv->cs); +out2: + module_put(owner); +out1: kfree(drv); return NULL; } diff --git a/trunk/drivers/kvm/kvm.h b/trunk/drivers/kvm/kvm.h index 2db1ca4c6800..91e0c75aca8f 100644 --- a/trunk/drivers/kvm/kvm.h +++ b/trunk/drivers/kvm/kvm.h @@ -242,7 +242,6 @@ struct kvm_vcpu { u64 pdptrs[4]; /* pae */ u64 shadow_efer; u64 apic_base; - u64 ia32_misc_enable_msr; int nmsrs; struct vmx_msr_entry *guest_msrs; struct vmx_msr_entry *host_msrs; diff --git a/trunk/drivers/kvm/kvm_main.c b/trunk/drivers/kvm/kvm_main.c index b10972ed0c9f..be4651abe72c 100644 --- a/trunk/drivers/kvm/kvm_main.c +++ b/trunk/drivers/kvm/kvm_main.c @@ -1226,9 +1226,6 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) case MSR_IA32_APICBASE: data = vcpu->apic_base; break; - case MSR_IA32_MISC_ENABLE: - data = vcpu->ia32_misc_enable_msr; - break; #ifdef CONFIG_X86_64 case MSR_EFER: data = vcpu->shadow_efer; @@ -1300,9 +1297,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) case MSR_IA32_APICBASE: vcpu->apic_base = data; break; - case MSR_IA32_MISC_ENABLE: - vcpu->ia32_misc_enable_msr = data; - break; default: printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr); return 1; @@ -1606,10 +1600,6 @@ static u32 msrs_to_save[] = { static unsigned num_msrs_to_save; -static u32 emulated_msrs[] = { - MSR_IA32_MISC_ENABLE, -}; - static __init void kvm_init_msr_list(void) { u32 dummy[2]; @@ -1935,7 +1925,7 @@ static long kvm_dev_ioctl(struct file *filp, if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list)) goto out; n = msr_list.nmsrs; - msr_list.nmsrs = num_msrs_to_save + ARRAY_SIZE(emulated_msrs); + msr_list.nmsrs = num_msrs_to_save; if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list)) goto out; r = -E2BIG; @@ -1945,11 +1935,6 @@ static long kvm_dev_ioctl(struct file *filp, if (copy_to_user(user_msr_list->indices, &msrs_to_save, num_msrs_to_save * sizeof(u32))) goto out; - if (copy_to_user(user_msr_list->indices - + num_msrs_to_save * sizeof(u32), - &emulated_msrs, - ARRAY_SIZE(emulated_msrs) * sizeof(u32))) - goto out; r = 0; break; } diff --git a/trunk/drivers/kvm/mmu.c b/trunk/drivers/kvm/mmu.c index 22c426cd8cb2..c6f972914f08 100644 --- a/trunk/drivers/kvm/mmu.c +++ b/trunk/drivers/kvm/mmu.c @@ -143,7 +143,6 @@ static int dbg = 1; #define PFERR_PRESENT_MASK (1U << 0) #define PFERR_WRITE_MASK (1U << 1) #define PFERR_USER_MASK (1U << 2) -#define PFERR_FETCH_MASK (1U << 4) #define PT64_ROOT_LEVEL 4 #define PT32_ROOT_LEVEL 2 @@ -169,11 +168,6 @@ static int is_cpuid_PSE36(void) return 1; } -static int is_nx(struct kvm_vcpu *vcpu) -{ - return vcpu->shadow_efer & EFER_NX; -} - static int is_present_pte(unsigned long pte) { return pte & PT_PRESENT_MASK; @@ -998,6 +992,16 @@ static inline int fix_read_pf(u64 *shadow_ent) return 0; } +static int may_access(u64 pte, int write, int user) +{ + + if (user && !(pte & PT_USER_MASK)) + return 0; + if (write && !(pte & PT_WRITABLE_MASK)) + return 0; + return 1; +} + static void paging_free(struct kvm_vcpu *vcpu) { nonpaging_free(vcpu); diff --git a/trunk/drivers/kvm/paging_tmpl.h b/trunk/drivers/kvm/paging_tmpl.h index 149fa45fd9a5..6bc41950fbb3 100644 --- a/trunk/drivers/kvm/paging_tmpl.h +++ b/trunk/drivers/kvm/paging_tmpl.h @@ -63,15 +63,13 @@ struct guest_walker { pt_element_t *ptep; pt_element_t inherited_ar; gfn_t gfn; - u32 error_code; }; /* * Fetch a guest pte for a guest virtual address */ -static int FNAME(walk_addr)(struct guest_walker *walker, - struct kvm_vcpu *vcpu, gva_t addr, - int write_fault, int user_fault, int fetch_fault) +static void FNAME(walk_addr)(struct guest_walker *walker, + struct kvm_vcpu *vcpu, gva_t addr) { hpa_t hpa; struct kvm_memory_slot *slot; @@ -88,7 +86,7 @@ static int FNAME(walk_addr)(struct guest_walker *walker, walker->ptep = &vcpu->pdptrs[(addr >> 30) & 3]; root = *walker->ptep; if (!(root & PT_PRESENT_MASK)) - goto not_present; + return; --walker->level; } #endif @@ -113,23 +111,11 @@ static int FNAME(walk_addr)(struct guest_walker *walker, ASSERT(((unsigned long)walker->table & PAGE_MASK) == ((unsigned long)ptep & PAGE_MASK)); - if (!is_present_pte(*ptep)) - goto not_present; - - if (write_fault && !is_writeble_pte(*ptep)) - if (user_fault || is_write_protection(vcpu)) - goto access_error; - - if (user_fault && !(*ptep & PT_USER_MASK)) - goto access_error; - -#if PTTYPE == 64 - if (fetch_fault && is_nx(vcpu) && (*ptep & PT64_NX_MASK)) - goto access_error; -#endif + if (is_present_pte(*ptep) && !(*ptep & PT_ACCESSED_MASK)) + *ptep |= PT_ACCESSED_MASK; - if (!(*ptep & PT_ACCESSED_MASK)) - *ptep |= PT_ACCESSED_MASK; /* avoid rmw */ + if (!is_present_pte(*ptep)) + break; if (walker->level == PT_PAGE_TABLE_LEVEL) { walker->gfn = (*ptep & PT_BASE_ADDR_MASK) @@ -160,23 +146,6 @@ static int FNAME(walk_addr)(struct guest_walker *walker, } walker->ptep = ptep; pgprintk("%s: pte %llx\n", __FUNCTION__, (u64)*ptep); - return 1; - -not_present: - walker->error_code = 0; - goto err; - -access_error: - walker->error_code = PFERR_PRESENT_MASK; - -err: - if (write_fault) - walker->error_code |= PFERR_WRITE_MASK; - if (user_fault) - walker->error_code |= PFERR_USER_MASK; - if (fetch_fault) - walker->error_code |= PFERR_FETCH_MASK; - return 0; } static void FNAME(release_walker)(struct guest_walker *walker) @@ -378,8 +347,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code) { int write_fault = error_code & PFERR_WRITE_MASK; + int pte_present = error_code & PFERR_PRESENT_MASK; int user_fault = error_code & PFERR_USER_MASK; - int fetch_fault = error_code & PFERR_FETCH_MASK; struct guest_walker walker; u64 *shadow_pte; int fixed; @@ -396,20 +365,19 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, /* * Look up the shadow pte for the faulting address. */ - r = FNAME(walk_addr)(&walker, vcpu, addr, write_fault, user_fault, - fetch_fault); + FNAME(walk_addr)(&walker, vcpu, addr); + shadow_pte = FNAME(fetch)(vcpu, addr, &walker); /* * The page is not mapped by the guest. Let the guest handle it. */ - if (!r) { - pgprintk("%s: guest page fault\n", __FUNCTION__); - inject_page_fault(vcpu, addr, walker.error_code); + if (!shadow_pte) { + pgprintk("%s: not mapped\n", __FUNCTION__); + inject_page_fault(vcpu, addr, error_code); FNAME(release_walker)(&walker); return 0; } - shadow_pte = FNAME(fetch)(vcpu, addr, &walker); pgprintk("%s: shadow pte %p %llx\n", __FUNCTION__, shadow_pte, *shadow_pte); @@ -431,7 +399,22 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, * mmio: emulate if accessible, otherwise its a guest fault. */ if (is_io_pte(*shadow_pte)) { - return 1; + if (may_access(*shadow_pte, write_fault, user_fault)) + return 1; + pgprintk("%s: io work, no access\n", __FUNCTION__); + inject_page_fault(vcpu, addr, + error_code | PFERR_PRESENT_MASK); + kvm_mmu_audit(vcpu, "post page fault (io)"); + return 0; + } + + /* + * pte not present, guest page fault. + */ + if (pte_present && !fixed && !write_pt) { + inject_page_fault(vcpu, addr, error_code); + kvm_mmu_audit(vcpu, "post page fault (guest)"); + return 0; } ++kvm_stat.pf_fixed; @@ -446,7 +429,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr) pt_element_t guest_pte; gpa_t gpa; - FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0); + FNAME(walk_addr)(&walker, vcpu, vaddr); guest_pte = *walker.ptep; FNAME(release_walker)(&walker); diff --git a/trunk/drivers/kvm/svm.c b/trunk/drivers/kvm/svm.c index 9c70ff65e6b7..7397bfbbcb1c 100644 --- a/trunk/drivers/kvm/svm.c +++ b/trunk/drivers/kvm/svm.c @@ -502,7 +502,6 @@ static void init_vmcb(struct vmcb *vmcb) (1ULL << INTERCEPT_IOIO_PROT) | (1ULL << INTERCEPT_MSR_PROT) | (1ULL << INTERCEPT_TASK_SWITCH) | - (1ULL << INTERCEPT_SHUTDOWN) | (1ULL << INTERCEPT_VMRUN) | (1ULL << INTERCEPT_VMMCALL) | (1ULL << INTERCEPT_VMLOAD) | @@ -681,14 +680,14 @@ static void svm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) static void svm_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) { - dt->limit = vcpu->svm->vmcb->save.idtr.limit; - dt->base = vcpu->svm->vmcb->save.idtr.base; + dt->limit = vcpu->svm->vmcb->save.ldtr.limit; + dt->base = vcpu->svm->vmcb->save.ldtr.base; } static void svm_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) { - vcpu->svm->vmcb->save.idtr.limit = dt->limit; - vcpu->svm->vmcb->save.idtr.base = dt->base ; + vcpu->svm->vmcb->save.ldtr.limit = dt->limit; + vcpu->svm->vmcb->save.ldtr.base = dt->base ; } static void svm_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) @@ -893,19 +892,6 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 0; } -static int shutdown_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - /* - * VMCB is undefined after a SHUTDOWN intercept - * so reinitialize it. - */ - memset(vcpu->svm->vmcb, 0, PAGE_SIZE); - init_vmcb(vcpu->svm->vmcb); - - kvm_run->exit_reason = KVM_EXIT_SHUTDOWN; - return 0; -} - static int io_get_override(struct kvm_vcpu *vcpu, struct vmcb_seg **seg, int *addr_override) @@ -1263,7 +1249,6 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu, [SVM_EXIT_IOIO] = io_interception, [SVM_EXIT_MSR] = msr_interception, [SVM_EXIT_TASK_SWITCH] = task_switch_interception, - [SVM_EXIT_SHUTDOWN] = shutdown_interception, [SVM_EXIT_VMRUN] = invalid_op_interception, [SVM_EXIT_VMMCALL] = invalid_op_interception, [SVM_EXIT_VMLOAD] = invalid_op_interception, diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index 11108165e264..5432d07c074d 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -479,12 +479,9 @@ static int bitmap_read_sb(struct bitmap *bitmap) int err = -EINVAL; /* page 0 is the superblock, read it... */ - if (bitmap->file) { - loff_t isize = i_size_read(bitmap->file->f_mapping->host); - int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize; - - bitmap->sb_page = read_page(bitmap->file, 0, bitmap, bytes); - } else { + if (bitmap->file) + bitmap->sb_page = read_page(bitmap->file, 0, bitmap, PAGE_SIZE); + else { bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset, 0); } if (IS_ERR(bitmap->sb_page)) { @@ -880,8 +877,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) int count; /* unmap the old page, we're done with it */ if (index == num_pages-1) - count = bytes + sizeof(bitmap_super_t) - - index * PAGE_SIZE; + count = bytes - index * PAGE_SIZE; else count = PAGE_SIZE; if (index == 0) { diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index 3668b170ea68..fe7c56e10435 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -1116,8 +1116,7 @@ static int __bind(struct mapped_device *md, struct dm_table *t) if (size != get_capacity(md->disk)) memset(&md->geometry, 0, sizeof(md->geometry)); - if (md->suspended_bdev) - __set_size(md, size); + __set_size(md, size); if (size == 0) return 0; @@ -1265,11 +1264,6 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) if (!dm_suspended(md)) goto out; - /* without bdev, the device size cannot be changed */ - if (!md->suspended_bdev) - if (get_capacity(md->disk) != dm_table_get_size(table)) - goto out; - __unbind(md); r = __bind(md, table); @@ -1347,14 +1341,11 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) /* This does not get reverted if there's an error later. */ dm_table_presuspend_targets(map); - /* bdget() can stall if the pending I/Os are not flushed */ - if (!noflush) { - md->suspended_bdev = bdget_disk(md->disk, 0); - if (!md->suspended_bdev) { - DMWARN("bdget failed in dm_suspend"); - r = -ENOMEM; - goto flush_and_out; - } + md->suspended_bdev = bdget_disk(md->disk, 0); + if (!md->suspended_bdev) { + DMWARN("bdget failed in dm_suspend"); + r = -ENOMEM; + goto flush_and_out; } /* @@ -1482,10 +1473,8 @@ int dm_resume(struct mapped_device *md) unlock_fs(md); - if (md->suspended_bdev) { - bdput(md->suspended_bdev); - md->suspended_bdev = NULL; - } + bdput(md->suspended_bdev); + md->suspended_bdev = NULL; clear_bit(DMF_SUSPENDED, &md->flags); diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index e8807ea5377d..d1cb45f6d6a9 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -1633,8 +1633,7 @@ static void md_update_sb(mddev_t * mddev, int force_change) * and 'events' is odd, we can roll back to the previous clean state */ if (nospares && (mddev->in_sync && mddev->recovery_cp == MaxSector) - && (mddev->events & 1) - && mddev->events != 1) + && (mddev->events & 1)) mddev->events--; else { /* otherwise we have to go forward and ... */ @@ -3564,8 +3563,6 @@ static int get_bitmap_file(mddev_t * mddev, void __user * arg) char *ptr, *buf = NULL; int err = -ENOMEM; - md_allow_write(mddev); - file = kmalloc(sizeof(*file), GFP_KERNEL); if (!file) goto out; @@ -5034,33 +5031,6 @@ void md_write_end(mddev_t *mddev) } } -/* md_allow_write(mddev) - * Calling this ensures that the array is marked 'active' so that writes - * may proceed without blocking. It is important to call this before - * attempting a GFP_KERNEL allocation while holding the mddev lock. - * Must be called with mddev_lock held. - */ -void md_allow_write(mddev_t *mddev) -{ - if (!mddev->pers) - return; - if (mddev->ro) - return; - - spin_lock_irq(&mddev->write_lock); - if (mddev->in_sync) { - mddev->in_sync = 0; - set_bit(MD_CHANGE_CLEAN, &mddev->flags); - if (mddev->safemode_delay && - mddev->safemode == 0) - mddev->safemode = 1; - spin_unlock_irq(&mddev->write_lock); - md_update_sb(mddev, 0); - } else - spin_unlock_irq(&mddev->write_lock); -} -EXPORT_SYMBOL_GPL(md_allow_write); - static DECLARE_WAIT_QUEUE_HEAD(resync_wait); #define SYNC_MARKS 10 diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index 97ee870b265d..164b25dca101 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -1266,11 +1266,6 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) sbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset; sbio->bi_bdev = conf->mirrors[i].rdev->bdev; - for (j = 0; j < vcnt ; j++) - memcpy(page_address(sbio->bi_io_vec[j].bv_page), - page_address(pbio->bi_io_vec[j].bv_page), - PAGE_SIZE); - } } } @@ -2104,8 +2099,6 @@ static int raid1_reshape(mddev_t *mddev) return -EINVAL; } - md_allow_write(mddev); - raid_disks = mddev->raid_disks + mddev->delta_disks; if (raid_disks < conf->raid_disks) { diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index 467c16982d02..be008f034ada 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -405,8 +405,6 @@ static int resize_stripes(raid5_conf_t *conf, int newsize) if (newsize <= conf->pool_size) return 0; /* never bother to shrink */ - md_allow_write(conf->mddev); - /* Step 1 */ sc = kmem_cache_create(conf->cache_name[1-conf->active_name], sizeof(struct stripe_head)+(newsize-1)*sizeof(struct r5dev), @@ -2680,7 +2678,7 @@ static int chunk_aligned_read(request_queue_t *q, struct bio * raid_bio) mdk_rdev_t *rdev; if (!in_chunk_boundary(mddev, raid_bio)) { - PRINTK("chunk_aligned_read : non aligned\n"); + printk("chunk_aligned_read : non aligned\n"); return 0; } /* @@ -3252,7 +3250,6 @@ raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len) else break; } - md_allow_write(mddev); while (new > conf->max_nr_stripes) { if (grow_one_stripe(conf)) conf->max_nr_stripes++; diff --git a/trunk/drivers/rtc/rtc-sysfs.c b/trunk/drivers/rtc/rtc-sysfs.c index 2ddd0cf07140..9418a59fb368 100644 --- a/trunk/drivers/rtc/rtc-sysfs.c +++ b/trunk/drivers/rtc/rtc-sysfs.c @@ -78,7 +78,7 @@ static struct attribute_group rtc_attr_group = { .attrs = rtc_attrs, }; -static int rtc_sysfs_add_device(struct class_device *class_dev, +static int __devinit rtc_sysfs_add_device(struct class_device *class_dev, struct class_interface *class_intf) { int err; diff --git a/trunk/drivers/spi/pxa2xx_spi.c b/trunk/drivers/spi/pxa2xx_spi.c index 8b41f9cc2560..6ed3f1da9296 100644 --- a/trunk/drivers/spi/pxa2xx_spi.c +++ b/trunk/drivers/spi/pxa2xx_spi.c @@ -1169,9 +1169,8 @@ static int setup(struct spi_device *spi) spi->bits_per_word - 16 : spi->bits_per_word) | SSCR0_SSE | (spi->bits_per_word > 16 ? SSCR0_EDSS : 0); - chip->cr1 &= ~(SSCR1_SPO | SSCR1_SPH); - chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) ? SSCR1_SPH : 0) - | (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0); + chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) << 4) + | (((spi->mode & SPI_CPOL) != 0) << 3); /* NOTE: PXA25x_SSP _could_ use external clocking ... */ if (drv_data->ssp_type != PXA25x_SSP) diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index 6307428d2c94..270e6211c2e3 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -366,6 +366,7 @@ spi_alloc_master(struct device *dev, unsigned size) class_device_initialize(&master->cdev); master->cdev.class = &spi_master_class; + kobj_set_kset_s(&master->cdev, spi_master_class.subsys); master->cdev.dev = get_device(dev); spi_master_set_devdata(master, &master[1]); @@ -465,20 +466,14 @@ EXPORT_SYMBOL_GPL(spi_unregister_master); */ struct spi_master *spi_busnum_to_master(u16 bus_num) { - struct class_device *cdev; - struct spi_master *master = NULL; - struct spi_master *m; - - down(&spi_master_class.sem); - list_for_each_entry(cdev, &spi_master_class.children, node) { - m = container_of(cdev, struct spi_master, cdev); - if (m->bus_num == bus_num) { - master = spi_master_get(m); - break; - } - } - up(&spi_master_class.sem); - return master; + char name[9]; + struct kobject *bus; + + snprintf(name, sizeof name, "spi%u", bus_num); + bus = kset_find_obj(&spi_master_class.subsys.kset, name); + if (bus) + return container_of(bus, struct spi_master, cdev.kobj); + return NULL; } EXPORT_SYMBOL_GPL(spi_busnum_to_master); diff --git a/trunk/drivers/spi/spi_s3c24xx.c b/trunk/drivers/spi/spi_s3c24xx.c index 651379c51ae6..8ca08713528e 100644 --- a/trunk/drivers/spi/spi_s3c24xx.c +++ b/trunk/drivers/spi/spi_s3c24xx.c @@ -10,6 +10,9 @@ * */ + +//#define DEBUG + #include #include #include @@ -41,9 +44,6 @@ struct s3c24xx_spi { int len; int count; - int (*set_cs)(struct s3c2410_spi_info *spi, - int cs, int pol); - /* data buffers */ const unsigned char *tx; unsigned char *rx; @@ -64,11 +64,6 @@ static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev) return spi_master_get_devdata(sdev->master); } -static void s3c24xx_spi_gpiocs(struct s3c2410_spi_info *spi, int cs, int pol) -{ - s3c2410_gpio_setpin(spi->pin_cs, pol); -} - static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) { struct s3c24xx_spi *hw = to_hw(spi); @@ -77,7 +72,10 @@ static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) switch (value) { case BITBANG_CS_INACTIVE: - hw->pdata->set_cs(hw->pdata, spi->chip_select, cspol^1); + if (hw->pdata->set_cs) + hw->pdata->set_cs(hw->pdata, value, cspol); + else + s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol ^ 1); break; case BITBANG_CS_ACTIVE: @@ -98,9 +96,14 @@ static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) /* write new configration */ writeb(spcon, hw->regs + S3C2410_SPCON); - hw->pdata->set_cs(hw->pdata, spi->chip_select, cspol); + + if (hw->pdata->set_cs) + hw->pdata->set_cs(hw->pdata, value, cspol); + else + s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol); break; + } } @@ -327,12 +330,9 @@ static int s3c24xx_spi_probe(struct platform_device *pdev) /* setup any gpio we can */ if (!hw->pdata->set_cs) { - hw->set_cs = s3c24xx_spi_gpiocs; - s3c2410_gpio_setpin(hw->pdata->pin_cs, 1); s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT); - } else - hw->set_cs = hw->pdata->set_cs; + } /* register our spi controller */ diff --git a/trunk/fs/9p/error.c b/trunk/fs/9p/error.c index 0d7fa4e08812..ae91555c1558 100644 --- a/trunk/fs/9p/error.c +++ b/trunk/fs/9p/error.c @@ -83,7 +83,6 @@ int v9fs_errstr2errno(char *errstr, int len) if (errno == 0) { /* TODO: if error isn't found, add it dynamically */ - errstr[len] = 0; printk(KERN_ERR "%s: errstr :%s: not found\n", __FUNCTION__, errstr); errno = 1; diff --git a/trunk/fs/9p/fid.c b/trunk/fs/9p/fid.c index a9b6301a04fc..27507201f9e7 100644 --- a/trunk/fs/9p/fid.c +++ b/trunk/fs/9p/fid.c @@ -25,7 +25,6 @@ #include #include #include -#include #include "debug.h" #include "v9fs.h" @@ -85,7 +84,6 @@ struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid) new->iounit = 0; new->rdir_pos = 0; new->rdir_fcall = NULL; - init_MUTEX(&new->lock); INIT_LIST_HEAD(&new->list); return new; @@ -104,11 +102,11 @@ void v9fs_fid_destroy(struct v9fs_fid *fid) } /** - * v9fs_fid_lookup - return a locked fid from a dentry + * v9fs_fid_lookup - retrieve the right fid from a particular dentry * @dentry: dentry to look for fid in + * @type: intent of lookup (operation or traversal) * - * find a fid in the dentry, obtain its semaphore and return a reference to it. - * code calling lookup is responsible for releasing lock + * find a fid in the dentry * * TODO: only match fids that have the same uid as current user * @@ -126,68 +124,7 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) if (!return_fid) { dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n"); - return_fid = ERR_PTR(-EBADF); } - if(down_interruptible(&return_fid->lock)) - return ERR_PTR(-EINTR); - return return_fid; } - -/** - * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and release it - * @dentry: dentry to look for fid in - * - * find a fid in the dentry and then clone to a new private fid - * - * TODO: only match fids that have the same uid as current user - * - */ - -struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry) -{ - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); - struct v9fs_fid *base_fid, *new_fid = ERR_PTR(-EBADF); - struct v9fs_fcall *fcall = NULL; - int fid, err; - - base_fid = v9fs_fid_lookup(dentry); - - if(IS_ERR(base_fid)) - return base_fid; - - if(base_fid) { /* clone fid */ - fid = v9fs_get_idpool(&v9ses->fidpool); - if (fid < 0) { - eprintk(KERN_WARNING, "newfid fails!\n"); - new_fid = ERR_PTR(-ENOSPC); - goto Release_Fid; - } - - err = v9fs_t_walk(v9ses, base_fid->fid, fid, NULL, &fcall); - if (err < 0) { - dprintk(DEBUG_ERROR, "clone walk didn't work\n"); - v9fs_put_idpool(fid, &v9ses->fidpool); - new_fid = ERR_PTR(err); - goto Free_Fcall; - } - new_fid = v9fs_fid_create(v9ses, fid); - if (new_fid == NULL) { - dprintk(DEBUG_ERROR, "out of memory\n"); - new_fid = ERR_PTR(-ENOMEM); - } -Free_Fcall: - kfree(fcall); - } - -Release_Fid: - up(&base_fid->lock); - return new_fid; -} - -void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid) -{ - v9fs_t_clunk(v9ses, fid->fid); - v9fs_fid_destroy(fid); -} diff --git a/trunk/fs/9p/fid.h b/trunk/fs/9p/fid.h index 48fc170c26c8..aa974d6875c3 100644 --- a/trunk/fs/9p/fid.h +++ b/trunk/fs/9p/fid.h @@ -30,8 +30,6 @@ struct v9fs_fid { struct list_head list; /* list of fids associated with a dentry */ struct list_head active; /* XXX - debug */ - struct semaphore lock; - u32 fid; unsigned char fidopen; /* set when fid is opened */ unsigned char fidclunked; /* set when fid has already been clunked */ @@ -57,6 +55,3 @@ struct v9fs_fid *v9fs_fid_get_created(struct dentry *); void v9fs_fid_destroy(struct v9fs_fid *fid); struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *, int fid); int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry); -struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry); -void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid); - diff --git a/trunk/fs/9p/mux.c b/trunk/fs/9p/mux.c index 147ceef8e537..944273c3dbff 100644 --- a/trunk/fs/9p/mux.c +++ b/trunk/fs/9p/mux.c @@ -132,10 +132,8 @@ int v9fs_mux_global_init(void) v9fs_mux_poll_tasks[i].task = NULL; v9fs_mux_wq = create_workqueue("v9fs"); - if (!v9fs_mux_wq) { - printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n"); + if (!v9fs_mux_wq) return -ENOMEM; - } return 0; } diff --git a/trunk/fs/9p/v9fs.c b/trunk/fs/9p/v9fs.c index d9b561ba5e58..0b96fae8b479 100644 --- a/trunk/fs/9p/v9fs.c +++ b/trunk/fs/9p/v9fs.c @@ -457,19 +457,14 @@ static int __init init_v9fs(void) v9fs_error_init(); - printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); + printk(KERN_INFO "Installing v9fs 9P2000 file system support\n"); ret = v9fs_mux_global_init(); - if (ret) { - printk(KERN_WARNING "v9fs: starting mux failed\n"); + if (!ret) return ret; - } ret = register_filesystem(&v9fs_fs_type); - if (ret) { - printk(KERN_WARNING "v9fs: registering file system failed\n"); + if (!ret) v9fs_mux_global_exit(); - } - return ret; } diff --git a/trunk/fs/9p/vfs_file.c b/trunk/fs/9p/vfs_file.c index 9f17b0cacdd0..e86a07151280 100644 --- a/trunk/fs/9p/vfs_file.c +++ b/trunk/fs/9p/vfs_file.c @@ -55,22 +55,53 @@ int v9fs_file_open(struct inode *inode, struct file *file) struct v9fs_fid *vfid; struct v9fs_fcall *fcall = NULL; int omode; + int fid = V9FS_NOFID; int err; dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); - vfid = v9fs_fid_clone(file->f_path.dentry); - if (IS_ERR(vfid)) - return PTR_ERR(vfid); + vfid = v9fs_fid_lookup(file->f_path.dentry); + if (!vfid) { + dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); + return -EBADF; + } + + fid = v9fs_get_idpool(&v9ses->fidpool); + if (fid < 0) { + eprintk(KERN_WARNING, "newfid fails!\n"); + return -ENOSPC; + } + err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, &fcall); + if (err < 0) { + dprintk(DEBUG_ERROR, "rewalk didn't work\n"); + if (fcall && fcall->id == RWALK) + goto clunk_fid; + else { + v9fs_put_idpool(fid, &v9ses->fidpool); + goto free_fcall; + } + } + kfree(fcall); + + /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ + /* translate open mode appropriately */ omode = v9fs_uflags2omode(file->f_flags); - err = v9fs_t_open(v9ses, vfid->fid, omode, &fcall); + err = v9fs_t_open(v9ses, fid, omode, &fcall); if (err < 0) { PRINT_FCALL_ERROR("open failed", fcall); - goto Clunk_Fid; + goto clunk_fid; + } + + vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); + if (vfid == NULL) { + dprintk(DEBUG_ERROR, "out of memory\n"); + err = -ENOMEM; + goto clunk_fid; } file->private_data = vfid; + vfid->fid = fid; vfid->fidopen = 1; vfid->fidclunked = 0; vfid->iounit = fcall->params.ropen.iounit; @@ -81,8 +112,10 @@ int v9fs_file_open(struct inode *inode, struct file *file) return 0; -Clunk_Fid: - v9fs_fid_clunk(v9ses, vfid); +clunk_fid: + v9fs_t_clunk(v9ses, fid); + +free_fcall: kfree(fcall); return err; diff --git a/trunk/fs/9p/vfs_inode.c b/trunk/fs/9p/vfs_inode.c index 9109ba1d6969..18f26cdfd882 100644 --- a/trunk/fs/9p/vfs_inode.c +++ b/trunk/fs/9p/vfs_inode.c @@ -416,8 +416,12 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) sb = file_inode->i_sb; v9ses = v9fs_inode2v9ses(file_inode); v9fid = v9fs_fid_lookup(file); - if(IS_ERR(v9fid)) - return PTR_ERR(v9fid); + + if (!v9fid) { + dprintk(DEBUG_ERROR, + "no v9fs_fid\n"); + return -EBADF; + } fid = v9fid->fid; if (fid < 0) { @@ -429,13 +433,11 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) result = v9fs_t_remove(v9ses, fid, &fcall); if (result < 0) { PRINT_FCALL_ERROR("remove fails", fcall); - goto Error; } v9fs_put_idpool(fid, &v9ses->fidpool); v9fs_fid_destroy(v9fid); -Error: kfree(fcall); return result; } @@ -471,13 +473,9 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, inode = NULL; vfid = NULL; v9ses = v9fs_inode2v9ses(dir); - dfid = v9fs_fid_clone(dentry->d_parent); - if(IS_ERR(dfid)) { - err = PTR_ERR(dfid); - goto error; - } - + dfid = v9fs_fid_lookup(dentry->d_parent); perm = unixmode2p9mode(v9ses, mode); + if (nd && nd->flags & LOOKUP_OPEN) flags = nd->intent.open.flags - 1; else @@ -487,10 +485,9 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, perm, v9fs_uflags2omode(flags), NULL, &fid, &qid, &iounit); if (err) - goto clunk_dfid; + goto error; vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); - v9fs_fid_clunk(v9ses, dfid); if (IS_ERR(vfid)) { err = PTR_ERR(vfid); vfid = NULL; @@ -528,9 +525,6 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, return 0; -clunk_dfid: - v9fs_fid_clunk(v9ses, dfid); - error: if (vfid) v9fs_fid_destroy(vfid); @@ -557,12 +551,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) inode = NULL; vfid = NULL; v9ses = v9fs_inode2v9ses(dir); - dfid = v9fs_fid_clone(dentry->d_parent); - if(IS_ERR(dfid)) { - err = PTR_ERR(dfid); - goto error; - } - + dfid = v9fs_fid_lookup(dentry->d_parent); perm = unixmode2p9mode(v9ses, mode | S_IFDIR); err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, @@ -570,36 +559,37 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (err) { dprintk(DEBUG_ERROR, "create error %d\n", err); - goto clean_up_dfid; + goto error; + } + + err = v9fs_t_clunk(v9ses, fid); + if (err) { + dprintk(DEBUG_ERROR, "clunk error %d\n", err); + goto error; } vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); if (IS_ERR(vfid)) { err = PTR_ERR(vfid); vfid = NULL; - goto clean_up_dfid; + goto error; } - v9fs_fid_clunk(v9ses, dfid); inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); if (IS_ERR(inode)) { err = PTR_ERR(inode); inode = NULL; - goto clean_up_fids; + goto error; } dentry->d_op = &v9fs_dentry_operations; d_instantiate(dentry, inode); return 0; -clean_up_fids: +error: if (vfid) v9fs_fid_destroy(vfid); -clean_up_dfid: - v9fs_fid_clunk(v9ses, dfid); - -error: return err; } @@ -632,23 +622,28 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, dentry->d_op = &v9fs_dentry_operations; dirfid = v9fs_fid_lookup(dentry->d_parent); - if(IS_ERR(dirfid)) - return ERR_PTR(PTR_ERR(dirfid)); + if (!dirfid) { + dprintk(DEBUG_ERROR, "no dirfid\n"); + return ERR_PTR(-EINVAL); + } dirfidnum = dirfid->fid; + if (dirfidnum < 0) { + dprintk(DEBUG_ERROR, "no dirfid for inode %p, #%lu\n", + dir, dir->i_ino); + return ERR_PTR(-EBADF); + } + newfid = v9fs_get_idpool(&v9ses->fidpool); if (newfid < 0) { eprintk(KERN_WARNING, "newfid fails!\n"); - result = -ENOSPC; - goto Release_Dirfid; + return ERR_PTR(-ENOSPC); } result = v9fs_t_walk(v9ses, dirfidnum, newfid, (char *)dentry->d_name.name, &fcall); - up(&dirfid->lock); - if (result < 0) { if (fcall && fcall->id == RWALK) v9fs_t_clunk(v9ses, newfid); @@ -706,12 +701,8 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, return NULL; -Release_Dirfid: - up(&dirfid->lock); - -FreeFcall: + FreeFcall: kfree(fcall); - return ERR_PTR(result); } @@ -755,8 +746,10 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *old_inode = old_dentry->d_inode; struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); - struct v9fs_fid *olddirfid; - struct v9fs_fid *newdirfid; + struct v9fs_fid *olddirfid = + v9fs_fid_lookup(old_dentry->d_parent); + struct v9fs_fid *newdirfid = + v9fs_fid_lookup(new_dentry->d_parent); struct v9fs_wstat wstat; struct v9fs_fcall *fcall = NULL; int fid = -1; @@ -766,26 +759,16 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, dprintk(DEBUG_VFS, "\n"); - if(IS_ERR(oldfid)) - return PTR_ERR(oldfid); - - olddirfid = v9fs_fid_clone(old_dentry->d_parent); - if(IS_ERR(olddirfid)) { - retval = PTR_ERR(olddirfid); - goto Release_lock; - } - - newdirfid = v9fs_fid_clone(new_dentry->d_parent); - if(IS_ERR(newdirfid)) { - retval = PTR_ERR(newdirfid); - goto Clunk_olddir; + if ((!oldfid) || (!olddirfid) || (!newdirfid)) { + dprintk(DEBUG_ERROR, "problem with arguments\n"); + return -EBADF; } /* 9P can only handle file rename in the same directory */ if (memcmp(&olddirfid->qid, &newdirfid->qid, sizeof(newdirfid->qid))) { dprintk(DEBUG_ERROR, "old dir and new dir are different\n"); - retval = -EXDEV; - goto Clunk_newdir; + retval = -EPERM; + goto FreeFcallnBail; } fid = oldfid->fid; @@ -796,7 +779,7 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, dprintk(DEBUG_ERROR, "no fid for old file #%lu\n", old_inode->i_ino); retval = -EBADF; - goto Clunk_newdir; + goto FreeFcallnBail; } v9fs_blank_wstat(&wstat); @@ -805,20 +788,11 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall); + FreeFcallnBail: if (retval < 0) PRINT_FCALL_ERROR("wstat error", fcall); kfree(fcall); - -Clunk_newdir: - v9fs_fid_clunk(v9ses, newdirfid); - -Clunk_olddir: - v9fs_fid_clunk(v9ses, olddirfid); - -Release_lock: - up(&oldfid->lock); - return retval; } @@ -836,12 +810,15 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, { struct v9fs_fcall *fcall = NULL; struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); - struct v9fs_fid *fid = v9fs_fid_clone(dentry); + struct v9fs_fid *fid = v9fs_fid_lookup(dentry); int err = -EPERM; dprintk(DEBUG_VFS, "dentry: %p\n", dentry); - if(IS_ERR(fid)) - return PTR_ERR(fid); + if (!fid) { + dprintk(DEBUG_ERROR, + "couldn't find fid associated with dentry\n"); + return -EBADF; + } err = v9fs_t_stat(v9ses, fid->fid, &fcall); @@ -854,7 +831,6 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, } kfree(fcall); - v9fs_fid_clunk(v9ses, fid); return err; } @@ -868,14 +844,18 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) { struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); - struct v9fs_fid *fid = v9fs_fid_clone(dentry); + struct v9fs_fid *fid = v9fs_fid_lookup(dentry); struct v9fs_fcall *fcall = NULL; struct v9fs_wstat wstat; int res = -EPERM; dprintk(DEBUG_VFS, "\n"); - if(IS_ERR(fid)) - return PTR_ERR(fid); + + if (!fid) { + dprintk(DEBUG_ERROR, + "Couldn't find fid associated with dentry\n"); + return -EBADF; + } v9fs_blank_wstat(&wstat); if (iattr->ia_valid & ATTR_MODE) @@ -907,7 +887,6 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) if (res >= 0) res = inode_setattr(dentry->d_inode, iattr); - v9fs_fid_clunk(v9ses, fid); return res; } @@ -1008,15 +987,18 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) struct v9fs_fcall *fcall = NULL; struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); - struct v9fs_fid *fid = v9fs_fid_clone(dentry); + struct v9fs_fid *fid = v9fs_fid_lookup(dentry); - if(IS_ERR(fid)) - return PTR_ERR(fid); + if (!fid) { + dprintk(DEBUG_ERROR, "could not resolve fid from dentry\n"); + retval = -EBADF; + goto FreeFcall; + } if (!v9ses->extended) { retval = -EBADF; dprintk(DEBUG_ERROR, "not extended\n"); - goto ClunkFid; + goto FreeFcall; } dprintk(DEBUG_VFS, " %s\n", dentry->d_name.name); @@ -1027,10 +1009,8 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) goto FreeFcall; } - if (!fcall) { - retval = -EIO; - goto ClunkFid; - } + if (!fcall) + return -EIO; if (!(fcall->params.rstat.stat.mode & V9FS_DMSYMLINK)) { retval = -EINVAL; @@ -1048,12 +1028,9 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) fcall->params.rstat.stat.extension.str, buffer); retval = buflen; -FreeFcall: + FreeFcall: kfree(fcall); -ClunkFid: - v9fs_fid_clunk(v9ses, fid); - return retval; } @@ -1146,58 +1123,52 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, int err; u32 fid, perm; struct v9fs_session_info *v9ses; - struct v9fs_fid *dfid, *vfid = NULL; - struct inode *inode = NULL; + struct v9fs_fid *dfid, *vfid; + struct inode *inode; + inode = NULL; + vfid = NULL; v9ses = v9fs_inode2v9ses(dir); + dfid = v9fs_fid_lookup(dentry->d_parent); + perm = unixmode2p9mode(v9ses, mode); + if (!v9ses->extended) { dprintk(DEBUG_ERROR, "not extended\n"); return -EPERM; } - dfid = v9fs_fid_clone(dentry->d_parent); - if(IS_ERR(dfid)) { - err = PTR_ERR(dfid); - goto error; - } - - perm = unixmode2p9mode(v9ses, mode); - err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL); if (err) - goto clunk_dfid; + goto error; err = v9fs_t_clunk(v9ses, fid); if (err) - goto clunk_dfid; + goto error; vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); if (IS_ERR(vfid)) { err = PTR_ERR(vfid); vfid = NULL; - goto clunk_dfid; + goto error; } inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); if (IS_ERR(inode)) { err = PTR_ERR(inode); inode = NULL; - goto free_vfid; + goto error; } dentry->d_op = &v9fs_dentry_operations; d_instantiate(dentry, inode); return 0; -free_vfid: - v9fs_fid_destroy(vfid); - -clunk_dfid: - v9fs_fid_clunk(v9ses, dfid); - error: + if (vfid) + v9fs_fid_destroy(vfid); + return err; } @@ -1238,29 +1209,26 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) { int retval; - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); struct v9fs_fid *oldfid; char *name; dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, old_dentry->d_name.name); - oldfid = v9fs_fid_clone(old_dentry); - if(IS_ERR(oldfid)) - return PTR_ERR(oldfid); + oldfid = v9fs_fid_lookup(old_dentry); + if (!oldfid) { + dprintk(DEBUG_ERROR, "can't find oldfid\n"); + return -EPERM; + } name = __getname(); - if (unlikely(!name)) { - retval = -ENOMEM; - goto clunk_fid; - } + if (unlikely(!name)) + return -ENOMEM; sprintf(name, "%d\n", oldfid->fid); retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); __putname(name); -clunk_fid: - v9fs_fid_clunk(v9ses, oldfid); return retval; } diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index 669dbe5b0317..7cb28720f90e 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -682,15 +682,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) retval = PTR_ERR(interpreter); if (IS_ERR(interpreter)) goto out_free_interp; - - /* - * If the binary is not readable then enforce - * mm->dumpable = 0 regardless of the interpreter's - * permissions. - */ - if (file_permission(interpreter, MAY_READ) < 0) - bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP; - retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE); if (retval != BINPRM_BUF_SIZE) { @@ -1187,10 +1178,6 @@ static int dump_seek(struct file *file, loff_t off) */ static int maydump(struct vm_area_struct *vma) { - /* The vma can be set up to tell us the answer directly. */ - if (vma->vm_flags & VM_ALWAYSDUMP) - return 1; - /* Do not dump I/O mapped devices or special mappings */ if (vma->vm_flags & (VM_IO | VM_RESERVED)) return 0; @@ -1437,32 +1424,6 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t) return sz; } -static struct vm_area_struct *first_vma(struct task_struct *tsk, - struct vm_area_struct *gate_vma) -{ - struct vm_area_struct *ret = tsk->mm->mmap; - - if (ret) - return ret; - return gate_vma; -} -/* - * Helper function for iterating across a vma list. It ensures that the caller - * will visit `gate_vma' prior to terminating the search. - */ -static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma, - struct vm_area_struct *gate_vma) -{ - struct vm_area_struct *ret; - - ret = this_vma->vm_next; - if (ret) - return ret; - if (this_vma == gate_vma) - return NULL; - return gate_vma; -} - /* * Actual dumper * @@ -1478,7 +1439,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) int segs; size_t size = 0; int i; - struct vm_area_struct *vma, *gate_vma; + struct vm_area_struct *vma; struct elfhdr *elf = NULL; loff_t offset = 0, dataoff, foffset; unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; @@ -1564,10 +1525,6 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) segs += ELF_CORE_EXTRA_PHDRS; #endif - gate_vma = get_gate_vma(current); - if (gate_vma != NULL) - segs++; - /* Set up header */ fill_elf_header(elf, segs + 1); /* including notes section */ @@ -1635,8 +1592,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); /* Write program headers for segments dump */ - for (vma = first_vma(current, gate_vma); vma != NULL; - vma = next_vma(vma, gate_vma)) { + for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { struct elf_phdr phdr; size_t sz; @@ -1685,8 +1641,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) /* Align to page */ DUMP_SEEK(dataoff - foffset); - for (vma = first_vma(current, gate_vma); vma != NULL; - vma = next_vma(vma, gate_vma)) { + for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { unsigned long addr; if (!maydump(vma)) diff --git a/trunk/fs/binfmt_elf_fdpic.c b/trunk/fs/binfmt_elf_fdpic.c index a4d933a51208..6e6d4568d548 100644 --- a/trunk/fs/binfmt_elf_fdpic.c +++ b/trunk/fs/binfmt_elf_fdpic.c @@ -234,14 +234,6 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, goto error; } - /* - * If the binary is not readable then enforce - * mm->dumpable = 0 regardless of the interpreter's - * permissions. - */ - if (file_permission(interpreter, MAY_READ) < 0) - bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP; - retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE); if (retval < 0) diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 460f1c43238e..3b116078b4c3 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -2834,7 +2834,7 @@ int try_to_free_buffers(struct page *page) int ret = 0; BUG_ON(!PageLocked(page)); - if (PageWriteback(page)) + if (PageDirty(page) || PageWriteback(page)) return 0; if (mapping == NULL) { /* can this still happen? */ @@ -2845,19 +2845,6 @@ int try_to_free_buffers(struct page *page) spin_lock(&mapping->private_lock); ret = drop_buffers(page, &buffers_to_free); spin_unlock(&mapping->private_lock); - - /* - * If the filesystem writes its buffers by hand (eg ext3) - * then we can have clean buffers against a dirty page. We - * clean the page here; otherwise the VM will never notice - * that the filesystem did any IO at all. - * - * Also, during truncate, discard_buffer will have marked all - * the page's buffers clean. We discover that here and clean - * the page also. - */ - if (ret) - cancel_dirty_page(page, PAGE_CACHE_SIZE); out: if (buffers_to_free) { struct buffer_head *bh = buffers_to_free; diff --git a/trunk/fs/fs-writeback.c b/trunk/fs/fs-writeback.c index a4b142a6a2c7..c403b66ec83c 100644 --- a/trunk/fs/fs-writeback.c +++ b/trunk/fs/fs-writeback.c @@ -251,19 +251,8 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) WARN_ON(inode->i_state & I_WILL_FREE); if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) { - struct address_space *mapping = inode->i_mapping; - int ret; - list_move(&inode->i_list, &inode->i_sb->s_dirty); - - /* - * Even if we don't actually write the inode itself here, - * we can at least start some of the data writeout.. - */ - spin_unlock(&inode_lock); - ret = do_writepages(mapping, wbc); - spin_lock(&inode_lock); - return ret; + return 0; } /* diff --git a/trunk/fs/nfsd/nfs3xdr.c b/trunk/fs/nfsd/nfs3xdr.c index e695660921ec..277df40f098d 100644 --- a/trunk/fs/nfsd/nfs3xdr.c +++ b/trunk/fs/nfsd/nfs3xdr.c @@ -990,16 +990,15 @@ encode_entry(struct readdir_cd *ccd, const char *name, } int -nfs3svc_encode_entry(void *cd, const char *name, - int namlen, loff_t offset, u64 ino, unsigned int d_type) +nfs3svc_encode_entry(struct readdir_cd *cd, const char *name, + int namlen, loff_t offset, ino_t ino, unsigned int d_type) { return encode_entry(cd, name, namlen, offset, ino, d_type, 0); } int -nfs3svc_encode_entry_plus(void *cd, const char *name, - int namlen, loff_t offset, u64 ino, - unsigned int d_type) +nfs3svc_encode_entry_plus(struct readdir_cd *cd, const char *name, + int namlen, loff_t offset, ino_t ino, unsigned int d_type) { return encode_entry(cd, name, namlen, offset, ino, d_type, 1); } diff --git a/trunk/fs/nfsd/nfs4xdr.c b/trunk/fs/nfsd/nfs4xdr.c index 18aa9440df14..fea46368afb2 100644 --- a/trunk/fs/nfsd/nfs4xdr.c +++ b/trunk/fs/nfsd/nfs4xdr.c @@ -1880,10 +1880,9 @@ nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr) } static int -nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, - loff_t offset, u64 ino, unsigned int d_type) +nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen, + loff_t offset, ino_t ino, unsigned int d_type) { - struct readdir_cd *ccd = ccdv; struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); int buflen; __be32 *p = cd->buffer; diff --git a/trunk/fs/nfsd/nfssvc.c b/trunk/fs/nfsd/nfssvc.c index fbf5d51947ea..0aaccb03bf76 100644 --- a/trunk/fs/nfsd/nfssvc.c +++ b/trunk/fs/nfsd/nfssvc.c @@ -72,7 +72,7 @@ static struct svc_program nfsd_acl_program = { .pg_prog = NFS_ACL_PROGRAM, .pg_nvers = NFSD_ACL_NRVERS, .pg_vers = nfsd_acl_versions, - .pg_name = "nfsacl", + .pg_name = "nfsd", .pg_class = "nfsd", .pg_stats = &nfsd_acl_svcstats, .pg_authenticate = &svc_set_client, @@ -118,16 +118,16 @@ int nfsd_vers(int vers, enum vers_op change) switch(change) { case NFSD_SET: nfsd_versions[vers] = nfsd_version[vers]; + break; #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) if (vers < NFSD_ACL_NRVERS) - nfsd_acl_versions[vers] = nfsd_acl_version[vers]; + nfsd_acl_version[vers] = nfsd_acl_version[vers]; #endif - break; case NFSD_CLEAR: nfsd_versions[vers] = NULL; #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) if (vers < NFSD_ACL_NRVERS) - nfsd_acl_versions[vers] = NULL; + nfsd_acl_version[vers] = NULL; #endif break; case NFSD_TEST: diff --git a/trunk/fs/nfsd/nfsxdr.c b/trunk/fs/nfsd/nfsxdr.c index 6555c50d9006..f5243f943996 100644 --- a/trunk/fs/nfsd/nfsxdr.c +++ b/trunk/fs/nfsd/nfsxdr.c @@ -462,10 +462,9 @@ nfssvc_encode_statfsres(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_encode_entry(void *ccdv, const char *name, - int namlen, loff_t offset, u64 ino, unsigned int d_type) +nfssvc_encode_entry(struct readdir_cd *ccd, const char *name, + int namlen, loff_t offset, ino_t ino, unsigned int d_type) { - struct readdir_cd *ccd = ccdv; struct nfsd_readdirres *cd = container_of(ccd, struct nfsd_readdirres, common); __be32 *p = cd->buffer; int buflen, slen; diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index 5d32e5fa697e..7a79c23aa6d4 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -822,8 +822,7 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset rqstp->rq_res.page_len = size; } else if (page != pp[-1]) { get_page(page); - if (*pp) - put_page(*pp); + put_page(*pp); *pp = page; rqstp->rq_resused++; rqstp->rq_res.page_len += size; @@ -1245,6 +1244,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, __be32 err; int host_err; __u32 v_mtime=0, v_atime=0; + int v_mode=0; err = nfserr_perm; if (!flen) @@ -1281,11 +1281,16 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, goto out; if (createmode == NFS3_CREATE_EXCLUSIVE) { - /* solaris7 gets confused (bugid 4218508) if these have - * the high bit set, so just clear the high bits. + /* while the verifier would fit in mtime+atime, + * solaris7 gets confused (bugid 4218508) if these have + * the high bit set, so we use the mode as well */ v_mtime = verifier[0]&0x7fffffff; v_atime = verifier[1]&0x7fffffff; + v_mode = S_IFREG + | ((verifier[0]&0x80000000) >> (32-7)) /* u+x */ + | ((verifier[1]&0x80000000) >> (32-9)) /* u+r */ + ; } if (dchild->d_inode) { @@ -1313,6 +1318,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, case NFS3_CREATE_EXCLUSIVE: if ( dchild->d_inode->i_mtime.tv_sec == v_mtime && dchild->d_inode->i_atime.tv_sec == v_atime + && dchild->d_inode->i_mode == v_mode && dchild->d_inode->i_size == 0 ) break; /* fallthru */ @@ -1334,22 +1340,26 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, } if (createmode == NFS3_CREATE_EXCLUSIVE) { - /* Cram the verifier into atime/mtime */ + /* Cram the verifier into atime/mtime/mode */ iap->ia_valid = ATTR_MTIME|ATTR_ATIME - | ATTR_MTIME_SET|ATTR_ATIME_SET; + | ATTR_MTIME_SET|ATTR_ATIME_SET + | ATTR_MODE; /* XXX someone who knows this better please fix it for nsec */ iap->ia_mtime.tv_sec = v_mtime; iap->ia_atime.tv_sec = v_atime; iap->ia_mtime.tv_nsec = 0; iap->ia_atime.tv_nsec = 0; + iap->ia_mode = v_mode; } /* Set file attributes. + * Mode has already been set but we might need to reset it + * for CREATE_EXCLUSIVE * Irix appears to send along the gid when it tries to * implement setgid directories via NFS. Clear out all that cruft. */ set_attr: - if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) { + if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) { __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); if (err2) err = err2; @@ -1716,7 +1726,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, */ __be32 nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, - struct readdir_cd *cdp, filldir_t func) + struct readdir_cd *cdp, encode_dent_fn func) { __be32 err; int host_err; @@ -1741,7 +1751,7 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, do { cdp->err = nfserr_eof; /* will be cleared on successful read */ - host_err = vfs_readdir(file, func, cdp); + host_err = vfs_readdir(file, (filldir_t) func, cdp); } while (host_err >=0 && cdp->err == nfs_ok); if (host_err) err = nfserrno(host_err); diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index ff7a66850602..77a57b5799c4 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -371,11 +371,9 @@ static int mounts_open(struct inode *inode, struct file *file) if (task) { task_lock(task); - if (task->nsproxy) { - ns = task->nsproxy->mnt_ns; - if (ns) - get_mnt_ns(ns); - } + ns = task->nsproxy->mnt_ns; + if (ns) + get_mnt_ns(ns); task_unlock(task); put_task_struct(task); } diff --git a/trunk/include/asm-generic/libata-portmap.h b/trunk/include/asm-generic/libata-portmap.h index 62fb3618293d..9202fd02d5be 100644 --- a/trunk/include/asm-generic/libata-portmap.h +++ b/trunk/include/asm-generic/libata-portmap.h @@ -3,10 +3,10 @@ #define ATA_PRIMARY_CMD 0x1F0 #define ATA_PRIMARY_CTL 0x3F6 -#define ATA_PRIMARY_IRQ(dev) 14 +#define ATA_PRIMARY_IRQ 14 #define ATA_SECONDARY_CMD 0x170 #define ATA_SECONDARY_CTL 0x376 -#define ATA_SECONDARY_IRQ(dev) 15 +#define ATA_SECONDARY_IRQ 15 #endif diff --git a/trunk/include/asm-i386/elf.h b/trunk/include/asm-i386/elf.h index 369035dfe4b6..45d21a0c95bf 100644 --- a/trunk/include/asm-i386/elf.h +++ b/trunk/include/asm-i386/elf.h @@ -143,9 +143,12 @@ extern int dump_task_extended_fpu (struct task_struct *, struct user_fxsr_struct # define VDSO_PRELINK 0 #endif -#define VDSO_SYM(x) \ +#define VDSO_COMPAT_SYM(x) \ (VDSO_COMPAT_BASE + (unsigned long)(x) - VDSO_PRELINK) +#define VDSO_SYM(x) \ + (VDSO_BASE + (unsigned long)(x) - VDSO_PRELINK) + #define VDSO_HIGH_EHDR ((const struct elfhdr *) VDSO_HIGH_BASE) #define VDSO_EHDR ((const struct elfhdr *) VDSO_COMPAT_BASE) @@ -153,12 +156,10 @@ extern void __kernel_vsyscall; #define VDSO_ENTRY VDSO_SYM(&__kernel_vsyscall) -#ifndef CONFIG_COMPAT_VDSO #define ARCH_HAS_SETUP_ADDITIONAL_PAGES struct linux_binprm; extern int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack); -#endif extern unsigned int vdso_enabled; @@ -168,6 +169,50 @@ do if (vdso_enabled) { \ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_COMPAT_BASE); \ } while (0) +/* + * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out + * extra segments containing the vsyscall DSO contents. Dumping its + * contents makes post-mortem fully interpretable later without matching up + * the same kernel and hardware config to see what PC values meant. + * Dumping its extra ELF program headers includes all the other information + * a debugger needs to easily find how the vsyscall DSO was being used. + */ +#define ELF_CORE_EXTRA_PHDRS (VDSO_HIGH_EHDR->e_phnum) +#define ELF_CORE_WRITE_EXTRA_PHDRS \ +do { \ + const struct elf_phdr *const vsyscall_phdrs = \ + (const struct elf_phdr *) (VDSO_HIGH_BASE \ + + VDSO_HIGH_EHDR->e_phoff); \ + int i; \ + Elf32_Off ofs = 0; \ + for (i = 0; i < VDSO_HIGH_EHDR->e_phnum; ++i) { \ + struct elf_phdr phdr = vsyscall_phdrs[i]; \ + if (phdr.p_type == PT_LOAD) { \ + BUG_ON(ofs != 0); \ + ofs = phdr.p_offset = offset; \ + phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \ + phdr.p_filesz = phdr.p_memsz; \ + offset += phdr.p_filesz; \ + } \ + else \ + phdr.p_offset += ofs; \ + phdr.p_paddr = 0; /* match other core phdrs */ \ + DUMP_WRITE(&phdr, sizeof(phdr)); \ + } \ +} while (0) +#define ELF_CORE_WRITE_EXTRA_DATA \ +do { \ + const struct elf_phdr *const vsyscall_phdrs = \ + (const struct elf_phdr *) (VDSO_HIGH_BASE \ + + VDSO_HIGH_EHDR->e_phoff); \ + int i; \ + for (i = 0; i < VDSO_HIGH_EHDR->e_phnum; ++i) { \ + if (vsyscall_phdrs[i].p_type == PT_LOAD) \ + DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr, \ + PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ + } \ +} while (0) + #endif #endif diff --git a/trunk/include/asm-i386/fixmap.h b/trunk/include/asm-i386/fixmap.h index 3e9f610c35df..02428cb36621 100644 --- a/trunk/include/asm-i386/fixmap.h +++ b/trunk/include/asm-i386/fixmap.h @@ -23,8 +23,6 @@ extern unsigned long __FIXADDR_TOP; #else #define __FIXADDR_TOP 0xfffff000 -#define FIXADDR_USER_START __fix_to_virt(FIX_VDSO) -#define FIXADDR_USER_END __fix_to_virt(FIX_VDSO - 1) #endif #ifndef __ASSEMBLY__ diff --git a/trunk/include/asm-i386/page.h b/trunk/include/asm-i386/page.h index 7b19f454761d..fd3f64ace248 100644 --- a/trunk/include/asm-i386/page.h +++ b/trunk/include/asm-i386/page.h @@ -143,9 +143,7 @@ extern int page_is_ram(unsigned long pagenr); #include #include -#ifndef CONFIG_COMPAT_VDSO #define __HAVE_ARCH_GATE_AREA 1 -#endif #endif /* __KERNEL__ */ #endif /* _I386_PAGE_H */ diff --git a/trunk/include/asm-powerpc/libata-portmap.h b/trunk/include/asm-powerpc/libata-portmap.h deleted file mode 100644 index 4d8518049f4d..000000000000 --- a/trunk/include/asm-powerpc/libata-portmap.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __ASM_POWERPC_LIBATA_PORTMAP_H -#define __ASM_POWERPC_LIBATA_PORTMAP_H - -#define ATA_PRIMARY_CMD 0x1F0 -#define ATA_PRIMARY_CTL 0x3F6 -#define ATA_PRIMARY_IRQ(dev) pci_get_legacy_ide_irq(dev, 0) - -#define ATA_SECONDARY_CMD 0x170 -#define ATA_SECONDARY_CTL 0x376 -#define ATA_SECONDARY_IRQ(dev) pci_get_legacy_ide_irq(dev, 1) - -#endif diff --git a/trunk/include/asm-x86_64/uaccess.h b/trunk/include/asm-x86_64/uaccess.h index c0eac519840b..d5dbc87274f8 100644 --- a/trunk/include/asm-x86_64/uaccess.h +++ b/trunk/include/asm-x86_64/uaccess.h @@ -157,7 +157,7 @@ do { \ case 1: __put_user_asm(x,ptr,retval,"b","b","iq",-EFAULT); break;\ case 2: __put_user_asm(x,ptr,retval,"w","w","ir",-EFAULT); break;\ case 4: __put_user_asm(x,ptr,retval,"l","k","ir",-EFAULT); break;\ - case 8: __put_user_asm(x,ptr,retval,"q","","Zr",-EFAULT); break;\ + case 8: __put_user_asm(x,ptr,retval,"q","","ir",-EFAULT); break;\ default: __put_user_bad(); \ } \ } while (0) diff --git a/trunk/include/linux/bitops.h b/trunk/include/linux/bitops.h index 638165f571da..5d1eabcde5d5 100644 --- a/trunk/include/linux/bitops.h +++ b/trunk/include/linux/bitops.h @@ -31,8 +31,9 @@ static inline unsigned long hweight_long(unsigned long w) return sizeof(w) == 4 ? hweight32(w) : hweight64(w); } -/** +/* * rol32 - rotate a 32-bit value left + * * @word: value to rotate * @shift: bits to roll */ @@ -41,8 +42,9 @@ static inline __u32 rol32(__u32 word, unsigned int shift) return (word << shift) | (word >> (32 - shift)); } -/** +/* * ror32 - rotate a 32-bit value right + * * @word: value to rotate * @shift: bits to roll */ diff --git a/trunk/include/linux/kvm.h b/trunk/include/linux/kvm.h index 1be148f0fce4..bc8b4616bad7 100644 --- a/trunk/include/linux/kvm.h +++ b/trunk/include/linux/kvm.h @@ -46,7 +46,6 @@ enum kvm_exit_reason { KVM_EXIT_HLT = 5, KVM_EXIT_MMIO = 6, KVM_EXIT_IRQ_WINDOW_OPEN = 7, - KVM_EXIT_SHUTDOWN = 8, }; /* for KVM_RUN */ diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index 22aa69e20905..f7f268e38749 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -177,7 +177,6 @@ enum { * Register FIS clearing BSY */ ATA_FLAG_DEBUGMSG = (1 << 13), ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */ - ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */ /* The following flag belongs to ap->pflags but is kept in * ap->flags because it's referenced in many LLDs and will be @@ -613,11 +612,11 @@ struct ata_port_operations { void (*dev_select)(struct ata_port *ap, unsigned int device); void (*phy_reset) (struct ata_port *ap); /* obsolete */ - int (*set_mode) (struct ata_port *ap, struct ata_device **r_failed_dev); + void (*set_mode) (struct ata_port *ap); void (*post_set_mode) (struct ata_port *ap); - int (*check_atapi_dma) (struct ata_queued_cmd *qc); + int (*check_atapi_dma) (struct ata_queued_cmd *qc); void (*bmdma_setup) (struct ata_queued_cmd *qc); void (*bmdma_start) (struct ata_queued_cmd *qc); diff --git a/trunk/include/linux/list.h b/trunk/include/linux/list.h index 611059d633f4..a9c90287c0ff 100644 --- a/trunk/include/linux/list.h +++ b/trunk/include/linux/list.h @@ -227,13 +227,13 @@ static inline void list_replace_init(struct list_head *old, INIT_LIST_HEAD(old); } -/** +/* * list_replace_rcu - replace old entry by new one * @old : the element to be replaced * @new : the new element to insert * - * The @old entry will be replaced with the @new entry atomically. - * Note: @old should not be empty. + * The old entry will be replaced with the new entry atomically. + * Note: 'old' should not be empty. */ static inline void list_replace_rcu(struct list_head *old, struct list_head *new) @@ -680,12 +680,12 @@ static inline void hlist_del_init(struct hlist_node *n) } } -/** +/* * hlist_replace_rcu - replace old entry by new one * @old : the element to be replaced * @new : the new element to insert * - * The @old entry will be replaced with the @new entry atomically. + * The old entry will be replaced with the new entry atomically. */ static inline void hlist_replace_rcu(struct hlist_node *old, struct hlist_node *new) diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 2d2c08d5f473..76912231af41 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -168,7 +168,6 @@ extern unsigned int kobjsize(const void *objp); #define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */ #define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */ #define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */ -#define VM_ALWAYSDUMP 0x04000000 /* Always include in core dumps */ #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS diff --git a/trunk/include/linux/mutex.h b/trunk/include/linux/mutex.h index b81bc2adaeff..a7544afd7582 100644 --- a/trunk/include/linux/mutex.h +++ b/trunk/include/linux/mutex.h @@ -105,7 +105,7 @@ do { \ extern void __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key); -/** +/*** * mutex_is_locked - is the mutex locked * @lock: the mutex to be queried * diff --git a/trunk/include/linux/nfsd/nfsd.h b/trunk/include/linux/nfsd/nfsd.h index 4b7c4b568f6d..0727774772ba 100644 --- a/trunk/include/linux/nfsd/nfsd.h +++ b/trunk/include/linux/nfsd/nfsd.h @@ -52,6 +52,8 @@ struct readdir_cd { __be32 err; /* 0, nfserr, or nfserr_eof */ }; +typedef int (*encode_dent_fn)(struct readdir_cd *, const char *, + int, loff_t, ino_t, unsigned int); typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int); extern struct svc_program nfsd_program; @@ -115,7 +117,7 @@ __be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, int nfsd_truncate(struct svc_rqst *, struct svc_fh *, unsigned long size); __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, - loff_t *, struct readdir_cd *, filldir_t); + loff_t *, struct readdir_cd *, encode_dent_fn); __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, struct kstatfs *); diff --git a/trunk/include/linux/nfsd/nfsfh.h b/trunk/include/linux/nfsd/nfsfh.h index d9c6c382165d..f3b51d62ec7d 100644 --- a/trunk/include/linux/nfsd/nfsfh.h +++ b/trunk/include/linux/nfsd/nfsfh.h @@ -217,7 +217,11 @@ void fh_put(struct svc_fh *); static __inline__ struct svc_fh * fh_copy(struct svc_fh *dst, struct svc_fh *src) { - WARN_ON(src->fh_dentry || src->fh_locked); + if (src->fh_dentry || src->fh_locked) { + struct dentry *dentry = src->fh_dentry; + printk(KERN_ERR "fh_copy: copying %s/%s, already verified!\n", + dentry->d_parent->d_name.name, dentry->d_name.name); + } *dst = *src; return dst; @@ -296,8 +300,10 @@ fh_lock_nested(struct svc_fh *fhp, unsigned int subclass) dfprintk(FILEOP, "nfsd: fh_lock(%s) locked = %d\n", SVCFH_fmt(fhp), fhp->fh_locked); - BUG_ON(!dentry); - + if (!fhp->fh_dentry) { + printk(KERN_ERR "fh_lock: fh not verified!\n"); + return; + } if (fhp->fh_locked) { printk(KERN_WARNING "fh_lock: %s/%s already locked!\n", dentry->d_parent->d_name.name, dentry->d_name.name); @@ -322,7 +328,8 @@ fh_lock(struct svc_fh *fhp) static inline void fh_unlock(struct svc_fh *fhp) { - BUG_ON(!fhp->fh_dentry); + if (!fhp->fh_dentry) + printk(KERN_ERR "fh_unlock: fh not verified!\n"); if (fhp->fh_locked) { fill_post_wcc(fhp); diff --git a/trunk/include/linux/nfsd/xdr.h b/trunk/include/linux/nfsd/xdr.h index 67885d5e6e50..877192d3ae79 100644 --- a/trunk/include/linux/nfsd/xdr.h +++ b/trunk/include/linux/nfsd/xdr.h @@ -165,8 +165,8 @@ int nfssvc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd_readres *); int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *, struct nfsd_statfsres *); int nfssvc_encode_readdirres(struct svc_rqst *, __be32 *, struct nfsd_readdirres *); -int nfssvc_encode_entry(void *, const char *name, - int namlen, loff_t offset, u64 ino, unsigned int); +int nfssvc_encode_entry(struct readdir_cd *, const char *name, + int namlen, loff_t offset, ino_t ino, unsigned int); int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); diff --git a/trunk/include/linux/nfsd/xdr3.h b/trunk/include/linux/nfsd/xdr3.h index 89d9d6061a62..79963867b0d7 100644 --- a/trunk/include/linux/nfsd/xdr3.h +++ b/trunk/include/linux/nfsd/xdr3.h @@ -331,11 +331,11 @@ int nfs3svc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd3_attrstat *); int nfs3svc_release_fhandle2(struct svc_rqst *, __be32 *, struct nfsd3_fhandle_pair *); -int nfs3svc_encode_entry(void *, const char *name, - int namlen, loff_t offset, u64 ino, +int nfs3svc_encode_entry(struct readdir_cd *, const char *name, + int namlen, loff_t offset, ino_t ino, unsigned int); -int nfs3svc_encode_entry_plus(void *, const char *name, - int namlen, loff_t offset, u64 ino, +int nfs3svc_encode_entry_plus(struct readdir_cd *, const char *name, + int namlen, loff_t offset, ino_t ino, unsigned int); /* Helper functions for NFSv3 ACL code */ __be32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, diff --git a/trunk/include/linux/raid/md.h b/trunk/include/linux/raid/md.h index fbaeda79b2e9..866a1e2b0ce0 100644 --- a/trunk/include/linux/raid/md.h +++ b/trunk/include/linux/raid/md.h @@ -94,7 +94,7 @@ extern int sync_page_io(struct block_device *bdev, sector_t sector, int size, struct page *page, int rw); extern void md_do_sync(mddev_t *mddev); extern void md_new_event(mddev_t *mddev); -extern void md_allow_write(mddev_t *mddev); + #endif /* CONFIG_MD */ #endif diff --git a/trunk/include/linux/rtmutex.h b/trunk/include/linux/rtmutex.h index 382bb7951166..b0090e9f7884 100644 --- a/trunk/include/linux/rtmutex.h +++ b/trunk/include/linux/rtmutex.h @@ -16,7 +16,7 @@ #include #include -/** +/* * The rt_mutex structure * * @wait_lock: spinlock to protect the structure @@ -71,7 +71,7 @@ struct hrtimer_sleeper; #define DEFINE_RT_MUTEX(mutexname) \ struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname) -/** +/*** * rt_mutex_is_locked - is the mutex locked * @lock: the mutex to be queried * diff --git a/trunk/include/linux/sunrpc/svc.h b/trunk/include/linux/sunrpc/svc.h index 64f3d60c72af..965d6c20086e 100644 --- a/trunk/include/linux/sunrpc/svc.h +++ b/trunk/include/linux/sunrpc/svc.h @@ -144,11 +144,8 @@ extern u32 svc_max_payload(const struct svc_rqst *rqstp); * * Each request/reply pair can have at most one "payload", plus two pages, * one for the request, and one for the reply. - * We using ->sendfile to return read data, we might need one extra page - * if the request is not page-aligned. So add another '1'. */ -#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE \ - + 2 + 1) +#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2) static inline u32 svc_getnl(struct kvec *iov) { diff --git a/trunk/include/linux/timer.h b/trunk/include/linux/timer.h index fb5edaaf0ebd..eeef6643d4c6 100644 --- a/trunk/include/linux/timer.h +++ b/trunk/include/linux/timer.h @@ -41,7 +41,7 @@ static inline void setup_timer(struct timer_list * timer, init_timer(timer); } -/** +/*** * timer_pending - is a timer pending? * @timer: the timer in question * @@ -63,7 +63,7 @@ extern int mod_timer(struct timer_list *timer, unsigned long expires); extern unsigned long next_timer_interrupt(void); -/** +/*** * add_timer - start a timer * @timer: the timer to be added * diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index ef09f0acb1d8..af227d26e104 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -2606,15 +2606,8 @@ static int __init gate_vma_init(void) gate_vma.vm_mm = NULL; gate_vma.vm_start = FIXADDR_USER_START; gate_vma.vm_end = FIXADDR_USER_END; - gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; - gate_vma.vm_page_prot = __P101; - /* - * Make sure the vDSO gets into every core dump. - * Dumping its contents makes post-mortem fully interpretable later - * without matching up the same kernel and hardware config to see - * what PC values meant. - */ - gate_vma.vm_flags |= VM_ALWAYSDUMP; + gate_vma.vm_page_prot = PAGE_READONLY; + gate_vma.vm_flags = 0; return 0; } __initcall(gate_vma_init); diff --git a/trunk/mm/truncate.c b/trunk/mm/truncate.c index 5df947de7654..6c79ca4a1ca7 100644 --- a/trunk/mm/truncate.c +++ b/trunk/mm/truncate.c @@ -51,22 +51,15 @@ static inline void truncate_partial_page(struct page *page, unsigned partial) do_invalidatepage(page, partial); } -/* - * This cancels just the dirty bit on the kernel page itself, it - * does NOT actually remove dirty bits on any mmap's that may be - * around. It also leaves the page tagged dirty, so any sync - * activity will still find it on the dirty lists, and in particular, - * clear_page_dirty_for_io() will still look at the dirty bits in - * the VM. - * - * Doing this should *normally* only ever be done when a page - * is truncated, and is not actually mapped anywhere at all. However, - * fs/buffer.c does this when it notices that somebody has cleaned - * out all the buffers on a page without actually doing it through - * the VM. Can you say "ext3 is horribly ugly"? Tought you could. - */ void cancel_dirty_page(struct page *page, unsigned int account_size) { + /* If we're cancelling the page, it had better not be mapped any more */ + if (page_mapped(page)) { + static unsigned int warncount; + + WARN_ON(++warncount < 5); + } + if (TestClearPageDirty(page)) { struct address_space *mapping = page->mapping; if (mapping && mapping_cap_account_dirty(mapping)) { @@ -429,6 +422,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping, pagevec_release(&pvec); cond_resched(); } + WARN_ON_ONCE(ret); return ret; } EXPORT_SYMBOL_GPL(invalidate_inode_pages2_range); diff --git a/trunk/net/ipv4/fib_trie.c b/trunk/net/ipv4/fib_trie.c index cfb249cc0a58..13307c04d5a1 100644 --- a/trunk/net/ipv4/fib_trie.c +++ b/trunk/net/ipv4/fib_trie.c @@ -1989,6 +1989,10 @@ static struct node *fib_trie_get_next(struct fib_trie_iter *iter) unsigned cindex = iter->index; struct tnode *p; + /* A single entry routing table */ + if (!tn) + return NULL; + pr_debug("get_next iter={node=%p index=%d depth=%d}\n", iter->tnode, iter->index, iter->depth); rescan: @@ -2037,11 +2041,18 @@ static struct node *fib_trie_get_first(struct fib_trie_iter *iter, if(!iter) return NULL; - if (n && IS_TNODE(n)) { - iter->tnode = (struct tnode *) n; - iter->trie = t; - iter->index = 0; - iter->depth = 1; + if (n) { + if (IS_TNODE(n)) { + iter->tnode = (struct tnode *) n; + iter->trie = t; + iter->index = 0; + iter->depth = 1; + } else { + iter->tnode = NULL; + iter->trie = t; + iter->index = 0; + iter->depth = 0; + } return n; } return NULL; diff --git a/trunk/net/sunrpc/svc.c b/trunk/net/sunrpc/svc.c index bf21a2047010..f3001f3626f6 100644 --- a/trunk/net/sunrpc/svc.c +++ b/trunk/net/sunrpc/svc.c @@ -910,8 +910,7 @@ svc_process(struct svc_rqst *rqstp) err_bad_vers: #ifdef RPC_PARANOIA - printk("svc: unknown version (%d for prog %d, %s)\n", - vers, prog, progp->pg_name); + printk("svc: unknown version (%d)\n", vers); #endif serv->sv_stats->rpcbadfmt++; svc_putnl(resv, RPC_PROG_MISMATCH); diff --git a/trunk/net/sunrpc/svcsock.c b/trunk/net/sunrpc/svcsock.c index 45120f268d03..99f54fb6d669 100644 --- a/trunk/net/sunrpc/svcsock.c +++ b/trunk/net/sunrpc/svcsock.c @@ -1278,8 +1278,6 @@ svc_recv(struct svc_rqst *rqstp, long timeout) schedule_timeout_uninterruptible(msecs_to_jiffies(500)); rqstp->rq_pages[i] = p; } - rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */ - BUG_ON(pages >= RPCSVC_MAXPAGES); /* Make arg->head point to first page and arg->pages point to rest */ arg = &rqstp->rq_arg;