From: Marc Fiuczynski Date: Tue, 26 Dec 2006 20:16:05 +0000 (+0000) Subject: Merge to Fedora kernel-2.6.18-1.2257_FC5 patched with stable patch-2.6.18.5-vs2.0... X-Git-Tag: fedora-2_6_18-1_2257_FC5-vs2_0_3-rc1~1 X-Git-Url: http://git.onelab.eu/?p=linux-2.6.git;a=commitdiff_plain;h=c469b50b11a8eaa1dc314687c2b6030c8fdea5b7 Merge to Fedora kernel-2.6.18-1.2257_FC5 patched with stable patch-2.6.18.5-vs2.0.3-rc1.diff --- diff --git a/.config b/.config index 8877438e8..5472124cf 100644 --- a/.config +++ b/.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:37 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:33 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -155,7 +155,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y CONFIG_RESOURCES_64BIT=y CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y -CONFIG_NR_CPUS=255 +CONFIG_NR_CPUS=64 CONFIG_HOTPLUG_CPU=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_HPET_TIMER=y @@ -2884,10 +2884,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/.config.old b/.config.old index 90ead9a07..8db28ce90 100644 --- a/.config.old +++ b/.config.old @@ -2883,7 +2883,7 @@ CONFIG_NUMA=y CONFIG_K8_NUMA=y CONFIG_X86_64_ACPI_NUMA=y # CONFIG_NUMA_EMU is not set -CONFIG_NR_CPUS=255 +CONFIG_NR_CPUS=64 CONFIG_X86_POWERNOW_K8=y CONFIG_IA32_EMULATION=y # CONFIG_IA32_AOUT is not set diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 83c02a708..fa5c40c31 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -331,6 +331,19 @@ CALL(sys_mbind) /* 320 */ CALL(sys_get_mempolicy) CALL(sys_set_mempolicy) + CALL(sys_openat) + CALL(sys_mkdirat) + CALL(sys_mknodat) +/* 325 */ CALL(sys_fchownat) + CALL(sys_futimesat) + CALL(sys_fstatat64) + CALL(sys_unlinkat) + CALL(sys_renameat) +/* 330 */ CALL(sys_linkat) + CALL(sys_symlinkat) + CALL(sys_readlinkat) + CALL(sys_fchmodat) + CALL(sys_faccessat) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S index ac6d840b3..5b01fd209 100644 --- a/arch/m32r/kernel/entry.S +++ b/arch/m32r/kernel/entry.S @@ -23,35 +23,35 @@ * updated in fork.c:copy_thread, signal.c:do_signal, * ptrace.c and ptrace.h * - * M32Rx/M32R2 M32R - * @(sp) - r4 ditto - * @(0x04,sp) - r5 ditto - * @(0x08,sp) - r6 ditto - * @(0x0c,sp) - *pt_regs ditto - * @(0x10,sp) - r0 ditto - * @(0x14,sp) - r1 ditto - * @(0x18,sp) - r2 ditto - * @(0x1c,sp) - r3 ditto - * @(0x20,sp) - r7 ditto - * @(0x24,sp) - r8 ditto - * @(0x28,sp) - r9 ditto - * @(0x2c,sp) - r10 ditto - * @(0x30,sp) - r11 ditto - * @(0x34,sp) - r12 ditto - * @(0x38,sp) - syscall_nr ditto - * @(0x3c,sp) - acc0h @(0x3c,sp) - acch - * @(0x40,sp) - acc0l @(0x40,sp) - accl - * @(0x44,sp) - acc1h @(0x44,sp) - dummy_acc1h - * @(0x48,sp) - acc1l @(0x48,sp) - dummy_acc1l - * @(0x4c,sp) - psw ditto - * @(0x50,sp) - bpc ditto - * @(0x54,sp) - bbpsw ditto - * @(0x58,sp) - bbpc ditto - * @(0x5c,sp) - spu (cr3) ditto - * @(0x60,sp) - fp (r13) ditto - * @(0x64,sp) - lr (r14) ditto - * @(0x68,sp) - spi (cr2) ditto - * @(0x6c,sp) - orig_r0 ditto + * M32R/M32Rx/M32R2 + * @(sp) - r4 + * @(0x04,sp) - r5 + * @(0x08,sp) - r6 + * @(0x0c,sp) - *pt_regs + * @(0x10,sp) - r0 + * @(0x14,sp) - r1 + * @(0x18,sp) - r2 + * @(0x1c,sp) - r3 + * @(0x20,sp) - r7 + * @(0x24,sp) - r8 + * @(0x28,sp) - r9 + * @(0x2c,sp) - r10 + * @(0x30,sp) - r11 + * @(0x34,sp) - r12 + * @(0x38,sp) - syscall_nr + * @(0x3c,sp) - acc0h + * @(0x40,sp) - acc0l + * @(0x44,sp) - acc1h ; ISA_DSP_LEVEL2 only + * @(0x48,sp) - acc1l ; ISA_DSP_LEVEL2 only + * @(0x4c,sp) - psw + * @(0x50,sp) - bpc + * @(0x54,sp) - bbpsw + * @(0x58,sp) - bbpc + * @(0x5c,sp) - spu (cr3) + * @(0x60,sp) - fp (r13) + * @(0x64,sp) - lr (r14) + * @(0x68,sp) - spi (cr2) + * @(0x6c,sp) - orig_r0 */ #include @@ -95,17 +95,10 @@ #define R11(reg) @(0x30,reg) #define R12(reg) @(0x34,reg) #define SYSCALL_NR(reg) @(0x38,reg) -#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2) #define ACC0H(reg) @(0x3C,reg) #define ACC0L(reg) @(0x40,reg) #define ACC1H(reg) @(0x44,reg) #define ACC1L(reg) @(0x48,reg) -#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) -#define ACCH(reg) @(0x3C,reg) -#define ACCL(reg) @(0x40,reg) -#else -#error unknown isa configuration -#endif #define PSW(reg) @(0x4C,reg) #define BPC(reg) @(0x50,reg) #define BBPSW(reg) @(0x54,reg) diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 4b39f0da1..40a74d489 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -1011,7 +1011,10 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) if ((c->x86 == 0xf && c->x86_model >= 0x03) || (c->x86 == 0x6 && c->x86_model >= 0x0e)) set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); - set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); + if (c->x86 == 15) + set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); + else + clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); c->x86_max_cores = intel_num_cpu_cores(c); srat_detect_node(); diff --git a/configs/kernel-2.6.18-i586-smp.config b/configs/kernel-2.6.18-i586-smp.config index 74a7737de..7031af6cb 100644 --- a/configs/kernel-2.6.18-i586-smp.config +++ b/configs/kernel-2.6.18-i586-smp.config @@ -1,8 +1,8 @@ # i386 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:30 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:26 2006 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -3097,10 +3097,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-i586.config b/configs/kernel-2.6.18-i586.config index 4bb100b19..2960893d4 100644 --- a/configs/kernel-2.6.18-i586.config +++ b/configs/kernel-2.6.18-i586.config @@ -1,8 +1,8 @@ # i386 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:31 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:26 2006 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -3094,10 +3094,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-i686-kdump.config b/configs/kernel-2.6.18-i686-kdump.config index 128ca73f9..f5b9e6247 100644 --- a/configs/kernel-2.6.18-i686-kdump.config +++ b/configs/kernel-2.6.18-i686-kdump.config @@ -1,8 +1,8 @@ # i386 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:31 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:27 2006 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -3134,10 +3134,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-i686-smp.config b/configs/kernel-2.6.18-i686-smp.config index 224e29a3c..b2c40783d 100644 --- a/configs/kernel-2.6.18-i686-smp.config +++ b/configs/kernel-2.6.18-i686-smp.config @@ -1,8 +1,8 @@ # i386 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:31 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:27 2006 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -3131,10 +3131,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-i686-xen.config b/configs/kernel-2.6.18-i686-xen.config index 7fb1817e1..a6165c52a 100644 --- a/configs/kernel-2.6.18-i686-xen.config +++ b/configs/kernel-2.6.18-i686-xen.config @@ -1,8 +1,8 @@ # i386 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:32 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:27 2006 # CONFIG_X86_32=y CONFIG_LOCKDEP_SUPPORT=y @@ -2934,10 +2934,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-i686-xen0.config b/configs/kernel-2.6.18-i686-xen0.config index 4ca808586..16438720b 100644 --- a/configs/kernel-2.6.18-i686-xen0.config +++ b/configs/kernel-2.6.18-i686-xen0.config @@ -1,8 +1,8 @@ # i386 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:32 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:28 2006 # CONFIG_X86_32=y CONFIG_LOCKDEP_SUPPORT=y @@ -2932,10 +2932,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-i686-xenU.config b/configs/kernel-2.6.18-i686-xenU.config index b60115464..7bef09257 100644 --- a/configs/kernel-2.6.18-i686-xenU.config +++ b/configs/kernel-2.6.18-i686-xenU.config @@ -1,8 +1,8 @@ # i386 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:32 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:28 2006 # CONFIG_X86_32=y CONFIG_LOCKDEP_SUPPORT=y @@ -1338,10 +1338,6 @@ CONFIG_BEFS_FS=m CONFIG_BFS_FS=m CONFIG_EFS_FS=m CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-i686.config b/configs/kernel-2.6.18-i686.config index ceaff0f28..29fb9f674 100644 --- a/configs/kernel-2.6.18-i686.config +++ b/configs/kernel-2.6.18-i686.config @@ -1,8 +1,8 @@ # i386 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:33 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:28 2006 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -3133,10 +3133,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-ia64-xen.config b/configs/kernel-2.6.18-ia64-xen.config index 20030da26..abec6965f 100644 --- a/configs/kernel-2.6.18-ia64-xen.config +++ b/configs/kernel-2.6.18-ia64-xen.config @@ -1,8 +1,8 @@ # ia64 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:33 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:29 2006 # CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -2584,10 +2584,6 @@ CONFIG_BEFS_FS=m CONFIG_BFS_FS=m CONFIG_EFS_FS=m CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-ia64.config b/configs/kernel-2.6.18-ia64.config index 50a65eb13..3282a40ad 100644 --- a/configs/kernel-2.6.18-ia64.config +++ b/configs/kernel-2.6.18-ia64.config @@ -1,8 +1,8 @@ # ia64 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:34 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:29 2006 # CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -2632,10 +2632,6 @@ CONFIG_BEFS_FS=m CONFIG_BFS_FS=m CONFIG_EFS_FS=m CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-ppc-smp.config b/configs/kernel-2.6.18-ppc-smp.config index 90fedf19d..7e33c5497 100644 --- a/configs/kernel-2.6.18-ppc-smp.config +++ b/configs/kernel-2.6.18-ppc-smp.config @@ -1,8 +1,8 @@ # powerpc # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:34 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:29 2006 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -2944,10 +2944,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-ppc.config b/configs/kernel-2.6.18-ppc.config index ef5ea67ae..2699ead48 100644 --- a/configs/kernel-2.6.18-ppc.config +++ b/configs/kernel-2.6.18-ppc.config @@ -1,8 +1,8 @@ # powerpc # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:34 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:30 2006 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -2948,10 +2948,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-ppc64-kdump.config b/configs/kernel-2.6.18-ppc64-kdump.config index 7792d069c..8d851c40e 100644 --- a/configs/kernel-2.6.18-ppc64-kdump.config +++ b/configs/kernel-2.6.18-ppc64-kdump.config @@ -1,8 +1,8 @@ # powerpc # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:34 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:30 2006 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -2776,10 +2776,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-ppc64.config b/configs/kernel-2.6.18-ppc64.config index 9ee604bd4..411ab6236 100644 --- a/configs/kernel-2.6.18-ppc64.config +++ b/configs/kernel-2.6.18-ppc64.config @@ -1,8 +1,8 @@ # powerpc # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:35 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:30 2006 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -2775,10 +2775,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-ppc64iseries.config b/configs/kernel-2.6.18-ppc64iseries.config index 726bc8d02..ab48ca669 100644 --- a/configs/kernel-2.6.18-ppc64iseries.config +++ b/configs/kernel-2.6.18-ppc64iseries.config @@ -1,8 +1,8 @@ # powerpc # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:35 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:30 2006 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -1335,10 +1335,6 @@ CONFIG_BEFS_FS=m CONFIG_BFS_FS=m CONFIG_EFS_FS=m CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-s390.config b/configs/kernel-2.6.18-s390.config index 57879c585..0887d7f4f 100644 --- a/configs/kernel-2.6.18-s390.config +++ b/configs/kernel-2.6.18-s390.config @@ -1,8 +1,8 @@ # s390 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:35 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:31 2006 # CONFIG_MMU=y CONFIG_LOCKDEP_SUPPORT=y @@ -889,10 +889,6 @@ CONFIG_BEFS_FS=m CONFIG_BFS_FS=m CONFIG_EFS_FS=m CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-s390x.config b/configs/kernel-2.6.18-s390x.config index 79e22c138..6928ca9cb 100644 --- a/configs/kernel-2.6.18-s390x.config +++ b/configs/kernel-2.6.18-s390x.config @@ -1,8 +1,8 @@ # s390 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:35 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:31 2006 # CONFIG_MMU=y CONFIG_LOCKDEP_SUPPORT=y @@ -887,10 +887,6 @@ CONFIG_BEFS_FS=m CONFIG_BFS_FS=m CONFIG_EFS_FS=m CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-x86_64-kdump.config b/configs/kernel-2.6.18-x86_64-kdump.config index 64e99b25f..ae155864a 100644 --- a/configs/kernel-2.6.18-x86_64-kdump.config +++ b/configs/kernel-2.6.18-x86_64-kdump.config @@ -1,8 +1,8 @@ # x86_64 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:36 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:31 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -2871,10 +2871,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-x86_64-xen.config b/configs/kernel-2.6.18-x86_64-xen.config index 11ebc6cdb..8bb58f7c5 100644 --- a/configs/kernel-2.6.18-x86_64-xen.config +++ b/configs/kernel-2.6.18-x86_64-xen.config @@ -1,8 +1,8 @@ # x86_64 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:36 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:32 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -2842,10 +2842,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-x86_64-xen0.config b/configs/kernel-2.6.18-x86_64-xen0.config index 85a593cd0..32be42fd7 100644 --- a/configs/kernel-2.6.18-x86_64-xen0.config +++ b/configs/kernel-2.6.18-x86_64-xen0.config @@ -1,8 +1,8 @@ # x86_64 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:36 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:32 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -2842,10 +2842,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-x86_64-xenU.config b/configs/kernel-2.6.18-x86_64-xenU.config index b3f4b2ac3..2c47cdbf3 100644 --- a/configs/kernel-2.6.18-x86_64-xenU.config +++ b/configs/kernel-2.6.18-x86_64-xenU.config @@ -1,8 +1,8 @@ # x86_64 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:36 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:33 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -1304,10 +1304,6 @@ CONFIG_BEFS_FS=m CONFIG_BFS_FS=m CONFIG_EFS_FS=m CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/configs/kernel-2.6.18-x86_64.config b/configs/kernel-2.6.18-x86_64.config index a6e596316..8ff437668 100644 --- a/configs/kernel-2.6.18-x86_64.config +++ b/configs/kernel-2.6.18-x86_64.config @@ -1,8 +1,8 @@ # x86_64 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18.5 -# Wed Dec 13 17:11:37 2006 +# Linux kernel version: 2.6.18.6-rc2 +# Tue Dec 26 19:31:33 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -156,7 +156,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y CONFIG_RESOURCES_64BIT=y CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y -CONFIG_NR_CPUS=255 +CONFIG_NR_CPUS=64 CONFIG_HOTPLUG_CPU=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_HPET_TIMER=y @@ -2885,10 +2885,6 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 448df2773..ab5a6b526 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c @@ -3218,6 +3218,19 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, struct ti_ohci *ohci; /* shortcut to currently handled device */ resource_size_t ohci_base; +#ifdef CONFIG_PPC_PMAC + /* Necessary on some machines if ohci1394 was loaded/ unloaded before */ + if (machine_is(powermac)) { + struct device_node *of_node = pci_device_to_OF_node(dev); + + if (of_node) { + pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, of_node, + 0, 1); + pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 1); + } + } +#endif /* CONFIG_PPC_PMAC */ + if (pci_enable_device(dev)) FAIL(-ENXIO, "Failed to enable OHCI hardware"); pci_set_master(dev); @@ -3506,11 +3519,9 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) #endif #ifdef CONFIG_PPC_PMAC - /* On UniNorth, power down the cable and turn off the chip - * clock when the module is removed to save power on - * laptops. Turning it back ON is done by the arch code when - * pci_enable_device() is called */ - { + /* On UniNorth, power down the cable and turn off the chip clock + * to save power on laptops */ + if (machine_is(powermac)) { struct device_node* of_node; of_node = pci_device_to_OF_node(ohci->dev); diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 6022ed12a..31e498fd8 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -717,13 +717,15 @@ static int crypt_endio(struct bio *bio, unsigned int done, int error) if (bio->bi_size) return 1; + if (!bio_flagged(bio, BIO_UPTODATE) && !error) + error = -EIO; + bio_put(bio); /* * successful reads are decrypted by the worker thread */ - if ((bio_data_dir(bio) == READ) - && bio_flagged(bio, BIO_UPTODATE)) { + if (bio_data_dir(io->bio) == READ && !error) { kcryptd_queue_io(io); return 0; } diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 1d0fafda0..6578b260f 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -691,6 +691,7 @@ static void pending_complete(struct pending_exception *pe, int success) free_exception(e); + remove_exception(&pe->e); error_snapshot_bios(pe); goto out; } diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index 9a354708b..467f1994f 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c @@ -435,9 +435,6 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) /* Test signal does not exist flag */ /* as well as the AGC lock flag. */ *status |= FE_HAS_SIGNAL; - } else { - /* Without a signal all other status bits are meaningless */ - return 0; } /* @@ -500,9 +497,6 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status) /* Test input signal does not exist flag */ /* as well as the AGC lock flag. */ *status |= FE_HAS_SIGNAL; - } else { - /* Without a signal all other status bits are meaningless */ - return 0; } /* Carrier Recovery Lock Status Register */ diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index abe37cf63..a17cc8e97 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c @@ -108,6 +108,7 @@ static int tuner_stereo(struct i2c_client *c) case TUNER_PHILIPS_FM1216ME_MK3: case TUNER_PHILIPS_FM1236_MK3: case TUNER_PHILIPS_FM1256_IH3: + case TUNER_LG_NTSC_TAPE: stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); break; default: @@ -419,6 +420,7 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) case TUNER_PHILIPS_FM1216ME_MK3: case TUNER_PHILIPS_FM1236_MK3: case TUNER_PHILIPS_FMD1216ME_MK3: + case TUNER_LG_NTSC_TAPE: buffer[3] = 0x19; break; case TUNER_TNF_5335MF: diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index 8b542599e..c37115915 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c @@ -671,16 +671,6 @@ static struct tuner_params tuner_panasonic_vp27_params[] = { }, }; -/* ------------ TUNER_LG_NTSC_TAPE - LGINNOTEK NTSC ------------ */ - -static struct tuner_params tuner_lg_ntsc_tape_params[] = { - { - .type = TUNER_PARAM_TYPE_NTSC, - .ranges = tuner_fm1236_mk3_ntsc_ranges, - .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), - }, -}; - /* ------------ TUNER_TNF_8831BGFF - Philips PAL ------------ */ static struct tuner_range tuner_tnf_8831bgff_pal_ranges[] = { @@ -1331,8 +1321,8 @@ struct tunertype tuners[] = { }, [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */ .name = "LG NTSC (TAPE series)", - .params = tuner_lg_ntsc_tape_params, - .count = ARRAY_SIZE(tuner_lg_ntsc_tape_params), + .params = tuner_fm1236_mk3_params, + .count = ARRAY_SIZE(tuner_fm1236_mk3_params), }, [TUNER_TNF_8831BGFF] = { /* Philips PAL */ .name = "Tenna TNF 8831 BGFF)", diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 61bd17923..cf906d73c 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3547,7 +3547,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd mii->val_out = 0; read_lock_bh(&bond->lock); read_lock(&bond->curr_slave_lock); - if (bond->curr_active_slave) { + if (netif_carrier_ok(bond->dev)) { mii->val_out = BMSR_LSTATUS; } read_unlock(&bond->curr_slave_lock); diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 38e8bfae4..c7605867e 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -2695,11 +2695,13 @@ static int nv_request_irq(struct net_device *dev, int intr_test) } if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { if ((ret = pci_enable_msi(np->pci_dev)) == 0) { + pci_intx(np->pci_dev, 0); np->msi_flags |= NV_MSI_ENABLED; if ((!intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq, IRQF_SHARED, dev->name, dev) != 0) || (intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq_test, IRQF_SHARED, dev->name, dev) != 0)) { printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); pci_disable_msi(np->pci_dev); + pci_intx(np->pci_dev, 1); np->msi_flags &= ~NV_MSI_ENABLED; goto out_err; } @@ -2742,6 +2744,7 @@ static void nv_free_irq(struct net_device *dev) free_irq(np->pci_dev->irq, dev); if (np->msi_flags & NV_MSI_ENABLED) { pci_disable_msi(np->pci_dev); + pci_intx(np->pci_dev, 1); np->msi_flags &= ~NV_MSI_ENABLED; } } diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index c6f5bc3c0..3bbf0c80b 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -3012,6 +3012,11 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, #endif err = -ENODEV; + + if (pci_enable_device(pdev)) + goto err_out; + pci_set_master(pdev); + if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) { qp = quattro_pci_find(pdev); if (qp == NULL) diff --git a/fs/Kconfig b/fs/Kconfig index 7a818f518..75b7c0785 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -1285,71 +1285,6 @@ config CRAMFS If unsure, say N. -config SQUASHFS - tristate "SquashFS 3.1 - Squashed file system support" - select ZLIB_INFLATE - help - Saying Y here includes support for SquashFS 3.1 (a Compressed Read-Only File - System). Squashfs is a highly compressed read-only filesystem for Linux. - It uses zlib compression to compress both files, inodes and directories. - Inodes in the system are very small and all blocks are packed to minimise - data overhead. Block sizes greater than 4K are supported up to a maximum of 64K. - SquashFS 3.1 supports 64 bit filesystems and files (larger than 4GB), full - uid/gid information, hard links and timestamps. - - Squashfs is intended for general read-only filesystem use, for archival - use (i.e. in cases where a .tar.gz file may be used), and in embedded - systems where low overhead is needed. Further information and filesystem tools - are available from http://squashfs.sourceforge.net. - - If you want to compile this as a module ( = code which can be - inserted in and removed from the running kernel whenever you want), - say M here and read . The module - will be called squashfs. Note that the root file system (the one - containing the directory /) cannot be compiled as a module. - - If unsure, say N. - -config SQUASHFS_EMBEDDED - - bool "Additional options for memory-constrained systems" - depends on SQUASHFS - default n - help - Saying Y here allows you to specify cache sizes and how Squashfs - allocates memory. This is only intended for memory constrained - systems. - - If unsure, say N. - -config SQUASHFS_FRAGMENT_CACHE_SIZE - int "Number of fragments cached" if SQUASHFS_EMBEDDED - depends on SQUASHFS - default "3" - help - By default SquashFS caches the last 3 fragments read from - the filesystem. Increasing this amount may mean SquashFS - has to re-read fragments less often from disk, at the expense - of extra system memory. Decreasing this amount will mean - SquashFS uses less memory at the expense of extra reads from disk. - - Note there must be at least one cached fragment. Anything - much more than three will probably not make much difference. - -config SQUASHFS_VMALLOC - bool "Use Vmalloc rather than Kmalloc" if SQUASHFS_EMBEDDED - depends on SQUASHFS - default n - help - By default SquashFS uses kmalloc to obtain fragment cache memory. - Kmalloc memory is the standard kernel allocator, but it can fail - on memory constrained systems. Because of the way Vmalloc works, - Vmalloc can succeed when kmalloc fails. Specifying this option - will make SquashFS always use Vmalloc to allocate the - fragment cache memory. - - If unsure, say N. - config VXFS_FS tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)" help diff --git a/fs/Makefile b/fs/Makefile index 970aed37e..e5efb4b69 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -58,7 +58,6 @@ obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 obj-$(CONFIG_JBD) += jbd/ obj-$(CONFIG_EXT2_FS) += ext2/ obj-$(CONFIG_CRAMFS) += cramfs/ -obj-$(CONFIG_SQUASHFS) += squashfs/ obj-$(CONFIG_RAMFS) += ramfs/ obj-$(CONFIG_HUGETLBFS) += hugetlbfs/ obj-$(CONFIG_CODA_FS) += coda/ diff --git a/fs/compat.c b/fs/compat.c index 55cf40514..797368739 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -873,7 +873,7 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, retval = -EINVAL; - if (type_page) { + if (type_page && data_page) { if (!strcmp((char *)type_page, SMBFS_NAME)) { do_smb_super_data_conv((void *)data_page); } else if (!strcmp((char *)type_page, NCPFS_NAME)) { diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c index 9e8ae2607..ccbaeb6bf 100644 --- a/fs/squashfs/inode.c +++ b/fs/squashfs/inode.c @@ -56,12 +56,14 @@ static int init_inodecache(void); static void destroy_inodecache(void); static struct dentry *squashfs_lookup(struct inode *, struct dentry *, struct nameidata *); -static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode); +static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode); static long long read_blocklist(struct inode *inode, int index, int readahead_blks, char *block_list, unsigned short **block_p, unsigned int *bsize); -static int squashfs_get_sb(struct file_system_type *, int, - const char *, void *, struct vfsmount *); +static int squashfs_get_sb(struct file_system_type *,int, const char *, void *, + struct vfsmount *); +static void vfs_read_inode(struct inode *i); +static struct dentry *squashfs_get_parent(struct dentry *child); static struct file_system_type squashfs_fs_type = { .owner = THIS_MODULE, @@ -75,13 +77,25 @@ static unsigned char squashfs_filetype_table[] = { DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK }; -static struct super_operations squashfs_ops = { +static struct super_operations squashfs_super_ops = { .alloc_inode = squashfs_alloc_inode, .destroy_inode = squashfs_destroy_inode, .statfs = squashfs_statfs, .put_super = squashfs_put_super, }; +static struct super_operations squashfs_export_super_ops = { + .alloc_inode = squashfs_alloc_inode, + .destroy_inode = squashfs_destroy_inode, + .statfs = squashfs_statfs, + .put_super = squashfs_put_super, + .read_inode = vfs_read_inode +}; + +struct export_operations squashfs_export_ops = { + .get_parent = squashfs_get_parent +}; + SQSH_EXTERN struct address_space_operations squashfs_symlink_aops = { .readpage = squashfs_symlink_readpage }; @@ -195,8 +209,8 @@ SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer, TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index, compressed ? "" : "un", (unsigned int) c_byte, srclength); - if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used) - goto read_failure; + if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used) + goto read_failure; if (!(bh[0] = sb_getblk(s, cur_index))) goto block_release; @@ -208,8 +222,8 @@ SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer, } ll_rw_block(READ, b, bh); } else { - if (index < 0 || (index + 2) > sblk->bytes_used) - goto read_failure; + if (index < 0 || (index + 2) > sblk->bytes_used) + goto read_failure; if (!(bh[0] = get_block_length(s, &cur_index, &offset, &c_byte))) @@ -223,8 +237,8 @@ SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer, TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed ? "" : "un", (unsigned int) c_byte); - if (c_byte > srclength || (index + c_byte) > sblk->bytes_used) - goto read_failure; + if (c_byte > srclength || (index + c_byte) > sblk->bytes_used) + goto read_failure; for (b = 1; bytes < c_byte; b++) { if (!(bh[b] = sb_getblk(s, ++cur_index))) @@ -259,14 +273,17 @@ SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer, msblk->stream.next_in = c_buffer; msblk->stream.avail_in = c_byte; msblk->stream.next_out = buffer; + //msblk->stream.avail_out = msblk->read_size;//srclength; msblk->stream.avail_out = srclength; if (((zlib_err = zlib_inflateInit(&msblk->stream)) != Z_OK) || ((zlib_err = zlib_inflate(&msblk->stream, Z_FINISH)) != Z_STREAM_END) || ((zlib_err = zlib_inflateEnd(&msblk->stream)) != Z_OK)) { - ERROR("zlib_fs returned unexpected result 0x%x\n", - zlib_err); + //ERROR("zlib_fs returned unexpected result 0x%x\n", + // zlib_err); + ERROR("zlib_fs returned unexpected result 0x%x, srclength %d\n", + zlib_err, srclength); bytes = 0; } else bytes = msblk->stream.total_out; @@ -346,20 +363,18 @@ SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, char *buffer, msblk->block_cache[i].block = SQUASHFS_USED_BLK; up(&msblk->block_cache_mutex); - msblk->block_cache[i].length = squashfs_read_data(s, - msblk->block_cache[i].data, block, 0, &next_index, - SQUASHFS_METADATA_SIZE); - - if (msblk->block_cache[i].length == 0) { - ERROR("Unable to read cache block [%llx:%x]\n", - block, offset); - down(&msblk->block_cache_mutex); - msblk->block_cache[i].block = SQUASHFS_INVALID_BLK; - kfree(msblk->block_cache[i].data); - wake_up(&msblk->waitq); - up(&msblk->block_cache_mutex); - goto out; - } + msblk->block_cache[i].length = squashfs_read_data(s, + msblk->block_cache[i].data, block, 0, &next_index, SQUASHFS_METADATA_SIZE); + if (msblk->block_cache[i].length == 0) { + ERROR("Unable to read cache block [%llx:%x]\n", + block, offset); + down(&msblk->block_cache_mutex); + msblk->block_cache[i].block = SQUASHFS_INVALID_BLK; + kfree(msblk->block_cache[i].data); + wake_up(&msblk->waitq); + up(&msblk->block_cache_mutex); + goto out; + } down(&msblk->block_cache_mutex); wake_up(&msblk->waitq); @@ -373,11 +388,12 @@ SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, char *buffer, continue; } - bytes = msblk->block_cache[i].length - offset; + bytes = msblk->block_cache[i].length - offset; - if (bytes < 1) - goto out; - else if (bytes >= length) { + if (bytes < 1) { + up(&msblk->block_cache_mutex); + goto out; + } else if (bytes >= length) { if (buffer) memcpy(buffer, msblk->block_cache[i].data + offset, length); @@ -462,7 +478,7 @@ SQSH_EXTERN struct squashfs_fragment_cache *get_cached_fragment(struct super_blo { int i, n; struct squashfs_sb_info *msblk = s->s_fs_info; - struct squashfs_super_block *sblk = &msblk->sblk; + struct squashfs_super_block *sblk = &msblk->sblk; while ( 1 ) { down(&msblk->fragment_mutex); @@ -508,8 +524,7 @@ SQSH_EXTERN struct squashfs_fragment_cache *get_cached_fragment(struct super_blo if (!(msblk->fragment[i].length = squashfs_read_data(s, msblk->fragment[i].data, - start_block, length, NULL, - sblk->block_size))) { + start_block, length, NULL, sblk->block_size))) { ERROR("Unable to read fragment cache block " "[%llx]\n", start_block); msblk->fragment[i].locked = 0; @@ -538,33 +553,105 @@ out: } -static struct inode *squashfs_new_inode(struct super_block *s, +static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i, struct squashfs_base_inode_header *inodeb) +{ + i->i_ino = inodeb->inode_number; + i->i_mtime.tv_sec = inodeb->mtime; + i->i_atime.tv_sec = inodeb->mtime; + i->i_ctime.tv_sec = inodeb->mtime; + i->i_uid = msblk->uid[inodeb->uid]; + i->i_mode = inodeb->mode; + i->i_size = 0; + if (inodeb->guid == SQUASHFS_GUIDS) + i->i_gid = i->i_uid; + else + i->i_gid = msblk->guid[inodeb->guid]; +} + + +static squashfs_inode_t squashfs_inode_lookup(struct super_block *s, int ino) { struct squashfs_sb_info *msblk = s->s_fs_info; - struct inode *i = new_inode(s); - - if (i) { - i->i_ino = inodeb->inode_number; - i->i_mtime.tv_sec = inodeb->mtime; - i->i_atime.tv_sec = inodeb->mtime; - i->i_ctime.tv_sec = inodeb->mtime; - i->i_uid = msblk->uid[inodeb->uid]; - i->i_mode = inodeb->mode; - i->i_size = 0; - if (inodeb->guid == SQUASHFS_GUIDS) - i->i_gid = i->i_uid; - else - i->i_gid = msblk->guid[inodeb->guid]; + long long start = msblk->inode_lookup_table[SQUASHFS_LOOKUP_BLOCK(ino - 1)]; + int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino - 1); + squashfs_inode_t inode; + + TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino); + + if (msblk->swap) { + squashfs_inode_t sinode; + + if (!squashfs_get_cached_block(s, (char *) &sinode, start, offset, + sizeof(sinode), &start, &offset)) + goto out; + SQUASHFS_SWAP_INODE_T((&inode), &sinode); + } else if (!squashfs_get_cached_block(s, (char *) &inode, start, offset, + sizeof(inode), &start, &offset)) + goto out; + + TRACE("squashfs_inode_lookup, inode = 0x%llx\n", inode); + + return inode; + +out: + return SQUASHFS_INVALID_BLK; +} + + +static void vfs_read_inode(struct inode *i) +{ + struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; + squashfs_inode_t inode = squashfs_inode_lookup(i->i_sb, i->i_ino); + + TRACE("Entered vfs_read_inode\n"); + + if(inode != SQUASHFS_INVALID_BLK) + (msblk->read_inode)(i, inode); +} + + +static struct dentry *squashfs_get_parent(struct dentry *child) +{ + struct inode *i = child->d_inode; + struct inode *parent = iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode); + struct dentry *rv; + + TRACE("Entered squashfs_get_parent\n"); + + if(parent == NULL) { + rv = ERR_PTR(-EACCES); + goto out; + } + + rv = d_alloc_anon(parent); + if(rv == NULL) + rv = ERR_PTR(-ENOMEM); + +out: + return rv; +} + + +SQSH_EXTERN struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode, unsigned int inode_number) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct inode *i = iget_locked(s, inode_number); + + TRACE("Entered squashfs_iget\n"); + + if(i && (i->i_state & I_NEW)) { + (msblk->read_inode)(i, inode); + unlock_new_inode(i); } return i; } -static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode) +static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode) { - struct inode *i; + struct super_block *s = i->i_sb; struct squashfs_sb_info *msblk = s->s_fs_info; struct squashfs_super_block *sblk = &msblk->sblk; long long block = SQUASHFS_INODE_BLK(inode) + @@ -576,7 +663,7 @@ static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode struct squashfs_base_inode_header *inodeb = &id.base, *sinodeb = &sid.base; - TRACE("Entered squashfs_iget\n"); + TRACE("Entered squashfs_read_inode\n"); if (msblk->swap) { if (!squashfs_get_cached_block(s, (char *) sinodeb, block, @@ -591,6 +678,8 @@ static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode &next_offset)) goto failed_read; + squashfs_new_inode(msblk, i, inodeb); + switch(inodeb->inode_type) { case SQUASHFS_FILE_TYPE: { unsigned int frag_size; @@ -618,9 +707,6 @@ static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode inodep->fragment, &frag_blk, &frag_size)) goto failed_read; - if((i = squashfs_new_inode(s, inodeb)) == NULL) - goto failed_read1; - i->i_nlink = 1; i->i_size = inodep->file_size; i->i_fop = &generic_ro_fops; @@ -670,9 +756,6 @@ static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode inodep->fragment, &frag_blk, &frag_size)) goto failed_read; - if((i = squashfs_new_inode(s, inodeb)) == NULL) - goto failed_read1; - i->i_nlink = inodep->nlink; i->i_size = inodep->file_size; i->i_fop = &generic_ro_fops; @@ -714,9 +797,6 @@ static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode &next_offset)) goto failed_read; - if((i = squashfs_new_inode(s, inodeb)) == NULL) - goto failed_read1; - i->i_nlink = inodep->nlink; i->i_size = inodep->file_size; i->i_op = &squashfs_dir_inode_ops; @@ -752,9 +832,6 @@ static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode &next_offset)) goto failed_read; - if((i = squashfs_new_inode(s, inodeb)) == NULL) - goto failed_read1; - i->i_nlink = inodep->nlink; i->i_size = inodep->file_size; i->i_op = &squashfs_dir_inode_ops; @@ -796,9 +873,6 @@ static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode &next_offset)) goto failed_read; - if((i = squashfs_new_inode(s, inodeb)) == NULL) - goto failed_read1; - i->i_nlink = inodep->nlink; i->i_size = inodep->symlink_size; i->i_op = &page_symlink_inode_operations; @@ -832,9 +906,6 @@ static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode &next_offset)) goto failed_read; - if ((i = squashfs_new_inode(s, inodeb)) == NULL) - goto failed_read1; - i->i_nlink = inodep->nlink; i->i_mode |= (inodeb->inode_type == SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : @@ -866,9 +937,6 @@ static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode &next_offset)) goto failed_read; - if ((i = squashfs_new_inode(s, inodeb)) == NULL) - goto failed_read1; - i->i_nlink = inodep->nlink; i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) ? S_IFIFO : S_IFSOCK; @@ -881,14 +949,50 @@ static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode goto failed_read1; } - insert_inode_hash(i); - return i; + return 1; failed_read: ERROR("Unable to read inode [%llx:%x]\n", block, offset); failed_read1: - return NULL; + make_bad_inode(i); + return 0; +} + + +static int read_inode_lookup_table(struct super_block *s) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(sblk->inodes); + + TRACE("In read_inode_lookup_table, length %d\n", length); + + /* Allocate inode lookup table */ + if (!(msblk->inode_lookup_table = kmalloc(length, GFP_KERNEL))) { + ERROR("Failed to allocate inode lookup table\n"); + return 0; + } + + if (!squashfs_read_data(s, (char *) msblk->inode_lookup_table, + sblk->lookup_table_start, length | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) { + ERROR("unable to read inode lookup table\n"); + return 0; + } + + if (msblk->swap) { + int i; + long long block; + + for (i = 0; i < SQUASHFS_LOOKUP_BLOCKS(sblk->inodes); i++) { + SQUASHFS_SWAP_LOOKUP_BLOCKS((&block), + &msblk->inode_lookup_table[i], 1); + msblk->inode_lookup_table[i] = block; + } + } + + return 1; } @@ -898,13 +1002,12 @@ static int read_fragment_index_table(struct super_block *s) struct squashfs_super_block *sblk = &msblk->sblk; unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments); - if (length == 0) + if(length == 0) return 1; /* Allocate fragment index table */ - if (!(msblk->fragment_index = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES - (sblk->fragments), GFP_KERNEL))) { - ERROR("Failed to allocate uid/gid table\n"); + if (!(msblk->fragment_index = kmalloc(length, GFP_KERNEL))) { + ERROR("Failed to allocate fragment index table\n"); return 0; } @@ -919,8 +1022,7 @@ static int read_fragment_index_table(struct super_block *s) int i; long long fragment; - for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments); - i++) { + for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments); i++) { SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment), &msblk->fragment_index[i], 1); msblk->fragment_index[i] = fragment; @@ -935,7 +1037,7 @@ static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int sil { struct squashfs_super_block *sblk = &msblk->sblk; - msblk->iget = squashfs_iget; + msblk->read_inode = squashfs_read_inode; msblk->read_blocklist = read_blocklist; msblk->read_fragment_index_table = read_fragment_index_table; @@ -1005,8 +1107,7 @@ static int squashfs_fill_super(struct super_block *s, void *data, int silent) sblk->bytes_used = sizeof(struct squashfs_super_block); if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START, sizeof(struct squashfs_super_block) | - SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, - sizeof(struct squashfs_super_block))) { + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, sizeof(struct squashfs_super_block))) { SERROR("unable to read superblock\n"); goto failed_mount; } @@ -1034,14 +1135,14 @@ static int squashfs_fill_super(struct super_block *s, void *data, int silent) if(!supported_squashfs_filesystem(msblk, silent)) goto failed_mount; - /* Check the filesystem does not extend beyond the end of the - block device */ - if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode)) - goto failed_mount; + /* Check the filesystem does not extend beyond the end of the + block device */ + if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode)) + goto failed_mount; - /* Check the root inode for sanity */ - if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE) - goto failed_mount; + /* Check the root inode for sanity */ + if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE) + goto failed_mount; TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b)); TRACE("Inodes are %scompressed\n", @@ -1068,7 +1169,7 @@ static int squashfs_fill_super(struct super_block *s, void *data, int silent) TRACE("sblk->uid_start %llx\n", sblk->uid_start); s->s_flags |= MS_RDONLY; - s->s_op = &squashfs_ops; + s->s_op = &squashfs_super_ops; /* Init inode_table block pointer array */ if (!(msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) * @@ -1112,9 +1213,7 @@ static int squashfs_fill_super(struct super_block *s, void *data, int silent) if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start, ((sblk->no_uids + sblk->no_guids) * sizeof(unsigned int)) | - SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, - (sblk->no_uids + sblk->no_guids) * - sizeof(unsigned int))) { + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) { ERROR("unable to read uid/gid table\n"); goto failed_mount; } @@ -1125,9 +1224,7 @@ static int squashfs_fill_super(struct super_block *s, void *data, int silent) if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start, ((sblk->no_uids + sblk->no_guids) * sizeof(unsigned int)) | - SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, - (sblk->no_uids + sblk->no_guids) * - sizeof(unsigned int))) { + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) { ERROR("unable to read uid/gid table\n"); goto failed_mount; } @@ -1150,13 +1247,25 @@ static int squashfs_fill_super(struct super_block *s, void *data, int silent) msblk->next_fragment = 0; - /* Allocate fragment index table */ + /* Allocate and read fragment index table */ if (msblk->read_fragment_index_table(s) == 0) goto failed_mount; + if(sblk->lookup_table_start == SQUASHFS_INVALID_BLK) + goto allocate_root; + + /* Allocate and read inode lookup table */ + if (read_inode_lookup_table(s) == 0) + goto failed_mount; + + s->s_op = &squashfs_export_super_ops; + s->s_export_op = &squashfs_export_ops; + allocate_root: - if ((root = (msblk->iget)(s, sblk->root_inode)) == NULL) + root = new_inode(s); + if ((msblk->read_inode)(root, sblk->root_inode) == 0) goto failed_mount; + insert_inode_hash(root); if ((s->s_root = d_alloc_root(root)) == NULL) { ERROR("Root inode create failed\n"); @@ -1168,6 +1277,7 @@ allocate_root: return 0; failed_mount: + kfree(msblk->inode_lookup_table); kfree(msblk->fragment_index); kfree(msblk->fragment); kfree(msblk->uid); @@ -1185,9 +1295,9 @@ failure: } -static int squashfs_statfs(struct dentry *s, struct kstatfs *buf) +static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf) { - struct squashfs_sb_info *msblk = s->d_sb->s_fs_info; + struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info; struct squashfs_super_block *sblk = &msblk->sblk; TRACE("Entered squashfs_statfs\n"); @@ -1413,6 +1523,8 @@ static int get_meta_index(struct inode *inode, int index, skip)) == NULL) goto all_done; } else { + if(meta->entries == 0) + goto failed; offset = index < meta->offset + meta->entries ? index : meta->offset + meta->entries - 1; meta_entry = &meta->meta_entry[offset - meta->offset]; @@ -1553,8 +1665,7 @@ static int squashfs_readpage(struct file *file, struct page *page) down(&msblk->read_page_mutex); if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page, - block, bsize, NULL, - msblk->read_size))) { + block, bsize, NULL, sblk->block_size))) { ERROR("Unable to read page, block %llx, size %x\n", block, bsize); up(&msblk->read_page_mutex); @@ -1583,36 +1694,31 @@ static int squashfs_readpage(struct file *file, struct page *page) for (i = start_index; i <= end_index && byte_offset < bytes; i++, byte_offset += PAGE_CACHE_SIZE) { struct page *push_page; - int available_bytes = (bytes - byte_offset) > PAGE_CACHE_SIZE ? + int avail = (bytes - byte_offset) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE : bytes - byte_offset; TRACE("bytes %d, i %d, byte_offset %d, available_bytes %d\n", - bytes, i, byte_offset, available_bytes); + bytes, i, byte_offset, avail); - if (i == page->index) { - pageaddr = kmap_atomic(page, KM_USER0); - memcpy(pageaddr, data_ptr + byte_offset, - available_bytes); - memset(pageaddr + available_bytes, 0, - PAGE_CACHE_SIZE - available_bytes); - kunmap_atomic(pageaddr, KM_USER0); - flush_dcache_page(page); - SetPageUptodate(page); - unlock_page(page); - } else if ((push_page = - grab_cache_page_nowait(page->mapping, i))) { - pageaddr = kmap_atomic(push_page, KM_USER0); - - memcpy(pageaddr, data_ptr + byte_offset, - available_bytes); - memset(pageaddr + available_bytes, 0, - PAGE_CACHE_SIZE - available_bytes); - kunmap_atomic(pageaddr, KM_USER0); - flush_dcache_page(push_page); - SetPageUptodate(push_page); - unlock_page(push_page); + push_page = (i == page->index) ? page : + grab_cache_page_nowait(page->mapping, i); + + if (!push_page) + continue; + + if (PageUptodate(push_page)) + goto skip_page; + + pageaddr = kmap_atomic(push_page, KM_USER0); + memcpy(pageaddr, data_ptr + byte_offset, avail); + memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail); + kunmap_atomic(pageaddr, KM_USER0); + flush_dcache_page(push_page); + SetPageUptodate(push_page); +skip_page: + unlock_page(push_page); + if(i != page->index) page_cache_release(push_page); - } } if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK @@ -1668,10 +1774,12 @@ static int squashfs_readpage4K(struct file *file, struct page *page) sblk->block_log)) { block = (msblk->read_blocklist)(inode, page->index, 1, block_list, NULL, &bsize); + if(block == 0) + goto skip_read; down(&msblk->read_page_mutex); bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block, - bsize, NULL, msblk->read_size); + bsize, NULL, sblk->block_size); if (bytes) { pageaddr = kmap_atomic(page, KM_USER0); memcpy(pageaddr, msblk->read_page, bytes); @@ -1956,6 +2064,7 @@ finish: failed_read: ERROR("Unable to read directory block [%llx:%x]\n", next_block, next_offset); + kfree(dire); return 0; } @@ -1980,11 +2089,11 @@ static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry, if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { ERROR("Failed to allocate squashfs_dir_entry\n"); - goto exit_loop; + goto exit_lookup; } if (len > SQUASHFS_NAME_LEN) - goto exit_loop; + goto exit_lookup; length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset, SQUASHFS_I(i)->u.s2.directory_index_start, @@ -2042,35 +2151,35 @@ static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry, length += dire->size + 1; if (name[0] < dire->name[0]) - goto exit_loop; + goto exit_lookup; - if ((len == dire->size + 1) && !strncmp(name, - dire->name, len)) { - squashfs_inode_t ino = - SQUASHFS_MKINODE(dirh.start_block, - dire->offset); + if ((len == dire->size + 1) && !strncmp(name, dire->name, len)) { + squashfs_inode_t ino = SQUASHFS_MKINODE(dirh.start_block, + dire->offset); TRACE("calling squashfs_iget for directory " "entry %s, inode %x:%x, %d\n", name, dirh.start_block, dire->offset, dirh.inode_number + dire->inode_number); - inode = (msblk->iget)(i->i_sb, ino); + inode = squashfs_iget(i->i_sb, ino, dirh.inode_number + dire->inode_number); - goto exit_loop; + goto exit_lookup; } } } -exit_loop: +exit_lookup: kfree(dire); + if (inode) + return d_splice_alias(inode, dentry); d_add(dentry, inode); return ERR_PTR(0); failed_read: ERROR("Unable to read directory block [%llx:%x]\n", next_block, next_offset); - goto exit_loop; + goto exit_lookup; } @@ -2103,10 +2212,12 @@ static void squashfs_put_super(struct super_block *s) } -static int squashfs_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data, struct vfsmount *mnt) +static int squashfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, + struct vfsmount *mnt) { - return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super, mnt); + return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super, + mnt); } @@ -2116,7 +2227,7 @@ static int __init init_squashfs_fs(void) if (err) goto out; - printk(KERN_INFO "squashfs: version 3.1 (2006/08/09) " + printk(KERN_INFO "squashfs: version 3.2-alpha (2006/12/12) " "Phillip Lougher\n"); if ((err = register_filesystem(&squashfs_fs_type))) @@ -2177,14 +2288,12 @@ static int __init init_inodecache(void) static void destroy_inodecache(void) { - if (kmem_cache_destroy(squashfs_inode_cachep)) - printk(KERN_INFO "squashfs_inode_cache: not all structures " - "were freed\n"); + kmem_cache_destroy(squashfs_inode_cachep); } module_init(init_squashfs_fs); module_exit(exit_squashfs_fs); -MODULE_DESCRIPTION("squashfs, a compressed read-only filesystem"); +MODULE_DESCRIPTION("squashfs 3.2, a compressed read-only filesystem"); MODULE_AUTHOR("Phillip Lougher "); MODULE_LICENSE("GPL"); diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h index 170e568c4..8ce7730d7 100644 --- a/fs/squashfs/squashfs.h +++ b/fs/squashfs/squashfs.h @@ -31,7 +31,7 @@ #define TRACE(s, args...) {} #endif -#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args) +#define ERROR(s, args...) printk(KERN_NOTICE "SQUASHFS error: "s, ## args) #define SERROR(s, args...) do { \ if (!silent) \ @@ -59,6 +59,7 @@ extern void release_cached_fragment(struct squashfs_sb_info *msblk, struct extern struct squashfs_fragment_cache *get_cached_fragment(struct super_block *s, long long start_block, int length); +extern struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode, unsigned int inode_number); extern struct address_space_operations squashfs_symlink_aops; extern struct address_space_operations squashfs_aops; extern struct address_space_operations squashfs_aops_4K; diff --git a/fs/squashfs/squashfs2_0.c b/fs/squashfs/squashfs2_0.c index f163523a4..38ee73679 100644 --- a/fs/squashfs/squashfs2_0.c +++ b/fs/squashfs/squashfs2_0.c @@ -73,13 +73,12 @@ static int read_fragment_index_table_2(struct super_block *s) } if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) && - !squashfs_read_data(s, (char *) - msblk->fragment_index_2, - sblk->fragment_table_start, - SQUASHFS_FRAGMENT_INDEX_BYTES_2 - (sblk->fragments) | - SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, - SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments))) { + !squashfs_read_data(s, (char *) + msblk->fragment_index_2, + sblk->fragment_table_start, + SQUASHFS_FRAGMENT_INDEX_BYTES_2 + (sblk->fragments) | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments))) { ERROR("unable to read fragment index table\n"); return 0; } @@ -136,42 +135,35 @@ out: } -static struct inode *squashfs_new_inode(struct super_block *s, +static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i, struct squashfs_base_inode_header_2 *inodeb, unsigned int ino) { - struct squashfs_sb_info *msblk = s->s_fs_info; struct squashfs_super_block *sblk = &msblk->sblk; - struct inode *i = new_inode(s); - - if (i) { - i->i_ino = ino; - i->i_mtime.tv_sec = sblk->mkfs_time; - i->i_atime.tv_sec = sblk->mkfs_time; - i->i_ctime.tv_sec = sblk->mkfs_time; - i->i_uid = msblk->uid[inodeb->uid]; - i->i_mode = inodeb->mode; - i->i_nlink = 1; - i->i_size = 0; - if (inodeb->guid == SQUASHFS_GUIDS) - i->i_gid = i->i_uid; - else - i->i_gid = msblk->guid[inodeb->guid]; - } - return i; + i->i_ino = ino; + i->i_mtime.tv_sec = sblk->mkfs_time; + i->i_atime.tv_sec = sblk->mkfs_time; + i->i_ctime.tv_sec = sblk->mkfs_time; + i->i_uid = msblk->uid[inodeb->uid]; + i->i_mode = inodeb->mode; + i->i_nlink = 1; + i->i_size = 0; + if (inodeb->guid == SQUASHFS_GUIDS) + i->i_gid = i->i_uid; + else + i->i_gid = msblk->guid[inodeb->guid]; } -static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t inode) +static int squashfs_read_inode_2(struct inode *i, squashfs_inode_t inode) { - struct inode *i; + struct super_block *s = i->i_sb; struct squashfs_sb_info *msblk = s->s_fs_info; struct squashfs_super_block *sblk = &msblk->sblk; unsigned int block = SQUASHFS_INODE_BLK(inode) + sblk->inode_table_start; unsigned int offset = SQUASHFS_INODE_OFFSET(inode); - unsigned int ino = SQUASHFS_MK_VFS_INODE(block - - sblk->inode_table_start, offset); + unsigned int ino = i->i_ino; long long next_block; unsigned int next_offset; union squashfs_inode_header_2 id, sid; @@ -193,6 +185,8 @@ static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t ino &next_offset)) goto failed_read; + squashfs_new_inode(msblk, i, inodeb, ino); + switch(inodeb->inode_type) { case SQUASHFS_FILE_TYPE: { struct squashfs_reg_inode_header_2 *inodep = &id.reg; @@ -220,9 +214,6 @@ static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t ino inodep->fragment, &frag_blk, &frag_size)) goto failed_read; - if((i = squashfs_new_inode(s, inodeb, ino)) == NULL) - goto failed_read1; - i->i_size = inodep->file_size; i->i_fop = &generic_ro_fops; i->i_mode |= S_IFREG; @@ -266,9 +257,6 @@ static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t ino &next_offset)) goto failed_read; - if((i = squashfs_new_inode(s, inodeb, ino)) == NULL) - goto failed_read1; - i->i_size = inodep->file_size; i->i_op = &squashfs_dir_inode_ops_2; i->i_fop = &squashfs_dir_ops_2; @@ -306,9 +294,6 @@ static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t ino &next_offset)) goto failed_read; - if((i = squashfs_new_inode(s, inodeb, ino)) == NULL) - goto failed_read1; - i->i_size = inodep->file_size; i->i_op = &squashfs_dir_inode_ops_2; i->i_fop = &squashfs_dir_ops_2; @@ -352,9 +337,6 @@ static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t ino &next_offset)) goto failed_read; - if((i = squashfs_new_inode(s, inodeb, ino)) == NULL) - goto failed_read1; - i->i_size = inodep->symlink_size; i->i_op = &page_symlink_inode_operations; i->i_data.a_ops = &squashfs_symlink_aops; @@ -387,9 +369,6 @@ static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t ino &next_offset)) goto failed_read; - if ((i = squashfs_new_inode(s, inodeb, ino)) == NULL) - goto failed_read1; - i->i_mode |= (inodeb->inode_type == SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : S_IFBLK; @@ -403,8 +382,6 @@ static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t ino } case SQUASHFS_FIFO_TYPE: case SQUASHFS_SOCKET_TYPE: { - if ((i = squashfs_new_inode(s, inodeb, ino)) == NULL) - goto failed_read1; i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) ? S_IFIFO : S_IFSOCK; @@ -417,14 +394,13 @@ static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t ino goto failed_read1; } - insert_inode_hash(i); - return i; + return 1; failed_read: ERROR("Unable to read inode [%x:%x]\n", block, offset); failed_read1: - return NULL; + return 0; } @@ -486,12 +462,18 @@ static int get_dir_index_using_name(struct super_block *s, long long struct squashfs_sb_info *msblk = s->s_fs_info; struct squashfs_super_block *sblk = &msblk->sblk; int i, length = 0; - char buffer[sizeof(struct squashfs_dir_index_2) + SQUASHFS_NAME_LEN + 1]; - struct squashfs_dir_index_2 *index = (struct squashfs_dir_index_2 *) buffer; - char str[SQUASHFS_NAME_LEN + 1]; + struct squashfs_dir_index_2 *index; + char *str; TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); + if (!(str = kmalloc(sizeof(struct squashfs_dir_index) + + (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) { + ERROR("Failed to allocate squashfs_dir_index\n"); + goto failure; + } + + index = (struct squashfs_dir_index_2 *) (str + SQUASHFS_NAME_LEN + 1); strncpy(str, name, size); str[size] = '\0'; @@ -523,6 +505,8 @@ static int get_dir_index_using_name(struct super_block *s, long long } *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; + kfree(str); +failure: return length; } @@ -534,14 +518,19 @@ static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir struct squashfs_super_block *sblk = &msblk->sblk; long long next_block = SQUASHFS_I(i)->start_block + sblk->directory_table_start; - int next_offset = SQUASHFS_I(i)->offset, length = 0, dirs_read = 0, + int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count; struct squashfs_dir_header_2 dirh; - char buffer[sizeof(struct squashfs_dir_entry_2) + SQUASHFS_NAME_LEN + 1]; - struct squashfs_dir_entry_2 *dire = (struct squashfs_dir_entry_2 *) buffer; + struct squashfs_dir_entry_2 *dire; TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset); + if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + + SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { + ERROR("Failed to allocate squashfs_dir_entry\n"); + goto finish; + } + length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset, SQUASHFS_I(i)->u.s2.directory_index_start, SQUASHFS_I(i)->u.s2.directory_index_offset, @@ -619,16 +608,17 @@ static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir goto finish; } file->f_pos = length; - dirs_read++; } } finish: - return dirs_read; + kfree(dire); + return 0; failed_read: ERROR("Unable to read directory block [%llx:%x]\n", next_block, next_offset); + kfree(dire); return 0; } @@ -646,11 +636,16 @@ static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry, int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count; struct squashfs_dir_header_2 dirh; - char buffer[sizeof(struct squashfs_dir_entry_2) + SQUASHFS_NAME_LEN]; - struct squashfs_dir_entry_2 *dire = (struct squashfs_dir_entry_2 *) buffer; + struct squashfs_dir_entry_2 *dire; int sorted = sblk->s_major == 2 && sblk->s_minor >= 1; - TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset); + TRACE("Entered squashfs_lookup_2 [%llx:%x]\n", next_block, next_offset); + + if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + + SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { + ERROR("Failed to allocate squashfs_dir_entry\n"); + goto exit_loop; + } if (len > SQUASHFS_NAME_LEN) goto exit_loop; @@ -718,12 +713,14 @@ static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry, squashfs_inode_t ino = SQUASHFS_MKINODE(dirh.start_block, dire->offset); + unsigned int inode_number = SQUASHFS_MK_VFS_INODE(dirh.start_block, + dire->offset); TRACE("calling squashfs_iget for directory " "entry %s, inode %x:%x, %lld\n", name, dirh.start_block, dire->offset, ino); - inode = (msblk->iget)(i->i_sb, ino); + inode = squashfs_iget(i->i_sb, ino, inode_number); goto exit_loop; } @@ -731,6 +728,7 @@ static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry, } exit_loop: + kfree(dire); d_add(dentry, inode); return ERR_PTR(0); @@ -745,7 +743,7 @@ int squashfs_2_0_supported(struct squashfs_sb_info *msblk) { struct squashfs_super_block *sblk = &msblk->sblk; - msblk->iget = squashfs_iget_2; + msblk->read_inode = squashfs_read_inode_2; msblk->read_fragment_index_table = read_fragment_index_table_2; sblk->bytes_used = sblk->bytes_used_2; diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h index 1e891f860..188e24be7 100644 --- a/include/asm-arm/unistd.h +++ b/include/asm-arm/unistd.h @@ -347,6 +347,19 @@ #define __NR_mbind (__NR_SYSCALL_BASE+319) #define __NR_get_mempolicy (__NR_SYSCALL_BASE+320) #define __NR_set_mempolicy (__NR_SYSCALL_BASE+321) +#define __NR_openat (__NR_SYSCALL_BASE+322) +#define __NR_mkdirat (__NR_SYSCALL_BASE+323) +#define __NR_mknodat (__NR_SYSCALL_BASE+324) +#define __NR_fchownat (__NR_SYSCALL_BASE+325) +#define __NR_futimesat (__NR_SYSCALL_BASE+326) +#define __NR_fstatat64 (__NR_SYSCALL_BASE+327) +#define __NR_unlinkat (__NR_SYSCALL_BASE+328) +#define __NR_renameat (__NR_SYSCALL_BASE+329) +#define __NR_linkat (__NR_SYSCALL_BASE+330) +#define __NR_symlinkat (__NR_SYSCALL_BASE+331) +#define __NR_readlinkat (__NR_SYSCALL_BASE+332) +#define __NR_fchmodat (__NR_SYSCALL_BASE+333) +#define __NR_faccessat (__NR_SYSCALL_BASE+334) /* * The following SWIs are ARM private. diff --git a/include/asm-m32r/ptrace.h b/include/asm-m32r/ptrace.h index 2d2a6c973..632b4ce42 100644 --- a/include/asm-m32r/ptrace.h +++ b/include/asm-m32r/ptrace.h @@ -33,21 +33,10 @@ #define PT_R15 PT_SP /* processor status and miscellaneous context registers. */ -#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2) #define PT_ACC0H 15 #define PT_ACC0L 16 -#define PT_ACC1H 17 -#define PT_ACC1L 18 -#define PT_ACCH PT_ACC0H -#define PT_ACCL PT_ACC0L -#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) -#define PT_ACCH 15 -#define PT_ACCL 16 -#define PT_DUMMY_ACC1H 17 -#define PT_DUMMY_ACC1L 18 -#else -#error unknown isa conifiguration -#endif +#define PT_ACC1H 17 /* ISA_DSP_LEVEL2 only */ +#define PT_ACC1L 18 /* ISA_DSP_LEVEL2 only */ #define PT_PSW 19 #define PT_BPC 20 #define PT_BBPSW 21 @@ -103,19 +92,10 @@ struct pt_regs { long syscall_nr; /* Saved main processor status and miscellaneous context registers. */ -#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2) unsigned long acc0h; unsigned long acc0l; - unsigned long acc1h; - unsigned long acc1l; -#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) - unsigned long acch; - unsigned long accl; - unsigned long dummy_acc1h; - unsigned long dummy_acc1l; -#else -#error unknown isa configuration -#endif + unsigned long acc1h; /* ISA_DSP_LEVEL2 only */ + unsigned long acc1l; /* ISA_DSP_LEVEL2 only */ unsigned long psw; unsigned long bpc; /* saved PC for TRAP syscalls */ unsigned long bbpsw; diff --git a/include/asm-m32r/sigcontext.h b/include/asm-m32r/sigcontext.h index 73025c0c4..62537dc4d 100644 --- a/include/asm-m32r/sigcontext.h +++ b/include/asm-m32r/sigcontext.h @@ -23,19 +23,10 @@ struct sigcontext { unsigned long sc_r12; /* Saved main processor status and miscellaneous context registers. */ -#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2) unsigned long sc_acc0h; unsigned long sc_acc0l; - unsigned long sc_acc1h; - unsigned long sc_acc1l; -#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) - unsigned long sc_acch; - unsigned long sc_accl; - unsigned long sc_dummy_acc1h; - unsigned long sc_dummy_acc1l; -#else -#error unknown isa configuration -#endif + unsigned long sc_acc1h; /* ISA_DSP_LEVEL2 only */ + unsigned long sc_acc1l; /* ISA_DSP_LEVEL2 only */ unsigned long sc_psw; unsigned long sc_bpc; /* saved PC for TRAP syscalls */ unsigned long sc_bbpsw; diff --git a/include/linux/squashfs_fs.h b/include/linux/squashfs_fs.h index ef01d8874..47529be7e 100644 --- a/include/linux/squashfs_fs.h +++ b/include/linux/squashfs_fs.h @@ -35,7 +35,7 @@ #define SQUASHFS_ALLOC(a) kmalloc(a, GFP_KERNEL) #define SQUASHFS_FREE(a) kfree(a) #endif -#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE +#define SQUASHFS_CACHED_FRAGMENTS 3 #define SQUASHFS_MAJOR 3 #define SQUASHFS_MINOR 0 #define SQUASHFS_MAGIC 0x73717368 @@ -72,6 +72,7 @@ #define SQUASHFS_NO_FRAG 4 #define SQUASHFS_ALWAYS_FRAG 5 #define SQUASHFS_DUPLICATE 6 +#define SQUASHFS_EXPORT 7 #define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1) @@ -93,13 +94,16 @@ #define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \ SQUASHFS_DUPLICATE) +#define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_EXPORT) + #define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \ SQUASHFS_CHECK) #define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \ - duplicate_checking) (noi | (nod << 1) | (check_data << 2) \ + duplicate_checking, exortable) (noi | (nod << 1) | (check_data << 2) \ | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \ - (duplicate_checking << 6)) + (duplicate_checking << 6) | (exportable << 7)) /* Max number of types and file types */ #define SQUASHFS_DIR_TYPE 1 @@ -153,7 +157,7 @@ #define SQUASHFS_MODE(a) ((a) & 0xfff) /* fragment and fragment table defines */ -#define SQUASHFS_FRAGMENT_BYTES(A) (A * sizeof(struct squashfs_fragment_entry)) +#define SQUASHFS_FRAGMENT_BYTES(A) ((A) * sizeof(struct squashfs_fragment_entry)) #define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \ SQUASHFS_METADATA_SIZE) @@ -168,6 +172,22 @@ #define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\ sizeof(long long)) +/* inode lookup table defines */ +#define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(squashfs_inode_t)) + +#define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \ + SQUASHFS_METADATA_SIZE - 1) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(A) *\ + sizeof(long long)) + /* cached data constants for filesystem */ #define SQUASHFS_CACHED_BLKS 8 @@ -235,7 +255,7 @@ struct squashfs_super_block { long long inode_table_start; long long directory_table_start; long long fragment_table_start; - long long unused; + long long lookup_table_start; } __attribute__ ((packed)); struct squashfs_dir_index { @@ -342,7 +362,7 @@ struct squashfs_dir_header { struct squashfs_fragment_entry { long long start_block; unsigned int size; - unsigned int unused; + unsigned int pending; } __attribute__ ((packed)); extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen); @@ -391,7 +411,7 @@ extern int squashfs_uncompress_exit(void); SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\ SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\ SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\ - SQUASHFS_SWAP((s)->unused, d, 888, 64);\ + SQUASHFS_SWAP((s)->lookup_table_start, d, 888, 64);\ } #define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ @@ -507,6 +527,8 @@ extern int squashfs_uncompress_exit(void); SQUASHFS_SWAP((s)->size, d, 64, 32);\ } +#define SQUASHFS_SWAP_INODE_T(s, d) SQUASHFS_SWAP_LONG_LONGS(s, d, 1) + #define SQUASHFS_SWAP_SHORTS(s, d, n) {\ int entry;\ int bit_position;\ @@ -548,6 +570,7 @@ extern int squashfs_uncompress_exit(void); } #define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) +#define SQUASHFS_SWAP_LOOKUP_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) #ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY diff --git a/include/linux/squashfs_fs_sb.h b/include/linux/squashfs_fs_sb.h index 6b35e64d0..4e61e98ec 100644 --- a/include/linux/squashfs_fs_sb.h +++ b/include/linux/squashfs_fs_sb.h @@ -65,7 +65,8 @@ struct squashfs_sb_info { wait_queue_head_t fragment_wait_queue; struct meta_index *meta_index; z_stream stream; - struct inode *(*iget)(struct super_block *s, squashfs_inode_t \ + long long *inode_lookup_table; + int (*read_inode)(struct inode *i, squashfs_inode_t \ inode); long long (*read_blocklist)(struct inode *inode, int \ index, int readahead_blks, char *block_list, \ diff --git a/kernel/softirq.c b/kernel/softirq.c index 3789ca981..aee8b98a4 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -574,8 +574,6 @@ static int __cpuinit cpu_callback(struct notifier_block *nfb, switch (action) { case CPU_UP_PREPARE: - BUG_ON(per_cpu(tasklet_vec, hotcpu).list); - BUG_ON(per_cpu(tasklet_hi_vec, hotcpu).list); p = kthread_create(ksoftirqd, hcpu, "ksoftirqd/%d", hotcpu); if (IS_ERR(p)) { printk("ksoftirqd for %i failed\n", hotcpu); diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index be04e9fb1..ab166b48c 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c @@ -196,6 +196,9 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s switch (CAPIMSG_SUBCOMMAND(skb->data)) { case CAPI_CONF: + if (skb->len < CAPI_MSG_BASELEN + 10) + break; + func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5); info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8); @@ -226,6 +229,9 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s break; case CAPI_FUNCTION_GET_PROFILE: + if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile)) + break; + controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11); msgnum = CAPIMSG_MSGID(skb->data); @@ -246,17 +252,26 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s break; case CAPI_FUNCTION_GET_MANUFACTURER: + if (skb->len < CAPI_MSG_BASELEN + 15) + break; + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10); if (!info && ctrl) { + int len = min_t(uint, CAPI_MANUFACTURER_LEN, + skb->data[CAPI_MSG_BASELEN + 14]); + + memset(ctrl->manu, 0, CAPI_MANUFACTURER_LEN); strncpy(ctrl->manu, - skb->data + CAPI_MSG_BASELEN + 15, - skb->data[CAPI_MSG_BASELEN + 14]); + skb->data + CAPI_MSG_BASELEN + 15, len); } break; case CAPI_FUNCTION_GET_VERSION: + if (skb->len < CAPI_MSG_BASELEN + 32) + break; + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); if (!info && ctrl) { @@ -269,13 +284,18 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s break; case CAPI_FUNCTION_GET_SERIAL_NUMBER: + if (skb->len < CAPI_MSG_BASELEN + 17) + break; + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); if (!info && ctrl) { + int len = min_t(uint, CAPI_SERIAL_LEN, + skb->data[CAPI_MSG_BASELEN + 16]); + memset(ctrl->serial, 0, CAPI_SERIAL_LEN); strncpy(ctrl->serial, - skb->data + CAPI_MSG_BASELEN + 17, - skb->data[CAPI_MSG_BASELEN + 16]); + skb->data + CAPI_MSG_BASELEN + 17, len); } break; @@ -284,14 +304,18 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s break; case CAPI_IND: + if (skb->len < CAPI_MSG_BASELEN + 6) + break; + func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3); if (func == CAPI_FUNCTION_LOOPBACK) { + int len = min_t(uint, skb->len - CAPI_MSG_BASELEN - 6, + skb->data[CAPI_MSG_BASELEN + 5]); appl = CAPIMSG_APPID(skb->data); msgnum = CAPIMSG_MSGID(skb->data); cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func, - skb->data + CAPI_MSG_BASELEN + 6, - skb->data[CAPI_MSG_BASELEN + 5]); + skb->data + CAPI_MSG_BASELEN + 6, len); } break; @@ -309,6 +333,9 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb) BT_DBG("session %p skb %p len %d", session, skb, skb->len); + if (skb->len < CAPI_MSG_BASELEN) + return; + if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) { cmtp_recv_interopmsg(session, skb); return; diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 3a13ed643..1969658a4 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -360,10 +360,11 @@ ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, const char *name, unsigned int hookmask, unsigned int *cnt) { struct ebt_match *match; + size_t left = ((char *)e + e->watchers_offset) - (char *)m; int ret; - if (((char *)m) + m->match_size + sizeof(struct ebt_entry_match) > - ((char *)e) + e->watchers_offset) + if (left < sizeof(struct ebt_entry_match) || + left - sizeof(struct ebt_entry_match) < m->match_size) return -EINVAL; match = find_match_lock(m->u.name, &ret, &ebt_mutex); if (!match) @@ -389,10 +390,11 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e, const char *name, unsigned int hookmask, unsigned int *cnt) { struct ebt_watcher *watcher; + size_t left = ((char *)e + e->target_offset) - (char *)w; int ret; - if (((char *)w) + w->watcher_size + sizeof(struct ebt_entry_watcher) > - ((char *)e) + e->target_offset) + if (left < sizeof(struct ebt_entry_watcher) || + left - sizeof(struct ebt_entry_watcher) < w->watcher_size) return -EINVAL; watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex); if (!watcher) @@ -423,19 +425,23 @@ ebt_check_entry_size_and_hooks(struct ebt_entry *e, struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt, unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks) { + unsigned int offset = (char *)e - newinfo->entries; + size_t left = (limit - base) - offset; int i; + if (left < sizeof(unsigned int)) + goto Esmall; + for (i = 0; i < NF_BR_NUMHOOKS; i++) { if ((valid_hooks & (1 << i)) == 0) continue; - if ( (char *)hook_entries[i] - base == - (char *)e - newinfo->entries) + if ((char *)hook_entries[i] == base + offset) break; } /* beginning of a new chain if i == NF_BR_NUMHOOKS it must be a user defined chain */ if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) { - if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) != 0) { + if (e->bitmask != 0) { /* we make userspace set this right, so there is no misunderstanding */ BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set " @@ -450,11 +456,8 @@ ebt_check_entry_size_and_hooks(struct ebt_entry *e, return -EINVAL; } /* before we look at the struct, be sure it is not too big */ - if ((char *)hook_entries[i] + sizeof(struct ebt_entries) - > limit) { - BUGPRINT("entries_size too small\n"); - return -EINVAL; - } + if (left < sizeof(struct ebt_entries)) + goto Esmall; if (((struct ebt_entries *)e)->policy != EBT_DROP && ((struct ebt_entries *)e)->policy != EBT_ACCEPT) { /* only RETURN from udc */ @@ -477,6 +480,8 @@ ebt_check_entry_size_and_hooks(struct ebt_entry *e, return 0; } /* a plain old entry, heh */ + if (left < sizeof(struct ebt_entry)) + goto Esmall; if (sizeof(struct ebt_entry) > e->watchers_offset || e->watchers_offset > e->target_offset || e->target_offset >= e->next_offset) { @@ -488,10 +493,16 @@ ebt_check_entry_size_and_hooks(struct ebt_entry *e, BUGPRINT("target size too small\n"); return -EINVAL; } + if (left < e->next_offset) + goto Esmall; (*cnt)++; (*totalcnt)++; return 0; + +Esmall: + BUGPRINT("entries_size too small\n"); + return -EINVAL; } struct ebt_cl_stack @@ -513,7 +524,7 @@ ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo, int i; /* we're only interested in chain starts */ - if (e->bitmask & EBT_ENTRY_OR_ENTRIES) + if (e->bitmask) return 0; for (i = 0; i < NF_BR_NUMHOOKS; i++) { if ((valid_hooks & (1 << i)) == 0) @@ -563,7 +574,7 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) { struct ebt_entry_target *t; - if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) + if (e->bitmask == 0) return 0; /* we're done */ if (cnt && (*cnt)-- == 0) @@ -586,10 +597,11 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, struct ebt_entry_target *t; struct ebt_target *target; unsigned int i, j, hook = 0, hookmask = 0; + size_t gap = e->next_offset - e->target_offset; int ret; /* don't mess with the struct ebt_entries */ - if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) + if (e->bitmask == 0) return 0; if (e->bitmask & ~EBT_F_MASK) { @@ -647,8 +659,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, t->u.target = target; if (t->u.target == &ebt_standard_target) { - if (e->target_offset + sizeof(struct ebt_standard_target) > - e->next_offset) { + if (gap < sizeof(struct ebt_standard_target)) { BUGPRINT("Standard target size too big\n"); ret = -EFAULT; goto cleanup_watchers; @@ -659,8 +670,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, ret = -EFAULT; goto cleanup_watchers; } - } else if ((e->target_offset + t->target_size + - sizeof(struct ebt_entry_target) > e->next_offset) || + } else if (t->target_size > gap - sizeof(struct ebt_entry_target) || (t->u.target->check && t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){ module_put(t->u.target->me); @@ -730,7 +740,9 @@ static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s BUGPRINT("loop\n"); return -1; } - /* this can't be 0, so the above test is correct */ + if (cl_s[i].hookmask & (1 << hooknr)) + goto letscontinue; + /* this can't be 0, so the loop test is correct */ cl_s[i].cs.n = pos + 1; pos = 0; cl_s[i].cs.e = ((void *)e + e->next_offset); @@ -1307,7 +1319,7 @@ static inline int ebt_make_names(struct ebt_entry *e, char *base, char *ubase) char *hlp; struct ebt_entry_target *t; - if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) + if (e->bitmask == 0) return 0; hlp = ubase - base + (char *)e + e->target_offset; diff --git a/net/ieee80211/softmac/ieee80211softmac_scan.c b/net/ieee80211/softmac/ieee80211softmac_scan.c index d31cf7749..ad67368b5 100644 --- a/net/ieee80211/softmac/ieee80211softmac_scan.c +++ b/net/ieee80211/softmac/ieee80211softmac_scan.c @@ -47,7 +47,6 @@ ieee80211softmac_start_scan(struct ieee80211softmac_device *sm) sm->scanning = 1; spin_unlock_irqrestore(&sm->lock, flags); - netif_tx_disable(sm->ieee->dev); ret = sm->start_scan(sm->dev); if (ret) { spin_lock_irqsave(&sm->lock, flags); @@ -248,7 +247,6 @@ void ieee80211softmac_scan_finished(struct ieee80211softmac_device *sm) if (net) sm->set_channel(sm->dev, net->channel); } - netif_wake_queue(sm->ieee->dev); ieee80211softmac_call_events(sm, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, NULL); } EXPORT_SYMBOL_GPL(ieee80211softmac_scan_finished); diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index e96443699..a560c5537 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1989,6 +1989,8 @@ compat_get_entries(struct compat_ipt_get_entries __user *uptr, int *len) return ret; } +static int do_ipt_get_ctl(struct sock *, int, void __user *, int *); + static int compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) { @@ -2005,8 +2007,7 @@ compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) ret = compat_get_entries(user, len); break; default: - duprintf("compat_do_ipt_get_ctl: unknown request %i\n", cmd); - ret = -EINVAL; + ret = do_ipt_get_ctl(sk, cmd, user, len); } return ret; } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index b873cbcdd..c7a806b82 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1775,7 +1775,7 @@ static inline int __mkroute_input(struct sk_buff *skb, #endif if (in_dev->cnf.no_policy) rth->u.dst.flags |= DST_NOPOLICY; - if (in_dev->cnf.no_xfrm) + if (out_dev->cnf.no_xfrm) rth->u.dst.flags |= DST_NOXFRM; rth->fl.fl4_dst = daddr; rth->rt_dst = daddr; diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 8f50eae47..eae687d4d 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -252,6 +252,8 @@ static void xfrm4_dst_destroy(struct dst_entry *dst) if (likely(xdst->u.rt.idev)) in_dev_put(xdst->u.rt.idev); + if (likely(xdst->u.rt.peer)) + inet_putpeer(xdst->u.rt.peer); xfrm_dst_destroy(xdst); } diff --git a/net/irda/irttp.c b/net/irda/irttp.c index 42acf1cde..be0d8fa85 100644 --- a/net/irda/irttp.c +++ b/net/irda/irttp.c @@ -1098,7 +1098,7 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel, return -ENOMEM; /* Reserve space for MUX_CONTROL and LAP header */ - skb_reserve(tx_skb, TTP_MAX_HEADER); + skb_reserve(tx_skb, TTP_MAX_HEADER + TTP_SAR_HEADER); } else { tx_skb = userdata; /* @@ -1346,7 +1346,7 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, return -ENOMEM; /* Reserve space for MUX_CONTROL and LAP header */ - skb_reserve(tx_skb, TTP_MAX_HEADER); + skb_reserve(tx_skb, TTP_MAX_HEADER + TTP_SAR_HEADER); } else { tx_skb = userdata; /* diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index e75a147ad..a29d0f667 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -54,14 +54,14 @@ static DEFINE_RWLOCK(gact_lock); #ifdef CONFIG_GACT_PROB static int gact_net_rand(struct tcf_gact *p) { - if (net_random()%p->pval) + if (!p->pval || net_random()%p->pval) return p->action; return p->paction; } static int gact_determ(struct tcf_gact *p) { - if (p->bstats.packets%p->pval) + if (!p->pval || p->bstats.packets%p->pval) return p->action; return p->paction; } diff --git a/net/sched/act_police.c b/net/sched/act_police.c index da905d7b4..930e01047 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -44,6 +44,18 @@ static struct tcf_police *tcf_police_ht[MY_TAB_SIZE]; /* Policer hash table lock */ static DEFINE_RWLOCK(police_lock); +/* old policer structure from before tc actions */ +struct tc_police_compat +{ + u32 index; + int action; + u32 limit; + u32 burst; + u32 mtu; + struct tc_ratespec rate; + struct tc_ratespec peakrate; +}; + /* Each policer is serialized by its individual spinlock */ static __inline__ unsigned tcf_police_hash(u32 index) @@ -169,12 +181,15 @@ static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est, struct tc_police *parm; struct tcf_police *p; struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL; + int size; if (rta == NULL || rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0) return -EINVAL; - if (tb[TCA_POLICE_TBF-1] == NULL || - RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]) != sizeof(*parm)) + if (tb[TCA_POLICE_TBF-1] == NULL) + return -EINVAL; + size = RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]); + if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat)) return -EINVAL; parm = RTA_DATA(tb[TCA_POLICE_TBF-1]); @@ -413,12 +428,15 @@ struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est) struct tcf_police *p; struct rtattr *tb[TCA_POLICE_MAX]; struct tc_police *parm; + int size; if (rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0) return NULL; - if (tb[TCA_POLICE_TBF-1] == NULL || - RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]) != sizeof(*parm)) + if (tb[TCA_POLICE_TBF-1] == NULL) + return NULL; + size = RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]); + if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat)) return NULL; parm = RTA_DATA(tb[TCA_POLICE_TBF-1]);