diff options
81 files changed, 840 insertions, 539 deletions
diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt index 43b89c214d2..4d075a4558f 100644 --- a/Documentation/filesystems/9p.txt +++ b/Documentation/filesystems/9p.txt | |||
@@ -73,8 +73,22 @@ OPTIONS | |||
73 | RESOURCES | 73 | RESOURCES |
74 | ========= | 74 | ========= |
75 | 75 | ||
76 | The Linux version of the 9p server is now maintained under the npfs project | 76 | Our current recommendation is to use Inferno (http://www.vitanuova.com/inferno) |
77 | on sourceforge (http://sourceforge.net/projects/npfs). | 77 | as the 9p server. You can start a 9p server under Inferno by issuing the |
78 | following command: | ||
79 | ; styxlisten -A tcp!*!564 export '#U*' | ||
80 | |||
81 | The -A specifies an unauthenticated export. The 564 is the port # (you may | ||
82 | have to choose a higher port number if running as a normal user). The '#U*' | ||
83 | specifies exporting the root of the Linux name space. You may specify a | ||
84 | subset of the namespace by extending the path: '#U*'/tmp would just export | ||
85 | /tmp. For more information, see the Inferno manual pages covering styxlisten | ||
86 | and export. | ||
87 | |||
88 | A Linux version of the 9p server is now maintained under the npfs project | ||
89 | on sourceforge (http://sourceforge.net/projects/npfs). There is also a | ||
90 | more stable single-threaded version of the server (named spfs) available from | ||
91 | the same CVS repository. | ||
78 | 92 | ||
79 | There are user and developer mailing lists available through the v9fs project | 93 | There are user and developer mailing lists available through the v9fs project |
80 | on sourceforge (http://sourceforge.net/projects/v9fs). | 94 | on sourceforge (http://sourceforge.net/projects/v9fs). |
@@ -96,5 +110,5 @@ STATUS | |||
96 | 110 | ||
97 | The 2.6 kernel support is working on PPC and x86. | 111 | The 2.6 kernel support is working on PPC and x86. |
98 | 112 | ||
99 | PLEASE USE THE SOURCEFORGE BUG-TRACKER TO REPORT PROBLEMS. | 113 | PLEASE USE THE KERNEL BUGZILLA TO REPORT PROBLEMS. (http://bugzilla.kernel.org) |
100 | 114 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index d6f04a81f76..f0596e452c5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1137,9 +1137,9 @@ T: git kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git | |||
1137 | S: Maintained | 1137 | S: Maintained |
1138 | 1138 | ||
1139 | DSCC4 DRIVER | 1139 | DSCC4 DRIVER |
1140 | P: François Romieu | 1140 | P: Francois Romieu |
1141 | M: romieu@cogenit.fr | 1141 | M: romieu@fr.zoreil.com |
1142 | M: romieu@ensta.fr | 1142 | L: netdev@vger.kernel.org |
1143 | S: Maintained | 1143 | S: Maintained |
1144 | 1144 | ||
1145 | DVB SUBSYSTEM AND DRIVERS | 1145 | DVB SUBSYSTEM AND DRIVERS |
@@ -1928,11 +1928,10 @@ S: Maintained | |||
1928 | 1928 | ||
1929 | KERNEL NFSD | 1929 | KERNEL NFSD |
1930 | P: Neil Brown | 1930 | P: Neil Brown |
1931 | M: neilb@cse.unsw.edu.au | 1931 | M: neilb@suse.de |
1932 | L: nfs@lists.sourceforge.net | 1932 | L: nfs@lists.sourceforge.net |
1933 | W: http://nfs.sourceforge.net/ | 1933 | W: http://nfs.sourceforge.net/ |
1934 | W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/ | 1934 | S: Supported |
1935 | S: Maintained | ||
1936 | 1935 | ||
1937 | KERNEL VIRTUAL MACHINE (KVM) | 1936 | KERNEL VIRTUAL MACHINE (KVM) |
1938 | P: Avi Kivity | 1937 | P: Avi Kivity |
@@ -2993,9 +2992,9 @@ SOFTWARE RAID (Multiple Disks) SUPPORT | |||
2993 | P: Ingo Molnar | 2992 | P: Ingo Molnar |
2994 | M: mingo@redhat.com | 2993 | M: mingo@redhat.com |
2995 | P: Neil Brown | 2994 | P: Neil Brown |
2996 | M: neilb@cse.unsw.edu.au | 2995 | M: neilb@suse.de |
2997 | L: linux-raid@vger.kernel.org | 2996 | L: linux-raid@vger.kernel.org |
2998 | S: Maintained | 2997 | S: Supported |
2999 | 2998 | ||
3000 | SOFTWARE SUSPEND: | 2999 | SOFTWARE SUSPEND: |
3001 | P: Pavel Machek | 3000 | P: Pavel Machek |
@@ -3575,6 +3574,12 @@ M: khali@linux-fr.org | |||
3575 | L: i2c@lm-sensors.org | 3574 | L: i2c@lm-sensors.org |
3576 | S: Maintained | 3575 | S: Maintained |
3577 | 3576 | ||
3577 | VIA VELOCITY NETWORK DRIVER | ||
3578 | P: Francois Romieu | ||
3579 | M: romieu@fr.zoreil.com | ||
3580 | L: netdev@vger.kernel.org | ||
3581 | S: Maintained | ||
3582 | |||
3578 | UCLINUX (AND M68KNOMMU) | 3583 | UCLINUX (AND M68KNOMMU) |
3579 | P: Greg Ungerer | 3584 | P: Greg Ungerer |
3580 | M: gerg@uclinux.org | 3585 | M: gerg@uclinux.org |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 20 | 3 | SUBLEVEL = 20 |
4 | EXTRAVERSION =-rc5 | 4 | EXTRAVERSION =-rc6 |
5 | NAME = Homicidal Dwarf Hamster | 5 | NAME = Homicidal Dwarf Hamster |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 06461b8b715..5e47683fc63 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S | |||
@@ -302,12 +302,16 @@ sysenter_past_esp: | |||
302 | pushl $(__USER_CS) | 302 | pushl $(__USER_CS) |
303 | CFI_ADJUST_CFA_OFFSET 4 | 303 | CFI_ADJUST_CFA_OFFSET 4 |
304 | /*CFI_REL_OFFSET cs, 0*/ | 304 | /*CFI_REL_OFFSET cs, 0*/ |
305 | #ifndef CONFIG_COMPAT_VDSO | ||
305 | /* | 306 | /* |
306 | * Push current_thread_info()->sysenter_return to the stack. | 307 | * Push current_thread_info()->sysenter_return to the stack. |
307 | * A tiny bit of offset fixup is necessary - 4*4 means the 4 words | 308 | * A tiny bit of offset fixup is necessary - 4*4 means the 4 words |
308 | * pushed above; +8 corresponds to copy_thread's esp0 setting. | 309 | * pushed above; +8 corresponds to copy_thread's esp0 setting. |
309 | */ | 310 | */ |
310 | pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) | 311 | pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) |
312 | #else | ||
313 | pushl $SYSENTER_RETURN | ||
314 | #endif | ||
311 | CFI_ADJUST_CFA_OFFSET 4 | 315 | CFI_ADJUST_CFA_OFFSET 4 |
312 | CFI_REL_OFFSET eip, 0 | 316 | CFI_REL_OFFSET eip, 0 |
313 | 317 | ||
diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index 7de9117b5a3..5da744204d1 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c | |||
@@ -79,11 +79,6 @@ int __init sysenter_setup(void) | |||
79 | #ifdef CONFIG_COMPAT_VDSO | 79 | #ifdef CONFIG_COMPAT_VDSO |
80 | __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY); | 80 | __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY); |
81 | printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO)); | 81 | printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO)); |
82 | #else | ||
83 | /* | ||
84 | * In the non-compat case the ELF coredumping code needs the fixmap: | ||
85 | */ | ||
86 | __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_KERNEL_RO); | ||
87 | #endif | 82 | #endif |
88 | 83 | ||
89 | if (!boot_cpu_has(X86_FEATURE_SEP)) { | 84 | if (!boot_cpu_has(X86_FEATURE_SEP)) { |
@@ -100,6 +95,7 @@ int __init sysenter_setup(void) | |||
100 | return 0; | 95 | return 0; |
101 | } | 96 | } |
102 | 97 | ||
98 | #ifndef CONFIG_COMPAT_VDSO | ||
103 | static struct page *syscall_nopage(struct vm_area_struct *vma, | 99 | static struct page *syscall_nopage(struct vm_area_struct *vma, |
104 | unsigned long adr, int *type) | 100 | unsigned long adr, int *type) |
105 | { | 101 | { |
@@ -146,6 +142,13 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) | |||
146 | vma->vm_end = addr + PAGE_SIZE; | 142 | vma->vm_end = addr + PAGE_SIZE; |
147 | /* MAYWRITE to allow gdb to COW and set breakpoints */ | 143 | /* MAYWRITE to allow gdb to COW and set breakpoints */ |
148 | vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; | 144 | vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; |
145 | /* | ||
146 | * Make sure the vDSO gets into every core dump. | ||
147 | * Dumping its contents makes post-mortem fully interpretable later | ||
148 | * without matching up the same kernel and hardware config to see | ||
149 | * what PC values meant. | ||
150 | */ | ||
151 | vma->vm_flags |= VM_ALWAYSDUMP; | ||
149 | vma->vm_flags |= mm->def_flags; | 152 | vma->vm_flags |= mm->def_flags; |
150 | vma->vm_page_prot = protection_map[vma->vm_flags & 7]; | 153 | vma->vm_page_prot = protection_map[vma->vm_flags & 7]; |
151 | vma->vm_ops = &syscall_vm_ops; | 154 | vma->vm_ops = &syscall_vm_ops; |
@@ -187,3 +190,4 @@ int in_gate_area_no_task(unsigned long addr) | |||
187 | { | 190 | { |
188 | return 0; | 191 | return 0; |
189 | } | 192 | } |
193 | #endif | ||
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 0855d55c194..b268c417c0b 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -484,6 +484,7 @@ config PPC_MAPLE | |||
484 | select PPC_970_NAP | 484 | select PPC_970_NAP |
485 | select PPC_NATIVE | 485 | select PPC_NATIVE |
486 | select PPC_RTAS | 486 | select PPC_RTAS |
487 | select ATA_NONSTANDARD if ATA | ||
487 | default n | 488 | default n |
488 | help | 489 | help |
489 | This option enables support for the Maple 970FX Evaluation Board. | 490 | This option enables support for the Maple 970FX Evaluation Board. |
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index a4b28c73bba..ae0ede19879 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c | |||
@@ -284,6 +284,13 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, | |||
284 | * pages though | 284 | * pages though |
285 | */ | 285 | */ |
286 | vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC; | 286 | vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC; |
287 | /* | ||
288 | * Make sure the vDSO gets into every core dump. | ||
289 | * Dumping its contents makes post-mortem fully interpretable later | ||
290 | * without matching up the same kernel and hardware config to see | ||
291 | * what PC values meant. | ||
292 | */ | ||
293 | vma->vm_flags |= VM_ALWAYSDUMP; | ||
287 | vma->vm_flags |= mm->def_flags; | 294 | vma->vm_flags |= mm->def_flags; |
288 | vma->vm_page_prot = protection_map[vma->vm_flags & 0x7]; | 295 | vma->vm_page_prot = protection_map[vma->vm_flags & 0x7]; |
289 | vma->vm_ops = &vdso_vmops; | 296 | vma->vm_ops = &vdso_vmops; |
diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386 index f191a550a07..77558a88a2f 100644 --- a/arch/um/Kconfig.i386 +++ b/arch/um/Kconfig.i386 | |||
@@ -19,22 +19,22 @@ config SEMAPHORE_SLEEPERS | |||
19 | choice | 19 | choice |
20 | prompt "Host memory split" | 20 | prompt "Host memory split" |
21 | default HOST_VMSPLIT_3G | 21 | default HOST_VMSPLIT_3G |
22 | ---help--- | 22 | help |
23 | This is needed when the host kernel on which you run has a non-default | 23 | This is needed when the host kernel on which you run has a non-default |
24 | (like 2G/2G) memory split, instead of the customary 3G/1G. If you did | 24 | (like 2G/2G) memory split, instead of the customary 3G/1G. If you did |
25 | not recompile your own kernel but use the default distro's one, you can | 25 | not recompile your own kernel but use the default distro's one, you can |
26 | safely accept the "Default split" option. | 26 | safely accept the "Default split" option. |
27 | 27 | ||
28 | It can be enabled on recent (>=2.6.16-rc2) vanilla kernels via | 28 | It can be enabled on recent (>=2.6.16-rc2) vanilla kernels via |
29 | CONFIG_VM_SPLIT_*, or on previous kernels with special patches (-ck | 29 | CONFIG_VM_SPLIT_*, or on previous kernels with special patches (-ck |
30 | patchset by Con Kolivas, or other ones) - option names match closely the | 30 | patchset by Con Kolivas, or other ones) - option names match closely the |
31 | host CONFIG_VM_SPLIT_* ones. | 31 | host CONFIG_VM_SPLIT_* ones. |
32 | 32 | ||
33 | A lower setting (where 1G/3G is lowest and 3G/1G is higher) will | 33 | A lower setting (where 1G/3G is lowest and 3G/1G is higher) will |
34 | tolerate even more "normal" host kernels, but an higher setting will be | 34 | tolerate even more "normal" host kernels, but an higher setting will be |
35 | stricter. | 35 | stricter. |
36 | 36 | ||
37 | So, if you do not know what to do here, say 'Default split'. | 37 | So, if you do not know what to do here, say 'Default split'. |
38 | 38 | ||
39 | config HOST_VMSPLIT_3G | 39 | config HOST_VMSPLIT_3G |
40 | bool "Default split (3G/1G user/kernel host split)" | 40 | bool "Default split (3G/1G user/kernel host split)" |
@@ -67,13 +67,13 @@ config 3_LEVEL_PGTABLES | |||
67 | 67 | ||
68 | config STUB_CODE | 68 | config STUB_CODE |
69 | hex | 69 | hex |
70 | default 0xbfffe000 if !HOST_2G_2G | 70 | default 0xbfffe000 if !HOST_VMSPLIT_2G |
71 | default 0x7fffe000 if HOST_2G_2G | 71 | default 0x7fffe000 if HOST_VMSPLIT_2G |
72 | 72 | ||
73 | config STUB_DATA | 73 | config STUB_DATA |
74 | hex | 74 | hex |
75 | default 0xbffff000 if !HOST_2G_2G | 75 | default 0xbffff000 if !HOST_VMSPLIT_2G |
76 | default 0x7ffff000 if HOST_2G_2G | 76 | default 0x7ffff000 if HOST_VMSPLIT_2G |
77 | 77 | ||
78 | config STUB_START | 78 | config STUB_START |
79 | hex | 79 | hex |
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c index 543ef4f405e..5ce0bd486bb 100644 --- a/arch/x86_64/ia32/ia32_binfmt.c +++ b/arch/x86_64/ia32/ia32_binfmt.c | |||
@@ -64,55 +64,6 @@ typedef unsigned int elf_greg_t; | |||
64 | #define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t)) | 64 | #define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t)) |
65 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | 65 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; |
66 | 66 | ||
67 | /* | ||
68 | * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out | ||
69 | * extra segments containing the vsyscall DSO contents. Dumping its | ||
70 | * contents makes post-mortem fully interpretable later without matching up | ||
71 | * the same kernel and hardware config to see what PC values meant. | ||
72 | * Dumping its extra ELF program headers includes all the other information | ||
73 | * a debugger needs to easily find how the vsyscall DSO was being used. | ||
74 | */ | ||
75 | #define ELF_CORE_EXTRA_PHDRS (find_vma(current->mm, VSYSCALL32_BASE) ? \ | ||
76 | (VSYSCALL32_EHDR->e_phnum) : 0) | ||
77 | #define ELF_CORE_WRITE_EXTRA_PHDRS \ | ||
78 | do { \ | ||
79 | if (find_vma(current->mm, VSYSCALL32_BASE)) { \ | ||
80 | const struct elf32_phdr *const vsyscall_phdrs = \ | ||
81 | (const struct elf32_phdr *) (VSYSCALL32_BASE \ | ||
82 | + VSYSCALL32_EHDR->e_phoff);\ | ||
83 | int i; \ | ||
84 | Elf32_Off ofs = 0; \ | ||
85 | for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ | ||
86 | struct elf32_phdr phdr = vsyscall_phdrs[i]; \ | ||
87 | if (phdr.p_type == PT_LOAD) { \ | ||
88 | BUG_ON(ofs != 0); \ | ||
89 | ofs = phdr.p_offset = offset; \ | ||
90 | phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \ | ||
91 | phdr.p_filesz = phdr.p_memsz; \ | ||
92 | offset += phdr.p_filesz; \ | ||
93 | } \ | ||
94 | else \ | ||
95 | phdr.p_offset += ofs; \ | ||
96 | phdr.p_paddr = 0; /* match other core phdrs */ \ | ||
97 | DUMP_WRITE(&phdr, sizeof(phdr)); \ | ||
98 | } \ | ||
99 | } \ | ||
100 | } while (0) | ||
101 | #define ELF_CORE_WRITE_EXTRA_DATA \ | ||
102 | do { \ | ||
103 | if (find_vma(current->mm, VSYSCALL32_BASE)) { \ | ||
104 | const struct elf32_phdr *const vsyscall_phdrs = \ | ||
105 | (const struct elf32_phdr *) (VSYSCALL32_BASE \ | ||
106 | + VSYSCALL32_EHDR->e_phoff); \ | ||
107 | int i; \ | ||
108 | for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ | ||
109 | if (vsyscall_phdrs[i].p_type == PT_LOAD) \ | ||
110 | DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr,\ | ||
111 | PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ | ||
112 | } \ | ||
113 | } \ | ||
114 | } while (0) | ||
115 | |||
116 | struct elf_siginfo | 67 | struct elf_siginfo |
117 | { | 68 | { |
118 | int si_signo; /* signal number */ | 69 | int si_signo; /* signal number */ |
diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c index 3e5ed20cba4..59f1fa15591 100644 --- a/arch/x86_64/ia32/syscall32.c +++ b/arch/x86_64/ia32/syscall32.c | |||
@@ -59,6 +59,13 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) | |||
59 | vma->vm_end = VSYSCALL32_END; | 59 | vma->vm_end = VSYSCALL32_END; |
60 | /* MAYWRITE to allow gdb to COW and set breakpoints */ | 60 | /* MAYWRITE to allow gdb to COW and set breakpoints */ |
61 | vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; | 61 | vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; |
62 | /* | ||
63 | * Make sure the vDSO gets into every core dump. | ||
64 | * Dumping its contents makes post-mortem fully interpretable later | ||
65 | * without matching up the same kernel and hardware config to see | ||
66 | * what PC values meant. | ||
67 | */ | ||
68 | vma->vm_flags |= VM_ALWAYSDUMP; | ||
62 | vma->vm_flags |= mm->def_flags; | 69 | vma->vm_flags |= mm->def_flags; |
63 | vma->vm_page_prot = protection_map[vma->vm_flags & 7]; | 70 | vma->vm_page_prot = protection_map[vma->vm_flags & 7]; |
64 | vma->vm_ops = &syscall32_vm_ops; | 71 | vma->vm_ops = &syscall32_vm_ops; |
@@ -75,6 +82,14 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) | |||
75 | return 0; | 82 | return 0; |
76 | } | 83 | } |
77 | 84 | ||
85 | const char *arch_vma_name(struct vm_area_struct *vma) | ||
86 | { | ||
87 | if (vma->vm_start == VSYSCALL32_BASE && | ||
88 | vma->vm_mm && vma->vm_mm->task_size == IA32_PAGE_OFFSET) | ||
89 | return "[vdso]"; | ||
90 | return NULL; | ||
91 | } | ||
92 | |||
78 | static int __init init_syscall32(void) | 93 | static int __init init_syscall32(void) |
79 | { | 94 | { |
80 | syscall32_page = (void *)get_zeroed_page(GFP_KERNEL); | 95 | syscall32_page = (void *)get_zeroed_page(GFP_KERNEL); |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 5207f9e4b44..cbb6f0814ce 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -322,10 +322,6 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr) | |||
322 | if (result) | 322 | if (result) |
323 | return result; | 323 | return result; |
324 | 324 | ||
325 | result = acpi_processor_get_platform_limit(pr); | ||
326 | if (result) | ||
327 | return result; | ||
328 | |||
329 | return 0; | 325 | return 0; |
330 | } | 326 | } |
331 | 327 | ||
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index da21552d2b1..1c94b43d2c9 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -19,6 +19,10 @@ config ATA | |||
19 | 19 | ||
20 | if ATA | 20 | if ATA |
21 | 21 | ||
22 | config ATA_NONSTANDARD | ||
23 | bool | ||
24 | default n | ||
25 | |||
22 | config SATA_AHCI | 26 | config SATA_AHCI |
23 | tristate "AHCI SATA support" | 27 | tristate "AHCI SATA support" |
24 | depends on PCI | 28 | depends on PCI |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index e3c7b312287..28a82e3403f 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -75,6 +75,7 @@ enum { | |||
75 | AHCI_CMD_CLR_BUSY = (1 << 10), | 75 | AHCI_CMD_CLR_BUSY = (1 << 10), |
76 | 76 | ||
77 | RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ | 77 | RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ |
78 | RX_FIS_SDB = 0x58, /* offset of SDB FIS data */ | ||
78 | RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */ | 79 | RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */ |
79 | 80 | ||
80 | board_ahci = 0, | 81 | board_ahci = 0, |
@@ -202,6 +203,10 @@ struct ahci_port_priv { | |||
202 | dma_addr_t cmd_tbl_dma; | 203 | dma_addr_t cmd_tbl_dma; |
203 | void *rx_fis; | 204 | void *rx_fis; |
204 | dma_addr_t rx_fis_dma; | 205 | dma_addr_t rx_fis_dma; |
206 | /* for NCQ spurious interrupt analysis */ | ||
207 | int ncq_saw_spurious_sdb_cnt; | ||
208 | unsigned int ncq_saw_d2h:1; | ||
209 | unsigned int ncq_saw_dmas:1; | ||
205 | }; | 210 | }; |
206 | 211 | ||
207 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); | 212 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); |
@@ -898,7 +903,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) | |||
898 | 903 | ||
899 | /* clear D2H reception area to properly wait for D2H FIS */ | 904 | /* clear D2H reception area to properly wait for D2H FIS */ |
900 | ata_tf_init(ap->device, &tf); | 905 | ata_tf_init(ap->device, &tf); |
901 | tf.command = 0xff; | 906 | tf.command = 0x80; |
902 | ata_tf_to_fis(&tf, d2h_fis, 0); | 907 | ata_tf_to_fis(&tf, d2h_fis, 0); |
903 | 908 | ||
904 | rc = sata_std_hardreset(ap, class); | 909 | rc = sata_std_hardreset(ap, class); |
@@ -1109,8 +1114,9 @@ static void ahci_host_intr(struct ata_port *ap) | |||
1109 | void __iomem *mmio = ap->host->mmio_base; | 1114 | void __iomem *mmio = ap->host->mmio_base; |
1110 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 1115 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); |
1111 | struct ata_eh_info *ehi = &ap->eh_info; | 1116 | struct ata_eh_info *ehi = &ap->eh_info; |
1117 | struct ahci_port_priv *pp = ap->private_data; | ||
1112 | u32 status, qc_active; | 1118 | u32 status, qc_active; |
1113 | int rc; | 1119 | int rc, known_irq = 0; |
1114 | 1120 | ||
1115 | status = readl(port_mmio + PORT_IRQ_STAT); | 1121 | status = readl(port_mmio + PORT_IRQ_STAT); |
1116 | writel(status, port_mmio + PORT_IRQ_STAT); | 1122 | writel(status, port_mmio + PORT_IRQ_STAT); |
@@ -1137,17 +1143,53 @@ static void ahci_host_intr(struct ata_port *ap) | |||
1137 | 1143 | ||
1138 | /* hmmm... a spurious interupt */ | 1144 | /* hmmm... a spurious interupt */ |
1139 | 1145 | ||
1140 | /* some devices send D2H reg with I bit set during NCQ command phase */ | 1146 | /* if !NCQ, ignore. No modern ATA device has broken HSM |
1141 | if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS)) | 1147 | * implementation for non-NCQ commands. |
1148 | */ | ||
1149 | if (!ap->sactive) | ||
1142 | return; | 1150 | return; |
1143 | 1151 | ||
1144 | /* ignore interim PIO setup fis interrupts */ | 1152 | if (status & PORT_IRQ_D2H_REG_FIS) { |
1145 | if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS)) | 1153 | if (!pp->ncq_saw_d2h) |
1146 | return; | 1154 | ata_port_printk(ap, KERN_INFO, |
1155 | "D2H reg with I during NCQ, " | ||
1156 | "this message won't be printed again\n"); | ||
1157 | pp->ncq_saw_d2h = 1; | ||
1158 | known_irq = 1; | ||
1159 | } | ||
1160 | |||
1161 | if (status & PORT_IRQ_DMAS_FIS) { | ||
1162 | if (!pp->ncq_saw_dmas) | ||
1163 | ata_port_printk(ap, KERN_INFO, | ||
1164 | "DMAS FIS during NCQ, " | ||
1165 | "this message won't be printed again\n"); | ||
1166 | pp->ncq_saw_dmas = 1; | ||
1167 | known_irq = 1; | ||
1168 | } | ||
1169 | |||
1170 | if (status & PORT_IRQ_SDB_FIS && | ||
1171 | pp->ncq_saw_spurious_sdb_cnt < 10) { | ||
1172 | /* SDB FIS containing spurious completions might be | ||
1173 | * dangerous, we need to know more about them. Print | ||
1174 | * more of it. | ||
1175 | */ | ||
1176 | const u32 *f = pp->rx_fis + RX_FIS_SDB; | ||
1177 | |||
1178 | ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ " | ||
1179 | "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n", | ||
1180 | readl(port_mmio + PORT_CMD_ISSUE), | ||
1181 | readl(port_mmio + PORT_SCR_ACT), | ||
1182 | le32_to_cpu(f[0]), le32_to_cpu(f[1]), | ||
1183 | pp->ncq_saw_spurious_sdb_cnt < 10 ? | ||
1184 | "" : ", shutting up"); | ||
1185 | |||
1186 | pp->ncq_saw_spurious_sdb_cnt++; | ||
1187 | known_irq = 1; | ||
1188 | } | ||
1147 | 1189 | ||
1148 | if (ata_ratelimit()) | 1190 | if (!known_irq) |
1149 | ata_port_printk(ap, KERN_INFO, "spurious interrupt " | 1191 | ata_port_printk(ap, KERN_INFO, "spurious interrupt " |
1150 | "(irq_stat 0x%x active_tag %d sactive 0x%x)\n", | 1192 | "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n", |
1151 | status, ap->active_tag, ap->sactive); | 1193 | status, ap->active_tag, ap->sactive); |
1152 | } | 1194 | } |
1153 | 1195 | ||
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 908751d27e7..24af56081b5 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c | |||
@@ -64,6 +64,7 @@ static void generic_error_handler(struct ata_port *ap) | |||
64 | /** | 64 | /** |
65 | * generic_set_mode - mode setting | 65 | * generic_set_mode - mode setting |
66 | * @ap: interface to set up | 66 | * @ap: interface to set up |
67 | * @unused: returned device on error | ||
67 | * | 68 | * |
68 | * Use a non standard set_mode function. We don't want to be tuned. | 69 | * Use a non standard set_mode function. We don't want to be tuned. |
69 | * The BIOS configured everything. Our job is not to fiddle. We | 70 | * The BIOS configured everything. Our job is not to fiddle. We |
@@ -71,7 +72,7 @@ static void generic_error_handler(struct ata_port *ap) | |||
71 | * and respect them. | 72 | * and respect them. |
72 | */ | 73 | */ |
73 | 74 | ||
74 | static void generic_set_mode(struct ata_port *ap) | 75 | static int generic_set_mode(struct ata_port *ap, struct ata_device **unused) |
75 | { | 76 | { |
76 | int dma_enabled = 0; | 77 | int dma_enabled = 0; |
77 | int i; | 78 | int i; |
@@ -82,7 +83,7 @@ static void generic_set_mode(struct ata_port *ap) | |||
82 | 83 | ||
83 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 84 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
84 | struct ata_device *dev = &ap->device[i]; | 85 | struct ata_device *dev = &ap->device[i]; |
85 | if (ata_dev_enabled(dev)) { | 86 | if (ata_dev_ready(dev)) { |
86 | /* We don't really care */ | 87 | /* We don't really care */ |
87 | dev->pio_mode = XFER_PIO_0; | 88 | dev->pio_mode = XFER_PIO_0; |
88 | dev->dma_mode = XFER_MW_DMA_0; | 89 | dev->dma_mode = XFER_MW_DMA_0; |
@@ -99,6 +100,7 @@ static void generic_set_mode(struct ata_port *ap) | |||
99 | } | 100 | } |
100 | } | 101 | } |
101 | } | 102 | } |
103 | return 0; | ||
102 | } | 104 | } |
103 | 105 | ||
104 | static struct scsi_host_template generic_sht = { | 106 | static struct scsi_host_template generic_sht = { |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 0d51d13b16b..a388a8df004 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -2431,18 +2431,8 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) | |||
2431 | int i, rc = 0, used_dma = 0, found = 0; | 2431 | int i, rc = 0, used_dma = 0, found = 0; |
2432 | 2432 | ||
2433 | /* has private set_mode? */ | 2433 | /* has private set_mode? */ |
2434 | if (ap->ops->set_mode) { | 2434 | if (ap->ops->set_mode) |
2435 | /* FIXME: make ->set_mode handle no device case and | 2435 | return ap->ops->set_mode(ap, r_failed_dev); |
2436 | * return error code and failing device on failure. | ||
2437 | */ | ||
2438 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | ||
2439 | if (ata_dev_ready(&ap->device[i])) { | ||
2440 | ap->ops->set_mode(ap); | ||
2441 | break; | ||
2442 | } | ||
2443 | } | ||
2444 | return 0; | ||
2445 | } | ||
2446 | 2436 | ||
2447 | /* step 1: calculate xfer_mask */ | 2437 | /* step 1: calculate xfer_mask */ |
2448 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 2438 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 623cec914c9..12c88c58803 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -827,7 +827,8 @@ void ata_bmdma_error_handler(struct ata_port *ap) | |||
827 | */ | 827 | */ |
828 | void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) | 828 | void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) |
829 | { | 829 | { |
830 | ata_bmdma_stop(qc); | 830 | if (qc->ap->ioaddr.bmdma_addr) |
831 | ata_bmdma_stop(qc); | ||
831 | } | 832 | } |
832 | 833 | ||
833 | #ifdef CONFIG_PCI | 834 | #ifdef CONFIG_PCI |
@@ -870,7 +871,8 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int | |||
870 | pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; | 871 | pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; |
871 | bmdma = pci_resource_start(pdev, 4); | 872 | bmdma = pci_resource_start(pdev, 4); |
872 | if (bmdma) { | 873 | if (bmdma) { |
873 | if (inb(bmdma + 2) & 0x80) | 874 | if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) && |
875 | (inb(bmdma + 2) & 0x80)) | ||
874 | probe_ent->_host_flags |= ATA_HOST_SIMPLEX; | 876 | probe_ent->_host_flags |= ATA_HOST_SIMPLEX; |
875 | probe_ent->port[p].bmdma_addr = bmdma; | 877 | probe_ent->port[p].bmdma_addr = bmdma; |
876 | } | 878 | } |
@@ -886,7 +888,8 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int | |||
886 | bmdma = pci_resource_start(pdev, 4); | 888 | bmdma = pci_resource_start(pdev, 4); |
887 | if (bmdma) { | 889 | if (bmdma) { |
888 | bmdma += 8; | 890 | bmdma += 8; |
889 | if(inb(bmdma + 2) & 0x80) | 891 | if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) && |
892 | (inb(bmdma + 2) & 0x80)) | ||
890 | probe_ent->_host_flags |= ATA_HOST_SIMPLEX; | 893 | probe_ent->_host_flags |= ATA_HOST_SIMPLEX; |
891 | probe_ent->port[p].bmdma_addr = bmdma; | 894 | probe_ent->port[p].bmdma_addr = bmdma; |
892 | } | 895 | } |
@@ -914,13 +917,14 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, | |||
914 | probe_ent->irq_flags = IRQF_SHARED; | 917 | probe_ent->irq_flags = IRQF_SHARED; |
915 | 918 | ||
916 | if (port_mask & ATA_PORT_PRIMARY) { | 919 | if (port_mask & ATA_PORT_PRIMARY) { |
917 | probe_ent->irq = ATA_PRIMARY_IRQ; | 920 | probe_ent->irq = ATA_PRIMARY_IRQ(pdev); |
918 | probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD; | 921 | probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD; |
919 | probe_ent->port[0].altstatus_addr = | 922 | probe_ent->port[0].altstatus_addr = |
920 | probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL; | 923 | probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL; |
921 | if (bmdma) { | 924 | if (bmdma) { |
922 | probe_ent->port[0].bmdma_addr = bmdma; | 925 | probe_ent->port[0].bmdma_addr = bmdma; |
923 | if (inb(bmdma + 2) & 0x80) | 926 | if ((!(port[0]->flags & ATA_FLAG_IGN_SIMPLEX)) && |
927 | (inb(bmdma + 2) & 0x80)) | ||
924 | probe_ent->_host_flags |= ATA_HOST_SIMPLEX; | 928 | probe_ent->_host_flags |= ATA_HOST_SIMPLEX; |
925 | } | 929 | } |
926 | ata_std_ports(&probe_ent->port[0]); | 930 | ata_std_ports(&probe_ent->port[0]); |
@@ -929,15 +933,16 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, | |||
929 | 933 | ||
930 | if (port_mask & ATA_PORT_SECONDARY) { | 934 | if (port_mask & ATA_PORT_SECONDARY) { |
931 | if (probe_ent->irq) | 935 | if (probe_ent->irq) |
932 | probe_ent->irq2 = ATA_SECONDARY_IRQ; | 936 | probe_ent->irq2 = ATA_SECONDARY_IRQ(pdev); |
933 | else | 937 | else |
934 | probe_ent->irq = ATA_SECONDARY_IRQ; | 938 | probe_ent->irq = ATA_SECONDARY_IRQ(pdev); |
935 | probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD; | 939 | probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD; |
936 | probe_ent->port[1].altstatus_addr = | 940 | probe_ent->port[1].altstatus_addr = |
937 | probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL; | 941 | probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL; |
938 | if (bmdma) { | 942 | if (bmdma) { |
939 | probe_ent->port[1].bmdma_addr = bmdma + 8; | 943 | probe_ent->port[1].bmdma_addr = bmdma + 8; |
940 | if (inb(bmdma + 10) & 0x80) | 944 | if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) && |
945 | (inb(bmdma + 10) & 0x80)) | ||
941 | probe_ent->_host_flags |= ATA_HOST_SIMPLEX; | 946 | probe_ent->_host_flags |= ATA_HOST_SIMPLEX; |
942 | } | 947 | } |
943 | ata_std_ports(&probe_ent->port[1]); | 948 | ata_std_ports(&probe_ent->port[1]); |
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 15841a56369..449162cbf93 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c | |||
@@ -197,7 +197,7 @@ static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
197 | static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) | 197 | static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) |
198 | { | 198 | { |
199 | static const u8 udma_data[] = { | 199 | static const u8 udma_data[] = { |
200 | 0x31, 0x21, 0x11, 0x25, 0x15, 0x05 | 200 | 0x30, 0x20, 0x10, 0x20, 0x10, 0x00 |
201 | }; | 201 | }; |
202 | static const u8 mwdma_data[] = { | 202 | static const u8 mwdma_data[] = { |
203 | 0x30, 0x20, 0x10 | 203 | 0x30, 0x20, 0x10 |
@@ -213,12 +213,21 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
213 | pci_read_config_byte(pdev, pciD, ®D); | 213 | pci_read_config_byte(pdev, pciD, ®D); |
214 | pci_read_config_byte(pdev, pciU, ®U); | 214 | pci_read_config_byte(pdev, pciU, ®U); |
215 | 215 | ||
216 | regD &= ~(0x20 << shift); | 216 | /* DMA bits off */ |
217 | regU &= ~(0x35 << shift); | 217 | regD &= ~(0x20 << adev->devno); |
218 | /* DMA control bits */ | ||
219 | regU &= ~(0x30 << shift); | ||
220 | /* DMA timing bits */ | ||
221 | regU &= ~(0x05 << adev->devno); | ||
218 | 222 | ||
219 | if (adev->dma_mode >= XFER_UDMA_0) | 223 | if (adev->dma_mode >= XFER_UDMA_0) { |
224 | /* Merge thge timing value */ | ||
220 | regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift; | 225 | regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift; |
221 | else | 226 | /* Merge the control bits */ |
227 | regU |= 1 << adev->devno; /* UDMA on */ | ||
228 | if (adev->dma_mode > 2) /* 15nS timing */ | ||
229 | regU |= 4 << adev->devno; | ||
230 | } else | ||
222 | regD |= mwdma_data[adev->dma_mode - XFER_MW_DMA_0] << shift; | 231 | regD |= mwdma_data[adev->dma_mode - XFER_MW_DMA_0] << shift; |
223 | 232 | ||
224 | regD |= 0x20 << adev->devno; | 233 | regD |= 0x20 << adev->devno; |
@@ -239,8 +248,8 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc) | |||
239 | struct ata_port *ap = qc->ap; | 248 | struct ata_port *ap = qc->ap; |
240 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 249 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
241 | u8 dma_intr; | 250 | u8 dma_intr; |
242 | int dma_reg = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; | 251 | int dma_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; |
243 | int dma_mask = ap->port_no ? ARTTIM2 : CFR; | 252 | int dma_reg = ap->port_no ? ARTTIM2 : CFR; |
244 | 253 | ||
245 | ata_bmdma_stop(qc); | 254 | ata_bmdma_stop(qc); |
246 | 255 | ||
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index f6817b4093a..886fab9aa62 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/libata.h> | 25 | #include <linux/libata.h> |
26 | 26 | ||
27 | #define DRV_NAME "pata_hpt3x2n" | 27 | #define DRV_NAME "pata_hpt3x2n" |
28 | #define DRV_VERSION "0.3" | 28 | #define DRV_VERSION "0.3.2" |
29 | 29 | ||
30 | enum { | 30 | enum { |
31 | HPT_PCI_FAST = (1 << 31), | 31 | HPT_PCI_FAST = (1 << 31), |
@@ -297,11 +297,11 @@ static int hpt3x2n_pair_idle(struct ata_port *ap) | |||
297 | return 0; | 297 | return 0; |
298 | } | 298 | } |
299 | 299 | ||
300 | static int hpt3x2n_use_dpll(struct ata_port *ap, int reading) | 300 | static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) |
301 | { | 301 | { |
302 | long flags = (long)ap->host->private_data; | 302 | long flags = (long)ap->host->private_data; |
303 | /* See if we should use the DPLL */ | 303 | /* See if we should use the DPLL */ |
304 | if (reading == 0) | 304 | if (writing) |
305 | return USE_DPLL; /* Needed for write */ | 305 | return USE_DPLL; /* Needed for write */ |
306 | if (flags & PCI66) | 306 | if (flags & PCI66) |
307 | return USE_DPLL; /* Needed at 66Mhz */ | 307 | return USE_DPLL; /* Needed at 66Mhz */ |
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 0b56ff3d1cf..e8afd486434 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c | |||
@@ -476,6 +476,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc) | |||
476 | /** | 476 | /** |
477 | * it821x_smart_set_mode - mode setting | 477 | * it821x_smart_set_mode - mode setting |
478 | * @ap: interface to set up | 478 | * @ap: interface to set up |
479 | * @unused: device that failed (error only) | ||
479 | * | 480 | * |
480 | * Use a non standard set_mode function. We don't want to be tuned. | 481 | * Use a non standard set_mode function. We don't want to be tuned. |
481 | * The BIOS configured everything. Our job is not to fiddle. We | 482 | * The BIOS configured everything. Our job is not to fiddle. We |
@@ -483,7 +484,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc) | |||
483 | * and respect them. | 484 | * and respect them. |
484 | */ | 485 | */ |
485 | 486 | ||
486 | static void it821x_smart_set_mode(struct ata_port *ap) | 487 | static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused) |
487 | { | 488 | { |
488 | int dma_enabled = 0; | 489 | int dma_enabled = 0; |
489 | int i; | 490 | int i; |
@@ -512,6 +513,7 @@ static void it821x_smart_set_mode(struct ata_port *ap) | |||
512 | } | 513 | } |
513 | } | 514 | } |
514 | } | 515 | } |
516 | return 0; | ||
515 | } | 517 | } |
516 | 518 | ||
517 | /** | 519 | /** |
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index cb8924109f5..23b8aab3ebd 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c | |||
@@ -23,9 +23,9 @@ | |||
23 | #include <scsi/scsi_host.h> | 23 | #include <scsi/scsi_host.h> |
24 | 24 | ||
25 | #define DRV_NAME "pata_ixp4xx_cf" | 25 | #define DRV_NAME "pata_ixp4xx_cf" |
26 | #define DRV_VERSION "0.1.1" | 26 | #define DRV_VERSION "0.1.1ac1" |
27 | 27 | ||
28 | static void ixp4xx_set_mode(struct ata_port *ap) | 28 | static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device *adev) |
29 | { | 29 | { |
30 | int i; | 30 | int i; |
31 | 31 | ||
@@ -38,6 +38,7 @@ static void ixp4xx_set_mode(struct ata_port *ap) | |||
38 | dev->flags |= ATA_DFLAG_PIO; | 38 | dev->flags |= ATA_DFLAG_PIO; |
39 | } | 39 | } |
40 | } | 40 | } |
41 | return 0; | ||
41 | } | 42 | } |
42 | 43 | ||
43 | static void ixp4xx_phy_reset(struct ata_port *ap) | 44 | static void ixp4xx_phy_reset(struct ata_port *ap) |
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index e7bf9d89c8e..581cb33c6f4 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -96,6 +96,7 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */ | |||
96 | /** | 96 | /** |
97 | * legacy_set_mode - mode setting | 97 | * legacy_set_mode - mode setting |
98 | * @ap: IDE interface | 98 | * @ap: IDE interface |
99 | * @unused: Device that failed when error is returned | ||
99 | * | 100 | * |
100 | * Use a non standard set_mode function. We don't want to be tuned. | 101 | * Use a non standard set_mode function. We don't want to be tuned. |
101 | * | 102 | * |
@@ -105,7 +106,7 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */ | |||
105 | * expand on this as per hdparm in the base kernel. | 106 | * expand on this as per hdparm in the base kernel. |
106 | */ | 107 | */ |
107 | 108 | ||
108 | static void legacy_set_mode(struct ata_port *ap) | 109 | static int legacy_set_mode(struct ata_port *ap, struct ata_device **unused) |
109 | { | 110 | { |
110 | int i; | 111 | int i; |
111 | 112 | ||
@@ -118,6 +119,7 @@ static void legacy_set_mode(struct ata_port *ap) | |||
118 | dev->flags |= ATA_DFLAG_PIO; | 119 | dev->flags |= ATA_DFLAG_PIO; |
119 | } | 120 | } |
120 | } | 121 | } |
122 | return 0; | ||
121 | } | 123 | } |
122 | 124 | ||
123 | static struct scsi_host_template legacy_sht = { | 125 | static struct scsi_host_template legacy_sht = { |
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index adf4cc134f2..cec0729225e 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c | |||
@@ -52,19 +52,20 @@ static void rz1000_error_handler(struct ata_port *ap) | |||
52 | /** | 52 | /** |
53 | * rz1000_set_mode - mode setting function | 53 | * rz1000_set_mode - mode setting function |
54 | * @ap: ATA interface | 54 | * @ap: ATA interface |
55 | * @unused: returned device on set_mode failure | ||
55 | * | 56 | * |
56 | * Use a non standard set_mode function. We don't want to be tuned. We | 57 | * Use a non standard set_mode function. We don't want to be tuned. We |
57 | * would prefer to be BIOS generic but for the fact our hardware is | 58 | * would prefer to be BIOS generic but for the fact our hardware is |
58 | * whacked out. | 59 | * whacked out. |
59 | */ | 60 | */ |
60 | 61 | ||
61 | static void rz1000_set_mode(struct ata_port *ap) | 62 | static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused) |
62 | { | 63 | { |
63 | int i; | 64 | int i; |
64 | 65 | ||
65 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 66 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
66 | struct ata_device *dev = &ap->device[i]; | 67 | struct ata_device *dev = &ap->device[i]; |
67 | if (ata_dev_enabled(dev)) { | 68 | if (ata_dev_ready(dev)) { |
68 | /* We don't really care */ | 69 | /* We don't really care */ |
69 | dev->pio_mode = XFER_PIO_0; | 70 | dev->pio_mode = XFER_PIO_0; |
70 | dev->xfer_mode = XFER_PIO_0; | 71 | dev->xfer_mode = XFER_PIO_0; |
@@ -72,6 +73,7 @@ static void rz1000_set_mode(struct ata_port *ap) | |||
72 | dev->flags |= ATA_DFLAG_PIO; | 73 | dev->flags |= ATA_DFLAG_PIO; |
73 | } | 74 | } |
74 | } | 75 | } |
76 | return 0; | ||
75 | } | 77 | } |
76 | 78 | ||
77 | 79 | ||
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index 5c603ca3a50..a43aec62d50 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c | |||
@@ -128,7 +128,8 @@ static const struct ata_port_operations uli_ops = { | |||
128 | 128 | ||
129 | static struct ata_port_info uli_port_info = { | 129 | static struct ata_port_info uli_port_info = { |
130 | .sht = &uli_sht, | 130 | .sht = &uli_sht, |
131 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, | 131 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
132 | ATA_FLAG_IGN_SIMPLEX, | ||
132 | .pio_mask = 0x1f, /* pio0-4 */ | 133 | .pio_mask = 0x1f, /* pio0-4 */ |
133 | .udma_mask = 0x7f, /* udma0-6 */ | 134 | .udma_mask = 0x7f, /* udma0-6 */ |
134 | .port_ops = &uli_ops, | 135 | .port_ops = &uli_ops, |
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 88f0565c888..d3d5c0d5703 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c | |||
@@ -74,6 +74,7 @@ enum { | |||
74 | static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 74 | static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
75 | static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); | 75 | static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); |
76 | static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 76 | static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); |
77 | static void svia_noop_freeze(struct ata_port *ap); | ||
77 | static void vt6420_error_handler(struct ata_port *ap); | 78 | static void vt6420_error_handler(struct ata_port *ap); |
78 | 79 | ||
79 | static const struct pci_device_id svia_pci_tbl[] = { | 80 | static const struct pci_device_id svia_pci_tbl[] = { |
@@ -128,7 +129,7 @@ static const struct ata_port_operations vt6420_sata_ops = { | |||
128 | .qc_issue = ata_qc_issue_prot, | 129 | .qc_issue = ata_qc_issue_prot, |
129 | .data_xfer = ata_pio_data_xfer, | 130 | .data_xfer = ata_pio_data_xfer, |
130 | 131 | ||
131 | .freeze = ata_bmdma_freeze, | 132 | .freeze = svia_noop_freeze, |
132 | .thaw = ata_bmdma_thaw, | 133 | .thaw = ata_bmdma_thaw, |
133 | .error_handler = vt6420_error_handler, | 134 | .error_handler = vt6420_error_handler, |
134 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 135 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
@@ -204,6 +205,15 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | |||
204 | outl(val, ap->ioaddr.scr_addr + (4 * sc_reg)); | 205 | outl(val, ap->ioaddr.scr_addr + (4 * sc_reg)); |
205 | } | 206 | } |
206 | 207 | ||
208 | static void svia_noop_freeze(struct ata_port *ap) | ||
209 | { | ||
210 | /* Some VIA controllers choke if ATA_NIEN is manipulated in | ||
211 | * certain way. Leave it alone and just clear pending IRQ. | ||
212 | */ | ||
213 | ata_chk_status(ap); | ||
214 | ata_bmdma_irq_clear(ap); | ||
215 | } | ||
216 | |||
207 | /** | 217 | /** |
208 | * vt6420_prereset - prereset for vt6420 | 218 | * vt6420_prereset - prereset for vt6420 |
209 | * @ap: target ATA port | 219 | * @ap: target ATA port |
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 5ab5e393b88..c6281ccd4fe 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -122,8 +122,6 @@ struct efivar_entry { | |||
122 | struct kobject kobj; | 122 | struct kobject kobj; |
123 | }; | 123 | }; |
124 | 124 | ||
125 | #define get_efivar_entry(n) list_entry(n, struct efivar_entry, list) | ||
126 | |||
127 | struct efivar_attribute { | 125 | struct efivar_attribute { |
128 | struct attribute attr; | 126 | struct attribute attr; |
129 | ssize_t (*show) (struct efivar_entry *entry, char *buf); | 127 | ssize_t (*show) (struct efivar_entry *entry, char *buf); |
@@ -386,9 +384,6 @@ static struct sysfs_ops efivar_attr_ops = { | |||
386 | static void efivar_release(struct kobject *kobj) | 384 | static void efivar_release(struct kobject *kobj) |
387 | { | 385 | { |
388 | struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj); | 386 | struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj); |
389 | spin_lock(&efivars_lock); | ||
390 | list_del(&var->list); | ||
391 | spin_unlock(&efivars_lock); | ||
392 | kfree(var); | 387 | kfree(var); |
393 | } | 388 | } |
394 | 389 | ||
@@ -430,9 +425,8 @@ static ssize_t | |||
430 | efivar_create(struct subsystem *sub, const char *buf, size_t count) | 425 | efivar_create(struct subsystem *sub, const char *buf, size_t count) |
431 | { | 426 | { |
432 | struct efi_variable *new_var = (struct efi_variable *)buf; | 427 | struct efi_variable *new_var = (struct efi_variable *)buf; |
433 | struct efivar_entry *search_efivar = NULL; | 428 | struct efivar_entry *search_efivar, *n; |
434 | unsigned long strsize1, strsize2; | 429 | unsigned long strsize1, strsize2; |
435 | struct list_head *pos, *n; | ||
436 | efi_status_t status = EFI_NOT_FOUND; | 430 | efi_status_t status = EFI_NOT_FOUND; |
437 | int found = 0; | 431 | int found = 0; |
438 | 432 | ||
@@ -444,8 +438,7 @@ efivar_create(struct subsystem *sub, const char *buf, size_t count) | |||
444 | /* | 438 | /* |
445 | * Does this variable already exist? | 439 | * Does this variable already exist? |
446 | */ | 440 | */ |
447 | list_for_each_safe(pos, n, &efivar_list) { | 441 | list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { |
448 | search_efivar = get_efivar_entry(pos); | ||
449 | strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); | 442 | strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); |
450 | strsize2 = utf8_strsize(new_var->VariableName, 1024); | 443 | strsize2 = utf8_strsize(new_var->VariableName, 1024); |
451 | if (strsize1 == strsize2 && | 444 | if (strsize1 == strsize2 && |
@@ -490,9 +483,8 @@ static ssize_t | |||
490 | efivar_delete(struct subsystem *sub, const char *buf, size_t count) | 483 | efivar_delete(struct subsystem *sub, const char *buf, size_t count) |
491 | { | 484 | { |
492 | struct efi_variable *del_var = (struct efi_variable *)buf; | 485 | struct efi_variable *del_var = (struct efi_variable *)buf; |
493 | struct efivar_entry *search_efivar = NULL; | 486 | struct efivar_entry *search_efivar, *n; |
494 | unsigned long strsize1, strsize2; | 487 | unsigned long strsize1, strsize2; |
495 | struct list_head *pos, *n; | ||
496 | efi_status_t status = EFI_NOT_FOUND; | 488 | efi_status_t status = EFI_NOT_FOUND; |
497 | int found = 0; | 489 | int found = 0; |
498 | 490 | ||
@@ -504,8 +496,7 @@ efivar_delete(struct subsystem *sub, const char *buf, size_t count) | |||
504 | /* | 496 | /* |
505 | * Does this variable already exist? | 497 | * Does this variable already exist? |
506 | */ | 498 | */ |
507 | list_for_each_safe(pos, n, &efivar_list) { | 499 | list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { |
508 | search_efivar = get_efivar_entry(pos); | ||
509 | strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); | 500 | strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); |
510 | strsize2 = utf8_strsize(del_var->VariableName, 1024); | 501 | strsize2 = utf8_strsize(del_var->VariableName, 1024); |
511 | if (strsize1 == strsize2 && | 502 | if (strsize1 == strsize2 && |
@@ -537,9 +528,9 @@ efivar_delete(struct subsystem *sub, const char *buf, size_t count) | |||
537 | spin_unlock(&efivars_lock); | 528 | spin_unlock(&efivars_lock); |
538 | return -EIO; | 529 | return -EIO; |
539 | } | 530 | } |
531 | list_del(&search_efivar->list); | ||
540 | /* We need to release this lock before unregistering. */ | 532 | /* We need to release this lock before unregistering. */ |
541 | spin_unlock(&efivars_lock); | 533 | spin_unlock(&efivars_lock); |
542 | |||
543 | efivar_unregister(search_efivar); | 534 | efivar_unregister(search_efivar); |
544 | 535 | ||
545 | /* It's dead Jim.... */ | 536 | /* It's dead Jim.... */ |
@@ -768,10 +759,14 @@ out_free: | |||
768 | static void __exit | 759 | static void __exit |
769 | efivars_exit(void) | 760 | efivars_exit(void) |
770 | { | 761 | { |
771 | struct list_head *pos, *n; | 762 | struct efivar_entry *entry, *n; |
772 | 763 | ||
773 | list_for_each_safe(pos, n, &efivar_list) | 764 | list_for_each_entry_safe(entry, n, &efivar_list, list) { |
774 | efivar_unregister(get_efivar_entry(pos)); | 765 | spin_lock(&efivars_lock); |
766 | list_del(&entry->list); | ||
767 | spin_unlock(&efivars_lock); | ||
768 | efivar_unregister(entry); | ||
769 | } | ||
775 | 770 | ||
776 | subsystem_unregister(&vars_subsys); | 771 | subsystem_unregister(&vars_subsys); |
777 | firmware_unregister(&efi_subsys); | 772 | firmware_unregister(&efi_subsys); |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 95eff3b2917..4f75cce6fdf 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -356,16 +356,17 @@ static struct cardstate *alloc_cs(struct gigaset_driver *drv) | |||
356 | { | 356 | { |
357 | unsigned long flags; | 357 | unsigned long flags; |
358 | unsigned i; | 358 | unsigned i; |
359 | static struct cardstate *ret = NULL; | 359 | struct cardstate *ret = NULL; |
360 | 360 | ||
361 | spin_lock_irqsave(&drv->lock, flags); | 361 | spin_lock_irqsave(&drv->lock, flags); |
362 | for (i = 0; i < drv->minors; ++i) { | 362 | for (i = 0; i < drv->minors; ++i) { |
363 | if (!(drv->flags[i] & VALID_MINOR)) { | 363 | if (!(drv->flags[i] & VALID_MINOR)) { |
364 | drv->flags[i] = VALID_MINOR; | 364 | if (try_module_get(drv->owner)) { |
365 | ret = drv->cs + i; | 365 | drv->flags[i] = VALID_MINOR; |
366 | } | 366 | ret = drv->cs + i; |
367 | if (ret) | 367 | } |
368 | break; | 368 | break; |
369 | } | ||
369 | } | 370 | } |
370 | spin_unlock_irqrestore(&drv->lock, flags); | 371 | spin_unlock_irqrestore(&drv->lock, flags); |
371 | return ret; | 372 | return ret; |
@@ -376,6 +377,8 @@ static void free_cs(struct cardstate *cs) | |||
376 | unsigned long flags; | 377 | unsigned long flags; |
377 | struct gigaset_driver *drv = cs->driver; | 378 | struct gigaset_driver *drv = cs->driver; |
378 | spin_lock_irqsave(&drv->lock, flags); | 379 | spin_lock_irqsave(&drv->lock, flags); |
380 | if (drv->flags[cs->minor_index] & VALID_MINOR) | ||
381 | module_put(drv->owner); | ||
379 | drv->flags[cs->minor_index] = 0; | 382 | drv->flags[cs->minor_index] = 0; |
380 | spin_unlock_irqrestore(&drv->lock, flags); | 383 | spin_unlock_irqrestore(&drv->lock, flags); |
381 | } | 384 | } |
@@ -579,7 +582,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
579 | } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | 582 | } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) |
580 | skb_reserve(bcs->skb, HW_HDR_LEN); | 583 | skb_reserve(bcs->skb, HW_HDR_LEN); |
581 | else { | 584 | else { |
582 | warn("could not allocate skb\n"); | 585 | warn("could not allocate skb"); |
583 | bcs->inputstate |= INS_skip_frame; | 586 | bcs->inputstate |= INS_skip_frame; |
584 | } | 587 | } |
585 | 588 | ||
@@ -632,17 +635,25 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
632 | int i; | 635 | int i; |
633 | 636 | ||
634 | gig_dbg(DEBUG_INIT, "allocating cs"); | 637 | gig_dbg(DEBUG_INIT, "allocating cs"); |
635 | cs = alloc_cs(drv); | 638 | if (!(cs = alloc_cs(drv))) { |
636 | if (!cs) | 639 | err("maximum number of devices exceeded"); |
637 | goto error; | 640 | return NULL; |
641 | } | ||
642 | mutex_init(&cs->mutex); | ||
643 | mutex_lock(&cs->mutex); | ||
644 | |||
638 | gig_dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1); | 645 | gig_dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1); |
639 | cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); | 646 | cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); |
640 | if (!cs->bcs) | 647 | if (!cs->bcs) { |
648 | err("out of memory"); | ||
641 | goto error; | 649 | goto error; |
650 | } | ||
642 | gig_dbg(DEBUG_INIT, "allocating inbuf"); | 651 | gig_dbg(DEBUG_INIT, "allocating inbuf"); |
643 | cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL); | 652 | cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL); |
644 | if (!cs->inbuf) | 653 | if (!cs->inbuf) { |
654 | err("out of memory"); | ||
645 | goto error; | 655 | goto error; |
656 | } | ||
646 | 657 | ||
647 | cs->cs_init = 0; | 658 | cs->cs_init = 0; |
648 | cs->channels = channels; | 659 | cs->channels = channels; |
@@ -654,8 +665,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
654 | spin_lock_init(&cs->ev_lock); | 665 | spin_lock_init(&cs->ev_lock); |
655 | cs->ev_tail = 0; | 666 | cs->ev_tail = 0; |
656 | cs->ev_head = 0; | 667 | cs->ev_head = 0; |
657 | mutex_init(&cs->mutex); | ||
658 | mutex_lock(&cs->mutex); | ||
659 | 668 | ||
660 | tasklet_init(&cs->event_tasklet, &gigaset_handle_event, | 669 | tasklet_init(&cs->event_tasklet, &gigaset_handle_event, |
661 | (unsigned long) cs); | 670 | (unsigned long) cs); |
@@ -684,8 +693,10 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
684 | 693 | ||
685 | for (i = 0; i < channels; ++i) { | 694 | for (i = 0; i < channels; ++i) { |
686 | gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i); | 695 | gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i); |
687 | if (!gigaset_initbcs(cs->bcs + i, cs, i)) | 696 | if (!gigaset_initbcs(cs->bcs + i, cs, i)) { |
697 | err("could not allocate channel %d data", i); | ||
688 | goto error; | 698 | goto error; |
699 | } | ||
689 | } | 700 | } |
690 | 701 | ||
691 | ++cs->cs_init; | 702 | ++cs->cs_init; |
@@ -720,8 +731,10 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
720 | make_valid(cs, VALID_ID); | 731 | make_valid(cs, VALID_ID); |
721 | ++cs->cs_init; | 732 | ++cs->cs_init; |
722 | gig_dbg(DEBUG_INIT, "setting up hw"); | 733 | gig_dbg(DEBUG_INIT, "setting up hw"); |
723 | if (!cs->ops->initcshw(cs)) | 734 | if (!cs->ops->initcshw(cs)) { |
735 | err("could not allocate device specific data"); | ||
724 | goto error; | 736 | goto error; |
737 | } | ||
725 | 738 | ||
726 | ++cs->cs_init; | 739 | ++cs->cs_init; |
727 | 740 | ||
@@ -743,8 +756,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
743 | mutex_unlock(&cs->mutex); | 756 | mutex_unlock(&cs->mutex); |
744 | return cs; | 757 | return cs; |
745 | 758 | ||
746 | error: if (cs) | 759 | error: |
747 | mutex_unlock(&cs->mutex); | 760 | mutex_unlock(&cs->mutex); |
748 | gig_dbg(DEBUG_INIT, "failed"); | 761 | gig_dbg(DEBUG_INIT, "failed"); |
749 | gigaset_freecs(cs); | 762 | gigaset_freecs(cs); |
750 | return NULL; | 763 | return NULL; |
@@ -1040,7 +1053,6 @@ void gigaset_freedriver(struct gigaset_driver *drv) | |||
1040 | spin_unlock_irqrestore(&driver_lock, flags); | 1053 | spin_unlock_irqrestore(&driver_lock, flags); |
1041 | 1054 | ||
1042 | gigaset_if_freedriver(drv); | 1055 | gigaset_if_freedriver(drv); |
1043 | module_put(drv->owner); | ||
1044 | 1056 | ||
1045 | kfree(drv->cs); | 1057 | kfree(drv->cs); |
1046 | kfree(drv->flags); | 1058 | kfree(drv->flags); |
@@ -1072,10 +1084,6 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | |||
1072 | if (!drv) | 1084 | if (!drv) |
1073 | return NULL; | 1085 | return NULL; |
1074 | 1086 | ||
1075 | if (!try_module_get(owner)) | ||
1076 | goto out1; | ||
1077 | |||
1078 | drv->cs = NULL; | ||
1079 | drv->have_tty = 0; | 1087 | drv->have_tty = 0; |
1080 | drv->minor = minor; | 1088 | drv->minor = minor; |
1081 | drv->minors = minors; | 1089 | drv->minors = minors; |
@@ -1087,11 +1095,11 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | |||
1087 | 1095 | ||
1088 | drv->cs = kmalloc(minors * sizeof *drv->cs, GFP_KERNEL); | 1096 | drv->cs = kmalloc(minors * sizeof *drv->cs, GFP_KERNEL); |
1089 | if (!drv->cs) | 1097 | if (!drv->cs) |
1090 | goto out2; | 1098 | goto error; |
1091 | 1099 | ||
1092 | drv->flags = kmalloc(minors * sizeof *drv->flags, GFP_KERNEL); | 1100 | drv->flags = kmalloc(minors * sizeof *drv->flags, GFP_KERNEL); |
1093 | if (!drv->flags) | 1101 | if (!drv->flags) |
1094 | goto out3; | 1102 | goto error; |
1095 | 1103 | ||
1096 | for (i = 0; i < minors; ++i) { | 1104 | for (i = 0; i < minors; ++i) { |
1097 | drv->flags[i] = 0; | 1105 | drv->flags[i] = 0; |
@@ -1108,11 +1116,8 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | |||
1108 | 1116 | ||
1109 | return drv; | 1117 | return drv; |
1110 | 1118 | ||
1111 | out3: | 1119 | error: |
1112 | kfree(drv->cs); | 1120 | kfree(drv->cs); |
1113 | out2: | ||
1114 | module_put(owner); | ||
1115 | out1: | ||
1116 | kfree(drv); | 1121 | kfree(drv); |
1117 | return NULL; | 1122 | return NULL; |
1118 | } | 1123 | } |
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index 91e0c75aca8..2db1ca4c680 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h | |||
@@ -242,6 +242,7 @@ struct kvm_vcpu { | |||
242 | u64 pdptrs[4]; /* pae */ | 242 | u64 pdptrs[4]; /* pae */ |
243 | u64 shadow_efer; | 243 | u64 shadow_efer; |
244 | u64 apic_base; | 244 | u64 apic_base; |
245 | u64 ia32_misc_enable_msr; | ||
245 | int nmsrs; | 246 | int nmsrs; |
246 | struct vmx_msr_entry *guest_msrs; | 247 | struct vmx_msr_entry *guest_msrs; |
247 | struct vmx_msr_entry *host_msrs; | 248 | struct vmx_msr_entry *host_msrs; |
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index be4651abe72..b10972ed0c9 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -1226,6 +1226,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | |||
1226 | case MSR_IA32_APICBASE: | 1226 | case MSR_IA32_APICBASE: |
1227 | data = vcpu->apic_base; | 1227 | data = vcpu->apic_base; |
1228 | break; | 1228 | break; |
1229 | case MSR_IA32_MISC_ENABLE: | ||
1230 | data = vcpu->ia32_misc_enable_msr; | ||
1231 | break; | ||
1229 | #ifdef CONFIG_X86_64 | 1232 | #ifdef CONFIG_X86_64 |
1230 | case MSR_EFER: | 1233 | case MSR_EFER: |
1231 | data = vcpu->shadow_efer; | 1234 | data = vcpu->shadow_efer; |
@@ -1297,6 +1300,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) | |||
1297 | case MSR_IA32_APICBASE: | 1300 | case MSR_IA32_APICBASE: |
1298 | vcpu->apic_base = data; | 1301 | vcpu->apic_base = data; |
1299 | break; | 1302 | break; |
1303 | case MSR_IA32_MISC_ENABLE: | ||
1304 | vcpu->ia32_misc_enable_msr = data; | ||
1305 | break; | ||
1300 | default: | 1306 | default: |
1301 | printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr); | 1307 | printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr); |
1302 | return 1; | 1308 | return 1; |
@@ -1600,6 +1606,10 @@ static u32 msrs_to_save[] = { | |||
1600 | 1606 | ||
1601 | static unsigned num_msrs_to_save; | 1607 | static unsigned num_msrs_to_save; |
1602 | 1608 | ||
1609 | static u32 emulated_msrs[] = { | ||
1610 | MSR_IA32_MISC_ENABLE, | ||
1611 | }; | ||
1612 | |||
1603 | static __init void kvm_init_msr_list(void) | 1613 | static __init void kvm_init_msr_list(void) |
1604 | { | 1614 | { |
1605 | u32 dummy[2]; | 1615 | u32 dummy[2]; |
@@ -1925,7 +1935,7 @@ static long kvm_dev_ioctl(struct file *filp, | |||
1925 | if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list)) | 1935 | if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list)) |
1926 | goto out; | 1936 | goto out; |
1927 | n = msr_list.nmsrs; | 1937 | n = msr_list.nmsrs; |
1928 | msr_list.nmsrs = num_msrs_to_save; | 1938 | msr_list.nmsrs = num_msrs_to_save + ARRAY_SIZE(emulated_msrs); |
1929 | if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list)) | 1939 | if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list)) |
1930 | goto out; | 1940 | goto out; |
1931 | r = -E2BIG; | 1941 | r = -E2BIG; |
@@ -1935,6 +1945,11 @@ static long kvm_dev_ioctl(struct file *filp, | |||
1935 | if (copy_to_user(user_msr_list->indices, &msrs_to_save, | 1945 | if (copy_to_user(user_msr_list->indices, &msrs_to_save, |
1936 | num_msrs_to_save * sizeof(u32))) | 1946 | num_msrs_to_save * sizeof(u32))) |
1937 | goto out; | 1947 | goto out; |
1948 | if (copy_to_user(user_msr_list->indices | ||
1949 | + num_msrs_to_save * sizeof(u32), | ||
1950 | &emulated_msrs, | ||
1951 | ARRAY_SIZE(emulated_msrs) * sizeof(u32))) | ||
1952 | goto out; | ||
1938 | r = 0; | 1953 | r = 0; |
1939 | break; | 1954 | break; |
1940 | } | 1955 | } |
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c index c6f972914f0..22c426cd8cb 100644 --- a/drivers/kvm/mmu.c +++ b/drivers/kvm/mmu.c | |||
@@ -143,6 +143,7 @@ static int dbg = 1; | |||
143 | #define PFERR_PRESENT_MASK (1U << 0) | 143 | #define PFERR_PRESENT_MASK (1U << 0) |
144 | #define PFERR_WRITE_MASK (1U << 1) | 144 | #define PFERR_WRITE_MASK (1U << 1) |
145 | #define PFERR_USER_MASK (1U << 2) | 145 | #define PFERR_USER_MASK (1U << 2) |
146 | #define PFERR_FETCH_MASK (1U << 4) | ||
146 | 147 | ||
147 | #define PT64_ROOT_LEVEL 4 | 148 | #define PT64_ROOT_LEVEL 4 |
148 | #define PT32_ROOT_LEVEL 2 | 149 | #define PT32_ROOT_LEVEL 2 |
@@ -168,6 +169,11 @@ static int is_cpuid_PSE36(void) | |||
168 | return 1; | 169 | return 1; |
169 | } | 170 | } |
170 | 171 | ||
172 | static int is_nx(struct kvm_vcpu *vcpu) | ||
173 | { | ||
174 | return vcpu->shadow_efer & EFER_NX; | ||
175 | } | ||
176 | |||
171 | static int is_present_pte(unsigned long pte) | 177 | static int is_present_pte(unsigned long pte) |
172 | { | 178 | { |
173 | return pte & PT_PRESENT_MASK; | 179 | return pte & PT_PRESENT_MASK; |
@@ -992,16 +998,6 @@ static inline int fix_read_pf(u64 *shadow_ent) | |||
992 | return 0; | 998 | return 0; |
993 | } | 999 | } |
994 | 1000 | ||
995 | static int may_access(u64 pte, int write, int user) | ||
996 | { | ||
997 | |||
998 | if (user && !(pte & PT_USER_MASK)) | ||
999 | return 0; | ||
1000 | if (write && !(pte & PT_WRITABLE_MASK)) | ||
1001 | return 0; | ||
1002 | return 1; | ||
1003 | } | ||
1004 | |||
1005 | static void paging_free(struct kvm_vcpu *vcpu) | 1001 | static void paging_free(struct kvm_vcpu *vcpu) |
1006 | { | 1002 | { |
1007 | nonpaging_free(vcpu); | 1003 | nonpaging_free(vcpu); |
diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h index 6bc41950fbb..149fa45fd9a 100644 --- a/drivers/kvm/paging_tmpl.h +++ b/drivers/kvm/paging_tmpl.h | |||
@@ -63,13 +63,15 @@ struct guest_walker { | |||
63 | pt_element_t *ptep; | 63 | pt_element_t *ptep; |
64 | pt_element_t inherited_ar; | 64 | pt_element_t inherited_ar; |
65 | gfn_t gfn; | 65 | gfn_t gfn; |
66 | u32 error_code; | ||
66 | }; | 67 | }; |
67 | 68 | ||
68 | /* | 69 | /* |
69 | * Fetch a guest pte for a guest virtual address | 70 | * Fetch a guest pte for a guest virtual address |
70 | */ | 71 | */ |
71 | static void FNAME(walk_addr)(struct guest_walker *walker, | 72 | static int FNAME(walk_addr)(struct guest_walker *walker, |
72 | struct kvm_vcpu *vcpu, gva_t addr) | 73 | struct kvm_vcpu *vcpu, gva_t addr, |
74 | int write_fault, int user_fault, int fetch_fault) | ||
73 | { | 75 | { |
74 | hpa_t hpa; | 76 | hpa_t hpa; |
75 | struct kvm_memory_slot *slot; | 77 | struct kvm_memory_slot *slot; |
@@ -86,7 +88,7 @@ static void FNAME(walk_addr)(struct guest_walker *walker, | |||
86 | walker->ptep = &vcpu->pdptrs[(addr >> 30) & 3]; | 88 | walker->ptep = &vcpu->pdptrs[(addr >> 30) & 3]; |
87 | root = *walker->ptep; | 89 | root = *walker->ptep; |
88 | if (!(root & PT_PRESENT_MASK)) | 90 | if (!(root & PT_PRESENT_MASK)) |
89 | return; | 91 | goto not_present; |
90 | --walker->level; | 92 | --walker->level; |
91 | } | 93 | } |
92 | #endif | 94 | #endif |
@@ -111,11 +113,23 @@ static void FNAME(walk_addr)(struct guest_walker *walker, | |||
111 | ASSERT(((unsigned long)walker->table & PAGE_MASK) == | 113 | ASSERT(((unsigned long)walker->table & PAGE_MASK) == |
112 | ((unsigned long)ptep & PAGE_MASK)); | 114 | ((unsigned long)ptep & PAGE_MASK)); |
113 | 115 | ||
114 | if (is_present_pte(*ptep) && !(*ptep & PT_ACCESSED_MASK)) | ||
115 | *ptep |= PT_ACCESSED_MASK; | ||
116 | |||
117 | if (!is_present_pte(*ptep)) | 116 | if (!is_present_pte(*ptep)) |
118 | break; | 117 | goto not_present; |
118 | |||
119 | if (write_fault && !is_writeble_pte(*ptep)) | ||
120 | if (user_fault || is_write_protection(vcpu)) | ||
121 | goto access_error; | ||
122 | |||
123 | if (user_fault && !(*ptep & PT_USER_MASK)) | ||
124 | goto access_error; | ||
125 | |||
126 | #if PTTYPE == 64 | ||
127 | if (fetch_fault && is_nx(vcpu) && (*ptep & PT64_NX_MASK)) | ||
128 | goto access_error; | ||
129 | #endif | ||
130 | |||
131 | if (!(*ptep & PT_ACCESSED_MASK)) | ||
132 | *ptep |= PT_ACCESSED_MASK; /* avoid rmw */ | ||
119 | 133 | ||
120 | if (walker->level == PT_PAGE_TABLE_LEVEL) { | 134 | if (walker->level == PT_PAGE_TABLE_LEVEL) { |
121 | walker->gfn = (*ptep & PT_BASE_ADDR_MASK) | 135 | walker->gfn = (*ptep & PT_BASE_ADDR_MASK) |
@@ -146,6 +160,23 @@ static void FNAME(walk_addr)(struct guest_walker *walker, | |||
146 | } | 160 | } |
147 | walker->ptep = ptep; | 161 | walker->ptep = ptep; |
148 | pgprintk("%s: pte %llx\n", __FUNCTION__, (u64)*ptep); | 162 | pgprintk("%s: pte %llx\n", __FUNCTION__, (u64)*ptep); |
163 | return 1; | ||
164 | |||
165 | not_present: | ||
166 | walker->error_code = 0; | ||
167 | goto err; | ||
168 | |||
169 | access_error: | ||
170 | walker->error_code = PFERR_PRESENT_MASK; | ||
171 | |||
172 | err: | ||
173 | if (write_fault) | ||
174 | walker->error_code |= PFERR_WRITE_MASK; | ||
175 | if (user_fault) | ||
176 | walker->error_code |= PFERR_USER_MASK; | ||
177 | if (fetch_fault) | ||
178 | walker->error_code |= PFERR_FETCH_MASK; | ||
179 | return 0; | ||
149 | } | 180 | } |
150 | 181 | ||
151 | static void FNAME(release_walker)(struct guest_walker *walker) | 182 | static void FNAME(release_walker)(struct guest_walker *walker) |
@@ -347,8 +378,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, | |||
347 | u32 error_code) | 378 | u32 error_code) |
348 | { | 379 | { |
349 | int write_fault = error_code & PFERR_WRITE_MASK; | 380 | int write_fault = error_code & PFERR_WRITE_MASK; |
350 | int pte_present = error_code & PFERR_PRESENT_MASK; | ||
351 | int user_fault = error_code & PFERR_USER_MASK; | 381 | int user_fault = error_code & PFERR_USER_MASK; |
382 | int fetch_fault = error_code & PFERR_FETCH_MASK; | ||
352 | struct guest_walker walker; | 383 | struct guest_walker walker; |
353 | u64 *shadow_pte; | 384 | u64 *shadow_pte; |
354 | int fixed; | 385 | int fixed; |
@@ -365,19 +396,20 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, | |||
365 | /* | 396 | /* |
366 | * Look up the shadow pte for the faulting address. | 397 | * Look up the shadow pte for the faulting address. |
367 | */ | 398 | */ |
368 | FNAME(walk_addr)(&walker, vcpu, addr); | 399 | r = FNAME(walk_addr)(&walker, vcpu, addr, write_fault, user_fault, |
369 | shadow_pte = FNAME(fetch)(vcpu, addr, &walker); | 400 | fetch_fault); |
370 | 401 | ||
371 | /* | 402 | /* |
372 | * The page is not mapped by the guest. Let the guest handle it. | 403 | * The page is not mapped by the guest. Let the guest handle it. |
373 | */ | 404 | */ |
374 | if (!shadow_pte) { | 405 | if (!r) { |
375 | pgprintk("%s: not mapped\n", __FUNCTION__); | 406 | pgprintk("%s: guest page fault\n", __FUNCTION__); |
376 | inject_page_fault(vcpu, addr, error_code); | 407 | inject_page_fault(vcpu, addr, walker.error_code); |
377 | FNAME(release_walker)(&walker); | 408 | FNAME(release_walker)(&walker); |
378 | return 0; | 409 | return 0; |
379 | } | 410 | } |
380 | 411 | ||
412 | shadow_pte = FNAME(fetch)(vcpu, addr, &walker); | ||
381 | pgprintk("%s: shadow pte %p %llx\n", __FUNCTION__, | 413 | pgprintk("%s: shadow pte %p %llx\n", __FUNCTION__, |
382 | shadow_pte, *shadow_pte); | 414 | shadow_pte, *shadow_pte); |
383 | 415 | ||
@@ -399,22 +431,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, | |||
399 | * mmio: emulate if accessible, otherwise its a guest fault. | 431 | * mmio: emulate if accessible, otherwise its a guest fault. |
400 | */ | 432 | */ |
401 | if (is_io_pte(*shadow_pte)) { | 433 | if (is_io_pte(*shadow_pte)) { |
402 | if (may_access(*shadow_pte, write_fault, user_fault)) | 434 | return 1; |
403 | return 1; | ||
404 | pgprintk("%s: io work, no access\n", __FUNCTION__); | ||
405 | inject_page_fault(vcpu, addr, | ||
406 | error_code | PFERR_PRESENT_MASK); | ||
407 | kvm_mmu_audit(vcpu, "post page fault (io)"); | ||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | /* | ||
412 | * pte not present, guest page fault. | ||
413 | */ | ||
414 | if (pte_present && !fixed && !write_pt) { | ||
415 | inject_page_fault(vcpu, addr, error_code); | ||
416 | kvm_mmu_audit(vcpu, "post page fault (guest)"); | ||
417 | return 0; | ||
418 | } | 435 | } |
419 | 436 | ||
420 | ++kvm_stat.pf_fixed; | 437 | ++kvm_stat.pf_fixed; |
@@ -429,7 +446,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr) | |||
429 | pt_element_t guest_pte; | 446 | pt_element_t guest_pte; |
430 | gpa_t gpa; | 447 | gpa_t gpa; |
431 | 448 | ||
432 | FNAME(walk_addr)(&walker, vcpu, vaddr); | 449 | FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0); |
433 | guest_pte = *walker.ptep; | 450 | guest_pte = *walker.ptep; |
434 | FNAME(release_walker)(&walker); | 451 | FNAME(release_walker)(&walker); |
435 | 452 | ||
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 7397bfbbcb1..9c70ff65e6b 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c | |||
@@ -502,6 +502,7 @@ static void init_vmcb(struct vmcb *vmcb) | |||
502 | (1ULL << INTERCEPT_IOIO_PROT) | | 502 | (1ULL << INTERCEPT_IOIO_PROT) | |
503 | (1ULL << INTERCEPT_MSR_PROT) | | 503 | (1ULL << INTERCEPT_MSR_PROT) | |
504 | (1ULL << INTERCEPT_TASK_SWITCH) | | 504 | (1ULL << INTERCEPT_TASK_SWITCH) | |
505 | (1ULL << INTERCEPT_SHUTDOWN) | | ||
505 | (1ULL << INTERCEPT_VMRUN) | | 506 | (1ULL << INTERCEPT_VMRUN) | |
506 | (1ULL << INTERCEPT_VMMCALL) | | 507 | (1ULL << INTERCEPT_VMMCALL) | |
507 | (1ULL << INTERCEPT_VMLOAD) | | 508 | (1ULL << INTERCEPT_VMLOAD) | |
@@ -680,14 +681,14 @@ static void svm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) | |||
680 | 681 | ||
681 | static void svm_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 682 | static void svm_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) |
682 | { | 683 | { |
683 | dt->limit = vcpu->svm->vmcb->save.ldtr.limit; | 684 | dt->limit = vcpu->svm->vmcb->save.idtr.limit; |
684 | dt->base = vcpu->svm->vmcb->save.ldtr.base; | 685 | dt->base = vcpu->svm->vmcb->save.idtr.base; |
685 | } | 686 | } |
686 | 687 | ||
687 | static void svm_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 688 | static void svm_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) |
688 | { | 689 | { |
689 | vcpu->svm->vmcb->save.ldtr.limit = dt->limit; | 690 | vcpu->svm->vmcb->save.idtr.limit = dt->limit; |
690 | vcpu->svm->vmcb->save.ldtr.base = dt->base ; | 691 | vcpu->svm->vmcb->save.idtr.base = dt->base ; |
691 | } | 692 | } |
692 | 693 | ||
693 | static void svm_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 694 | static void svm_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) |
@@ -892,6 +893,19 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
892 | return 0; | 893 | return 0; |
893 | } | 894 | } |
894 | 895 | ||
896 | static int shutdown_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
897 | { | ||
898 | /* | ||
899 | * VMCB is undefined after a SHUTDOWN intercept | ||
900 | * so reinitialize it. | ||
901 | */ | ||
902 | memset(vcpu->svm->vmcb, 0, PAGE_SIZE); | ||
903 | init_vmcb(vcpu->svm->vmcb); | ||
904 | |||
905 | kvm_run->exit_reason = KVM_EXIT_SHUTDOWN; | ||
906 | return 0; | ||
907 | } | ||
908 | |||
895 | static int io_get_override(struct kvm_vcpu *vcpu, | 909 | static int io_get_override(struct kvm_vcpu *vcpu, |
896 | struct vmcb_seg **seg, | 910 | struct vmcb_seg **seg, |
897 | int *addr_override) | 911 | int *addr_override) |
@@ -1249,6 +1263,7 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu, | |||
1249 | [SVM_EXIT_IOIO] = io_interception, | 1263 | [SVM_EXIT_IOIO] = io_interception, |
1250 | [SVM_EXIT_MSR] = msr_interception, | 1264 | [SVM_EXIT_MSR] = msr_interception, |
1251 | [SVM_EXIT_TASK_SWITCH] = task_switch_interception, | 1265 | [SVM_EXIT_TASK_SWITCH] = task_switch_interception, |
1266 | [SVM_EXIT_SHUTDOWN] = shutdown_interception, | ||
1252 | [SVM_EXIT_VMRUN] = invalid_op_interception, | 1267 | [SVM_EXIT_VMRUN] = invalid_op_interception, |
1253 | [SVM_EXIT_VMMCALL] = invalid_op_interception, | 1268 | [SVM_EXIT_VMMCALL] = invalid_op_interception, |
1254 | [SVM_EXIT_VMLOAD] = invalid_op_interception, | 1269 | [SVM_EXIT_VMLOAD] = invalid_op_interception, |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 5432d07c074..11108165e26 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -479,9 +479,12 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
479 | int err = -EINVAL; | 479 | int err = -EINVAL; |
480 | 480 | ||
481 | /* page 0 is the superblock, read it... */ | 481 | /* page 0 is the superblock, read it... */ |
482 | if (bitmap->file) | 482 | if (bitmap->file) { |
483 | bitmap->sb_page = read_page(bitmap->file, 0, bitmap, PAGE_SIZE); | 483 | loff_t isize = i_size_read(bitmap->file->f_mapping->host); |
484 | else { | 484 | int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize; |
485 | |||
486 | bitmap->sb_page = read_page(bitmap->file, 0, bitmap, bytes); | ||
487 | } else { | ||
485 | bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset, 0); | 488 | bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset, 0); |
486 | } | 489 | } |
487 | if (IS_ERR(bitmap->sb_page)) { | 490 | if (IS_ERR(bitmap->sb_page)) { |
@@ -877,7 +880,8 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | |||
877 | int count; | 880 | int count; |
878 | /* unmap the old page, we're done with it */ | 881 | /* unmap the old page, we're done with it */ |
879 | if (index == num_pages-1) | 882 | if (index == num_pages-1) |
880 | count = bytes - index * PAGE_SIZE; | 883 | count = bytes + sizeof(bitmap_super_t) |
884 | - index * PAGE_SIZE; | ||
881 | else | 885 | else |
882 | count = PAGE_SIZE; | 886 | count = PAGE_SIZE; |
883 | if (index == 0) { | 887 | if (index == 0) { |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index fe7c56e1043..3668b170ea6 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -1116,7 +1116,8 @@ static int __bind(struct mapped_device *md, struct dm_table *t) | |||
1116 | if (size != get_capacity(md->disk)) | 1116 | if (size != get_capacity(md->disk)) |
1117 | memset(&md->geometry, 0, sizeof(md->geometry)); | 1117 | memset(&md->geometry, 0, sizeof(md->geometry)); |
1118 | 1118 | ||
1119 | __set_size(md, size); | 1119 | if (md->suspended_bdev) |
1120 | __set_size(md, size); | ||
1120 | if (size == 0) | 1121 | if (size == 0) |
1121 | return 0; | 1122 | return 0; |
1122 | 1123 | ||
@@ -1264,6 +1265,11 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) | |||
1264 | if (!dm_suspended(md)) | 1265 | if (!dm_suspended(md)) |
1265 | goto out; | 1266 | goto out; |
1266 | 1267 | ||
1268 | /* without bdev, the device size cannot be changed */ | ||
1269 | if (!md->suspended_bdev) | ||
1270 | if (get_capacity(md->disk) != dm_table_get_size(table)) | ||
1271 | goto out; | ||
1272 | |||
1267 | __unbind(md); | 1273 | __unbind(md); |
1268 | r = __bind(md, table); | 1274 | r = __bind(md, table); |
1269 | 1275 | ||
@@ -1341,11 +1347,14 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) | |||
1341 | /* This does not get reverted if there's an error later. */ | 1347 | /* This does not get reverted if there's an error later. */ |
1342 | dm_table_presuspend_targets(map); | 1348 | dm_table_presuspend_targets(map); |
1343 | 1349 | ||
1344 | md->suspended_bdev = bdget_disk(md->disk, 0); | 1350 | /* bdget() can stall if the pending I/Os are not flushed */ |
1345 | if (!md->suspended_bdev) { | 1351 | if (!noflush) { |
1346 | DMWARN("bdget failed in dm_suspend"); | 1352 | md->suspended_bdev = bdget_disk(md->disk, 0); |
1347 | r = -ENOMEM; | 1353 | if (!md->suspended_bdev) { |
1348 | goto flush_and_out; | 1354 | DMWARN("bdget failed in dm_suspend"); |
1355 | r = -ENOMEM; | ||
1356 | goto flush_and_out; | ||
1357 | } | ||
1349 | } | 1358 | } |
1350 | 1359 | ||
1351 | /* | 1360 | /* |
@@ -1473,8 +1482,10 @@ int dm_resume(struct mapped_device *md) | |||
1473 | 1482 | ||
1474 | unlock_fs(md); | 1483 | unlock_fs(md); |
1475 | 1484 | ||
1476 | bdput(md->suspended_bdev); | 1485 | if (md->suspended_bdev) { |
1477 | md->suspended_bdev = NULL; | 1486 | bdput(md->suspended_bdev); |
1487 | md->suspended_bdev = NULL; | ||
1488 | } | ||
1478 | 1489 | ||
1479 | clear_bit(DMF_SUSPENDED, &md->flags); | 1490 | clear_bit(DMF_SUSPENDED, &md->flags); |
1480 | 1491 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index d1cb45f6d6a..e8807ea5377 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1633,7 +1633,8 @@ repeat: | |||
1633 | * and 'events' is odd, we can roll back to the previous clean state */ | 1633 | * and 'events' is odd, we can roll back to the previous clean state */ |
1634 | if (nospares | 1634 | if (nospares |
1635 | && (mddev->in_sync && mddev->recovery_cp == MaxSector) | 1635 | && (mddev->in_sync && mddev->recovery_cp == MaxSector) |
1636 | && (mddev->events & 1)) | 1636 | && (mddev->events & 1) |
1637 | && mddev->events != 1) | ||
1637 | mddev->events--; | 1638 | mddev->events--; |
1638 | else { | 1639 | else { |
1639 | /* otherwise we have to go forward and ... */ | 1640 | /* otherwise we have to go forward and ... */ |
@@ -3563,6 +3564,8 @@ static int get_bitmap_file(mddev_t * mddev, void __user * arg) | |||
3563 | char *ptr, *buf = NULL; | 3564 | char *ptr, *buf = NULL; |
3564 | int err = -ENOMEM; | 3565 | int err = -ENOMEM; |
3565 | 3566 | ||
3567 | md_allow_write(mddev); | ||
3568 | |||
3566 | file = kmalloc(sizeof(*file), GFP_KERNEL); | 3569 | file = kmalloc(sizeof(*file), GFP_KERNEL); |
3567 | if (!file) | 3570 | if (!file) |
3568 | goto out; | 3571 | goto out; |
@@ -5031,6 +5034,33 @@ void md_write_end(mddev_t *mddev) | |||
5031 | } | 5034 | } |
5032 | } | 5035 | } |
5033 | 5036 | ||
5037 | /* md_allow_write(mddev) | ||
5038 | * Calling this ensures that the array is marked 'active' so that writes | ||
5039 | * may proceed without blocking. It is important to call this before | ||
5040 | * attempting a GFP_KERNEL allocation while holding the mddev lock. | ||
5041 | * Must be called with mddev_lock held. | ||
5042 | */ | ||
5043 | void md_allow_write(mddev_t *mddev) | ||
5044 | { | ||
5045 | if (!mddev->pers) | ||
5046 | return; | ||
5047 | if (mddev->ro) | ||
5048 | return; | ||
5049 | |||
5050 | spin_lock_irq(&mddev->write_lock); | ||
5051 | if (mddev->in_sync) { | ||
5052 | mddev->in_sync = 0; | ||
5053 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | ||
5054 | if (mddev->safemode_delay && | ||
5055 | mddev->safemode == 0) | ||
5056 | mddev->safemode = 1; | ||
5057 | spin_unlock_irq(&mddev->write_lock); | ||
5058 | md_update_sb(mddev, 0); | ||
5059 | } else | ||
5060 | spin_unlock_irq(&mddev->write_lock); | ||
5061 | } | ||
5062 | EXPORT_SYMBOL_GPL(md_allow_write); | ||
5063 | |||
5034 | static DECLARE_WAIT_QUEUE_HEAD(resync_wait); | 5064 | static DECLARE_WAIT_QUEUE_HEAD(resync_wait); |
5035 | 5065 | ||
5036 | #define SYNC_MARKS 10 | 5066 | #define SYNC_MARKS 10 |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 164b25dca10..97ee870b265 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1266,6 +1266,11 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) | |||
1266 | sbio->bi_sector = r1_bio->sector + | 1266 | sbio->bi_sector = r1_bio->sector + |
1267 | conf->mirrors[i].rdev->data_offset; | 1267 | conf->mirrors[i].rdev->data_offset; |
1268 | sbio->bi_bdev = conf->mirrors[i].rdev->bdev; | 1268 | sbio->bi_bdev = conf->mirrors[i].rdev->bdev; |
1269 | for (j = 0; j < vcnt ; j++) | ||
1270 | memcpy(page_address(sbio->bi_io_vec[j].bv_page), | ||
1271 | page_address(pbio->bi_io_vec[j].bv_page), | ||
1272 | PAGE_SIZE); | ||
1273 | |||
1269 | } | 1274 | } |
1270 | } | 1275 | } |
1271 | } | 1276 | } |
@@ -2099,6 +2104,8 @@ static int raid1_reshape(mddev_t *mddev) | |||
2099 | return -EINVAL; | 2104 | return -EINVAL; |
2100 | } | 2105 | } |
2101 | 2106 | ||
2107 | md_allow_write(mddev); | ||
2108 | |||
2102 | raid_disks = mddev->raid_disks + mddev->delta_disks; | 2109 | raid_disks = mddev->raid_disks + mddev->delta_disks; |
2103 | 2110 | ||
2104 | if (raid_disks < conf->raid_disks) { | 2111 | if (raid_disks < conf->raid_disks) { |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index be008f034ad..467c16982d0 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -405,6 +405,8 @@ static int resize_stripes(raid5_conf_t *conf, int newsize) | |||
405 | if (newsize <= conf->pool_size) | 405 | if (newsize <= conf->pool_size) |
406 | return 0; /* never bother to shrink */ | 406 | return 0; /* never bother to shrink */ |
407 | 407 | ||
408 | md_allow_write(conf->mddev); | ||
409 | |||
408 | /* Step 1 */ | 410 | /* Step 1 */ |
409 | sc = kmem_cache_create(conf->cache_name[1-conf->active_name], | 411 | sc = kmem_cache_create(conf->cache_name[1-conf->active_name], |
410 | sizeof(struct stripe_head)+(newsize-1)*sizeof(struct r5dev), | 412 | sizeof(struct stripe_head)+(newsize-1)*sizeof(struct r5dev), |
@@ -2678,7 +2680,7 @@ static int chunk_aligned_read(request_queue_t *q, struct bio * raid_bio) | |||
2678 | mdk_rdev_t *rdev; | 2680 | mdk_rdev_t *rdev; |
2679 | 2681 | ||
2680 | if (!in_chunk_boundary(mddev, raid_bio)) { | 2682 | if (!in_chunk_boundary(mddev, raid_bio)) { |
2681 | printk("chunk_aligned_read : non aligned\n"); | 2683 | PRINTK("chunk_aligned_read : non aligned\n"); |
2682 | return 0; | 2684 | return 0; |
2683 | } | 2685 | } |
2684 | /* | 2686 | /* |
@@ -3250,6 +3252,7 @@ raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len) | |||
3250 | else | 3252 | else |
3251 | break; | 3253 | break; |
3252 | } | 3254 | } |
3255 | md_allow_write(mddev); | ||
3253 | while (new > conf->max_nr_stripes) { | 3256 | while (new > conf->max_nr_stripes) { |
3254 | if (grow_one_stripe(conf)) | 3257 | if (grow_one_stripe(conf)) |
3255 | conf->max_nr_stripes++; | 3258 | conf->max_nr_stripes++; |
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 9418a59fb36..2ddd0cf0714 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c | |||
@@ -78,7 +78,7 @@ static struct attribute_group rtc_attr_group = { | |||
78 | .attrs = rtc_attrs, | 78 | .attrs = rtc_attrs, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | static int __devinit rtc_sysfs_add_device(struct class_device *class_dev, | 81 | static int rtc_sysfs_add_device(struct class_device *class_dev, |
82 | struct class_interface *class_intf) | 82 | struct class_interface *class_intf) |
83 | { | 83 | { |
84 | int err; | 84 | int err; |
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 6ed3f1da929..8b41f9cc256 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -1169,8 +1169,9 @@ static int setup(struct spi_device *spi) | |||
1169 | spi->bits_per_word - 16 : spi->bits_per_word) | 1169 | spi->bits_per_word - 16 : spi->bits_per_word) |
1170 | | SSCR0_SSE | 1170 | | SSCR0_SSE |
1171 | | (spi->bits_per_word > 16 ? SSCR0_EDSS : 0); | 1171 | | (spi->bits_per_word > 16 ? SSCR0_EDSS : 0); |
1172 | chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) << 4) | 1172 | chip->cr1 &= ~(SSCR1_SPO | SSCR1_SPH); |
1173 | | (((spi->mode & SPI_CPOL) != 0) << 3); | 1173 | chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) ? SSCR1_SPH : 0) |
1174 | | (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0); | ||
1174 | 1175 | ||
1175 | /* NOTE: PXA25x_SSP _could_ use external clocking ... */ | 1176 | /* NOTE: PXA25x_SSP _could_ use external clocking ... */ |
1176 | if (drv_data->ssp_type != PXA25x_SSP) | 1177 | if (drv_data->ssp_type != PXA25x_SSP) |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 270e6211c2e..6307428d2c9 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -366,7 +366,6 @@ spi_alloc_master(struct device *dev, unsigned size) | |||
366 | 366 | ||
367 | class_device_initialize(&master->cdev); | 367 | class_device_initialize(&master->cdev); |
368 | master->cdev.class = &spi_master_class; | 368 | master->cdev.class = &spi_master_class; |
369 | kobj_set_kset_s(&master->cdev, spi_master_class.subsys); | ||
370 | master->cdev.dev = get_device(dev); | 369 | master->cdev.dev = get_device(dev); |
371 | spi_master_set_devdata(master, &master[1]); | 370 | spi_master_set_devdata(master, &master[1]); |
372 | 371 | ||
@@ -466,14 +465,20 @@ EXPORT_SYMBOL_GPL(spi_unregister_master); | |||
466 | */ | 465 | */ |
467 | struct spi_master *spi_busnum_to_master(u16 bus_num) | 466 | struct spi_master *spi_busnum_to_master(u16 bus_num) |
468 | { | 467 | { |
469 | char name[9]; | 468 | struct class_device *cdev; |
470 | struct kobject *bus; | 469 | struct spi_master *master = NULL; |
471 | 470 | struct spi_master *m; | |
472 | snprintf(name, sizeof name, "spi%u", bus_num); | 471 | |
473 | bus = kset_find_obj(&spi_master_class.subsys.kset, name); | 472 | down(&spi_master_class.sem); |
474 | if (bus) | 473 | list_for_each_entry(cdev, &spi_master_class.children, node) { |
475 | return container_of(bus, struct spi_master, cdev.kobj); | 474 | m = container_of(cdev, struct spi_master, cdev); |
476 | return NULL; | 475 | if (m->bus_num == bus_num) { |
476 | master = spi_master_get(m); | ||
477 | break; | ||
478 | } | ||
479 | } | ||
480 | up(&spi_master_class.sem); | ||
481 | return master; | ||
477 | } | 482 | } |
478 | EXPORT_SYMBOL_GPL(spi_busnum_to_master); | 483 | EXPORT_SYMBOL_GPL(spi_busnum_to_master); |
479 | 484 | ||
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index 8ca08713528..651379c51ae 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c | |||
@@ -10,9 +10,6 @@ | |||
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | 12 | ||
13 | |||
14 | //#define DEBUG | ||
15 | |||
16 | #include <linux/init.h> | 13 | #include <linux/init.h> |
17 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
18 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
@@ -44,6 +41,9 @@ struct s3c24xx_spi { | |||
44 | int len; | 41 | int len; |
45 | int count; | 42 | int count; |
46 | 43 | ||
44 | int (*set_cs)(struct s3c2410_spi_info *spi, | ||
45 | int cs, int pol); | ||
46 | |||
47 | /* data buffers */ | 47 | /* data buffers */ |
48 | const unsigned char *tx; | 48 | const unsigned char *tx; |
49 | unsigned char *rx; | 49 | unsigned char *rx; |
@@ -64,6 +64,11 @@ static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev) | |||
64 | return spi_master_get_devdata(sdev->master); | 64 | return spi_master_get_devdata(sdev->master); |
65 | } | 65 | } |
66 | 66 | ||
67 | static void s3c24xx_spi_gpiocs(struct s3c2410_spi_info *spi, int cs, int pol) | ||
68 | { | ||
69 | s3c2410_gpio_setpin(spi->pin_cs, pol); | ||
70 | } | ||
71 | |||
67 | static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) | 72 | static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) |
68 | { | 73 | { |
69 | struct s3c24xx_spi *hw = to_hw(spi); | 74 | struct s3c24xx_spi *hw = to_hw(spi); |
@@ -72,10 +77,7 @@ static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) | |||
72 | 77 | ||
73 | switch (value) { | 78 | switch (value) { |
74 | case BITBANG_CS_INACTIVE: | 79 | case BITBANG_CS_INACTIVE: |
75 | if (hw->pdata->set_cs) | 80 | hw->pdata->set_cs(hw->pdata, spi->chip_select, cspol^1); |
76 | hw->pdata->set_cs(hw->pdata, value, cspol); | ||
77 | else | ||
78 | s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol ^ 1); | ||
79 | break; | 81 | break; |
80 | 82 | ||
81 | case BITBANG_CS_ACTIVE: | 83 | case BITBANG_CS_ACTIVE: |
@@ -96,14 +98,9 @@ static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) | |||
96 | /* write new configration */ | 98 | /* write new configration */ |
97 | 99 | ||
98 | writeb(spcon, hw->regs + S3C2410_SPCON); | 100 | writeb(spcon, hw->regs + S3C2410_SPCON); |
99 | 101 | hw->pdata->set_cs(hw->pdata, spi->chip_select, cspol); | |
100 | if (hw->pdata->set_cs) | ||
101 | hw->pdata->set_cs(hw->pdata, value, cspol); | ||
102 | else | ||
103 | s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol); | ||
104 | 102 | ||
105 | break; | 103 | break; |
106 | |||
107 | } | 104 | } |
108 | } | 105 | } |
109 | 106 | ||
@@ -330,9 +327,12 @@ static int s3c24xx_spi_probe(struct platform_device *pdev) | |||
330 | /* setup any gpio we can */ | 327 | /* setup any gpio we can */ |
331 | 328 | ||
332 | if (!hw->pdata->set_cs) { | 329 | if (!hw->pdata->set_cs) { |
330 | hw->set_cs = s3c24xx_spi_gpiocs; | ||
331 | |||
333 | s3c2410_gpio_setpin(hw->pdata->pin_cs, 1); | 332 | s3c2410_gpio_setpin(hw->pdata->pin_cs, 1); |
334 | s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT); | 333 | s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT); |
335 | } | 334 | } else |
335 | hw->set_cs = hw->pdata->set_cs; | ||
336 | 336 | ||
337 | /* register our spi controller */ | 337 | /* register our spi controller */ |
338 | 338 | ||
diff --git a/fs/9p/error.c b/fs/9p/error.c index ae91555c155..0d7fa4e0881 100644 --- a/fs/9p/error.c +++ b/fs/9p/error.c | |||
@@ -83,6 +83,7 @@ int v9fs_errstr2errno(char *errstr, int len) | |||
83 | 83 | ||
84 | if (errno == 0) { | 84 | if (errno == 0) { |
85 | /* TODO: if error isn't found, add it dynamically */ | 85 | /* TODO: if error isn't found, add it dynamically */ |
86 | errstr[len] = 0; | ||
86 | printk(KERN_ERR "%s: errstr :%s: not found\n", __FUNCTION__, | 87 | printk(KERN_ERR "%s: errstr :%s: not found\n", __FUNCTION__, |
87 | errstr); | 88 | errstr); |
88 | errno = 1; | 89 | errno = 1; |
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 27507201f9e..a9b6301a04f 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
28 | #include <asm/semaphore.h> | ||
28 | 29 | ||
29 | #include "debug.h" | 30 | #include "debug.h" |
30 | #include "v9fs.h" | 31 | #include "v9fs.h" |
@@ -84,6 +85,7 @@ struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid) | |||
84 | new->iounit = 0; | 85 | new->iounit = 0; |
85 | new->rdir_pos = 0; | 86 | new->rdir_pos = 0; |
86 | new->rdir_fcall = NULL; | 87 | new->rdir_fcall = NULL; |
88 | init_MUTEX(&new->lock); | ||
87 | INIT_LIST_HEAD(&new->list); | 89 | INIT_LIST_HEAD(&new->list); |
88 | 90 | ||
89 | return new; | 91 | return new; |
@@ -102,11 +104,11 @@ void v9fs_fid_destroy(struct v9fs_fid *fid) | |||
102 | } | 104 | } |
103 | 105 | ||
104 | /** | 106 | /** |
105 | * v9fs_fid_lookup - retrieve the right fid from a particular dentry | 107 | * v9fs_fid_lookup - return a locked fid from a dentry |
106 | * @dentry: dentry to look for fid in | 108 | * @dentry: dentry to look for fid in |
107 | * @type: intent of lookup (operation or traversal) | ||
108 | * | 109 | * |
109 | * find a fid in the dentry | 110 | * find a fid in the dentry, obtain its semaphore and return a reference to it. |
111 | * code calling lookup is responsible for releasing lock | ||
110 | * | 112 | * |
111 | * TODO: only match fids that have the same uid as current user | 113 | * TODO: only match fids that have the same uid as current user |
112 | * | 114 | * |
@@ -124,7 +126,68 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) | |||
124 | 126 | ||
125 | if (!return_fid) { | 127 | if (!return_fid) { |
126 | dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n"); | 128 | dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n"); |
129 | return_fid = ERR_PTR(-EBADF); | ||
127 | } | 130 | } |
128 | 131 | ||
132 | if(down_interruptible(&return_fid->lock)) | ||
133 | return ERR_PTR(-EINTR); | ||
134 | |||
129 | return return_fid; | 135 | return return_fid; |
130 | } | 136 | } |
137 | |||
138 | /** | ||
139 | * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and release it | ||
140 | * @dentry: dentry to look for fid in | ||
141 | * | ||
142 | * find a fid in the dentry and then clone to a new private fid | ||
143 | * | ||
144 | * TODO: only match fids that have the same uid as current user | ||
145 | * | ||
146 | */ | ||
147 | |||
148 | struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry) | ||
149 | { | ||
150 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | ||
151 | struct v9fs_fid *base_fid, *new_fid = ERR_PTR(-EBADF); | ||
152 | struct v9fs_fcall *fcall = NULL; | ||
153 | int fid, err; | ||
154 | |||
155 | base_fid = v9fs_fid_lookup(dentry); | ||
156 | |||
157 | if(IS_ERR(base_fid)) | ||
158 | return base_fid; | ||
159 | |||
160 | if(base_fid) { /* clone fid */ | ||
161 | fid = v9fs_get_idpool(&v9ses->fidpool); | ||
162 | if (fid < 0) { | ||
163 | eprintk(KERN_WARNING, "newfid fails!\n"); | ||
164 | new_fid = ERR_PTR(-ENOSPC); | ||
165 | goto Release_Fid; | ||
166 | } | ||
167 | |||
168 | err = v9fs_t_walk(v9ses, base_fid->fid, fid, NULL, &fcall); | ||
169 | if (err < 0) { | ||
170 | dprintk(DEBUG_ERROR, "clone walk didn't work\n"); | ||
171 | v9fs_put_idpool(fid, &v9ses->fidpool); | ||
172 | new_fid = ERR_PTR(err); | ||
173 | goto Free_Fcall; | ||
174 | } | ||
175 | new_fid = v9fs_fid_create(v9ses, fid); | ||
176 | if (new_fid == NULL) { | ||
177 | dprintk(DEBUG_ERROR, "out of memory\n"); | ||
178 | new_fid = ERR_PTR(-ENOMEM); | ||
179 | } | ||
180 | Free_Fcall: | ||
181 | kfree(fcall); | ||
182 | } | ||
183 | |||
184 | Release_Fid: | ||
185 | up(&base_fid->lock); | ||
186 | return new_fid; | ||
187 | } | ||
188 | |||
189 | void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid) | ||
190 | { | ||
191 | v9fs_t_clunk(v9ses, fid->fid); | ||
192 | v9fs_fid_destroy(fid); | ||
193 | } | ||
diff --git a/fs/9p/fid.h b/fs/9p/fid.h index aa974d6875c..48fc170c26c 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h | |||
@@ -30,6 +30,8 @@ struct v9fs_fid { | |||
30 | struct list_head list; /* list of fids associated with a dentry */ | 30 | struct list_head list; /* list of fids associated with a dentry */ |
31 | struct list_head active; /* XXX - debug */ | 31 | struct list_head active; /* XXX - debug */ |
32 | 32 | ||
33 | struct semaphore lock; | ||
34 | |||
33 | u32 fid; | 35 | u32 fid; |
34 | unsigned char fidopen; /* set when fid is opened */ | 36 | unsigned char fidopen; /* set when fid is opened */ |
35 | unsigned char fidclunked; /* set when fid has already been clunked */ | 37 | unsigned char fidclunked; /* set when fid has already been clunked */ |
@@ -55,3 +57,6 @@ struct v9fs_fid *v9fs_fid_get_created(struct dentry *); | |||
55 | void v9fs_fid_destroy(struct v9fs_fid *fid); | 57 | void v9fs_fid_destroy(struct v9fs_fid *fid); |
56 | struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *, int fid); | 58 | struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *, int fid); |
57 | int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry); | 59 | int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry); |
60 | struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry); | ||
61 | void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid); | ||
62 | |||
diff --git a/fs/9p/mux.c b/fs/9p/mux.c index 944273c3dbf..147ceef8e53 100644 --- a/fs/9p/mux.c +++ b/fs/9p/mux.c | |||
@@ -132,8 +132,10 @@ int v9fs_mux_global_init(void) | |||
132 | v9fs_mux_poll_tasks[i].task = NULL; | 132 | v9fs_mux_poll_tasks[i].task = NULL; |
133 | 133 | ||
134 | v9fs_mux_wq = create_workqueue("v9fs"); | 134 | v9fs_mux_wq = create_workqueue("v9fs"); |
135 | if (!v9fs_mux_wq) | 135 | if (!v9fs_mux_wq) { |
136 | printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n"); | ||
136 | return -ENOMEM; | 137 | return -ENOMEM; |
138 | } | ||
137 | 139 | ||
138 | return 0; | 140 | return 0; |
139 | } | 141 | } |
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 0b96fae8b47..d9b561ba5e5 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -457,14 +457,19 @@ static int __init init_v9fs(void) | |||
457 | 457 | ||
458 | v9fs_error_init(); | 458 | v9fs_error_init(); |
459 | 459 | ||
460 | printk(KERN_INFO "Installing v9fs 9P2000 file system support\n"); | 460 | printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); |
461 | 461 | ||
462 | ret = v9fs_mux_global_init(); | 462 | ret = v9fs_mux_global_init(); |
463 | if (!ret) | 463 | if (ret) { |
464 | printk(KERN_WARNING "v9fs: starting mux failed\n"); | ||
464 | return ret; | 465 | return ret; |
466 | } | ||
465 | ret = register_filesystem(&v9fs_fs_type); | 467 | ret = register_filesystem(&v9fs_fs_type); |
466 | if (!ret) | 468 | if (ret) { |
469 | printk(KERN_WARNING "v9fs: registering file system failed\n"); | ||
467 | v9fs_mux_global_exit(); | 470 | v9fs_mux_global_exit(); |
471 | } | ||
472 | |||
468 | return ret; | 473 | return ret; |
469 | } | 474 | } |
470 | 475 | ||
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index e86a0715128..9f17b0cacdd 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -55,53 +55,22 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
55 | struct v9fs_fid *vfid; | 55 | struct v9fs_fid *vfid; |
56 | struct v9fs_fcall *fcall = NULL; | 56 | struct v9fs_fcall *fcall = NULL; |
57 | int omode; | 57 | int omode; |
58 | int fid = V9FS_NOFID; | ||
59 | int err; | 58 | int err; |
60 | 59 | ||
61 | dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); | 60 | dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); |
62 | 61 | ||
63 | vfid = v9fs_fid_lookup(file->f_path.dentry); | 62 | vfid = v9fs_fid_clone(file->f_path.dentry); |
64 | if (!vfid) { | 63 | if (IS_ERR(vfid)) |
65 | dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); | 64 | return PTR_ERR(vfid); |
66 | return -EBADF; | ||
67 | } | ||
68 | |||
69 | fid = v9fs_get_idpool(&v9ses->fidpool); | ||
70 | if (fid < 0) { | ||
71 | eprintk(KERN_WARNING, "newfid fails!\n"); | ||
72 | return -ENOSPC; | ||
73 | } | ||
74 | 65 | ||
75 | err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, &fcall); | ||
76 | if (err < 0) { | ||
77 | dprintk(DEBUG_ERROR, "rewalk didn't work\n"); | ||
78 | if (fcall && fcall->id == RWALK) | ||
79 | goto clunk_fid; | ||
80 | else { | ||
81 | v9fs_put_idpool(fid, &v9ses->fidpool); | ||
82 | goto free_fcall; | ||
83 | } | ||
84 | } | ||
85 | kfree(fcall); | ||
86 | |||
87 | /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ | ||
88 | /* translate open mode appropriately */ | ||
89 | omode = v9fs_uflags2omode(file->f_flags); | 66 | omode = v9fs_uflags2omode(file->f_flags); |
90 | err = v9fs_t_open(v9ses, fid, omode, &fcall); | 67 | err = v9fs_t_open(v9ses, vfid->fid, omode, &fcall); |
91 | if (err < 0) { | 68 | if (err < 0) { |
92 | PRINT_FCALL_ERROR("open failed", fcall); | 69 | PRINT_FCALL_ERROR("open failed", fcall); |
93 | goto clunk_fid; | 70 | goto Clunk_Fid; |
94 | } | ||
95 | |||
96 | vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); | ||
97 | if (vfid == NULL) { | ||
98 | dprintk(DEBUG_ERROR, "out of memory\n"); | ||
99 | err = -ENOMEM; | ||
100 | goto clunk_fid; | ||
101 | } | 71 | } |
102 | 72 | ||
103 | file->private_data = vfid; | 73 | file->private_data = vfid; |
104 | vfid->fid = fid; | ||
105 | vfid->fidopen = 1; | 74 | vfid->fidopen = 1; |
106 | vfid->fidclunked = 0; | 75 | vfid->fidclunked = 0; |
107 | vfid->iounit = fcall->params.ropen.iounit; | 76 | vfid->iounit = fcall->params.ropen.iounit; |
@@ -112,10 +81,8 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
112 | 81 | ||
113 | return 0; | 82 | return 0; |
114 | 83 | ||
115 | clunk_fid: | 84 | Clunk_Fid: |
116 | v9fs_t_clunk(v9ses, fid); | 85 | v9fs_fid_clunk(v9ses, vfid); |
117 | |||
118 | free_fcall: | ||
119 | kfree(fcall); | 86 | kfree(fcall); |
120 | 87 | ||
121 | return err; | 88 | return err; |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 18f26cdfd88..9109ba1d696 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -416,12 +416,8 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) | |||
416 | sb = file_inode->i_sb; | 416 | sb = file_inode->i_sb; |
417 | v9ses = v9fs_inode2v9ses(file_inode); | 417 | v9ses = v9fs_inode2v9ses(file_inode); |
418 | v9fid = v9fs_fid_lookup(file); | 418 | v9fid = v9fs_fid_lookup(file); |
419 | 419 | if(IS_ERR(v9fid)) | |
420 | if (!v9fid) { | 420 | return PTR_ERR(v9fid); |
421 | dprintk(DEBUG_ERROR, | ||
422 | "no v9fs_fid\n"); | ||
423 | return -EBADF; | ||
424 | } | ||
425 | 421 | ||
426 | fid = v9fid->fid; | 422 | fid = v9fid->fid; |
427 | if (fid < 0) { | 423 | if (fid < 0) { |
@@ -433,11 +429,13 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) | |||
433 | result = v9fs_t_remove(v9ses, fid, &fcall); | 429 | result = v9fs_t_remove(v9ses, fid, &fcall); |
434 | if (result < 0) { | 430 | if (result < 0) { |
435 | PRINT_FCALL_ERROR("remove fails", fcall); | 431 | PRINT_FCALL_ERROR("remove fails", fcall); |
432 | goto Error; | ||
436 | } | 433 | } |
437 | 434 | ||
438 | v9fs_put_idpool(fid, &v9ses->fidpool); | 435 | v9fs_put_idpool(fid, &v9ses->fidpool); |
439 | v9fs_fid_destroy(v9fid); | 436 | v9fs_fid_destroy(v9fid); |
440 | 437 | ||
438 | Error: | ||
441 | kfree(fcall); | 439 | kfree(fcall); |
442 | return result; | 440 | return result; |
443 | } | 441 | } |
@@ -473,9 +471,13 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
473 | inode = NULL; | 471 | inode = NULL; |
474 | vfid = NULL; | 472 | vfid = NULL; |
475 | v9ses = v9fs_inode2v9ses(dir); | 473 | v9ses = v9fs_inode2v9ses(dir); |
476 | dfid = v9fs_fid_lookup(dentry->d_parent); | 474 | dfid = v9fs_fid_clone(dentry->d_parent); |
477 | perm = unixmode2p9mode(v9ses, mode); | 475 | if(IS_ERR(dfid)) { |
476 | err = PTR_ERR(dfid); | ||
477 | goto error; | ||
478 | } | ||
478 | 479 | ||
480 | perm = unixmode2p9mode(v9ses, mode); | ||
479 | if (nd && nd->flags & LOOKUP_OPEN) | 481 | if (nd && nd->flags & LOOKUP_OPEN) |
480 | flags = nd->intent.open.flags - 1; | 482 | flags = nd->intent.open.flags - 1; |
481 | else | 483 | else |
@@ -485,9 +487,10 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
485 | perm, v9fs_uflags2omode(flags), NULL, &fid, &qid, &iounit); | 487 | perm, v9fs_uflags2omode(flags), NULL, &fid, &qid, &iounit); |
486 | 488 | ||
487 | if (err) | 489 | if (err) |
488 | goto error; | 490 | goto clunk_dfid; |
489 | 491 | ||
490 | vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); | 492 | vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); |
493 | v9fs_fid_clunk(v9ses, dfid); | ||
491 | if (IS_ERR(vfid)) { | 494 | if (IS_ERR(vfid)) { |
492 | err = PTR_ERR(vfid); | 495 | err = PTR_ERR(vfid); |
493 | vfid = NULL; | 496 | vfid = NULL; |
@@ -525,6 +528,9 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
525 | 528 | ||
526 | return 0; | 529 | return 0; |
527 | 530 | ||
531 | clunk_dfid: | ||
532 | v9fs_fid_clunk(v9ses, dfid); | ||
533 | |||
528 | error: | 534 | error: |
529 | if (vfid) | 535 | if (vfid) |
530 | v9fs_fid_destroy(vfid); | 536 | v9fs_fid_destroy(vfid); |
@@ -551,7 +557,12 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
551 | inode = NULL; | 557 | inode = NULL; |
552 | vfid = NULL; | 558 | vfid = NULL; |
553 | v9ses = v9fs_inode2v9ses(dir); | 559 | v9ses = v9fs_inode2v9ses(dir); |
554 | dfid = v9fs_fid_lookup(dentry->d_parent); | 560 | dfid = v9fs_fid_clone(dentry->d_parent); |
561 | if(IS_ERR(dfid)) { | ||
562 | err = PTR_ERR(dfid); | ||
563 | goto error; | ||
564 | } | ||
565 | |||
555 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); | 566 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); |
556 | 567 | ||
557 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 568 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, |
@@ -559,37 +570,36 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
559 | 570 | ||
560 | if (err) { | 571 | if (err) { |
561 | dprintk(DEBUG_ERROR, "create error %d\n", err); | 572 | dprintk(DEBUG_ERROR, "create error %d\n", err); |
562 | goto error; | 573 | goto clean_up_dfid; |
563 | } | ||
564 | |||
565 | err = v9fs_t_clunk(v9ses, fid); | ||
566 | if (err) { | ||
567 | dprintk(DEBUG_ERROR, "clunk error %d\n", err); | ||
568 | goto error; | ||
569 | } | 574 | } |
570 | 575 | ||
571 | vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); | 576 | vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); |
572 | if (IS_ERR(vfid)) { | 577 | if (IS_ERR(vfid)) { |
573 | err = PTR_ERR(vfid); | 578 | err = PTR_ERR(vfid); |
574 | vfid = NULL; | 579 | vfid = NULL; |
575 | goto error; | 580 | goto clean_up_dfid; |
576 | } | 581 | } |
577 | 582 | ||
583 | v9fs_fid_clunk(v9ses, dfid); | ||
578 | inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); | 584 | inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); |
579 | if (IS_ERR(inode)) { | 585 | if (IS_ERR(inode)) { |
580 | err = PTR_ERR(inode); | 586 | err = PTR_ERR(inode); |
581 | inode = NULL; | 587 | inode = NULL; |
582 | goto error; | 588 | goto clean_up_fids; |
583 | } | 589 | } |
584 | 590 | ||
585 | dentry->d_op = &v9fs_dentry_operations; | 591 | dentry->d_op = &v9fs_dentry_operations; |
586 | d_instantiate(dentry, inode); | 592 | d_instantiate(dentry, inode); |
587 | return 0; | 593 | return 0; |
588 | 594 | ||
589 | error: | 595 | clean_up_fids: |
590 | if (vfid) | 596 | if (vfid) |
591 | v9fs_fid_destroy(vfid); | 597 | v9fs_fid_destroy(vfid); |
592 | 598 | ||
599 | clean_up_dfid: | ||
600 | v9fs_fid_clunk(v9ses, dfid); | ||
601 | |||
602 | error: | ||
593 | return err; | 603 | return err; |
594 | } | 604 | } |
595 | 605 | ||
@@ -622,28 +632,23 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
622 | dentry->d_op = &v9fs_dentry_operations; | 632 | dentry->d_op = &v9fs_dentry_operations; |
623 | dirfid = v9fs_fid_lookup(dentry->d_parent); | 633 | dirfid = v9fs_fid_lookup(dentry->d_parent); |
624 | 634 | ||
625 | if (!dirfid) { | 635 | if(IS_ERR(dirfid)) |
626 | dprintk(DEBUG_ERROR, "no dirfid\n"); | 636 | return ERR_PTR(PTR_ERR(dirfid)); |
627 | return ERR_PTR(-EINVAL); | ||
628 | } | ||
629 | 637 | ||
630 | dirfidnum = dirfid->fid; | 638 | dirfidnum = dirfid->fid; |
631 | 639 | ||
632 | if (dirfidnum < 0) { | ||
633 | dprintk(DEBUG_ERROR, "no dirfid for inode %p, #%lu\n", | ||
634 | dir, dir->i_ino); | ||
635 | return ERR_PTR(-EBADF); | ||
636 | } | ||
637 | |||
638 | newfid = v9fs_get_idpool(&v9ses->fidpool); | 640 | newfid = v9fs_get_idpool(&v9ses->fidpool); |
639 | if (newfid < 0) { | 641 | if (newfid < 0) { |
640 | eprintk(KERN_WARNING, "newfid fails!\n"); | 642 | eprintk(KERN_WARNING, "newfid fails!\n"); |
641 | return ERR_PTR(-ENOSPC); | 643 | result = -ENOSPC; |
644 | goto Release_Dirfid; | ||
642 | } | 645 | } |
643 | 646 | ||
644 | result = v9fs_t_walk(v9ses, dirfidnum, newfid, | 647 | result = v9fs_t_walk(v9ses, dirfidnum, newfid, |
645 | (char *)dentry->d_name.name, &fcall); | 648 | (char *)dentry->d_name.name, &fcall); |
646 | 649 | ||
650 | up(&dirfid->lock); | ||
651 | |||
647 | if (result < 0) { | 652 | if (result < 0) { |
648 | if (fcall && fcall->id == RWALK) | 653 | if (fcall && fcall->id == RWALK) |
649 | v9fs_t_clunk(v9ses, newfid); | 654 | v9fs_t_clunk(v9ses, newfid); |
@@ -701,8 +706,12 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
701 | 706 | ||
702 | return NULL; | 707 | return NULL; |
703 | 708 | ||
704 | FreeFcall: | 709 | Release_Dirfid: |
710 | up(&dirfid->lock); | ||
711 | |||
712 | FreeFcall: | ||
705 | kfree(fcall); | 713 | kfree(fcall); |
714 | |||
706 | return ERR_PTR(result); | 715 | return ERR_PTR(result); |
707 | } | 716 | } |
708 | 717 | ||
@@ -746,10 +755,8 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
746 | struct inode *old_inode = old_dentry->d_inode; | 755 | struct inode *old_inode = old_dentry->d_inode; |
747 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); | 756 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); |
748 | struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); | 757 | struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); |
749 | struct v9fs_fid *olddirfid = | 758 | struct v9fs_fid *olddirfid; |
750 | v9fs_fid_lookup(old_dentry->d_parent); | 759 | struct v9fs_fid *newdirfid; |
751 | struct v9fs_fid *newdirfid = | ||
752 | v9fs_fid_lookup(new_dentry->d_parent); | ||
753 | struct v9fs_wstat wstat; | 760 | struct v9fs_wstat wstat; |
754 | struct v9fs_fcall *fcall = NULL; | 761 | struct v9fs_fcall *fcall = NULL; |
755 | int fid = -1; | 762 | int fid = -1; |
@@ -759,16 +766,26 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
759 | 766 | ||
760 | dprintk(DEBUG_VFS, "\n"); | 767 | dprintk(DEBUG_VFS, "\n"); |
761 | 768 | ||
762 | if ((!oldfid) || (!olddirfid) || (!newdirfid)) { | 769 | if(IS_ERR(oldfid)) |
763 | dprintk(DEBUG_ERROR, "problem with arguments\n"); | 770 | return PTR_ERR(oldfid); |
764 | return -EBADF; | 771 | |
772 | olddirfid = v9fs_fid_clone(old_dentry->d_parent); | ||
773 | if(IS_ERR(olddirfid)) { | ||
774 | retval = PTR_ERR(olddirfid); | ||
775 | goto Release_lock; | ||
776 | } | ||
777 | |||
778 | newdirfid = v9fs_fid_clone(new_dentry->d_parent); | ||
779 | if(IS_ERR(newdirfid)) { | ||
780 | retval = PTR_ERR(newdirfid); | ||
781 | goto Clunk_olddir; | ||
765 | } | 782 | } |
766 | 783 | ||
767 | /* 9P can only handle file rename in the same directory */ | 784 | /* 9P can only handle file rename in the same directory */ |
768 | if (memcmp(&olddirfid->qid, &newdirfid->qid, sizeof(newdirfid->qid))) { | 785 | if (memcmp(&olddirfid->qid, &newdirfid->qid, sizeof(newdirfid->qid))) { |
769 | dprintk(DEBUG_ERROR, "old dir and new dir are different\n"); | 786 | dprintk(DEBUG_ERROR, "old dir and new dir are different\n"); |
770 | retval = -EPERM; | 787 | retval = -EXDEV; |
771 | goto FreeFcallnBail; | 788 | goto Clunk_newdir; |
772 | } | 789 | } |
773 | 790 | ||
774 | fid = oldfid->fid; | 791 | fid = oldfid->fid; |
@@ -779,7 +796,7 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
779 | dprintk(DEBUG_ERROR, "no fid for old file #%lu\n", | 796 | dprintk(DEBUG_ERROR, "no fid for old file #%lu\n", |
780 | old_inode->i_ino); | 797 | old_inode->i_ino); |
781 | retval = -EBADF; | 798 | retval = -EBADF; |
782 | goto FreeFcallnBail; | 799 | goto Clunk_newdir; |
783 | } | 800 | } |
784 | 801 | ||
785 | v9fs_blank_wstat(&wstat); | 802 | v9fs_blank_wstat(&wstat); |
@@ -788,11 +805,20 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
788 | 805 | ||
789 | retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall); | 806 | retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall); |
790 | 807 | ||
791 | FreeFcallnBail: | ||
792 | if (retval < 0) | 808 | if (retval < 0) |
793 | PRINT_FCALL_ERROR("wstat error", fcall); | 809 | PRINT_FCALL_ERROR("wstat error", fcall); |
794 | 810 | ||
795 | kfree(fcall); | 811 | kfree(fcall); |
812 | |||
813 | Clunk_newdir: | ||
814 | v9fs_fid_clunk(v9ses, newdirfid); | ||
815 | |||
816 | Clunk_olddir: | ||
817 | v9fs_fid_clunk(v9ses, olddirfid); | ||
818 | |||
819 | Release_lock: | ||
820 | up(&oldfid->lock); | ||
821 | |||
796 | return retval; | 822 | return retval; |
797 | } | 823 | } |
798 | 824 | ||
@@ -810,15 +836,12 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
810 | { | 836 | { |
811 | struct v9fs_fcall *fcall = NULL; | 837 | struct v9fs_fcall *fcall = NULL; |
812 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 838 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); |
813 | struct v9fs_fid *fid = v9fs_fid_lookup(dentry); | 839 | struct v9fs_fid *fid = v9fs_fid_clone(dentry); |
814 | int err = -EPERM; | 840 | int err = -EPERM; |
815 | 841 | ||
816 | dprintk(DEBUG_VFS, "dentry: %p\n", dentry); | 842 | dprintk(DEBUG_VFS, "dentry: %p\n", dentry); |
817 | if (!fid) { | 843 | if(IS_ERR(fid)) |
818 | dprintk(DEBUG_ERROR, | 844 | return PTR_ERR(fid); |
819 | "couldn't find fid associated with dentry\n"); | ||
820 | return -EBADF; | ||
821 | } | ||
822 | 845 | ||
823 | err = v9fs_t_stat(v9ses, fid->fid, &fcall); | 846 | err = v9fs_t_stat(v9ses, fid->fid, &fcall); |
824 | 847 | ||
@@ -831,6 +854,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
831 | } | 854 | } |
832 | 855 | ||
833 | kfree(fcall); | 856 | kfree(fcall); |
857 | v9fs_fid_clunk(v9ses, fid); | ||
834 | return err; | 858 | return err; |
835 | } | 859 | } |
836 | 860 | ||
@@ -844,18 +868,14 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
844 | static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | 868 | static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) |
845 | { | 869 | { |
846 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 870 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); |
847 | struct v9fs_fid *fid = v9fs_fid_lookup(dentry); | 871 | struct v9fs_fid *fid = v9fs_fid_clone(dentry); |
848 | struct v9fs_fcall *fcall = NULL; | 872 | struct v9fs_fcall *fcall = NULL; |
849 | struct v9fs_wstat wstat; | 873 | struct v9fs_wstat wstat; |
850 | int res = -EPERM; | 874 | int res = -EPERM; |
851 | 875 | ||
852 | dprintk(DEBUG_VFS, "\n"); | 876 | dprintk(DEBUG_VFS, "\n"); |
853 | 877 | if(IS_ERR(fid)) | |
854 | if (!fid) { | 878 | return PTR_ERR(fid); |
855 | dprintk(DEBUG_ERROR, | ||
856 | "Couldn't find fid associated with dentry\n"); | ||
857 | return -EBADF; | ||
858 | } | ||
859 | 879 | ||
860 | v9fs_blank_wstat(&wstat); | 880 | v9fs_blank_wstat(&wstat); |
861 | if (iattr->ia_valid & ATTR_MODE) | 881 | if (iattr->ia_valid & ATTR_MODE) |
@@ -887,6 +907,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
887 | if (res >= 0) | 907 | if (res >= 0) |
888 | res = inode_setattr(dentry->d_inode, iattr); | 908 | res = inode_setattr(dentry->d_inode, iattr); |
889 | 909 | ||
910 | v9fs_fid_clunk(v9ses, fid); | ||
890 | return res; | 911 | return res; |
891 | } | 912 | } |
892 | 913 | ||
@@ -987,18 +1008,15 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
987 | 1008 | ||
988 | struct v9fs_fcall *fcall = NULL; | 1009 | struct v9fs_fcall *fcall = NULL; |
989 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 1010 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); |
990 | struct v9fs_fid *fid = v9fs_fid_lookup(dentry); | 1011 | struct v9fs_fid *fid = v9fs_fid_clone(dentry); |
991 | 1012 | ||
992 | if (!fid) { | 1013 | if(IS_ERR(fid)) |
993 | dprintk(DEBUG_ERROR, "could not resolve fid from dentry\n"); | 1014 | return PTR_ERR(fid); |
994 | retval = -EBADF; | ||
995 | goto FreeFcall; | ||
996 | } | ||
997 | 1015 | ||
998 | if (!v9ses->extended) { | 1016 | if (!v9ses->extended) { |
999 | retval = -EBADF; | 1017 | retval = -EBADF; |
1000 | dprintk(DEBUG_ERROR, "not extended\n"); | 1018 | dprintk(DEBUG_ERROR, "not extended\n"); |
1001 | goto FreeFcall; | 1019 | goto ClunkFid; |
1002 | } | 1020 | } |
1003 | 1021 | ||
1004 | dprintk(DEBUG_VFS, " %s\n", dentry->d_name.name); | 1022 | dprintk(DEBUG_VFS, " %s\n", dentry->d_name.name); |
@@ -1009,8 +1027,10 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
1009 | goto FreeFcall; | 1027 | goto FreeFcall; |
1010 | } | 1028 | } |
1011 | 1029 | ||
1012 | if (!fcall) | 1030 | if (!fcall) { |
1013 | return -EIO; | 1031 | retval = -EIO; |
1032 | goto ClunkFid; | ||
1033 | } | ||
1014 | 1034 | ||
1015 | if (!(fcall->params.rstat.stat.mode & V9FS_DMSYMLINK)) { | 1035 | if (!(fcall->params.rstat.stat.mode & V9FS_DMSYMLINK)) { |
1016 | retval = -EINVAL; | 1036 | retval = -EINVAL; |
@@ -1028,9 +1048,12 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
1028 | fcall->params.rstat.stat.extension.str, buffer); | 1048 | fcall->params.rstat.stat.extension.str, buffer); |
1029 | retval = buflen; | 1049 | retval = buflen; |
1030 | 1050 | ||
1031 | FreeFcall: | 1051 | FreeFcall: |
1032 | kfree(fcall); | 1052 | kfree(fcall); |
1033 | 1053 | ||
1054 | ClunkFid: | ||
1055 | v9fs_fid_clunk(v9ses, fid); | ||
1056 | |||
1034 | return retval; | 1057 | return retval; |
1035 | } | 1058 | } |
1036 | 1059 | ||
@@ -1123,52 +1146,58 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, | |||
1123 | int err; | 1146 | int err; |
1124 | u32 fid, perm; | 1147 | u32 fid, perm; |
1125 | struct v9fs_session_info *v9ses; | 1148 | struct v9fs_session_info *v9ses; |
1126 | struct v9fs_fid *dfid, *vfid; | 1149 | struct v9fs_fid *dfid, *vfid = NULL; |
1127 | struct inode *inode; | 1150 | struct inode *inode = NULL; |
1128 | 1151 | ||
1129 | inode = NULL; | ||
1130 | vfid = NULL; | ||
1131 | v9ses = v9fs_inode2v9ses(dir); | 1152 | v9ses = v9fs_inode2v9ses(dir); |
1132 | dfid = v9fs_fid_lookup(dentry->d_parent); | ||
1133 | perm = unixmode2p9mode(v9ses, mode); | ||
1134 | |||
1135 | if (!v9ses->extended) { | 1153 | if (!v9ses->extended) { |
1136 | dprintk(DEBUG_ERROR, "not extended\n"); | 1154 | dprintk(DEBUG_ERROR, "not extended\n"); |
1137 | return -EPERM; | 1155 | return -EPERM; |
1138 | } | 1156 | } |
1139 | 1157 | ||
1158 | dfid = v9fs_fid_clone(dentry->d_parent); | ||
1159 | if(IS_ERR(dfid)) { | ||
1160 | err = PTR_ERR(dfid); | ||
1161 | goto error; | ||
1162 | } | ||
1163 | |||
1164 | perm = unixmode2p9mode(v9ses, mode); | ||
1165 | |||
1140 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 1166 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, |
1141 | perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL); | 1167 | perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL); |
1142 | 1168 | ||
1143 | if (err) | 1169 | if (err) |
1144 | goto error; | 1170 | goto clunk_dfid; |
1145 | 1171 | ||
1146 | err = v9fs_t_clunk(v9ses, fid); | 1172 | err = v9fs_t_clunk(v9ses, fid); |
1147 | if (err) | 1173 | if (err) |
1148 | goto error; | 1174 | goto clunk_dfid; |
1149 | 1175 | ||
1150 | vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); | 1176 | vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); |
1151 | if (IS_ERR(vfid)) { | 1177 | if (IS_ERR(vfid)) { |
1152 | err = PTR_ERR(vfid); | 1178 | err = PTR_ERR(vfid); |
1153 | vfid = NULL; | 1179 | vfid = NULL; |
1154 | goto error; | 1180 | goto clunk_dfid; |
1155 | } | 1181 | } |
1156 | 1182 | ||
1157 | inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); | 1183 | inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); |
1158 | if (IS_ERR(inode)) { | 1184 | if (IS_ERR(inode)) { |
1159 | err = PTR_ERR(inode); | 1185 | err = PTR_ERR(inode); |
1160 | inode = NULL; | 1186 | inode = NULL; |
1161 | goto error; | 1187 | goto free_vfid; |
1162 | } | 1188 | } |
1163 | 1189 | ||
1164 | dentry->d_op = &v9fs_dentry_operations; | 1190 | dentry->d_op = &v9fs_dentry_operations; |
1165 | d_instantiate(dentry, inode); | 1191 | d_instantiate(dentry, inode); |
1166 | return 0; | 1192 | return 0; |
1167 | 1193 | ||
1168 | error: | 1194 | free_vfid: |
1169 | if (vfid) | 1195 | v9fs_fid_destroy(vfid); |
1170 | v9fs_fid_destroy(vfid); | 1196 | |
1197 | clunk_dfid: | ||
1198 | v9fs_fid_clunk(v9ses, dfid); | ||
1171 | 1199 | ||
1200 | error: | ||
1172 | return err; | 1201 | return err; |
1173 | 1202 | ||
1174 | } | 1203 | } |
@@ -1209,26 +1238,29 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1209 | struct dentry *dentry) | 1238 | struct dentry *dentry) |
1210 | { | 1239 | { |
1211 | int retval; | 1240 | int retval; |
1241 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); | ||
1212 | struct v9fs_fid *oldfid; | 1242 | struct v9fs_fid *oldfid; |
1213 | char *name; | 1243 | char *name; |
1214 | 1244 | ||
1215 | dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, | 1245 | dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, |
1216 | old_dentry->d_name.name); | 1246 | old_dentry->d_name.name); |
1217 | 1247 | ||
1218 | oldfid = v9fs_fid_lookup(old_dentry); | 1248 | oldfid = v9fs_fid_clone(old_dentry); |
1219 | if (!oldfid) { | 1249 | if(IS_ERR(oldfid)) |
1220 | dprintk(DEBUG_ERROR, "can't find oldfid\n"); | 1250 | return PTR_ERR(oldfid); |
1221 | return -EPERM; | ||
1222 | } | ||
1223 | 1251 | ||
1224 | name = __getname(); | 1252 | name = __getname(); |
1225 | if (unlikely(!name)) | 1253 | if (unlikely(!name)) { |
1226 | return -ENOMEM; | 1254 | retval = -ENOMEM; |
1255 | goto clunk_fid; | ||
1256 | } | ||
1227 | 1257 | ||
1228 | sprintf(name, "%d\n", oldfid->fid); | 1258 | sprintf(name, "%d\n", oldfid->fid); |
1229 | retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); | 1259 | retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); |
1230 | __putname(name); | 1260 | __putname(name); |
1231 | 1261 | ||
1262 | clunk_fid: | ||
1263 | v9fs_fid_clunk(v9ses, oldfid); | ||
1232 | return retval; | 1264 | return retval; |
1233 | } | 1265 | } |
1234 | 1266 | ||
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 7cb28720f90..669dbe5b031 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -682,6 +682,15 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
682 | retval = PTR_ERR(interpreter); | 682 | retval = PTR_ERR(interpreter); |
683 | if (IS_ERR(interpreter)) | 683 | if (IS_ERR(interpreter)) |
684 | goto out_free_interp; | 684 | goto out_free_interp; |
685 | |||
686 | /* | ||
687 | * If the binary is not readable then enforce | ||
688 | * mm->dumpable = 0 regardless of the interpreter's | ||
689 | * permissions. | ||
690 | */ | ||
691 | if (file_permission(interpreter, MAY_READ) < 0) | ||
692 | bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP; | ||
693 | |||
685 | retval = kernel_read(interpreter, 0, bprm->buf, | 694 | retval = kernel_read(interpreter, 0, bprm->buf, |
686 | BINPRM_BUF_SIZE); | 695 | BINPRM_BUF_SIZE); |
687 | if (retval != BINPRM_BUF_SIZE) { | 696 | if (retval != BINPRM_BUF_SIZE) { |
@@ -1178,6 +1187,10 @@ static int dump_seek(struct file *file, loff_t off) | |||
1178 | */ | 1187 | */ |
1179 | static int maydump(struct vm_area_struct *vma) | 1188 | static int maydump(struct vm_area_struct *vma) |
1180 | { | 1189 | { |
1190 | /* The vma can be set up to tell us the answer directly. */ | ||
1191 | if (vma->vm_flags & VM_ALWAYSDUMP) | ||
1192 | return 1; | ||
1193 | |||
1181 | /* Do not dump I/O mapped devices or special mappings */ | 1194 | /* Do not dump I/O mapped devices or special mappings */ |
1182 | if (vma->vm_flags & (VM_IO | VM_RESERVED)) | 1195 | if (vma->vm_flags & (VM_IO | VM_RESERVED)) |
1183 | return 0; | 1196 | return 0; |
@@ -1424,6 +1437,32 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t) | |||
1424 | return sz; | 1437 | return sz; |
1425 | } | 1438 | } |
1426 | 1439 | ||
1440 | static struct vm_area_struct *first_vma(struct task_struct *tsk, | ||
1441 | struct vm_area_struct *gate_vma) | ||
1442 | { | ||
1443 | struct vm_area_struct *ret = tsk->mm->mmap; | ||
1444 | |||
1445 | if (ret) | ||
1446 | return ret; | ||
1447 | return gate_vma; | ||
1448 | } | ||
1449 | /* | ||
1450 | * Helper function for iterating across a vma list. It ensures that the caller | ||
1451 | * will visit `gate_vma' prior to terminating the search. | ||
1452 | */ | ||
1453 | static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma, | ||
1454 | struct vm_area_struct *gate_vma) | ||
1455 | { | ||
1456 | struct vm_area_struct *ret; | ||
1457 | |||
1458 | ret = this_vma->vm_next; | ||
1459 | if (ret) | ||
1460 | return ret; | ||
1461 | if (this_vma == gate_vma) | ||
1462 | return NULL; | ||
1463 | return gate_vma; | ||
1464 | } | ||
1465 | |||
1427 | /* | 1466 | /* |
1428 | * Actual dumper | 1467 | * Actual dumper |
1429 | * | 1468 | * |
@@ -1439,7 +1478,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1439 | int segs; | 1478 | int segs; |
1440 | size_t size = 0; | 1479 | size_t size = 0; |
1441 | int i; | 1480 | int i; |
1442 | struct vm_area_struct *vma; | 1481 | struct vm_area_struct *vma, *gate_vma; |
1443 | struct elfhdr *elf = NULL; | 1482 | struct elfhdr *elf = NULL; |
1444 | loff_t offset = 0, dataoff, foffset; | 1483 | loff_t offset = 0, dataoff, foffset; |
1445 | unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; | 1484 | unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; |
@@ -1525,6 +1564,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1525 | segs += ELF_CORE_EXTRA_PHDRS; | 1564 | segs += ELF_CORE_EXTRA_PHDRS; |
1526 | #endif | 1565 | #endif |
1527 | 1566 | ||
1567 | gate_vma = get_gate_vma(current); | ||
1568 | if (gate_vma != NULL) | ||
1569 | segs++; | ||
1570 | |||
1528 | /* Set up header */ | 1571 | /* Set up header */ |
1529 | fill_elf_header(elf, segs + 1); /* including notes section */ | 1572 | fill_elf_header(elf, segs + 1); /* including notes section */ |
1530 | 1573 | ||
@@ -1592,7 +1635,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1592 | dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); | 1635 | dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); |
1593 | 1636 | ||
1594 | /* Write program headers for segments dump */ | 1637 | /* Write program headers for segments dump */ |
1595 | for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { | 1638 | for (vma = first_vma(current, gate_vma); vma != NULL; |
1639 | vma = next_vma(vma, gate_vma)) { | ||
1596 | struct elf_phdr phdr; | 1640 | struct elf_phdr phdr; |
1597 | size_t sz; | 1641 | size_t sz; |
1598 | 1642 | ||
@@ -1641,7 +1685,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1641 | /* Align to page */ | 1685 | /* Align to page */ |
1642 | DUMP_SEEK(dataoff - foffset); | 1686 | DUMP_SEEK(dataoff - foffset); |
1643 | 1687 | ||
1644 | for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { | 1688 | for (vma = first_vma(current, gate_vma); vma != NULL; |
1689 | vma = next_vma(vma, gate_vma)) { | ||
1645 | unsigned long addr; | 1690 | unsigned long addr; |
1646 | 1691 | ||
1647 | if (!maydump(vma)) | 1692 | if (!maydump(vma)) |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 6e6d4568d54..a4d933a5120 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -234,6 +234,14 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, | |||
234 | goto error; | 234 | goto error; |
235 | } | 235 | } |
236 | 236 | ||
237 | /* | ||
238 | * If the binary is not readable then enforce | ||
239 | * mm->dumpable = 0 regardless of the interpreter's | ||
240 | * permissions. | ||
241 | */ | ||
242 | if (file_permission(interpreter, MAY_READ) < 0) | ||
243 | bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP; | ||
244 | |||
237 | retval = kernel_read(interpreter, 0, bprm->buf, | 245 | retval = kernel_read(interpreter, 0, bprm->buf, |
238 | BINPRM_BUF_SIZE); | 246 | BINPRM_BUF_SIZE); |
239 | if (retval < 0) | 247 | if (retval < 0) |
diff --git a/fs/buffer.c b/fs/buffer.c index 3b116078b4c..460f1c43238 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -2834,7 +2834,7 @@ int try_to_free_buffers(struct page *page) | |||
2834 | int ret = 0; | 2834 | int ret = 0; |
2835 | 2835 | ||
2836 | BUG_ON(!PageLocked(page)); | 2836 | BUG_ON(!PageLocked(page)); |
2837 | if (PageDirty(page) || PageWriteback(page)) | 2837 | if (PageWriteback(page)) |
2838 | return 0; | 2838 | return 0; |
2839 | 2839 | ||
2840 | if (mapping == NULL) { /* can this still happen? */ | 2840 | if (mapping == NULL) { /* can this still happen? */ |
@@ -2845,6 +2845,19 @@ int try_to_free_buffers(struct page *page) | |||
2845 | spin_lock(&mapping->private_lock); | 2845 | spin_lock(&mapping->private_lock); |
2846 | ret = drop_buffers(page, &buffers_to_free); | 2846 | ret = drop_buffers(page, &buffers_to_free); |
2847 | spin_unlock(&mapping->private_lock); | 2847 | spin_unlock(&mapping->private_lock); |
2848 | |||
2849 | /* | ||
2850 | * If the filesystem writes its buffers by hand (eg ext3) | ||
2851 | * then we can have clean buffers against a dirty page. We | ||
2852 | * clean the page here; otherwise the VM will never notice | ||
2853 | * that the filesystem did any IO at all. | ||
2854 | * | ||
2855 | * Also, during truncate, discard_buffer will have marked all | ||
2856 | * the page's buffers clean. We discover that here and clean | ||
2857 | * the page also. | ||
2858 | */ | ||
2859 | if (ret) | ||
2860 | cancel_dirty_page(page, PAGE_CACHE_SIZE); | ||
2848 | out: | 2861 | out: |
2849 | if (buffers_to_free) { | 2862 | if (buffers_to_free) { |
2850 | struct buffer_head *bh = buffers_to_free; | 2863 | struct buffer_head *bh = buffers_to_free; |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index c403b66ec83..a4b142a6a2c 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -251,8 +251,19 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
251 | WARN_ON(inode->i_state & I_WILL_FREE); | 251 | WARN_ON(inode->i_state & I_WILL_FREE); |
252 | 252 | ||
253 | if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) { | 253 | if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) { |
254 | struct address_space *mapping = inode->i_mapping; | ||
255 | int ret; | ||
256 | |||
254 | list_move(&inode->i_list, &inode->i_sb->s_dirty); | 257 | list_move(&inode->i_list, &inode->i_sb->s_dirty); |
255 | return 0; | 258 | |
259 | /* | ||
260 | * Even if we don't actually write the inode itself here, | ||
261 | * we can at least start some of the data writeout.. | ||
262 | */ | ||
263 | spin_unlock(&inode_lock); | ||
264 | ret = do_writepages(mapping, wbc); | ||
265 | spin_lock(&inode_lock); | ||
266 | return ret; | ||
256 | } | 267 | } |
257 | 268 | ||
258 | /* | 269 | /* |
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 277df40f098..e695660921e 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -990,15 +990,16 @@ encode_entry(struct readdir_cd *ccd, const char *name, | |||
990 | } | 990 | } |
991 | 991 | ||
992 | int | 992 | int |
993 | nfs3svc_encode_entry(struct readdir_cd *cd, const char *name, | 993 | nfs3svc_encode_entry(void *cd, const char *name, |
994 | int namlen, loff_t offset, ino_t ino, unsigned int d_type) | 994 | int namlen, loff_t offset, u64 ino, unsigned int d_type) |
995 | { | 995 | { |
996 | return encode_entry(cd, name, namlen, offset, ino, d_type, 0); | 996 | return encode_entry(cd, name, namlen, offset, ino, d_type, 0); |
997 | } | 997 | } |
998 | 998 | ||
999 | int | 999 | int |
1000 | nfs3svc_encode_entry_plus(struct readdir_cd *cd, const char *name, | 1000 | nfs3svc_encode_entry_plus(void *cd, const char *name, |
1001 | int namlen, loff_t offset, ino_t ino, unsigned int d_type) | 1001 | int namlen, loff_t offset, u64 ino, |
1002 | unsigned int d_type) | ||
1002 | { | 1003 | { |
1003 | return encode_entry(cd, name, namlen, offset, ino, d_type, 1); | 1004 | return encode_entry(cd, name, namlen, offset, ino, d_type, 1); |
1004 | } | 1005 | } |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index fea46368afb..18aa9440df1 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -1880,9 +1880,10 @@ nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr) | |||
1880 | } | 1880 | } |
1881 | 1881 | ||
1882 | static int | 1882 | static int |
1883 | nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen, | 1883 | nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, |
1884 | loff_t offset, ino_t ino, unsigned int d_type) | 1884 | loff_t offset, u64 ino, unsigned int d_type) |
1885 | { | 1885 | { |
1886 | struct readdir_cd *ccd = ccdv; | ||
1886 | struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); | 1887 | struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); |
1887 | int buflen; | 1888 | int buflen; |
1888 | __be32 *p = cd->buffer; | 1889 | __be32 *p = cd->buffer; |
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 0aaccb03bf7..fbf5d51947e 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
@@ -72,7 +72,7 @@ static struct svc_program nfsd_acl_program = { | |||
72 | .pg_prog = NFS_ACL_PROGRAM, | 72 | .pg_prog = NFS_ACL_PROGRAM, |
73 | .pg_nvers = NFSD_ACL_NRVERS, | 73 | .pg_nvers = NFSD_ACL_NRVERS, |
74 | .pg_vers = nfsd_acl_versions, | 74 | .pg_vers = nfsd_acl_versions, |
75 | .pg_name = "nfsd", | 75 | .pg_name = "nfsacl", |
76 | .pg_class = "nfsd", | 76 | .pg_class = "nfsd", |
77 | .pg_stats = &nfsd_acl_svcstats, | 77 | .pg_stats = &nfsd_acl_svcstats, |
78 | .pg_authenticate = &svc_set_client, | 78 | .pg_authenticate = &svc_set_client, |
@@ -118,16 +118,16 @@ int nfsd_vers(int vers, enum vers_op change) | |||
118 | switch(change) { | 118 | switch(change) { |
119 | case NFSD_SET: | 119 | case NFSD_SET: |
120 | nfsd_versions[vers] = nfsd_version[vers]; | 120 | nfsd_versions[vers] = nfsd_version[vers]; |
121 | break; | ||
122 | #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) | 121 | #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) |
123 | if (vers < NFSD_ACL_NRVERS) | 122 | if (vers < NFSD_ACL_NRVERS) |
124 | nfsd_acl_version[vers] = nfsd_acl_version[vers]; | 123 | nfsd_acl_versions[vers] = nfsd_acl_version[vers]; |
125 | #endif | 124 | #endif |
125 | break; | ||
126 | case NFSD_CLEAR: | 126 | case NFSD_CLEAR: |
127 | nfsd_versions[vers] = NULL; | 127 | nfsd_versions[vers] = NULL; |
128 | #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) | 128 | #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) |
129 | if (vers < NFSD_ACL_NRVERS) | 129 | if (vers < NFSD_ACL_NRVERS) |
130 | nfsd_acl_version[vers] = NULL; | 130 | nfsd_acl_versions[vers] = NULL; |
131 | #endif | 131 | #endif |
132 | break; | 132 | break; |
133 | case NFSD_TEST: | 133 | case NFSD_TEST: |
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index f5243f94399..6555c50d900 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c | |||
@@ -462,9 +462,10 @@ nfssvc_encode_statfsres(struct svc_rqst *rqstp, __be32 *p, | |||
462 | } | 462 | } |
463 | 463 | ||
464 | int | 464 | int |
465 | nfssvc_encode_entry(struct readdir_cd *ccd, const char *name, | 465 | nfssvc_encode_entry(void *ccdv, const char *name, |
466 | int namlen, loff_t offset, ino_t ino, unsigned int d_type) | 466 | int namlen, loff_t offset, u64 ino, unsigned int d_type) |
467 | { | 467 | { |
468 | struct readdir_cd *ccd = ccdv; | ||
468 | struct nfsd_readdirres *cd = container_of(ccd, struct nfsd_readdirres, common); | 469 | struct nfsd_readdirres *cd = container_of(ccd, struct nfsd_readdirres, common); |
469 | __be32 *p = cd->buffer; | 470 | __be32 *p = cd->buffer; |
470 | int buflen, slen; | 471 | int buflen, slen; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 7a79c23aa6d..5d32e5fa697 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -822,7 +822,8 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset | |||
822 | rqstp->rq_res.page_len = size; | 822 | rqstp->rq_res.page_len = size; |
823 | } else if (page != pp[-1]) { | 823 | } else if (page != pp[-1]) { |
824 | get_page(page); | 824 | get_page(page); |
825 | put_page(*pp); | 825 | if (*pp) |
826 | put_page(*pp); | ||
826 | *pp = page; | 827 | *pp = page; |
827 | rqstp->rq_resused++; | 828 | rqstp->rq_resused++; |
828 | rqstp->rq_res.page_len += size; | 829 | rqstp->rq_res.page_len += size; |
@@ -1244,7 +1245,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1244 | __be32 err; | 1245 | __be32 err; |
1245 | int host_err; | 1246 | int host_err; |
1246 | __u32 v_mtime=0, v_atime=0; | 1247 | __u32 v_mtime=0, v_atime=0; |
1247 | int v_mode=0; | ||
1248 | 1248 | ||
1249 | err = nfserr_perm; | 1249 | err = nfserr_perm; |
1250 | if (!flen) | 1250 | if (!flen) |
@@ -1281,16 +1281,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1281 | goto out; | 1281 | goto out; |
1282 | 1282 | ||
1283 | if (createmode == NFS3_CREATE_EXCLUSIVE) { | 1283 | if (createmode == NFS3_CREATE_EXCLUSIVE) { |
1284 | /* while the verifier would fit in mtime+atime, | 1284 | /* solaris7 gets confused (bugid 4218508) if these have |
1285 | * solaris7 gets confused (bugid 4218508) if these have | 1285 | * the high bit set, so just clear the high bits. |
1286 | * the high bit set, so we use the mode as well | ||
1287 | */ | 1286 | */ |
1288 | v_mtime = verifier[0]&0x7fffffff; | 1287 | v_mtime = verifier[0]&0x7fffffff; |
1289 | v_atime = verifier[1]&0x7fffffff; | 1288 | v_atime = verifier[1]&0x7fffffff; |
1290 | v_mode = S_IFREG | ||
1291 | | ((verifier[0]&0x80000000) >> (32-7)) /* u+x */ | ||
1292 | | ((verifier[1]&0x80000000) >> (32-9)) /* u+r */ | ||
1293 | ; | ||
1294 | } | 1289 | } |
1295 | 1290 | ||
1296 | if (dchild->d_inode) { | 1291 | if (dchild->d_inode) { |
@@ -1318,7 +1313,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1318 | case NFS3_CREATE_EXCLUSIVE: | 1313 | case NFS3_CREATE_EXCLUSIVE: |
1319 | if ( dchild->d_inode->i_mtime.tv_sec == v_mtime | 1314 | if ( dchild->d_inode->i_mtime.tv_sec == v_mtime |
1320 | && dchild->d_inode->i_atime.tv_sec == v_atime | 1315 | && dchild->d_inode->i_atime.tv_sec == v_atime |
1321 | && dchild->d_inode->i_mode == v_mode | ||
1322 | && dchild->d_inode->i_size == 0 ) | 1316 | && dchild->d_inode->i_size == 0 ) |
1323 | break; | 1317 | break; |
1324 | /* fallthru */ | 1318 | /* fallthru */ |
@@ -1340,26 +1334,22 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1340 | } | 1334 | } |
1341 | 1335 | ||
1342 | if (createmode == NFS3_CREATE_EXCLUSIVE) { | 1336 | if (createmode == NFS3_CREATE_EXCLUSIVE) { |
1343 | /* Cram the verifier into atime/mtime/mode */ | 1337 | /* Cram the verifier into atime/mtime */ |
1344 | iap->ia_valid = ATTR_MTIME|ATTR_ATIME | 1338 | iap->ia_valid = ATTR_MTIME|ATTR_ATIME |
1345 | | ATTR_MTIME_SET|ATTR_ATIME_SET | 1339 | | ATTR_MTIME_SET|ATTR_ATIME_SET; |
1346 | | ATTR_MODE; | ||
1347 | /* XXX someone who knows this better please fix it for nsec */ | 1340 | /* XXX someone who knows this better please fix it for nsec */ |
1348 | iap->ia_mtime.tv_sec = v_mtime; | 1341 | iap->ia_mtime.tv_sec = v_mtime; |
1349 | iap->ia_atime.tv_sec = v_atime; | 1342 | iap->ia_atime.tv_sec = v_atime; |
1350 | iap->ia_mtime.tv_nsec = 0; | 1343 | iap->ia_mtime.tv_nsec = 0; |
1351 | iap->ia_atime.tv_nsec = 0; | 1344 | iap->ia_atime.tv_nsec = 0; |
1352 | iap->ia_mode = v_mode; | ||
1353 | } | 1345 | } |
1354 | 1346 | ||
1355 | /* Set file attributes. | 1347 | /* Set file attributes. |
1356 | * Mode has already been set but we might need to reset it | ||
1357 | * for CREATE_EXCLUSIVE | ||
1358 | * Irix appears to send along the gid when it tries to | 1348 | * Irix appears to send along the gid when it tries to |
1359 | * implement setgid directories via NFS. Clear out all that cruft. | 1349 | * implement setgid directories via NFS. Clear out all that cruft. |
1360 | */ | 1350 | */ |
1361 | set_attr: | 1351 | set_attr: |
1362 | if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) { | 1352 | if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) { |
1363 | __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); | 1353 | __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); |
1364 | if (err2) | 1354 | if (err2) |
1365 | err = err2; | 1355 | err = err2; |
@@ -1726,7 +1716,7 @@ out: | |||
1726 | */ | 1716 | */ |
1727 | __be32 | 1717 | __be32 |
1728 | nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, | 1718 | nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, |
1729 | struct readdir_cd *cdp, encode_dent_fn func) | 1719 | struct readdir_cd *cdp, filldir_t func) |
1730 | { | 1720 | { |
1731 | __be32 err; | 1721 | __be32 err; |
1732 | int host_err; | 1722 | int host_err; |
@@ -1751,7 +1741,7 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, | |||
1751 | 1741 | ||
1752 | do { | 1742 | do { |
1753 | cdp->err = nfserr_eof; /* will be cleared on successful read */ | 1743 | cdp->err = nfserr_eof; /* will be cleared on successful read */ |
1754 | host_err = vfs_readdir(file, (filldir_t) func, cdp); | 1744 | host_err = vfs_readdir(file, func, cdp); |
1755 | } while (host_err >=0 && cdp->err == nfs_ok); | 1745 | } while (host_err >=0 && cdp->err == nfs_ok); |
1756 | if (host_err) | 1746 | if (host_err) |
1757 | err = nfserrno(host_err); | 1747 | err = nfserrno(host_err); |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 77a57b5799c..ff7a6685060 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -371,9 +371,11 @@ static int mounts_open(struct inode *inode, struct file *file) | |||
371 | 371 | ||
372 | if (task) { | 372 | if (task) { |
373 | task_lock(task); | 373 | task_lock(task); |
374 | ns = task->nsproxy->mnt_ns; | 374 | if (task->nsproxy) { |
375 | if (ns) | 375 | ns = task->nsproxy->mnt_ns; |
376 | get_mnt_ns(ns); | 376 | if (ns) |
377 | get_mnt_ns(ns); | ||
378 | } | ||
377 | task_unlock(task); | 379 | task_unlock(task); |
378 | put_task_struct(task); | 380 | put_task_struct(task); |
379 | } | 381 | } |
diff --git a/include/asm-generic/libata-portmap.h b/include/asm-generic/libata-portmap.h index 9202fd02d5b..62fb3618293 100644 --- a/include/asm-generic/libata-portmap.h +++ b/include/asm-generic/libata-portmap.h | |||
@@ -3,10 +3,10 @@ | |||
3 | 3 | ||
4 | #define ATA_PRIMARY_CMD 0x1F0 | 4 | #define ATA_PRIMARY_CMD 0x1F0 |
5 | #define ATA_PRIMARY_CTL 0x3F6 | 5 | #define ATA_PRIMARY_CTL 0x3F6 |
6 | #define ATA_PRIMARY_IRQ 14 | 6 | #define ATA_PRIMARY_IRQ(dev) 14 |
7 | 7 | ||
8 | #define ATA_SECONDARY_CMD 0x170 | 8 | #define ATA_SECONDARY_CMD 0x170 |
9 | #define ATA_SECONDARY_CTL 0x376 | 9 | #define ATA_SECONDARY_CTL 0x376 |
10 | #define ATA_SECONDARY_IRQ 15 | 10 | #define ATA_SECONDARY_IRQ(dev) 15 |
11 | 11 | ||
12 | #endif | 12 | #endif |
diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h index 45d21a0c95b..369035dfe4b 100644 --- a/include/asm-i386/elf.h +++ b/include/asm-i386/elf.h | |||
@@ -143,11 +143,8 @@ extern int dump_task_extended_fpu (struct task_struct *, struct user_fxsr_struct | |||
143 | # define VDSO_PRELINK 0 | 143 | # define VDSO_PRELINK 0 |
144 | #endif | 144 | #endif |
145 | 145 | ||
146 | #define VDSO_COMPAT_SYM(x) \ | ||
147 | (VDSO_COMPAT_BASE + (unsigned long)(x) - VDSO_PRELINK) | ||
148 | |||
149 | #define VDSO_SYM(x) \ | 146 | #define VDSO_SYM(x) \ |
150 | (VDSO_BASE + (unsigned long)(x) - VDSO_PRELINK) | 147 | (VDSO_COMPAT_BASE + (unsigned long)(x) - VDSO_PRELINK) |
151 | 148 | ||
152 | #define VDSO_HIGH_EHDR ((const struct elfhdr *) VDSO_HIGH_BASE) | 149 | #define VDSO_HIGH_EHDR ((const struct elfhdr *) VDSO_HIGH_BASE) |
153 | #define VDSO_EHDR ((const struct elfhdr *) VDSO_COMPAT_BASE) | 150 | #define VDSO_EHDR ((const struct elfhdr *) VDSO_COMPAT_BASE) |
@@ -156,10 +153,12 @@ extern void __kernel_vsyscall; | |||
156 | 153 | ||
157 | #define VDSO_ENTRY VDSO_SYM(&__kernel_vsyscall) | 154 | #define VDSO_ENTRY VDSO_SYM(&__kernel_vsyscall) |
158 | 155 | ||
156 | #ifndef CONFIG_COMPAT_VDSO | ||
159 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES | 157 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES |
160 | struct linux_binprm; | 158 | struct linux_binprm; |
161 | extern int arch_setup_additional_pages(struct linux_binprm *bprm, | 159 | extern int arch_setup_additional_pages(struct linux_binprm *bprm, |
162 | int executable_stack); | 160 | int executable_stack); |
161 | #endif | ||
163 | 162 | ||
164 | extern unsigned int vdso_enabled; | 163 | extern unsigned int vdso_enabled; |
165 | 164 | ||
@@ -169,50 +168,6 @@ do if (vdso_enabled) { \ | |||
169 | NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_COMPAT_BASE); \ | 168 | NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_COMPAT_BASE); \ |
170 | } while (0) | 169 | } while (0) |
171 | 170 | ||
172 | /* | ||
173 | * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out | ||
174 | * extra segments containing the vsyscall DSO contents. Dumping its | ||
175 | * contents makes post-mortem fully interpretable later without matching up | ||
176 | * the same kernel and hardware config to see what PC values meant. | ||
177 | * Dumping its extra ELF program headers includes all the other information | ||
178 | * a debugger needs to easily find how the vsyscall DSO was being used. | ||
179 | */ | ||
180 | #define ELF_CORE_EXTRA_PHDRS (VDSO_HIGH_EHDR->e_phnum) | ||
181 | #define ELF_CORE_WRITE_EXTRA_PHDRS \ | ||
182 | do { \ | ||
183 | const struct elf_phdr *const vsyscall_phdrs = \ | ||
184 | (const struct elf_phdr *) (VDSO_HIGH_BASE \ | ||
185 | + VDSO_HIGH_EHDR->e_phoff); \ | ||
186 | int i; \ | ||
187 | Elf32_Off ofs = 0; \ | ||
188 | for (i = 0; i < VDSO_HIGH_EHDR->e_phnum; ++i) { \ | ||
189 | struct elf_phdr phdr = vsyscall_phdrs[i]; \ | ||
190 | if (phdr.p_type == PT_LOAD) { \ | ||
191 | BUG_ON(ofs != 0); \ | ||
192 | ofs = phdr.p_offset = offset; \ | ||
193 | phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \ | ||
194 | phdr.p_filesz = phdr.p_memsz; \ | ||
195 | offset += phdr.p_filesz; \ | ||
196 | } \ | ||
197 | else \ | ||
198 | phdr.p_offset += ofs; \ | ||
199 | phdr.p_paddr = 0; /* match other core phdrs */ \ | ||
200 | DUMP_WRITE(&phdr, sizeof(phdr)); \ | ||
201 | } \ | ||
202 | } while (0) | ||
203 | #define ELF_CORE_WRITE_EXTRA_DATA \ | ||
204 | do { \ | ||
205 | const struct elf_phdr *const vsyscall_phdrs = \ | ||
206 | (const struct elf_phdr *) (VDSO_HIGH_BASE \ | ||
207 | + VDSO_HIGH_EHDR->e_phoff); \ | ||
208 | int i; \ | ||
209 | for (i = 0; i < VDSO_HIGH_EHDR->e_phnum; ++i) { \ | ||
210 | if (vsyscall_phdrs[i].p_type == PT_LOAD) \ | ||
211 | DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr, \ | ||
212 | PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ | ||
213 | } \ | ||
214 | } while (0) | ||
215 | |||
216 | #endif | 171 | #endif |
217 | 172 | ||
218 | #endif | 173 | #endif |
diff --git a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h index 02428cb3662..3e9f610c35d 100644 --- a/include/asm-i386/fixmap.h +++ b/include/asm-i386/fixmap.h | |||
@@ -23,6 +23,8 @@ | |||
23 | extern unsigned long __FIXADDR_TOP; | 23 | extern unsigned long __FIXADDR_TOP; |
24 | #else | 24 | #else |
25 | #define __FIXADDR_TOP 0xfffff000 | 25 | #define __FIXADDR_TOP 0xfffff000 |
26 | #define FIXADDR_USER_START __fix_to_virt(FIX_VDSO) | ||
27 | #define FIXADDR_USER_END __fix_to_virt(FIX_VDSO - 1) | ||
26 | #endif | 28 | #endif |
27 | 29 | ||
28 | #ifndef __ASSEMBLY__ | 30 | #ifndef __ASSEMBLY__ |
diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h index fd3f64ace24..7b19f454761 100644 --- a/include/asm-i386/page.h +++ b/include/asm-i386/page.h | |||
@@ -143,7 +143,9 @@ extern int page_is_ram(unsigned long pagenr); | |||
143 | #include <asm-generic/memory_model.h> | 143 | #include <asm-generic/memory_model.h> |
144 | #include <asm-generic/page.h> | 144 | #include <asm-generic/page.h> |
145 | 145 | ||
146 | #ifndef CONFIG_COMPAT_VDSO | ||
146 | #define __HAVE_ARCH_GATE_AREA 1 | 147 | #define __HAVE_ARCH_GATE_AREA 1 |
148 | #endif | ||
147 | #endif /* __KERNEL__ */ | 149 | #endif /* __KERNEL__ */ |
148 | 150 | ||
149 | #endif /* _I386_PAGE_H */ | 151 | #endif /* _I386_PAGE_H */ |
diff --git a/include/asm-powerpc/libata-portmap.h b/include/asm-powerpc/libata-portmap.h new file mode 100644 index 00000000000..4d8518049f4 --- /dev/null +++ b/include/asm-powerpc/libata-portmap.h | |||
@@ -0,0 +1,12 @@ | |||
1 | #ifndef __ASM_POWERPC_LIBATA_PORTMAP_H | ||
2 | #define __ASM_POWERPC_LIBATA_PORTMAP_H | ||
3 | |||
4 | #define ATA_PRIMARY_CMD 0x1F0 | ||
5 | #define ATA_PRIMARY_CTL 0x3F6 | ||
6 | #define ATA_PRIMARY_IRQ(dev) pci_get_legacy_ide_irq(dev, 0) | ||
7 | |||
8 | #define ATA_SECONDARY_CMD 0x170 | ||
9 | #define ATA_SECONDARY_CTL 0x376 | ||
10 | #define ATA_SECONDARY_IRQ(dev) pci_get_legacy_ide_irq(dev, 1) | ||
11 | |||
12 | #endif | ||
diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h index d5dbc87274f..c0eac519840 100644 --- a/include/asm-x86_64/uaccess.h +++ b/include/asm-x86_64/uaccess.h | |||
@@ -157,7 +157,7 @@ do { \ | |||
157 | case 1: __put_user_asm(x,ptr,retval,"b","b","iq",-EFAULT); break;\ | 157 | case 1: __put_user_asm(x,ptr,retval,"b","b","iq",-EFAULT); break;\ |
158 | case 2: __put_user_asm(x,ptr,retval,"w","w","ir",-EFAULT); break;\ | 158 | case 2: __put_user_asm(x,ptr,retval,"w","w","ir",-EFAULT); break;\ |
159 | case 4: __put_user_asm(x,ptr,retval,"l","k","ir",-EFAULT); break;\ | 159 | case 4: __put_user_asm(x,ptr,retval,"l","k","ir",-EFAULT); break;\ |
160 | case 8: __put_user_asm(x,ptr,retval,"q","","ir",-EFAULT); break;\ | 160 | case 8: __put_user_asm(x,ptr,retval,"q","","Zr",-EFAULT); break;\ |
161 | default: __put_user_bad(); \ | 161 | default: __put_user_bad(); \ |
162 | } \ | 162 | } \ |
163 | } while (0) | 163 | } while (0) |
diff --git a/include/linux/bitops.h b/include/linux/bitops.h index 5d1eabcde5d..638165f571d 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h | |||
@@ -31,9 +31,8 @@ static inline unsigned long hweight_long(unsigned long w) | |||
31 | return sizeof(w) == 4 ? hweight32(w) : hweight64(w); | 31 | return sizeof(w) == 4 ? hweight32(w) : hweight64(w); |
32 | } | 32 | } |
33 | 33 | ||
34 | /* | 34 | /** |
35 | * rol32 - rotate a 32-bit value left | 35 | * rol32 - rotate a 32-bit value left |
36 | * | ||
37 | * @word: value to rotate | 36 | * @word: value to rotate |
38 | * @shift: bits to roll | 37 | * @shift: bits to roll |
39 | */ | 38 | */ |
@@ -42,9 +41,8 @@ static inline __u32 rol32(__u32 word, unsigned int shift) | |||
42 | return (word << shift) | (word >> (32 - shift)); | 41 | return (word << shift) | (word >> (32 - shift)); |
43 | } | 42 | } |
44 | 43 | ||
45 | /* | 44 | /** |
46 | * ror32 - rotate a 32-bit value right | 45 | * ror32 - rotate a 32-bit value right |
47 | * | ||
48 | * @word: value to rotate | 46 | * @word: value to rotate |
49 | * @shift: bits to roll | 47 | * @shift: bits to roll |
50 | */ | 48 | */ |
diff --git a/include/linux/kvm.h b/include/linux/kvm.h index bc8b4616bad..1be148f0fce 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h | |||
@@ -46,6 +46,7 @@ enum kvm_exit_reason { | |||
46 | KVM_EXIT_HLT = 5, | 46 | KVM_EXIT_HLT = 5, |
47 | KVM_EXIT_MMIO = 6, | 47 | KVM_EXIT_MMIO = 6, |
48 | KVM_EXIT_IRQ_WINDOW_OPEN = 7, | 48 | KVM_EXIT_IRQ_WINDOW_OPEN = 7, |
49 | KVM_EXIT_SHUTDOWN = 8, | ||
49 | }; | 50 | }; |
50 | 51 | ||
51 | /* for KVM_RUN */ | 52 | /* for KVM_RUN */ |
diff --git a/include/linux/libata.h b/include/linux/libata.h index f7f268e3874..22aa69e2090 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -177,6 +177,7 @@ enum { | |||
177 | * Register FIS clearing BSY */ | 177 | * Register FIS clearing BSY */ |
178 | ATA_FLAG_DEBUGMSG = (1 << 13), | 178 | ATA_FLAG_DEBUGMSG = (1 << 13), |
179 | ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */ | 179 | ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */ |
180 | ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */ | ||
180 | 181 | ||
181 | /* The following flag belongs to ap->pflags but is kept in | 182 | /* The following flag belongs to ap->pflags but is kept in |
182 | * ap->flags because it's referenced in many LLDs and will be | 183 | * ap->flags because it's referenced in many LLDs and will be |
@@ -612,11 +613,11 @@ struct ata_port_operations { | |||
612 | void (*dev_select)(struct ata_port *ap, unsigned int device); | 613 | void (*dev_select)(struct ata_port *ap, unsigned int device); |
613 | 614 | ||
614 | void (*phy_reset) (struct ata_port *ap); /* obsolete */ | 615 | void (*phy_reset) (struct ata_port *ap); /* obsolete */ |
615 | void (*set_mode) (struct ata_port *ap); | 616 | int (*set_mode) (struct ata_port *ap, struct ata_device **r_failed_dev); |
616 | 617 | ||
617 | void (*post_set_mode) (struct ata_port *ap); | 618 | void (*post_set_mode) (struct ata_port *ap); |
618 | 619 | ||
619 | int (*check_atapi_dma) (struct ata_queued_cmd *qc); | 620 | int (*check_atapi_dma) (struct ata_queued_cmd *qc); |
620 | 621 | ||
621 | void (*bmdma_setup) (struct ata_queued_cmd *qc); | 622 | void (*bmdma_setup) (struct ata_queued_cmd *qc); |
622 | void (*bmdma_start) (struct ata_queued_cmd *qc); | 623 | void (*bmdma_start) (struct ata_queued_cmd *qc); |
diff --git a/include/linux/list.h b/include/linux/list.h index a9c90287c0f..611059d633f 100644 --- a/include/linux/list.h +++ b/include/linux/list.h | |||
@@ -227,13 +227,13 @@ static inline void list_replace_init(struct list_head *old, | |||
227 | INIT_LIST_HEAD(old); | 227 | INIT_LIST_HEAD(old); |
228 | } | 228 | } |
229 | 229 | ||
230 | /* | 230 | /** |
231 | * list_replace_rcu - replace old entry by new one | 231 | * list_replace_rcu - replace old entry by new one |
232 | * @old : the element to be replaced | 232 | * @old : the element to be replaced |
233 | * @new : the new element to insert | 233 | * @new : the new element to insert |
234 | * | 234 | * |
235 | * The old entry will be replaced with the new entry atomically. | 235 | * The @old entry will be replaced with the @new entry atomically. |
236 | * Note: 'old' should not be empty. | 236 | * Note: @old should not be empty. |
237 | */ | 237 | */ |
238 | static inline void list_replace_rcu(struct list_head *old, | 238 | static inline void list_replace_rcu(struct list_head *old, |
239 | struct list_head *new) | 239 | struct list_head *new) |
@@ -680,12 +680,12 @@ static inline void hlist_del_init(struct hlist_node *n) | |||
680 | } | 680 | } |
681 | } | 681 | } |
682 | 682 | ||
683 | /* | 683 | /** |
684 | * hlist_replace_rcu - replace old entry by new one | 684 | * hlist_replace_rcu - replace old entry by new one |
685 | * @old : the element to be replaced | 685 | * @old : the element to be replaced |
686 | * @new : the new element to insert | 686 | * @new : the new element to insert |
687 | * | 687 | * |
688 | * The old entry will be replaced with the new entry atomically. | 688 | * The @old entry will be replaced with the @new entry atomically. |
689 | */ | 689 | */ |
690 | static inline void hlist_replace_rcu(struct hlist_node *old, | 690 | static inline void hlist_replace_rcu(struct hlist_node *old, |
691 | struct hlist_node *new) | 691 | struct hlist_node *new) |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 76912231af4..2d2c08d5f47 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -168,6 +168,7 @@ extern unsigned int kobjsize(const void *objp); | |||
168 | #define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */ | 168 | #define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */ |
169 | #define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */ | 169 | #define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */ |
170 | #define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */ | 170 | #define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */ |
171 | #define VM_ALWAYSDUMP 0x04000000 /* Always include in core dumps */ | ||
171 | 172 | ||
172 | #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ | 173 | #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ |
173 | #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS | 174 | #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS |
diff --git a/include/linux/mutex.h b/include/linux/mutex.h index a7544afd758..b81bc2adaef 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h | |||
@@ -105,7 +105,7 @@ do { \ | |||
105 | extern void __mutex_init(struct mutex *lock, const char *name, | 105 | extern void __mutex_init(struct mutex *lock, const char *name, |
106 | struct lock_class_key *key); | 106 | struct lock_class_key *key); |
107 | 107 | ||
108 | /*** | 108 | /** |
109 | * mutex_is_locked - is the mutex locked | 109 | * mutex_is_locked - is the mutex locked |
110 | * @lock: the mutex to be queried | 110 | * @lock: the mutex to be queried |
111 | * | 111 | * |
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h index 0727774772b..4b7c4b568f6 100644 --- a/include/linux/nfsd/nfsd.h +++ b/include/linux/nfsd/nfsd.h | |||
@@ -52,8 +52,6 @@ | |||
52 | struct readdir_cd { | 52 | struct readdir_cd { |
53 | __be32 err; /* 0, nfserr, or nfserr_eof */ | 53 | __be32 err; /* 0, nfserr, or nfserr_eof */ |
54 | }; | 54 | }; |
55 | typedef int (*encode_dent_fn)(struct readdir_cd *, const char *, | ||
56 | int, loff_t, ino_t, unsigned int); | ||
57 | typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int); | 55 | typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int); |
58 | 56 | ||
59 | extern struct svc_program nfsd_program; | 57 | extern struct svc_program nfsd_program; |
@@ -117,7 +115,7 @@ __be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, | |||
117 | int nfsd_truncate(struct svc_rqst *, struct svc_fh *, | 115 | int nfsd_truncate(struct svc_rqst *, struct svc_fh *, |
118 | unsigned long size); | 116 | unsigned long size); |
119 | __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, | 117 | __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, |
120 | loff_t *, struct readdir_cd *, encode_dent_fn); | 118 | loff_t *, struct readdir_cd *, filldir_t); |
121 | __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, | 119 | __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, |
122 | struct kstatfs *); | 120 | struct kstatfs *); |
123 | 121 | ||
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h index f3b51d62ec7..d9c6c382165 100644 --- a/include/linux/nfsd/nfsfh.h +++ b/include/linux/nfsd/nfsfh.h | |||
@@ -217,11 +217,7 @@ void fh_put(struct svc_fh *); | |||
217 | static __inline__ struct svc_fh * | 217 | static __inline__ struct svc_fh * |
218 | fh_copy(struct svc_fh *dst, struct svc_fh *src) | 218 | fh_copy(struct svc_fh *dst, struct svc_fh *src) |
219 | { | 219 | { |
220 | if (src->fh_dentry || src->fh_locked) { | 220 | WARN_ON(src->fh_dentry || src->fh_locked); |
221 | struct dentry *dentry = src->fh_dentry; | ||
222 | printk(KERN_ERR "fh_copy: copying %s/%s, already verified!\n", | ||
223 | dentry->d_parent->d_name.name, dentry->d_name.name); | ||
224 | } | ||
225 | 221 | ||
226 | *dst = *src; | 222 | *dst = *src; |
227 | return dst; | 223 | return dst; |
@@ -300,10 +296,8 @@ fh_lock_nested(struct svc_fh *fhp, unsigned int subclass) | |||
300 | dfprintk(FILEOP, "nfsd: fh_lock(%s) locked = %d\n", | 296 | dfprintk(FILEOP, "nfsd: fh_lock(%s) locked = %d\n", |
301 | SVCFH_fmt(fhp), fhp->fh_locked); | 297 | SVCFH_fmt(fhp), fhp->fh_locked); |
302 | 298 | ||
303 | if (!fhp->fh_dentry) { | 299 | BUG_ON(!dentry); |
304 | printk(KERN_ERR "fh_lock: fh not verified!\n"); | 300 | |
305 | return; | ||
306 | } | ||
307 | if (fhp->fh_locked) { | 301 | if (fhp->fh_locked) { |
308 | printk(KERN_WARNING "fh_lock: %s/%s already locked!\n", | 302 | printk(KERN_WARNING "fh_lock: %s/%s already locked!\n", |
309 | dentry->d_parent->d_name.name, dentry->d_name.name); | 303 | dentry->d_parent->d_name.name, dentry->d_name.name); |
@@ -328,8 +322,7 @@ fh_lock(struct svc_fh *fhp) | |||
328 | static inline void | 322 | static inline void |
329 | fh_unlock(struct svc_fh *fhp) | 323 | fh_unlock(struct svc_fh *fhp) |
330 | { | 324 | { |
331 | if (!fhp->fh_dentry) | 325 | BUG_ON(!fhp->fh_dentry); |
332 | printk(KERN_ERR "fh_unlock: fh not verified!\n"); | ||
333 | 326 | ||
334 | if (fhp->fh_locked) { | 327 | if (fhp->fh_locked) { |
335 | fill_post_wcc(fhp); | 328 | fill_post_wcc(fhp); |
diff --git a/include/linux/nfsd/xdr.h b/include/linux/nfsd/xdr.h index 877192d3ae7..67885d5e6e5 100644 --- a/include/linux/nfsd/xdr.h +++ b/include/linux/nfsd/xdr.h | |||
@@ -165,8 +165,8 @@ int nfssvc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd_readres *); | |||
165 | int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *, struct nfsd_statfsres *); | 165 | int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *, struct nfsd_statfsres *); |
166 | int nfssvc_encode_readdirres(struct svc_rqst *, __be32 *, struct nfsd_readdirres *); | 166 | int nfssvc_encode_readdirres(struct svc_rqst *, __be32 *, struct nfsd_readdirres *); |
167 | 167 | ||
168 | int nfssvc_encode_entry(struct readdir_cd *, const char *name, | 168 | int nfssvc_encode_entry(void *, const char *name, |
169 | int namlen, loff_t offset, ino_t ino, unsigned int); | 169 | int namlen, loff_t offset, u64 ino, unsigned int); |
170 | 170 | ||
171 | int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); | 171 | int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); |
172 | 172 | ||
diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h index 79963867b0d..89d9d6061a6 100644 --- a/include/linux/nfsd/xdr3.h +++ b/include/linux/nfsd/xdr3.h | |||
@@ -331,11 +331,11 @@ int nfs3svc_release_fhandle(struct svc_rqst *, __be32 *, | |||
331 | struct nfsd3_attrstat *); | 331 | struct nfsd3_attrstat *); |
332 | int nfs3svc_release_fhandle2(struct svc_rqst *, __be32 *, | 332 | int nfs3svc_release_fhandle2(struct svc_rqst *, __be32 *, |
333 | struct nfsd3_fhandle_pair *); | 333 | struct nfsd3_fhandle_pair *); |
334 | int nfs3svc_encode_entry(struct readdir_cd *, const char *name, | 334 | int nfs3svc_encode_entry(void *, const char *name, |
335 | int namlen, loff_t offset, ino_t ino, | 335 | int namlen, loff_t offset, u64 ino, |
336 | unsigned int); | 336 | unsigned int); |
337 | int nfs3svc_encode_entry_plus(struct readdir_cd *, const char *name, | 337 | int nfs3svc_encode_entry_plus(void *, const char *name, |
338 | int namlen, loff_t offset, ino_t ino, | 338 | int namlen, loff_t offset, u64 ino, |
339 | unsigned int); | 339 | unsigned int); |
340 | /* Helper functions for NFSv3 ACL code */ | 340 | /* Helper functions for NFSv3 ACL code */ |
341 | __be32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, | 341 | __be32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, |
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index 866a1e2b0ce..fbaeda79b2e 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h | |||
@@ -94,7 +94,7 @@ extern int sync_page_io(struct block_device *bdev, sector_t sector, int size, | |||
94 | struct page *page, int rw); | 94 | struct page *page, int rw); |
95 | extern void md_do_sync(mddev_t *mddev); | 95 | extern void md_do_sync(mddev_t *mddev); |
96 | extern void md_new_event(mddev_t *mddev); | 96 | extern void md_new_event(mddev_t *mddev); |
97 | 97 | extern void md_allow_write(mddev_t *mddev); | |
98 | 98 | ||
99 | #endif /* CONFIG_MD */ | 99 | #endif /* CONFIG_MD */ |
100 | #endif | 100 | #endif |
diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h index b0090e9f788..382bb795116 100644 --- a/include/linux/rtmutex.h +++ b/include/linux/rtmutex.h | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <linux/plist.h> | 16 | #include <linux/plist.h> |
17 | #include <linux/spinlock_types.h> | 17 | #include <linux/spinlock_types.h> |
18 | 18 | ||
19 | /* | 19 | /** |
20 | * The rt_mutex structure | 20 | * The rt_mutex structure |
21 | * | 21 | * |
22 | * @wait_lock: spinlock to protect the structure | 22 | * @wait_lock: spinlock to protect the structure |
@@ -71,7 +71,7 @@ struct hrtimer_sleeper; | |||
71 | #define DEFINE_RT_MUTEX(mutexname) \ | 71 | #define DEFINE_RT_MUTEX(mutexname) \ |
72 | struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname) | 72 | struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname) |
73 | 73 | ||
74 | /*** | 74 | /** |
75 | * rt_mutex_is_locked - is the mutex locked | 75 | * rt_mutex_is_locked - is the mutex locked |
76 | * @lock: the mutex to be queried | 76 | * @lock: the mutex to be queried |
77 | * | 77 | * |
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 965d6c20086..64f3d60c72a 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h | |||
@@ -144,8 +144,11 @@ extern u32 svc_max_payload(const struct svc_rqst *rqstp); | |||
144 | * | 144 | * |
145 | * Each request/reply pair can have at most one "payload", plus two pages, | 145 | * Each request/reply pair can have at most one "payload", plus two pages, |
146 | * one for the request, and one for the reply. | 146 | * one for the request, and one for the reply. |
147 | * We using ->sendfile to return read data, we might need one extra page | ||
148 | * if the request is not page-aligned. So add another '1'. | ||
147 | */ | 149 | */ |
148 | #define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2) | 150 | #define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE \ |
151 | + 2 + 1) | ||
149 | 152 | ||
150 | static inline u32 svc_getnl(struct kvec *iov) | 153 | static inline u32 svc_getnl(struct kvec *iov) |
151 | { | 154 | { |
diff --git a/include/linux/timer.h b/include/linux/timer.h index eeef6643d4c..fb5edaaf0eb 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h | |||
@@ -41,7 +41,7 @@ static inline void setup_timer(struct timer_list * timer, | |||
41 | init_timer(timer); | 41 | init_timer(timer); |
42 | } | 42 | } |
43 | 43 | ||
44 | /*** | 44 | /** |
45 | * timer_pending - is a timer pending? | 45 | * timer_pending - is a timer pending? |
46 | * @timer: the timer in question | 46 | * @timer: the timer in question |
47 | * | 47 | * |
@@ -63,7 +63,7 @@ extern int mod_timer(struct timer_list *timer, unsigned long expires); | |||
63 | 63 | ||
64 | extern unsigned long next_timer_interrupt(void); | 64 | extern unsigned long next_timer_interrupt(void); |
65 | 65 | ||
66 | /*** | 66 | /** |
67 | * add_timer - start a timer | 67 | * add_timer - start a timer |
68 | * @timer: the timer to be added | 68 | * @timer: the timer to be added |
69 | * | 69 | * |
diff --git a/mm/memory.c b/mm/memory.c index af227d26e10..ef09f0acb1d 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -2606,8 +2606,15 @@ static int __init gate_vma_init(void) | |||
2606 | gate_vma.vm_mm = NULL; | 2606 | gate_vma.vm_mm = NULL; |
2607 | gate_vma.vm_start = FIXADDR_USER_START; | 2607 | gate_vma.vm_start = FIXADDR_USER_START; |
2608 | gate_vma.vm_end = FIXADDR_USER_END; | 2608 | gate_vma.vm_end = FIXADDR_USER_END; |
2609 | gate_vma.vm_page_prot = PAGE_READONLY; | 2609 | gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; |
2610 | gate_vma.vm_flags = 0; | 2610 | gate_vma.vm_page_prot = __P101; |
2611 | /* | ||
2612 | * Make sure the vDSO gets into every core dump. | ||
2613 | * Dumping its contents makes post-mortem fully interpretable later | ||
2614 | * without matching up the same kernel and hardware config to see | ||
2615 | * what PC values meant. | ||
2616 | */ | ||
2617 | gate_vma.vm_flags |= VM_ALWAYSDUMP; | ||
2611 | return 0; | 2618 | return 0; |
2612 | } | 2619 | } |
2613 | __initcall(gate_vma_init); | 2620 | __initcall(gate_vma_init); |
diff --git a/mm/truncate.c b/mm/truncate.c index 6c79ca4a1ca..5df947de765 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
@@ -51,15 +51,22 @@ static inline void truncate_partial_page(struct page *page, unsigned partial) | |||
51 | do_invalidatepage(page, partial); | 51 | do_invalidatepage(page, partial); |
52 | } | 52 | } |
53 | 53 | ||
54 | /* | ||
55 | * This cancels just the dirty bit on the kernel page itself, it | ||
56 | * does NOT actually remove dirty bits on any mmap's that may be | ||
57 | * around. It also leaves the page tagged dirty, so any sync | ||
58 | * activity will still find it on the dirty lists, and in particular, | ||
59 | * clear_page_dirty_for_io() will still look at the dirty bits in | ||
60 | * the VM. | ||
61 | * | ||
62 | * Doing this should *normally* only ever be done when a page | ||
63 | * is truncated, and is not actually mapped anywhere at all. However, | ||
64 | * fs/buffer.c does this when it notices that somebody has cleaned | ||
65 | * out all the buffers on a page without actually doing it through | ||
66 | * the VM. Can you say "ext3 is horribly ugly"? Tought you could. | ||
67 | */ | ||
54 | void cancel_dirty_page(struct page *page, unsigned int account_size) | 68 | void cancel_dirty_page(struct page *page, unsigned int account_size) |
55 | { | 69 | { |
56 | /* If we're cancelling the page, it had better not be mapped any more */ | ||
57 | if (page_mapped(page)) { | ||
58 | static unsigned int warncount; | ||
59 | |||
60 | WARN_ON(++warncount < 5); | ||
61 | } | ||
62 | |||
63 | if (TestClearPageDirty(page)) { | 70 | if (TestClearPageDirty(page)) { |
64 | struct address_space *mapping = page->mapping; | 71 | struct address_space *mapping = page->mapping; |
65 | if (mapping && mapping_cap_account_dirty(mapping)) { | 72 | if (mapping && mapping_cap_account_dirty(mapping)) { |
@@ -422,7 +429,6 @@ int invalidate_inode_pages2_range(struct address_space *mapping, | |||
422 | pagevec_release(&pvec); | 429 | pagevec_release(&pvec); |
423 | cond_resched(); | 430 | cond_resched(); |
424 | } | 431 | } |
425 | WARN_ON_ONCE(ret); | ||
426 | return ret; | 432 | return ret; |
427 | } | 433 | } |
428 | EXPORT_SYMBOL_GPL(invalidate_inode_pages2_range); | 434 | EXPORT_SYMBOL_GPL(invalidate_inode_pages2_range); |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index f3001f3626f..bf21a204701 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -910,7 +910,8 @@ err_bad_prog: | |||
910 | 910 | ||
911 | err_bad_vers: | 911 | err_bad_vers: |
912 | #ifdef RPC_PARANOIA | 912 | #ifdef RPC_PARANOIA |
913 | printk("svc: unknown version (%d)\n", vers); | 913 | printk("svc: unknown version (%d for prog %d, %s)\n", |
914 | vers, prog, progp->pg_name); | ||
914 | #endif | 915 | #endif |
915 | serv->sv_stats->rpcbadfmt++; | 916 | serv->sv_stats->rpcbadfmt++; |
916 | svc_putnl(resv, RPC_PROG_MISMATCH); | 917 | svc_putnl(resv, RPC_PROG_MISMATCH); |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 99f54fb6d66..45120f268d0 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -1278,6 +1278,8 @@ svc_recv(struct svc_rqst *rqstp, long timeout) | |||
1278 | schedule_timeout_uninterruptible(msecs_to_jiffies(500)); | 1278 | schedule_timeout_uninterruptible(msecs_to_jiffies(500)); |
1279 | rqstp->rq_pages[i] = p; | 1279 | rqstp->rq_pages[i] = p; |
1280 | } | 1280 | } |
1281 | rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */ | ||
1282 | BUG_ON(pages >= RPCSVC_MAXPAGES); | ||
1281 | 1283 | ||
1282 | /* Make arg->head point to first page and arg->pages point to rest */ | 1284 | /* Make arg->head point to first page and arg->pages point to rest */ |
1283 | arg = &rqstp->rq_arg; | 1285 | arg = &rqstp->rq_arg; |