Merge to Fedora kernel-2.6.18-1.2257_FC5 patched with stable patch-2.6.18.5-vs2.0...
authorMarc Fiuczynski <mef@cs.princeton.edu>
Tue, 26 Dec 2006 20:16:05 +0000 (20:16 +0000)
committerMarc Fiuczynski <mef@cs.princeton.edu>
Tue, 26 Dec 2006 20:16:05 +0000 (20:16 +0000)
57 files changed:
.config
.config.old
arch/arm/kernel/calls.S
arch/m32r/kernel/entry.S
arch/x86_64/kernel/setup.c
configs/kernel-2.6.18-i586-smp.config
configs/kernel-2.6.18-i586.config
configs/kernel-2.6.18-i686-kdump.config
configs/kernel-2.6.18-i686-smp.config
configs/kernel-2.6.18-i686-xen.config
configs/kernel-2.6.18-i686-xen0.config
configs/kernel-2.6.18-i686-xenU.config
configs/kernel-2.6.18-i686.config
configs/kernel-2.6.18-ia64-xen.config
configs/kernel-2.6.18-ia64.config
configs/kernel-2.6.18-ppc-smp.config
configs/kernel-2.6.18-ppc.config
configs/kernel-2.6.18-ppc64-kdump.config
configs/kernel-2.6.18-ppc64.config
configs/kernel-2.6.18-ppc64iseries.config
configs/kernel-2.6.18-s390.config
configs/kernel-2.6.18-s390x.config
configs/kernel-2.6.18-x86_64-kdump.config
configs/kernel-2.6.18-x86_64-xen.config
configs/kernel-2.6.18-x86_64-xen0.config
configs/kernel-2.6.18-x86_64-xenU.config
configs/kernel-2.6.18-x86_64.config
drivers/ieee1394/ohci1394.c
drivers/md/dm-crypt.c
drivers/md/dm-snap.c
drivers/media/dvb/frontends/lgdt330x.c
drivers/media/video/tuner-simple.c
drivers/media/video/tuner-types.c
drivers/net/bonding/bond_main.c
drivers/net/forcedeth.c
drivers/net/sunhme.c
fs/Kconfig
fs/Makefile
fs/compat.c
fs/squashfs/inode.c
fs/squashfs/squashfs.h
fs/squashfs/squashfs2_0.c
include/asm-arm/unistd.h
include/asm-m32r/ptrace.h
include/asm-m32r/sigcontext.h
include/linux/squashfs_fs.h
include/linux/squashfs_fs_sb.h
kernel/softirq.c
net/bluetooth/cmtp/capi.c
net/bridge/netfilter/ebtables.c
net/ieee80211/softmac/ieee80211softmac_scan.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/route.c
net/ipv4/xfrm4_policy.c
net/irda/irttp.c
net/sched/act_gact.c
net/sched/act_police.c

diff --git a/.config b/.config
index 8877438..5472124 100644 (file)
--- 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
index 90ead9a..8db28ce 100644 (file)
@@ -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
index 83c02a7..fa5c40c 100644 (file)
                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
index ac6d840..5b01fd2 100644 (file)
  *     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 <linux/linkage.h>
 #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)
index 4b39f0d..40a74d4 100644 (file)
@@ -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();
index 74a7737..7031af6 100644 (file)
@@ -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
index 4bb100b..2960893 100644 (file)
@@ -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
index 128ca73..f5b9e62 100644 (file)
@@ -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
index 224e29a..b2c4078 100644 (file)
@@ -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
index 7fb1817..a6165c5 100644 (file)
@@ -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
index 4ca8085..1643872 100644 (file)
@@ -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
index b601154..7bef092 100644 (file)
@@ -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
index ceaff0f..29fb9f6 100644 (file)
@@ -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
index 20030da..abec696 100644 (file)
@@ -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
index 50a65eb..3282a40 100644 (file)
@@ -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
index 90fedf1..7e33c54 100644 (file)
@@ -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
index ef5ea67..2699ead 100644 (file)
@@ -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
index 7792d06..8d851c4 100644 (file)
@@ -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
index 9ee604b..411ab62 100644 (file)
@@ -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
index 726bc8d..ab48ca6 100644 (file)
@@ -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
index 57879c5..0887d7f 100644 (file)
@@ -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
index 79e22c1..6928ca9 100644 (file)
@@ -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
index 64e99b2..ae15586 100644 (file)
@@ -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
index 11ebc6c..8bb58f7 100644 (file)
@@ -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
index 85a593c..32be42f 100644 (file)
@@ -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
index b3f4b2a..2c47cdb 100644 (file)
@@ -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
index a6e5963..8ff4376 100644 (file)
@@ -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
index 448df27..ab5a6b5 100644 (file)
@@ -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);
index 6022ed1..31e498f 100644 (file)
@@ -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;
        }
index 1d0fafd..6578b26 100644 (file)
@@ -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;
        }
index 9a35470..467f199 100644 (file)
@@ -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 */
index abe37cf..a17cc8e 100644 (file)
@@ -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:
index 8b54259..c371159 100644 (file)
@@ -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)",
index 61bd179..cf906d7 100644 (file)
@@ -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);
index 38e8bfa..c760586 100644 (file)
@@ -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;
                }
        }
index c6f5bc3..3bbf0c8 100644 (file)
@@ -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)
index 7a818f5..75b7c07 100644 (file)
@@ -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 <file:Documentation/modules.txt>.  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
index 970aed3..e5efb4b 100644 (file)
@@ -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/
index 55cf405..7973687 100644 (file)
@@ -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)) {
index 9e8ae26..ccbaeb6 100644 (file)
@@ -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 <phillip@lougher.org.uk>");
 MODULE_LICENSE("GPL");
index 170e568..8ce7730 100644 (file)
@@ -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;
index f163523..38ee736 100644 (file)
@@ -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;
index 1e891f8..188e24b 100644 (file)
 #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.
index 2d2a6c9..632b4ce 100644 (file)
 #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;
index 73025c0..62537dc 100644 (file)
@@ -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;
index ef01d88..47529be 100644 (file)
@@ -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)
 
 #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
 #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)
 #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
 
index 6b35e64..4e61e98 100644 (file)
@@ -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, \
index 3789ca9..aee8b98 100644 (file)
@@ -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);
index be04e9f..ab166b4 100644 (file)
@@ -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;
index 3a13ed6..1969658 100644 (file)
@@ -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;
index d31cf77..ad67368 100644 (file)
@@ -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);
index e964436..a560c55 100644 (file)
@@ -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;
 }
index b873cbc..c7a806b 100644 (file)
@@ -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;
index 8f50eae..eae687d 100644 (file)
@@ -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);
 }
 
index 42acf1c..be0d8fa 100644 (file)
@@ -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;
                /*
index e75a147..a29d0f6 100644 (file)
@@ -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;
 }
index da905d7..930e010 100644 (file)
@@ -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]);