]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 19 Aug 2010 16:06:49 +0000 (09:06 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 19 Aug 2010 16:06:49 +0000 (09:06 -0700)
* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  kprobes/x86: Fix the return address of multiple kretprobes
  perf tools: Fix build error on read only source.
  perf, x86: Fix Intel-nhm PMU programming errata workaround

187 files changed:
Documentation/laptops/thinkpad-acpi.txt
Documentation/powerpc/booting-without-of.txt
arch/alpha/kernel/process.c
arch/arm/Makefile
arch/arm/include/asm/ptrace.h
arch/arm/include/asm/unistd.h
arch/arm/kernel/calls.S
arch/arm/kernel/kgdb.c
arch/arm/kernel/sys_arm.c
arch/avr32/kernel/process.c
arch/avr32/kernel/sys_avr32.c
arch/blackfin/kernel/process.c
arch/cris/arch-v10/kernel/process.c
arch/cris/arch-v32/kernel/process.c
arch/frv/kernel/process.c
arch/h8300/kernel/process.c
arch/h8300/kernel/sys_h8300.c
arch/ia64/include/asm/unistd.h
arch/ia64/kernel/process.c
arch/m32r/kernel/process.c
arch/m32r/kernel/sys_m32r.c
arch/m68k/include/asm/ide.h
arch/m68k/kernel/process.c
arch/m68k/kernel/sys_m68k.c
arch/m68knommu/kernel/process.c
arch/m68knommu/kernel/sys_m68k.c
arch/microblaze/kernel/prom_parse.c
arch/microblaze/kernel/sys_microblaze.c
arch/microblaze/pci/pci-common.c
arch/microblaze/pci/xilinx_pci.c
arch/mips/kernel/syscall.c
arch/mn10300/kernel/process.c
arch/parisc/hpux/fs.c
arch/parisc/kernel/process.c
arch/powerpc/kernel/process.c
arch/s390/kernel/process.c
arch/score/kernel/sys_score.c
arch/sh/kernel/process_32.c
arch/sh/kernel/process_64.c
arch/sh/kernel/sys_sh32.c
arch/sh/kernel/sys_sh64.c
arch/sparc/include/asm/atomic_64.h
arch/sparc/include/asm/fb.h
arch/sparc/include/asm/rwsem-const.h
arch/sparc/include/asm/unistd.h
arch/sparc/kernel/process_32.c
arch/sparc/kernel/process_64.c
arch/sparc/kernel/sys32.S
arch/sparc/kernel/sys_sparc_32.c
arch/sparc/kernel/sys_sparc_64.c
arch/sparc/kernel/systbls_32.S
arch/sparc/kernel/systbls_64.S
arch/tile/kernel/process.c
arch/um/kernel/exec.c
arch/um/kernel/syscall.c
arch/x86/include/asm/syscalls.h
arch/x86/kernel/kgdb.c
arch/x86/kernel/process.c
arch/x86/kernel/sys_i386_32.c
arch/xtensa/kernel/process.c
drivers/ata/sata_dwc_460ex.c
drivers/block/xsysace.c
drivers/char/pty.c
drivers/char/tty_io.c
drivers/char/vt.c
drivers/char/xilinx_hwicap/xilinx_hwicap.c
drivers/hid/hid-core.c
drivers/hid/hid-egalax.c
drivers/hid/hid-ids.h
drivers/hid/hid-picolcd.c
drivers/hid/usbhid/hiddev.c
drivers/md/md.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/mmc/core/host.c
drivers/mtd/maps/physmap_of.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath9k/eeprom.h
drivers/net/wireless/ath/ath9k/eeprom_9287.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ipw2x00/ipw2100.c
drivers/net/wireless/wl12xx/wl1251_cmd.c
drivers/platform/x86/asus_acpi.c
drivers/platform/x86/compal-laptop.c
drivers/platform/x86/dell-laptop.c
drivers/platform/x86/intel_ips.c
drivers/platform/x86/thinkpad_acpi.c
drivers/scsi/arcmsr/arcmsr_hba.c
drivers/serial/of_serial.c
drivers/serial/suncore.c
drivers/spi/coldfire_qspi.c
drivers/staging/pohmelfs/path_entry.c
drivers/video/amba-clcd.c
fs/binfmt_misc.c
fs/binfmt_script.c
fs/buffer.c
fs/cramfs/inode.c
fs/dcache.c
fs/exec.c
fs/fat/misc.c
fs/file_table.c
fs/fs_struct.c
fs/generic_acl.c
fs/hostfs/hostfs_kern.c
fs/internal.h
fs/jbd/checkpoint.c
fs/jbd/commit.c
fs/jbd/journal.c
fs/jbd/revoke.c
fs/jbd2/checkpoint.c
fs/jbd2/commit.c
fs/jbd2/journal.c
fs/jbd2/revoke.c
fs/mbcache.c
fs/namei.c
fs/namespace.c
fs/nfs/Kconfig
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/nfs4proc.c
fs/nfs/super.c
fs/nfsd/Kconfig
fs/nilfs2/super.c
fs/nilfs2/the_nilfs.c
fs/open.c
fs/pnode.c
fs/reiserfs/inode.c
fs/reiserfs/journal.c
fs/super.c
fs/ufs/balloc.c
fs/ufs/ialloc.c
fs/ufs/truncate.c
fs/ufs/util.c
fs/ufs/util.h
include/asm-generic/syscalls.h
include/linux/amba/clcd.h
include/linux/binfmts.h
include/linux/buffer_head.h
include/linux/fs.h
include/linux/fs_struct.h
include/linux/lglock.h [new file with mode: 0644]
include/linux/sched.h
include/linux/spi/spi.h
include/linux/syscalls.h
include/linux/tty.h
include/sound/emu10k1.h
init/do_mounts_initrd.c
init/main.c
kernel/debug/kdb/kdb_private.h
kernel/debug/kdb/kdb_support.c
kernel/exit.c
kernel/fork.c
kernel/kmod.c
mm/shmem.c
net/core/dev.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/route.c
net/netlink/af_netlink.c
net/sched/act_gact.c
net/sched/act_mirred.c
net/sched/act_nat.c
net/sched/act_simple.c
net/sched/act_skbedit.c
net/sunrpc/Kconfig
net/sunrpc/xprtrdma/rpc_rdma.c
net/sunrpc/xprtrdma/verbs.c
net/sunrpc/xprtsock.c
net/xfrm/xfrm_user.c
security/apparmor/lsm.c
security/apparmor/path.c
security/commoncap.c
security/selinux/hooks.c
sound/core/pcm_native.c
sound/pci/emu10k1/emu10k1.c
sound/pci/emu10k1/emupcm.c
sound/pci/emu10k1/memory.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/riptide/riptide.c
sound/soc/codecs/wm8776.c

index f6f80257addb12a3f498c65f6ae6cfe279439df5..1565eefd6fd52a4c225fd19f4036164b62af2cbc 100644 (file)
@@ -1024,6 +1024,10 @@ ThinkPad-specific interface.  The driver will disable its native
 backlight brightness control interface if it detects that the standard
 ACPI interface is available in the ThinkPad.
 
+If you want to use the thinkpad-acpi backlight brightness control
+instead of the generic ACPI video backlight brightness control for some
+reason, you should use the acpi_backlight=vendor kernel parameter.
+
 The brightness_enable module parameter can be used to control whether
 the LCD brightness control feature will be enabled when available.
 brightness_enable=0 forces it to be disabled.  brightness_enable=1
index 568fa08e82e54d03322810eab5bb26ae192f2065..302db5da49b37812eb19bf79ea0e2952e5f3a21f 100644 (file)
@@ -49,40 +49,13 @@ Table of Contents
       f) MDIO on GPIOs
       g) SPI busses
 
-  VII - Marvell Discovery mv64[345]6x System Controller chips
-    1) The /system-controller node
-    2) Child nodes of /system-controller
-      a) Marvell Discovery MDIO bus
-      b) Marvell Discovery ethernet controller
-      c) Marvell Discovery PHY nodes
-      d) Marvell Discovery SDMA nodes
-      e) Marvell Discovery BRG nodes
-      f) Marvell Discovery CUNIT nodes
-      g) Marvell Discovery MPSCROUTING nodes
-      h) Marvell Discovery MPSCINTR nodes
-      i) Marvell Discovery MPSC nodes
-      j) Marvell Discovery Watch Dog Timer nodes
-      k) Marvell Discovery I2C nodes
-      l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes
-      m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes
-      n) Marvell Discovery GPP (General Purpose Pins) nodes
-      o) Marvell Discovery PCI host bridge node
-      p) Marvell Discovery CPU Error nodes
-      q) Marvell Discovery SRAM Controller nodes
-      r) Marvell Discovery PCI Error Handler nodes
-      s) Marvell Discovery Memory Controller nodes
-
-  VIII - Specifying interrupt information for devices
+  VII - Specifying interrupt information for devices
     1) interrupts property
     2) interrupt-parent property
     3) OpenPIC Interrupt Controllers
     4) ISA Interrupt Controllers
 
-  IX - Specifying GPIO information for devices
-    1) gpios property
-    2) gpio-controller nodes
-
-  X - Specifying device power management information (sleep property)
+  VIII - Specifying device power management information (sleep property)
 
   Appendix A - Sample SOC node for MPC8540
 
index 88e608aebc8ccb61351d7be3b83364e4e590fe31..842dba308eab3065510857e50312496c674c1097 100644 (file)
@@ -387,8 +387,9 @@ EXPORT_SYMBOL(dump_elf_task_fp);
  * sys_execve() executes a new program.
  */
 asmlinkage int
-do_sys_execve(const char __user *ufilename, char __user * __user *argv,
-             char __user * __user *envp, struct pt_regs *regs)
+do_sys_execve(const char __user *ufilename,
+             const char __user *const __user *argv,
+             const char __user *const __user *envp, struct pt_regs *regs)
 {
        int error;
        char *filename;
index 99b8200138d203e49df0f0c3c4735a0bfd4255eb..59c1ce858fc8b18d4ec613e6dd2bfe62ed06047e 100644 (file)
@@ -21,6 +21,9 @@ GZFLAGS               :=-9
 # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
 KBUILD_CFLAGS  +=$(call cc-option,-marm,)
 
+# Never generate .eh_frame
+KBUILD_CFLAGS  += $(call cc-option,-fno-dwarf2-cfi-asm)
+
 # Do not use arch/arm/defconfig - it's always outdated.
 # Select a platform tht is kept up-to-date
 KBUILD_DEFCONFIG := versatile_defconfig
index c974be8913a76dda0a25e8c8f5ad1e7f3a03610d..7ce15eb15f72992289c899b5fa05385300aa0c8e 100644 (file)
@@ -158,15 +158,24 @@ struct pt_regs {
  */
 static inline int valid_user_regs(struct pt_regs *regs)
 {
-       if (user_mode(regs) && (regs->ARM_cpsr & PSR_I_BIT) == 0) {
-               regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT);
-               return 1;
+       unsigned long mode = regs->ARM_cpsr & MODE_MASK;
+
+       /*
+        * Always clear the F (FIQ) and A (delayed abort) bits
+        */
+       regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT);
+
+       if ((regs->ARM_cpsr & PSR_I_BIT) == 0) {
+               if (mode == USR_MODE)
+                       return 1;
+               if (elf_hwcap & HWCAP_26BIT && mode == USR26_MODE)
+                       return 1;
        }
 
        /*
         * Force CPSR to something logical...
         */
-       regs->ARM_cpsr &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | PSR_T_BIT | MODE32_BIT;
+       regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT;
        if (!(elf_hwcap & HWCAP_26BIT))
                regs->ARM_cpsr |= USR_MODE;
 
index dd2bf53000fe4cc06038e87f86587c6bc5e6c0f3..d02cfb683487eeafea4ef407a1a4e6f2d4ce4112 100644 (file)
 #define __NR_rt_tgsigqueueinfo         (__NR_SYSCALL_BASE+363)
 #define __NR_perf_event_open           (__NR_SYSCALL_BASE+364)
 #define __NR_recvmmsg                  (__NR_SYSCALL_BASE+365)
+#define __NR_accept4                   (__NR_SYSCALL_BASE+366)
 
 /*
  * The following SWIs are ARM private.
index 37ae301cc47c81ccf8bb80d02e4d7aaed67622e9..afeb71fa72cb81fc0e2fb5652c653ef34e7258bb 100644 (file)
                CALL(sys_rt_tgsigqueueinfo)
                CALL(sys_perf_event_open)
 /* 365 */      CALL(sys_recvmmsg)
+               CALL(sys_accept4)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
index 778c2f7024ff57304227ce67665e749f39b05fc7..d6e8b4d2e60dacde3ceff47584fe43b75ddb496d 100644 (file)
@@ -79,7 +79,7 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
                return;
 
        /* Initialize to zero */
-       for (regno = 0; regno < GDB_MAX_REGS; regno++)
+       for (regno = 0; regno < DBG_MAX_REG_NUM; regno++)
                gdb_regs[regno] = 0;
 
        /* Otherwise, we have only some registers from switch_to() */
index 5b7c541a4c63d0dc6ae9405f70470f1f4c2108c4..62e7c61d0342754193cf4833b16b57723b081f73 100644 (file)
@@ -62,8 +62,9 @@ asmlinkage int sys_vfork(struct pt_regs *regs)
 /* sys_execve() executes a new program.
  * This is called indirectly via a small wrapper
  */
-asmlinkage int sys_execve(const char __user *filenamei, char __user * __user *argv,
-                         char __user * __user *envp, struct pt_regs *regs)
+asmlinkage int sys_execve(const char __user *filenamei,
+                         const char __user *const __user *argv,
+                         const char __user *const __user *envp, struct pt_regs *regs)
 {
        int error;
        char * filename;
@@ -78,14 +79,17 @@ out:
        return error;
 }
 
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        struct pt_regs regs;
        int ret;
 
        memset(&regs, 0, sizeof(struct pt_regs));
-       ret = do_execve(filename, (char __user * __user *)argv,
-                       (char __user * __user *)envp, &regs);
+       ret = do_execve(filename,
+                       (const char __user *const __user *)argv,
+                       (const char __user *const __user *)envp, &regs);
        if (ret < 0)
                goto out;
 
index e5daddff397dd166e9ba16b089f2cdc2daf022fb..9c46aaad11ce67334385f2b70a99ef3700cd8c0f 100644 (file)
@@ -384,8 +384,9 @@ asmlinkage int sys_vfork(struct pt_regs *regs)
 }
 
 asmlinkage int sys_execve(const char __user *ufilename,
-                         char __user *__user *uargv,
-                         char __user *__user *uenvp, struct pt_regs *regs)
+                         const char __user *const __user *uargv,
+                         const char __user *const __user *uenvp,
+                         struct pt_regs *regs)
 {
        int error;
        char *filename;
index 459349b5ed5aa9d74982f2079edeb205ecdbef90..62635a09ae3eca1f37ae17b54ffe705b9086cb2f 100644 (file)
@@ -7,7 +7,9 @@
  */
 #include <linux/unistd.h>
 
-int kernel_execve(const char *file, char **argv, char **envp)
+int kernel_execve(const char *file,
+                 const char *const *argv,
+                 const char *const *envp)
 {
        register long scno asm("r8") = __NR_execve;
        register long sc1 asm("r12") = (long)file;
index a566f61c002aecaec8caa8f8ccca6a2f318ca7fa..01f98cb964d2654e4d7c235e6db4d647f893696b 100644 (file)
@@ -209,7 +209,9 @@ copy_thread(unsigned long clone_flags,
 /*
  * sys_execve() executes a new program.
  */
-asmlinkage int sys_execve(const char __user *name, char __user * __user *argv, char __user * __user *envp)
+asmlinkage int sys_execve(const char __user *name,
+                         const char __user *const __user *argv,
+                         const char __user *const __user *envp)
 {
        int error;
        char *filename;
index 93f0f64b132649d9446a5580d6b1ab740df255e3..9a57db6907f5bb81762c6cc97b543284b289e703 100644 (file)
@@ -204,7 +204,9 @@ asmlinkage int sys_vfork(long r10, long r11, long r12, long r13, long mof, long
 /*
  * sys_execve() executes a new program.
  */
-asmlinkage int sys_execve(const char *fname, char **argv, char **envp,
+asmlinkage int sys_execve(const char *fname,
+                         const char *const *argv,
+                         const char *const *envp,
                          long r13, long mof, long srp, 
                          struct pt_regs *regs)
 {
index 2661a9529d701a85d0d41358627912e192a10539..562f84718906b2de88416b1ca48e685992d0b400 100644 (file)
@@ -218,8 +218,10 @@ sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp,
 
 /* sys_execve() executes a new program. */
 asmlinkage int
-sys_execve(const char *fname, char **argv, char **envp, long r13, long mof, long srp,
-       struct pt_regs *regs)
+sys_execve(const char *fname,
+          const char *const *argv,
+          const char *const *envp, long r13, long mof, long srp,
+          struct pt_regs *regs)
 {
        int error;
        char *filename;
index 428931cf2f0c44adc9d6092bff72cca6c596c54a..2b63b0191f529d187f0cde1298c637e32973fabb 100644 (file)
@@ -250,8 +250,9 @@ int copy_thread(unsigned long clone_flags,
 /*
  * sys_execve() executes a new program.
  */
-asmlinkage int sys_execve(const char __user *name, char __user * __user *argv,
-                         char __user * __user *envp)
+asmlinkage int sys_execve(const char __user *name,
+                         const char __user *const __user *argv,
+                         const char __user *const __user *envp)
 {
        int error;
        char * filename;
index 8b7b78d77d5c46ba3b9d31bf1933cf504c7f377a..97478138e361ad702308539b4d067543402df7cb 100644 (file)
@@ -212,7 +212,10 @@ int copy_thread(unsigned long clone_flags,
 /*
  * sys_execve() executes a new program.
  */
-asmlinkage int sys_execve(const char *name, char **argv, char **envp,int dummy,...)
+asmlinkage int sys_execve(const char *name,
+                         const char *const *argv,
+                         const char *const *envp,
+                         int dummy, ...)
 {
        int error;
        char * filename;
index f9b3f44da69fe655dc7f2f1c0b82c4ac0b55990d..dc1ac0243b78d0532640c55517753cdbdeacc8f0 100644 (file)
@@ -51,7 +51,9 @@ asmlinkage void syscall_print(void *dummy,...)
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
  */
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        register long res __asm__("er0");
        register char *const *_c __asm__("er3") = envp;
index 87f1bd1efc82b7c46eb7a1e35c7e337c83625411..954d398a54b4e7f60de2aaeabef172a0774fd93f 100644 (file)
@@ -356,8 +356,6 @@ asmlinkage unsigned long sys_mmap2(
                                int fd, long pgoff);
 struct pt_regs;
 struct sigaction;
-long sys_execve(const char __user *filename, char __user * __user *argv,
-                          char __user * __user *envp, struct pt_regs *regs);
 asmlinkage long sys_ia64_pipe(void);
 asmlinkage long sys_rt_sigaction(int sig,
                                 const struct sigaction __user *act,
index a879c03b7f1cc0f97309c2cfff3ccb8b8a118385..16f1c7b04c69330c0c8a73cdd2e127f87122a627 100644 (file)
@@ -633,7 +633,9 @@ dump_fpu (struct pt_regs *pt, elf_fpregset_t dst)
 }
 
 long
-sys_execve (const char __user *filename, char __user * __user *argv, char __user * __user *envp,
+sys_execve (const char __user *filename,
+           const char __user *const __user *argv,
+           const char __user *const __user *envp,
            struct pt_regs *regs)
 {
        char *fname;
index 8665a4d868ecb6f48506c6c354b9813be3f92b69..422bea9f1dbcbcab749fe0d6a7317d366de45ba1 100644 (file)
@@ -289,8 +289,8 @@ asmlinkage int sys_vfork(unsigned long r0, unsigned long r1, unsigned long r2,
  * sys_execve() executes a new program.
  */
 asmlinkage int sys_execve(const char __user *ufilename,
-                         char __user * __user *uargv,
-                         char __user * __user *uenvp,
+                         const char __user *const __user *uargv,
+                         const char __user *const __user *uenvp,
                          unsigned long r3, unsigned long r4, unsigned long r5,
                          unsigned long r6, struct pt_regs regs)
 {
index 0a00f467edfa9645f49ea0d7b614c905921dcc44..d841fb6cc70325a23c25e71f3552b14751284b56 100644 (file)
@@ -93,7 +93,9 @@ asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
  */
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        register long __scno __asm__ ("r7") = __NR_execve;
        register long __arg3 __asm__ ("r2") = (long)(envp);
index 3958726664bad268c0e185a462f6859bfe3e67f5..492fee8a1ab2e6491f52c961b1a93017eef49a41 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  linux/include/asm-m68k/ide.h
- *
  *  Copyright (C) 1994-1996  Linus Torvalds & authors
  */
 
@@ -34,6 +32,8 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
+#ifdef CONFIG_MMU
+
 /*
  * Get rid of defs from io.h - ide has its private and conflicting versions
  * Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we
 #define __ide_mm_outsw(port, addr, n)  raw_outsw((u16 *)port, addr, n)
 #define __ide_mm_outsl(port, addr, n)  raw_outsl((u32 *)port, addr, n)
 
+#else
+
+#define __ide_mm_insw(port, addr, n)   io_insw((unsigned int)port, addr, n)
+#define __ide_mm_insl(port, addr, n)   io_insl((unsigned int)port, addr, n)
+#define __ide_mm_outsw(port, addr, n)  io_outsw((unsigned int)port, addr, n)
+#define __ide_mm_outsl(port, addr, n)  io_outsl((unsigned int)port, addr, n)
+
+#endif /* CONFIG_MMU */
+
 #endif /* __KERNEL__ */
 #endif /* _M68K_IDE_H */
index 221d0b71ce3934948a7e4c3581975bfe5b37c4d4..18732ab232923faeedbbcd80c02a98364f285215 100644 (file)
@@ -315,7 +315,9 @@ EXPORT_SYMBOL(dump_fpu);
 /*
  * sys_execve() executes a new program.
  */
-asmlinkage int sys_execve(const char __user *name, char __user * __user *argv, char __user * __user *envp)
+asmlinkage int sys_execve(const char __user *name,
+                         const char __user *const __user *argv,
+                         const char __user *const __user *envp)
 {
        int error;
        char * filename;
index 77896692eb0a69f34609cb4809e221fc84fb4bd3..2f431ece7b5f5c7f2afe8782eb7fe9b98cc26d6c 100644 (file)
@@ -459,7 +459,9 @@ asmlinkage int sys_getpagesize(void)
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
  */
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        register long __res asm ("%d0") = __NR_execve;
        register long __a asm ("%d1") = (long)(filename);
index 6350f68cd0262ba7f78c2a60f3fb76e574b2d857..6d3390590e5ba24be497b5c4a42d0327dbae6cf9 100644 (file)
@@ -316,14 +316,14 @@ void dump(struct pt_regs *fp)
                fp->d0, fp->d1, fp->d2, fp->d3);
        printk(KERN_EMERG "d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
                fp->d4, fp->d5, fp->a0, fp->a1);
-       printk(KERN_EMERG "\nUSP: %08x   TRAPFRAME: %08x\n",
-               (unsigned int) rdusp(), (unsigned int) fp);
+       printk(KERN_EMERG "\nUSP: %08x   TRAPFRAME: %p\n",
+               (unsigned int) rdusp(), fp);
 
        printk(KERN_EMERG "\nCODE:");
        tp = ((unsigned char *) fp->pc) - 0x20;
        for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
                if ((i % 0x10) == 0)
-                       printk(KERN_EMERG "%08x: ", (int) (tp + i));
+                       printk(KERN_EMERG "%p: ", tp + i);
                printk("%08x ", (int) *sp++);
        }
        printk(KERN_EMERG "\n");
@@ -332,7 +332,7 @@ void dump(struct pt_regs *fp)
        tp = ((unsigned char *) fp) - 0x40;
        for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
                if ((i % 0x10) == 0)
-                       printk(KERN_EMERG "%08x: ", (int) (tp + i));
+                       printk(KERN_EMERG "%p: ", tp + i);
                printk("%08x ", (int) *sp++);
        }
        printk(KERN_EMERG "\n");
@@ -341,7 +341,7 @@ void dump(struct pt_regs *fp)
        tp = (unsigned char *) (rdusp() - 0x10);
        for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
                if ((i % 0x10) == 0)
-                       printk(KERN_EMERG "%08x: ", (int) (tp + i));
+                       printk(KERN_EMERG "%p: ", tp + i);
                printk("%08x ", (int) *sp++);
        }
        printk(KERN_EMERG "\n");
@@ -350,7 +350,9 @@ void dump(struct pt_regs *fp)
 /*
  * sys_execve() executes a new program.
  */
-asmlinkage int sys_execve(const char *name, char **argv, char **envp)
+asmlinkage int sys_execve(const char *name,
+                         const char *const *argv,
+                         const char *const *envp)
 {
        int error;
        char * filename;
index d65e9c4c930cdf59821ffc5f61031a9d4a05b51c..68488ae47f0a4ba97f389e68d75c91a1402d123b 100644 (file)
@@ -44,7 +44,9 @@ asmlinkage int sys_getpagesize(void)
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
  */
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        register long __res asm ("%d0") = __NR_execve;
        register long __a asm ("%d1") = (long)(filename);
index d33ba17601fa20d61c86c3ea982aab72ca6508e1..99d9b61cccb592cb34985bf79fb777b0521a36bf 100644 (file)
@@ -73,7 +73,7 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
                /* We can only get here if we hit a P2P bridge with no node,
                 * let's do standard swizzling and try again
                 */
-               lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
+               lspec = pci_swizzle_interrupt_pin(pdev, lspec);
                pdev = ppdev;
        }
 
index 6abab6ebedbee2514d23ebe0cdfeeeec4fe3ad39..2250fe9d269b7e150333186b1948d059c4a1c85a 100644 (file)
@@ -47,8 +47,10 @@ asmlinkage long microblaze_clone(int flags, unsigned long stack, struct pt_regs
        return do_fork(flags, stack, regs, 0, NULL, NULL);
 }
 
-asmlinkage long microblaze_execve(const char __user *filenamei, char __user *__user *argv,
-                       char __user *__user *envp, struct pt_regs *regs)
+asmlinkage long microblaze_execve(const char __user *filenamei,
+                                 const char __user *const __user *argv,
+                                 const char __user *const __user *envp,
+                                 struct pt_regs *regs)
 {
        int error;
        char *filename;
@@ -77,7 +79,9 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
  */
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        register const char *__a __asm__("r5") = filename;
        register const void *__b __asm__("r6") = argv;
index 23be25fec4d67bf7e48d612b50e1da9f766371ae..55ef532f32be6fc3c174e1280a7971ffc5329406 100644 (file)
 #include <linux/irq.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
-#include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <asm/byteorder.h>
 
@@ -1077,7 +1078,7 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
                struct dev_archdata *sd = &dev->dev.archdata;
 
                /* Setup OF node pointer in archdata */
-               sd->of_node = pci_device_to_OF_node(dev);
+               dev->dev.of_node = pci_device_to_OF_node(dev);
 
                /* Fixup NUMA node as it may not be setup yet by the generic
                 * code and is needed by the DMA init
index 7869a41b0f94cadff95ad17dc4eaf5a713b536c3..0687a42a5bd475166afed6e816c721a51517b4c9 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/ioport.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/pci.h>
 #include <asm/io.h>
 
index bddce0bca1950ea599fcc8c7d954841250f85e0f..1dc6edff45e08a604377862ec3d8980c6b333cf0 100644 (file)
@@ -258,8 +258,10 @@ asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs)
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = do_execve(filename, (char __user *__user *) (long)regs.regs[5],
-                         (char __user *__user *) (long)regs.regs[6], &regs);
+       error = do_execve(filename,
+                         (const char __user *const __user *) (long)regs.regs[5],
+                         (const char __user *const __user *) (long)regs.regs[6],
+                         &regs);
        putname(filename);
 
 out:
@@ -436,7 +438,9 @@ asmlinkage void bad_stack(void)
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
  */
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        register unsigned long __a0 asm("$4") = (unsigned long) filename;
        register unsigned long __a1 asm("$5") = (unsigned long) argv;
index 762eb325b949a9869dac416318ef277ced79ece0..f48373e2bc1cffab139be817cf6f540776c51b79 100644 (file)
@@ -269,8 +269,8 @@ asmlinkage long sys_vfork(void)
 }
 
 asmlinkage long sys_execve(const char __user *name,
-                          char __user * __user *argv,
-                          char __user * __user *envp)
+                          const char __user *const __user *argv,
+                          const char __user *const __user *envp)
 {
        char *filename;
        int error;
index 1444875a761165334ff1f9916bc7c5c31dd6eb19..0dc8543acb4fc31e9e13c3ba0c124096b6471648 100644 (file)
@@ -41,8 +41,10 @@ int hpux_execve(struct pt_regs *regs)
        if (IS_ERR(filename))
                goto out;
 
-       error = do_execve(filename, (char __user * __user *) regs->gr[25],
-               (char __user * __user *) regs->gr[24], regs);
+       error = do_execve(filename,
+                         (const char __user *const __user *) regs->gr[25],
+                         (const char __user *const __user *) regs->gr[24],
+                         regs);
 
        putname(filename);
 
index 76332dadc6e93e64e6b0557dc0e5c0bd2e0b0986..4b4b9181a1a0aef8df25667f4a0229bb275e8d7f 100644 (file)
@@ -348,17 +348,22 @@ asmlinkage int sys_execve(struct pt_regs *regs)
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = do_execve(filename, (char __user * __user *) regs->gr[25],
-               (char __user * __user *) regs->gr[24], regs);
+       error = do_execve(filename,
+                         (const char __user *const __user *) regs->gr[25],
+                         (const char __user *const __user *) regs->gr[24],
+                         regs);
        putname(filename);
 out:
 
        return error;
 }
 
-extern int __execve(const char *filename, char *const argv[],
-               char *const envp[], struct task_struct *task);
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+extern int __execve(const char *filename,
+                   const char *const argv[],
+                   const char *const envp[], struct task_struct *task);
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        return __execve(filename, argv, envp, current);
 }
index feacfb7896863240eb5d447ea6c48b772c6906a9..91356ffda2ca3230e930245a0db1cc58cca323a0 100644 (file)
@@ -1034,8 +1034,9 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
        flush_fp_to_thread(current);
        flush_altivec_to_thread(current);
        flush_spe_to_thread(current);
-       error = do_execve(filename, (char __user * __user *) a1,
-                         (char __user * __user *) a2, regs);
+       error = do_execve(filename,
+                         (const char __user *const __user *) a1,
+                         (const char __user *const __user *) a2, regs);
        putname(filename);
 out:
        return error;
index 7eafaf2662b92fca4aff3f36ea980148695cb24a..d3a2d1c6438ee08c1216353c8fefec7f2ee0dc31 100644 (file)
@@ -267,8 +267,9 @@ asmlinkage void execve_tail(void)
 /*
  * sys_execve() executes a new program.
  */
-SYSCALL_DEFINE3(execve, const char __user *, name, char __user * __user *, argv,
-               char __user * __user *, envp)
+SYSCALL_DEFINE3(execve, const char __user *, name,
+               const char __user *const __user *, argv,
+               const char __user *const __user *, envp)
 {
        struct pt_regs *regs = task_pt_regs(current);
        char *filename;
index 651096ff8db49e2c9c4b564c00a0a12510a8b050..e478bf9a7e9181cd2e929535aaf0c3680e71a17b 100644 (file)
@@ -99,8 +99,10 @@ score_execve(struct pt_regs *regs)
        if (IS_ERR(filename))
                return error;
 
-       error = do_execve(filename, (char __user *__user*)regs->regs[5],
-                         (char __user *__user *) regs->regs[6], regs);
+       error = do_execve(filename,
+                         (const char __user *const __user *)regs->regs[5],
+                         (const char __user *const __user *)regs->regs[6],
+                         regs);
 
        putname(filename);
        return error;
@@ -110,7 +112,9 @@ score_execve(struct pt_regs *regs)
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
  */
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        register unsigned long __r4 asm("r4") = (unsigned long) filename;
        register unsigned long __r5 asm("r5") = (unsigned long) argv;
index 052981972ae68ecd299a00bf8ca1196de6605507..762a13984bbd76c897963c10f6513809d0cc345f 100644 (file)
@@ -296,9 +296,10 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
 /*
  * sys_execve() executes a new program.
  */
-asmlinkage int sys_execve(char __user *ufilename, char __user * __user *uargv,
-                         char __user * __user *uenvp, unsigned long r7,
-                         struct pt_regs __regs)
+asmlinkage int sys_execve(const char __user *ufilename,
+                         const char __user *const __user *uargv,
+                         const char __user *const __user *uenvp,
+                         unsigned long r7, struct pt_regs __regs)
 {
        struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        int error;
index 68d128d651b32cb7df96249260d73e6e49012c42..210c1cabcb7fd3fe0903442c40c56d37a34b2ccc 100644 (file)
@@ -497,8 +497,8 @@ asmlinkage int sys_execve(const char *ufilename, char **uargv,
                goto out;
 
        error = do_execve(filename,
-                         (char __user * __user *)uargv,
-                         (char __user * __user *)uenvp,
+                         (const char __user *const __user *)uargv,
+                         (const char __user *const __user *)uenvp,
                          pregs);
        putname(filename);
 out:
index eb68bfdd86e66be57464425896b887abd63c3af4..f56b6fe5c5d02d7cdb5084bce5732cba7c32ec68 100644 (file)
@@ -71,7 +71,9 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1,
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
  */
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        register long __sc0 __asm__ ("r3") = __NR_execve;
        register long __sc4 __asm__ ("r4") = (long) filename;
index 287235768bc5028bb0da239e5b5b46a10d891f8b..c5a38c4bf410f5375be87cc7416a003709c10a3b 100644 (file)
@@ -33,7 +33,9 @@
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
  */
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve);
        register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename;
index 2050ca02c4230cff6c447ee3d84c5f3e058cb24b..f0c74227c737e0a94efb33c95640375ad38c89bc 100644 (file)
@@ -25,9 +25,9 @@ extern void atomic_sub(int, atomic_t *);
 extern void atomic64_sub(int, atomic64_t *);
 
 extern int atomic_add_ret(int, atomic_t *);
-extern int atomic64_add_ret(int, atomic64_t *);
+extern long atomic64_add_ret(int, atomic64_t *);
 extern int atomic_sub_ret(int, atomic_t *);
-extern int atomic64_sub_ret(int, atomic64_t *);
+extern long atomic64_sub_ret(int, atomic64_t *);
 
 #define atomic_dec_return(v) atomic_sub_ret(1, v)
 #define atomic64_dec_return(v) atomic64_sub_ret(1, v)
@@ -91,7 +91,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
        ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
 #define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
 
-static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
+static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
 {
        long c, old;
        c = atomic64_read(v);
index e834880be2040944783d7b0e31be1158ed788d4c..2173432ad7f72ec8326f55048b440cbba7c68048 100644 (file)
@@ -1,5 +1,6 @@
 #ifndef _SPARC_FB_H_
 #define _SPARC_FB_H_
+#include <linux/console.h>
 #include <linux/fb.h>
 #include <linux/fs.h>
 #include <asm/page.h>
@@ -18,6 +19,9 @@ static inline int fb_is_primary_device(struct fb_info *info)
        struct device *dev = info->device;
        struct device_node *node;
 
+       if (console_set_on_cmdline)
+               return 0;
+
        node = dev->of_node;
        if (node &&
            node == of_console_device)
index a303c9d64d845989e313a326f4c5e92f283148a5..e4c61a18bb2843855c493bb86c45d7787e862a38 100644 (file)
@@ -5,7 +5,7 @@
 #define RWSEM_UNLOCKED_VALUE           0x00000000
 #define RWSEM_ACTIVE_BIAS              0x00000001
 #define RWSEM_ACTIVE_MASK              0x0000ffff
-#define RWSEM_WAITING_BIAS             0xffff0000
+#define RWSEM_WAITING_BIAS             (-0x00010000)
 #define RWSEM_ACTIVE_READ_BIAS         RWSEM_ACTIVE_BIAS
 #define RWSEM_ACTIVE_WRITE_BIAS                (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
 
index d0b3b01ac9d4316962ed744c71fa805e94d4d204..03eb5a8f6f9363ccc55410e011328f843aa05474 100644 (file)
 #define __NR_rt_tgsigqueueinfo 326
 #define __NR_perf_event_open   327
 #define __NR_recvmmsg          328
+#define __NR_fanotify_init     329
+#define __NR_fanotify_mark     330
+#define __NR_prlimit64         331
 
-#define NR_syscalls            329
+#define NR_syscalls            332
 
 #ifdef __32bit_syscall_numbers__
 /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
index 40e29fc8a4d62bff77080a791ebf0a8a280efaae..17529298c50a2e283ede3342830747fe54641384 100644 (file)
@@ -633,8 +633,10 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
        if(IS_ERR(filename))
                goto out;
        error = do_execve(filename,
-                         (char __user * __user *)regs->u_regs[base + UREG_I1],
-                         (char __user * __user *)regs->u_regs[base + UREG_I2],
+                         (const char __user *const  __user *)
+                         regs->u_regs[base + UREG_I1],
+                         (const char __user *const  __user *)
+                         regs->u_regs[base + UREG_I2],
                          regs);
        putname(filename);
 out:
index dbe81a368b4588001bb4cb56b20283a08cfcc264..485f547483847da14aebfaa0e327c6cbb75dce24 100644 (file)
@@ -739,9 +739,9 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
        if (IS_ERR(filename))
                goto out;
        error = do_execve(filename,
-                         (char __user * __user *)
+                         (const char __user *const __user *)
                          regs->u_regs[base + UREG_I1],
-                         (char __user * __user *)
+                         (const char __user *const __user *)
                          regs->u_regs[base + UREG_I2], regs);
        putname(filename);
        if (!error) {
index 46a76ba3fb4bd21d2b911b9ce99cf5f235264b68..44e5faf1ad5f47dbee83ff3b00e77f479d907d0d 100644 (file)
@@ -330,6 +330,15 @@ do_sys_accept4: /* sys_accept4(int, struct sockaddr *, int *, int) */
        nop
        nop
 
+       .globl          sys32_fanotify_mark
+sys32_fanotify_mark:
+       sethi           %hi(sys_fanotify_mark), %g1
+       sllx            %o2, 32, %o2
+       or              %o2, %o3, %o2
+       mov             %o4, %o3
+       jmpl            %g1 + %lo(sys_fanotify_mark), %g0
+        mov            %o5, %o4
+
        .section        __ex_table,"a"
        .align          4
        .word           1b, __retl_efault, 2b, __retl_efault
index ee995b7dae7e8d3f4509ed378761ac131266515a..50794137d710d71bfa197cbb055d14377f2cd770 100644 (file)
@@ -282,7 +282,9 @@ out:
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
  */
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        long __res;
        register long __g1 __asm__ ("g1") = __NR_execve;
index 3d435c42e6db58d62df3c5193a081816d6c7639a..f836f4e93afe08b66f37955084896abeb82a8a0a 100644 (file)
@@ -758,7 +758,9 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
  */
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        long __res;
        register long __g1 __asm__ ("g1") = __NR_execve;
index 801fc8e5a0e87cf20fc58550b4f603a6e4085723..ec396e1916b92e4560505175bcdee3b59b3fef49 100644 (file)
@@ -82,5 +82,6 @@ sys_call_table:
 /*310*/        .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
 /*315*/        .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
 /*320*/        .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
-/*325*/        .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg
+/*325*/        .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
+/*330*/        .long sys_fanotify_mark, sys_prlimit64
 
index 9db058dd039e5d0361e1276523e6a59f4cef8452..8cfcaa54958054535dcd376296c1f71f780cc147 100644 (file)
@@ -83,7 +83,8 @@ sys_call_table32:
 /*310*/        .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate
        .word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1
 /*320*/        .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv
-       .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg
+       .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init
+/*330*/        .word sys32_fanotify_mark, sys_prlimit64
 
 #endif /* CONFIG_COMPAT */
 
@@ -158,4 +159,5 @@ sys_call_table:
 /*310*/        .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
        .word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
 /*320*/        .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
-       .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg
+       .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
+/*330*/        .word sys_fanotify_mark, sys_prlimit64
index ed590ad0acdc614b65b8312835a2f573a1535ba8..985cc28c74c5696f91adcf82d6347439999bfa41 100644 (file)
@@ -543,8 +543,9 @@ long _sys_vfork(struct pt_regs *regs)
 /*
  * sys_execve() executes a new program.
  */
-long _sys_execve(char __user *path, char __user *__user *argv,
-                char __user *__user *envp, struct pt_regs *regs)
+long _sys_execve(const char __user *path,
+                const char __user *const __user *argv,
+                const char __user *const __user *envp, struct pt_regs *regs)
 {
        long error;
        char *filename;
index 59b20d93b6d43b80047bc4012089e2b8d31c1708..cd145eda357950b66b1ad2f05f55bd0094df6006 100644 (file)
@@ -44,8 +44,9 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
        PT_REGS_SP(regs) = esp;
 }
 
-static long execve1(const char *file, char __user * __user *argv,
-                   char __user *__user *env)
+static long execve1(const char *file,
+                   const char __user *const __user *argv,
+                   const char __user *const __user *env)
 {
        long error;
 
index 7427c0b1930cbb18879ccfb047b90391bb322e39..5ddb246626dbb87afe7484b87c0c495c8643de8f 100644 (file)
@@ -51,7 +51,9 @@ long old_mmap(unsigned long addr, unsigned long len,
        return err;
 }
 
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        mm_segment_t fs;
        int ret;
index feb2ff9bfc2d178855b19fb8cf4a26e506e3317a..f1d8b441fc775b4920b7397d6a151d2eed314a09 100644 (file)
@@ -23,8 +23,9 @@ long sys_iopl(unsigned int, struct pt_regs *);
 /* kernel/process.c */
 int sys_fork(struct pt_regs *);
 int sys_vfork(struct pt_regs *);
-long sys_execve(const char __user *, char __user * __user *,
-               char __user * __user *, struct pt_regs *);
+long sys_execve(const char __user *,
+               const char __user *const __user *,
+               const char __user *const __user *, struct pt_regs *);
 long sys_clone(unsigned long, unsigned long, void __user *,
               void __user *, struct pt_regs *);
 
index ef10940e1af0534e18c88635d79e25eff73797cf..852b81967a3774b3e252c8affed666423a5b784b 100644 (file)
@@ -194,7 +194,7 @@ static struct hw_breakpoint {
        unsigned long           addr;
        int                     len;
        int                     type;
-       struct perf_event       **pev;
+       struct perf_event       * __percpu *pev;
 } breakinfo[HBP_NUM];
 
 static unsigned long early_dr7;
index 64ecaf0af9af4a88132994049570250809a585ea..57d1868a86aadc060bc2260b34139809a98ffab5 100644 (file)
@@ -301,8 +301,9 @@ EXPORT_SYMBOL(kernel_thread);
 /*
  * sys_execve() executes a new program.
  */
-long sys_execve(const char __user *name, char __user * __user *argv,
-               char __user * __user *envp, struct pt_regs *regs)
+long sys_execve(const char __user *name,
+               const char __user *const __user *argv,
+               const char __user *const __user *envp, struct pt_regs *regs)
 {
        long error;
        char *filename;
index 196552bb412c76a129cc8f63ad6e836b91dd51ee..d5e06624e34a556552585690b4532509fe21552f 100644 (file)
@@ -28,7 +28,9 @@
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
  */
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
 {
        long __res;
        asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx"
index 7c2f38f68ebb5196e67f6a896a5a09ebce343179..e3558b9a58bab8f9d114e3cdab44d7fe3bf1ea4f 100644 (file)
@@ -318,8 +318,9 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp,
  */
 
 asmlinkage
-long xtensa_execve(const char __user *name, char __user * __user *argv,
-                   char __user * __user *envp,
+long xtensa_execve(const char __user *name,
+                  const char __user *const __user *argv,
+                   const char __user *const __user *envp,
                    long a3, long a4, long a5,
                    struct pt_regs *regs)
 {
index ea24c1e51be221e167ebc7fc7c2bd2658aff8e58..2673a3d1480654ceec39f2ab144b15cde72ba72e 100644 (file)
@@ -1588,7 +1588,7 @@ static const struct ata_port_info sata_dwc_port_info[] = {
        },
 };
 
-static int sata_dwc_probe(struct of_device *ofdev,
+static int sata_dwc_probe(struct platform_device *ofdev,
                        const struct of_device_id *match)
 {
        struct sata_dwc_device *hsdev;
@@ -1702,7 +1702,7 @@ error_out:
        return err;
 }
 
-static int sata_dwc_remove(struct of_device *ofdev)
+static int sata_dwc_remove(struct platform_device *ofdev)
 {
        struct device *dev = &ofdev->dev;
        struct ata_host *host = dev_get_drvdata(dev);
index 2982b3ee9465d1521a6296186c52be9c3a8dc462..057413bb16e294d20d476d49ea4770b56a8e986c 100644 (file)
@@ -94,6 +94,7 @@
 #include <linux/hdreg.h>
 #include <linux/platform_device.h>
 #if defined(CONFIG_OF)
+#include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
 #endif
index ad46eae1f9bb207847fd8ac2bf80b58d4f3922d8..c350d01716bdace6ef510809e964a57c7129134b 100644 (file)
@@ -675,8 +675,8 @@ static int ptmx_open(struct inode *inode, struct file *filp)
        }
 
        set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
-       filp->private_data = tty;
-       file_move(filp, &tty->tty_files);
+
+       tty_add_file(tty, filp);
 
        retval = devpts_pty_new(inode, tty->link);
        if (retval)
index 0350c42375a217c0337cdce4855fb9ad54a9455c..949067a0bd4743151515382b07ccf7aecad11316 100644 (file)
@@ -136,6 +136,9 @@ LIST_HEAD(tty_drivers);                     /* linked list of tty drivers */
 DEFINE_MUTEX(tty_mutex);
 EXPORT_SYMBOL(tty_mutex);
 
+/* Spinlock to protect the tty->tty_files list */
+DEFINE_SPINLOCK(tty_files_lock);
+
 static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
 static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
 ssize_t redirected_tty_write(struct file *, const char __user *,
@@ -185,6 +188,41 @@ void free_tty_struct(struct tty_struct *tty)
        kfree(tty);
 }
 
+static inline struct tty_struct *file_tty(struct file *file)
+{
+       return ((struct tty_file_private *)file->private_data)->tty;
+}
+
+/* Associate a new file with the tty structure */
+void tty_add_file(struct tty_struct *tty, struct file *file)
+{
+       struct tty_file_private *priv;
+
+       /* XXX: must implement proper error handling in callers */
+       priv = kmalloc(sizeof(*priv), GFP_KERNEL|__GFP_NOFAIL);
+
+       priv->tty = tty;
+       priv->file = file;
+       file->private_data = priv;
+
+       spin_lock(&tty_files_lock);
+       list_add(&priv->list, &tty->tty_files);
+       spin_unlock(&tty_files_lock);
+}
+
+/* Delete file from its tty */
+void tty_del_file(struct file *file)
+{
+       struct tty_file_private *priv = file->private_data;
+
+       spin_lock(&tty_files_lock);
+       list_del(&priv->list);
+       spin_unlock(&tty_files_lock);
+       file->private_data = NULL;
+       kfree(priv);
+}
+
+
 #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base)
 
 /**
@@ -235,11 +273,11 @@ static int check_tty_count(struct tty_struct *tty, const char *routine)
        struct list_head *p;
        int count = 0;
 
-       file_list_lock();
+       spin_lock(&tty_files_lock);
        list_for_each(p, &tty->tty_files) {
                count++;
        }
-       file_list_unlock();
+       spin_unlock(&tty_files_lock);
        if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
            tty->driver->subtype == PTY_TYPE_SLAVE &&
            tty->link && tty->link->count)
@@ -497,6 +535,7 @@ void __tty_hangup(struct tty_struct *tty)
        struct file *cons_filp = NULL;
        struct file *filp, *f = NULL;
        struct task_struct *p;
+       struct tty_file_private *priv;
        int    closecount = 0, n;
        unsigned long flags;
        int refs = 0;
@@ -506,7 +545,7 @@ void __tty_hangup(struct tty_struct *tty)
 
 
        spin_lock(&redirect_lock);
-       if (redirect && redirect->private_data == tty) {
+       if (redirect && file_tty(redirect) == tty) {
                f = redirect;
                redirect = NULL;
        }
@@ -519,9 +558,10 @@ void __tty_hangup(struct tty_struct *tty)
           workqueue with the lock held */
        check_tty_count(tty, "tty_hangup");
 
-       file_list_lock();
+       spin_lock(&tty_files_lock);
        /* This breaks for file handles being sent over AF_UNIX sockets ? */
-       list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) {
+       list_for_each_entry(priv, &tty->tty_files, list) {
+               filp = priv->file;
                if (filp->f_op->write == redirected_tty_write)
                        cons_filp = filp;
                if (filp->f_op->write != tty_write)
@@ -530,7 +570,7 @@ void __tty_hangup(struct tty_struct *tty)
                __tty_fasync(-1, filp, 0);      /* can't block */
                filp->f_op = &hung_up_tty_fops;
        }
-       file_list_unlock();
+       spin_unlock(&tty_files_lock);
 
        tty_ldisc_hangup(tty);
 
@@ -889,12 +929,10 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
                        loff_t *ppos)
 {
        int i;
-       struct tty_struct *tty;
-       struct inode *inode;
+       struct inode *inode = file->f_path.dentry->d_inode;
+       struct tty_struct *tty = file_tty(file);
        struct tty_ldisc *ld;
 
-       tty = file->private_data;
-       inode = file->f_path.dentry->d_inode;
        if (tty_paranoia_check(tty, inode, "tty_read"))
                return -EIO;
        if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
@@ -1065,12 +1103,11 @@ void tty_write_message(struct tty_struct *tty, char *msg)
 static ssize_t tty_write(struct file *file, const char __user *buf,
                                                size_t count, loff_t *ppos)
 {
-       struct tty_struct *tty;
        struct inode *inode = file->f_path.dentry->d_inode;
+       struct tty_struct *tty = file_tty(file);
+       struct tty_ldisc *ld;
        ssize_t ret;
-       struct tty_ldisc *ld;
 
-       tty = file->private_data;
        if (tty_paranoia_check(tty, inode, "tty_write"))
                return -EIO;
        if (!tty || !tty->ops->write ||
@@ -1424,9 +1461,9 @@ static void release_one_tty(struct work_struct *work)
        tty_driver_kref_put(driver);
        module_put(driver->owner);
 
-       file_list_lock();
+       spin_lock(&tty_files_lock);
        list_del_init(&tty->tty_files);
-       file_list_unlock();
+       spin_unlock(&tty_files_lock);
 
        put_pid(tty->pgrp);
        put_pid(tty->session);
@@ -1507,13 +1544,13 @@ static void release_tty(struct tty_struct *tty, int idx)
 
 int tty_release(struct inode *inode, struct file *filp)
 {
-       struct tty_struct *tty, *o_tty;
+       struct tty_struct *tty = file_tty(filp);
+       struct tty_struct *o_tty;
        int     pty_master, tty_closing, o_tty_closing, do_sleep;
        int     devpts;
        int     idx;
        char    buf[64];
 
-       tty = filp->private_data;
        if (tty_paranoia_check(tty, inode, "tty_release_dev"))
                return 0;
 
@@ -1671,8 +1708,7 @@ int tty_release(struct inode *inode, struct file *filp)
         *  - do_tty_hangup no longer sees this file descriptor as
         *    something that needs to be handled for hangups.
         */
-       file_kill(filp);
-       filp->private_data = NULL;
+       tty_del_file(filp);
 
        /*
         * Perform some housekeeping before deciding whether to return.
@@ -1839,8 +1875,8 @@ got_driver:
                return PTR_ERR(tty);
        }
 
-       filp->private_data = tty;
-       file_move(filp, &tty->tty_files);
+       tty_add_file(tty, filp);
+
        check_tty_count(tty, "tty_open");
        if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
            tty->driver->subtype == PTY_TYPE_MASTER)
@@ -1916,11 +1952,10 @@ got_driver:
 
 static unsigned int tty_poll(struct file *filp, poll_table *wait)
 {
-       struct tty_struct *tty;
+       struct tty_struct *tty = file_tty(filp);
        struct tty_ldisc *ld;
        int ret = 0;
 
-       tty = filp->private_data;
        if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll"))
                return 0;
 
@@ -1933,11 +1968,10 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait)
 
 static int __tty_fasync(int fd, struct file *filp, int on)
 {
-       struct tty_struct *tty;
+       struct tty_struct *tty = file_tty(filp);
        unsigned long flags;
        int retval = 0;
 
-       tty = filp->private_data;
        if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
                goto out;
 
@@ -2491,13 +2525,13 @@ EXPORT_SYMBOL(tty_pair_get_pty);
  */
 long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-       struct tty_struct *tty, *real_tty;
+       struct tty_struct *tty = file_tty(file);
+       struct tty_struct *real_tty;
        void __user *p = (void __user *)arg;
        int retval;
        struct tty_ldisc *ld;
        struct inode *inode = file->f_dentry->d_inode;
 
-       tty = file->private_data;
        if (tty_paranoia_check(tty, inode, "tty_ioctl"))
                return -EINVAL;
 
@@ -2619,7 +2653,7 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
                                unsigned long arg)
 {
        struct inode *inode = file->f_dentry->d_inode;
-       struct tty_struct *tty = file->private_data;
+       struct tty_struct *tty = file_tty(file);
        struct tty_ldisc *ld;
        int retval = -ENOIOCTLCMD;
 
@@ -2711,7 +2745,7 @@ void __do_SAK(struct tty_struct *tty)
                                if (!filp)
                                        continue;
                                if (filp->f_op->read == tty_read &&
-                                   filp->private_data == tty) {
+                                   file_tty(filp) == tty) {
                                        printk(KERN_NOTICE "SAK: killed process %d"
                                            " (%s): fd#%d opened to the tty\n",
                                            task_pid_nr(p), p->comm, i);
index c734f9b1263a7d020550f930e3619fb0f7759d80..50590c7f2c01ac4c2a71595e94fbebe930081079 100644 (file)
@@ -194,10 +194,11 @@ static DECLARE_WORK(console_work, console_callback);
 int fg_console;
 int last_console;
 int want_console = -1;
-int saved_fg_console;
-int saved_last_console;
-int saved_want_console;
-int saved_vc_mode;
+static int saved_fg_console;
+static int saved_last_console;
+static int saved_want_console;
+static int saved_vc_mode;
+static int saved_console_blanked;
 
 /*
  * For each existing display, we have a pointer to console currently visible
@@ -3449,6 +3450,7 @@ int con_debug_enter(struct vc_data *vc)
        saved_last_console = last_console;
        saved_want_console = want_console;
        saved_vc_mode = vc->vc_mode;
+       saved_console_blanked = console_blanked;
        vc->vc_mode = KD_TEXT;
        console_blanked = 0;
        if (vc->vc_sw->con_debug_enter)
@@ -3492,6 +3494,7 @@ int con_debug_leave(void)
        fg_console = saved_fg_console;
        last_console = saved_last_console;
        want_console = saved_want_console;
+       console_blanked = saved_console_blanked;
        vc_cons[fg_console].d->vc_mode = saved_vc_mode;
 
        vc = vc_cons[fg_console].d;
index 0ed763cd2e77499471bc6f4abc0da36e199ec3dd..b663d573aad99ed5257f9ab324d566309e70ac37 100644 (file)
@@ -94,6 +94,7 @@
 
 #ifdef CONFIG_OF
 /* For open firmware. */
+#include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
 #endif
index e635199a0cd258298d0f50fd658fbcaec647f569..0c52899be9643d85af5c7ac6be8c87bc67d6e6ce 100644 (file)
@@ -1299,6 +1299,7 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
        { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
        { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
index f44bdc084cb297eed86ea504c711eec6f91ebaf0..8ca7f65cf2f804d32120fadfa81cc9b900dfd94a 100644 (file)
@@ -159,6 +159,13 @@ static int egalax_event(struct hid_device *hid, struct hid_field *field,
 {
        struct egalax_data *td = hid_get_drvdata(hid);
 
+       /* Note, eGalax has two product lines: the first is resistive and
+        * uses a standard parallel multitouch protocol (product ID ==
+        * 48xx).  The second is capacitive and uses an unusual "serial"
+        * protocol with a different message for each multitouch finger
+        * (product ID == 72xx).  We do not yet generate a correct event
+        * sequence for the capacitive/serial protocol.
+        */
        if (hid->claimed & HID_CLAIMED_INPUT) {
                struct input_dev *input = field->hidinput->input;
 
@@ -246,6 +253,8 @@ static void egalax_remove(struct hid_device *hdev)
 static const struct hid_device_id egalax_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
                        USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
        { }
 };
 MODULE_DEVICE_TABLE(hid, egalax_devices);
index d3fc13ae094da4fcd5ef93671fbfab73332ff606..85c6d13c9ffa9369fca613eda828133b2b69a3e2 100644 (file)
 #define USB_VENDOR_ID_DWAV             0x0eef
 #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER   0x0001
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH   0x480d
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1  0x720c
 
 #define USB_VENDOR_ID_ELECOM           0x056e
 #define USB_DEVICE_ID_ELECOM_BM084     0x0061
index 346f0e34987e68454dddd3393c2b24cc1f640729..bc2e0774062864667ca92c52e3b4e7a23d923f53 100644 (file)
@@ -547,11 +547,11 @@ static void picolcd_fb_destroy(struct fb_info *info)
        ref_cnt--;
        mutex_lock(&info->lock);
        (*ref_cnt)--;
-       may_release = !ref_cnt;
+       may_release = !*ref_cnt;
        mutex_unlock(&info->lock);
        if (may_release) {
-               framebuffer_release(info);
                vfree((u8 *)info->fix.smem_start);
+               framebuffer_release(info);
        }
 }
 
index 254a003af048dd7a909e68f4a96ffcaae391bc96..0a29c51114aaf0d36c64f6c8c25195db5e2f3747 100644 (file)
@@ -266,13 +266,15 @@ static int hiddev_open(struct inode *inode, struct file *file)
 {
        struct hiddev_list *list;
        struct usb_interface *intf;
+       struct hid_device *hid;
        struct hiddev *hiddev;
        int res;
 
        intf = usb_find_interface(&hiddev_driver, iminor(inode));
        if (!intf)
                return -ENODEV;
-       hiddev = usb_get_intfdata(intf);
+       hid = usb_get_intfdata(intf);
+       hiddev = hid->hiddev;
 
        if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL)))
                return -ENOMEM;
@@ -587,7 +589,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        struct hiddev_list *list = file->private_data;
        struct hiddev *hiddev = list->hiddev;
        struct hid_device *hid = hiddev->hid;
-       struct usb_device *dev = hid_to_usb_dev(hid);
+       struct usb_device *dev;
        struct hiddev_collection_info cinfo;
        struct hiddev_report_info rinfo;
        struct hiddev_field_info finfo;
@@ -601,9 +603,11 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        /* Called without BKL by compat methods so no BKL taken */
 
        /* FIXME: Who or what stop this racing with a disconnect ?? */
-       if (!hiddev->exist)
+       if (!hiddev->exist || !hid)
                return -EIO;
 
+       dev = hid_to_usb_dev(hid);
+
        switch (cmd) {
 
        case HIDIOCGVERSION:
@@ -888,7 +892,6 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
        hid->hiddev = hiddev;
        hiddev->hid = hid;
        hiddev->exist = 1;
-       usb_set_intfdata(usbhid->intf, usbhid);
        retval = usb_register_dev(usbhid->intf, &hiddev_class);
        if (retval) {
                err_hid("Not able to get a minor for this device.");
index 11567c7999a243d3d95ebecdb623c26de49705ce..c148b630215484f9689bf9257d6acf286685c37a 100644 (file)
@@ -2136,16 +2136,6 @@ static void sync_sbs(mddev_t * mddev, int nospares)
         * with the rest of the array)
         */
        mdk_rdev_t *rdev;
-
-       /* First make sure individual recovery_offsets are correct */
-       list_for_each_entry(rdev, &mddev->disks, same_set) {
-               if (rdev->raid_disk >= 0 &&
-                   mddev->delta_disks >= 0 &&
-                   !test_bit(In_sync, &rdev->flags) &&
-                   mddev->curr_resync_completed > rdev->recovery_offset)
-                               rdev->recovery_offset = mddev->curr_resync_completed;
-
-       }       
        list_for_each_entry(rdev, &mddev->disks, same_set) {
                if (rdev->sb_events == mddev->events ||
                    (nospares &&
@@ -2167,12 +2157,27 @@ static void md_update_sb(mddev_t * mddev, int force_change)
        int sync_req;
        int nospares = 0;
 
-       mddev->utime = get_seconds();
-       if (mddev->external)
-               return;
 repeat:
+       /* First make sure individual recovery_offsets are correct */
+       list_for_each_entry(rdev, &mddev->disks, same_set) {
+               if (rdev->raid_disk >= 0 &&
+                   mddev->delta_disks >= 0 &&
+                   !test_bit(In_sync, &rdev->flags) &&
+                   mddev->curr_resync_completed > rdev->recovery_offset)
+                               rdev->recovery_offset = mddev->curr_resync_completed;
+
+       }       
+       if (mddev->external || !mddev->persistent) {
+               clear_bit(MD_CHANGE_DEVS, &mddev->flags);
+               clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
+               wake_up(&mddev->sb_wait);
+               return;
+       }
+
        spin_lock_irq(&mddev->write_lock);
 
+       mddev->utime = get_seconds();
+
        set_bit(MD_CHANGE_PENDING, &mddev->flags);
        if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags))
                force_change = 1;
@@ -2221,19 +2226,6 @@ repeat:
                MD_BUG();
                mddev->events --;
        }
-
-       /*
-        * do not write anything to disk if using
-        * nonpersistent superblocks
-        */
-       if (!mddev->persistent) {
-               if (!mddev->external)
-                       clear_bit(MD_CHANGE_PENDING, &mddev->flags);
-
-               spin_unlock_irq(&mddev->write_lock);
-               wake_up(&mddev->sb_wait);
-               return;
-       }
        sync_sbs(mddev, nospares);
        spin_unlock_irq(&mddev->write_lock);
 
index 73cc74ffc26bd5eefb7166aa37130e4c47daa56a..ad83a4dcadc3ed7cafa914d2e4dcb7ef1a939fdf 100644 (file)
@@ -787,8 +787,8 @@ static int make_request(mddev_t *mddev, struct bio * bio)
        struct bio_list bl;
        struct page **behind_pages = NULL;
        const int rw = bio_data_dir(bio);
-       const bool do_sync = (bio->bi_rw & REQ_SYNC);
-       bool do_barriers;
+       const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
+       unsigned long do_barriers;
        mdk_rdev_t *blocked_rdev;
 
        /*
@@ -1120,6 +1120,8 @@ static int raid1_spare_active(mddev_t *mddev)
 {
        int i;
        conf_t *conf = mddev->private;
+       int count = 0;
+       unsigned long flags;
 
        /*
         * Find all failed disks within the RAID1 configuration 
@@ -1131,15 +1133,16 @@ static int raid1_spare_active(mddev_t *mddev)
                if (rdev
                    && !test_bit(Faulty, &rdev->flags)
                    && !test_and_set_bit(In_sync, &rdev->flags)) {
-                       unsigned long flags;
-                       spin_lock_irqsave(&conf->device_lock, flags);
-                       mddev->degraded--;
-                       spin_unlock_irqrestore(&conf->device_lock, flags);
+                       count++;
+                       sysfs_notify_dirent(rdev->sysfs_state);
                }
        }
+       spin_lock_irqsave(&conf->device_lock, flags);
+       mddev->degraded -= count;
+       spin_unlock_irqrestore(&conf->device_lock, flags);
 
        print_conf(conf);
-       return 0;
+       return count;
 }
 
 
@@ -1640,7 +1643,7 @@ static void raid1d(mddev_t *mddev)
                         * We already have a nr_pending reference on these rdevs.
                         */
                        int i;
-                       const bool do_sync = (r1_bio->master_bio->bi_rw & REQ_SYNC);
+                       const unsigned long do_sync = (r1_bio->master_bio->bi_rw & REQ_SYNC);
                        clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
                        clear_bit(R1BIO_Barrier, &r1_bio->state);
                        for (i=0; i < conf->raid_disks; i++)
@@ -1696,7 +1699,7 @@ static void raid1d(mddev_t *mddev)
                                       (unsigned long long)r1_bio->sector);
                                raid_end_bio_io(r1_bio);
                        } else {
-                               const bool do_sync = r1_bio->master_bio->bi_rw & REQ_SYNC;
+                               const unsigned long do_sync = r1_bio->master_bio->bi_rw & REQ_SYNC;
                                r1_bio->bios[r1_bio->read_disk] =
                                        mddev->ro ? IO_BLOCKED : NULL;
                                r1_bio->read_disk = disk;
index a88aeb5198c76a6c3a5ed58693d71f751ae975a7..84718383124d665f2c9382f5149d99773acde408 100644 (file)
@@ -799,7 +799,7 @@ static int make_request(mddev_t *mddev, struct bio * bio)
        int i;
        int chunk_sects = conf->chunk_mask + 1;
        const int rw = bio_data_dir(bio);
-       const bool do_sync = (bio->bi_rw & REQ_SYNC);
+       const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
        struct bio_list bl;
        unsigned long flags;
        mdk_rdev_t *blocked_rdev;
@@ -1116,6 +1116,8 @@ static int raid10_spare_active(mddev_t *mddev)
        int i;
        conf_t *conf = mddev->private;
        mirror_info_t *tmp;
+       int count = 0;
+       unsigned long flags;
 
        /*
         * Find all non-in_sync disks within the RAID10 configuration
@@ -1126,15 +1128,16 @@ static int raid10_spare_active(mddev_t *mddev)
                if (tmp->rdev
                    && !test_bit(Faulty, &tmp->rdev->flags)
                    && !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
-                       unsigned long flags;
-                       spin_lock_irqsave(&conf->device_lock, flags);
-                       mddev->degraded--;
-                       spin_unlock_irqrestore(&conf->device_lock, flags);
+                       count++;
+                       sysfs_notify_dirent(tmp->rdev->sysfs_state);
                }
        }
+       spin_lock_irqsave(&conf->device_lock, flags);
+       mddev->degraded -= count;
+       spin_unlock_irqrestore(&conf->device_lock, flags);
 
        print_conf(conf);
-       return 0;
+       return count;
 }
 
 
@@ -1734,7 +1737,7 @@ static void raid10d(mddev_t *mddev)
                                raid_end_bio_io(r10_bio);
                                bio_put(bio);
                        } else {
-                               const bool do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC);
+                               const unsigned long do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC);
                                bio_put(bio);
                                rdev = conf->mirrors[mirror].rdev;
                                if (printk_ratelimit())
index 866d4b5a144c465daf21e439b9b0e6ef36571d6a..69b0a169e43d483094200d88cd7d4e5ae05e9d19 100644 (file)
@@ -5330,6 +5330,8 @@ static int raid5_spare_active(mddev_t *mddev)
        int i;
        raid5_conf_t *conf = mddev->private;
        struct disk_info *tmp;
+       int count = 0;
+       unsigned long flags;
 
        for (i = 0; i < conf->raid_disks; i++) {
                tmp = conf->disks + i;
@@ -5337,14 +5339,15 @@ static int raid5_spare_active(mddev_t *mddev)
                    && tmp->rdev->recovery_offset == MaxSector
                    && !test_bit(Faulty, &tmp->rdev->flags)
                    && !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
-                       unsigned long flags;
-                       spin_lock_irqsave(&conf->device_lock, flags);
-                       mddev->degraded--;
-                       spin_unlock_irqrestore(&conf->device_lock, flags);
+                       count++;
+                       sysfs_notify_dirent(tmp->rdev->sysfs_state);
                }
        }
+       spin_lock_irqsave(&conf->device_lock, flags);
+       mddev->degraded -= count;
+       spin_unlock_irqrestore(&conf->device_lock, flags);
        print_raid5_conf(conf);
-       return 0;
+       return count;
 }
 
 static int raid5_remove_disk(mddev_t *mddev, int number)
index 0efe631e50cab2ddda5e6a98022e5b8e49f46705..d80cfdc8edd2663841894348fa33e7dc4e597b1e 100644 (file)
@@ -86,7 +86,9 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
        init_waitqueue_head(&host->wq);
        INIT_DELAYED_WORK(&host->detect, mmc_rescan);
        INIT_DELAYED_WORK_DEFERRABLE(&host->disable, mmc_host_deeper_disable);
+#ifdef CONFIG_PM
        host->pm_notify.notifier_call = mmc_pm_notify;
+#endif
 
        /*
         * By default, hosts do not support SGIO or large requests.
index 00af55d7afba60785b61b011814aba2e46a6f0df..fe63f6bd663c1f7a5ac8db57a0014c1c4a019da0 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/concat.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/slab.h>
 
index 0d5de2574dd106af6c3bdbad8e8028b4c24b3987..373dcfec689c40c2bf1be9af2b9bddb7a15dcacb 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/netdevice.h>
 #include <linux/cache.h>
 #include <linux/pci.h>
+#include <linux/pci-aspm.h>
 #include <linux/ethtool.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
@@ -476,6 +477,26 @@ ath5k_pci_probe(struct pci_dev *pdev,
        int ret;
        u8 csz;
 
+       /*
+        * L0s needs to be disabled on all ath5k cards.
+        *
+        * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
+        * by default in the future in 2.6.36) this will also mean both L1 and
+        * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
+        * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
+        * though but cannot currently undue the effect of a blacklist, for
+        * details you can read pcie_aspm_sanity_check() and see how it adjusts
+        * the device link capability.
+        *
+        * It may be possible in the future to implement some PCI API to allow
+        * drivers to override blacklists for pre 1.1 PCIe but for now it is
+        * best to accept that both L0s and L1 will be disabled completely for
+        * distributions shipping with CONFIG_PCIEASPM rather than having this
+        * issue present. Motivation for adding this new API will be to help
+        * with power consumption for some of these devices.
+        */
+       pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
+
        ret = pci_enable_device(pdev);
        if (ret) {
                dev_err(&pdev->dev, "can't enable device\n");
index 8750c558c221658302c18fabff9a25f83906b730..7f48df1e2903008f0a68bf991817bee64edf5b81 100644 (file)
 #define AR9287_EEP_NO_BACK_VER       AR9287_EEP_MINOR_VER_1
 
 #define AR9287_EEP_START_LOC            128
+#define AR9287_HTC_EEP_START_LOC        256
 #define AR9287_NUM_2G_CAL_PIERS         3
 #define AR9287_NUM_2G_CCK_TARGET_POWERS 3
 #define AR9287_NUM_2G_20_TARGET_POWERS  3
index 4a52cf03808b1aa207acb02fdd1f0394c38b73fa..dff2da777312bbb0e5b1c8902b370e79c41f75b4 100644 (file)
@@ -34,9 +34,14 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
        struct ar9287_eeprom *eep = &ah->eeprom.map9287;
        struct ath_common *common = ath9k_hw_common(ah);
        u16 *eep_data;
-       int addr, eep_start_loc = AR9287_EEP_START_LOC;
+       int addr, eep_start_loc;
        eep_data = (u16 *)eep;
 
+       if (ah->hw_version.devid == 0x7015)
+               eep_start_loc = AR9287_HTC_EEP_START_LOC;
+       else
+               eep_start_loc = AR9287_EEP_START_LOC;
+
        if (!ath9k_hw_use_flash(ah)) {
                ath_print(common, ATH_DBG_EEPROM,
                          "Reading from EEPROM, not flash\n");
index 61c1bee3f26a1159b6ac869e621d1573e0250f5c..17e7a9a367e70340a42d13c57beb167bfd4979d3 100644 (file)
@@ -799,7 +799,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
        }
        kfree(buf);
 
-       if (hif_dev->device_id == 0x7010)
+       if ((hif_dev->device_id == 0x7010) || (hif_dev->device_id == 0x7015))
                firm_offset = AR7010_FIRMWARE_TEXT;
        else
                firm_offset = AR9271_FIRMWARE_TEXT;
@@ -901,6 +901,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
 
        switch(hif_dev->device_id) {
        case 0x7010:
+       case 0x7015:
        case 0x9018:
                if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202)
                        hif_dev->fw_name = FIRMWARE_AR7010_1_1;
@@ -912,11 +913,6 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
                break;
        }
 
-       if (!hif_dev->fw_name) {
-               dev_err(&udev->dev, "Can't determine firmware !\n");
-               goto err_htc_hw_alloc;
-       }
-
        ret = ath9k_hif_usb_dev_init(hif_dev);
        if (ret) {
                ret = -EINVAL;
index 148b43317fdb1d6b78502ff42d208b197be28c33..2d4279191d7a7d6d1690d12a809cf9eb6dd8ef8a 100644 (file)
@@ -245,6 +245,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid)
 
        switch(devid) {
        case 0x7010:
+       case 0x7015:
        case 0x9018:
                priv->htc->credits = 45;
                break;
index ebed9d1691a5110ee3222ab12e652da4dcdde9d5..7d09b4b17bbd4b5e1146fa295ea6a22ffb571014 100644 (file)
@@ -366,7 +366,8 @@ static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
                caps = WLAN_RC_HT_FLAG;
                if (sta->ht_cap.mcs.rx_mask[1])
                        caps |= WLAN_RC_DS_FLAG;
-               if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+               if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
+                    (conf_is_ht40(&priv->hw->conf)))
                        caps |= WLAN_RC_40_FLAG;
                if (conf_is_ht40(&priv->hw->conf) &&
                    (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40))
index bd0b4acc3ece542d15413a1409421c1e538b73da..2a6e45a293a90f38b7add877b0ca231c603ebe1b 100644 (file)
@@ -78,18 +78,23 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
        struct ieee80211_sta *sta = tx_info->control.sta;
        struct ath9k_htc_sta *ista;
-       struct ath9k_htc_vif *avp;
        struct ath9k_htc_tx_ctl tx_ctl;
        enum htc_endpoint_id epid;
        u16 qnum;
        __le16 fc;
        u8 *tx_fhdr;
-       u8 sta_idx;
+       u8 sta_idx, vif_idx;
 
        hdr = (struct ieee80211_hdr *) skb->data;
        fc = hdr->frame_control;
 
-       avp = (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv;
+       if (tx_info->control.vif &&
+                       (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv)
+               vif_idx = ((struct ath9k_htc_vif *)
+                               tx_info->control.vif->drv_priv)->index;
+       else
+               vif_idx = priv->nvifs;
+
        if (sta) {
                ista = (struct ath9k_htc_sta *) sta->drv_priv;
                sta_idx = ista->index;
@@ -106,7 +111,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
                memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
 
                tx_hdr.node_idx = sta_idx;
-               tx_hdr.vif_idx = avp->index;
+               tx_hdr.vif_idx = vif_idx;
 
                if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
                        tx_ctl.type = ATH9K_HTC_AMPDU;
@@ -169,7 +174,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
                tx_ctl.type = ATH9K_HTC_NORMAL;
 
                mgmt_hdr.node_idx = sta_idx;
-               mgmt_hdr.vif_idx = avp->index;
+               mgmt_hdr.vif_idx = vif_idx;
                mgmt_hdr.tidno = 0;
                mgmt_hdr.flags = 0;
 
index 633e3d949ec09f172fab67d797ab449a557ae4f1..d01c4adab8d67bef80e37dce242c668210a783b4 100644 (file)
 
 #define AR_DEVID_7010(_ah) \
        (((_ah)->hw_version.devid == 0x7010) || \
+        ((_ah)->hw_version.devid == 0x7015) || \
         ((_ah)->hw_version.devid == 0x9018))
 
 #define AR_RADIO_SREV_MAJOR                   0xf0
index 16bbfa3189a59cb65998318c8dc06b90995ee6c5..1189dbb6e2a62abcdc090ca5eea61a9eb5824aa7 100644 (file)
@@ -6665,12 +6665,13 @@ static int __init ipw2100_init(void)
        printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
        printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
 
+       pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
+                          PM_QOS_DEFAULT_VALUE);
+
        ret = pci_register_driver(&ipw2100_pci_driver);
        if (ret)
                goto out;
 
-       pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
-                          PM_QOS_DEFAULT_VALUE);
 #ifdef CONFIG_IPW2100_DEBUG
        ipw2100_debug_level = debug;
        ret = driver_create_file(&ipw2100_pci_driver.driver,
index a37b30cef4894c6da466989be64546de3f38af94..ce3722f4c3e38e532c587051bce253257bcd89eb 100644 (file)
@@ -484,7 +484,7 @@ int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout)
 
        cmd->timeout = timeout;
 
-       ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd));
+       ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, cmd, sizeof(*cmd));
        if (ret < 0) {
                wl1251_error("cmd trigger scan to failed: %d", ret);
                goto out;
index e058c2ba2a1585cf3a81442c845906b24fcc225b..ca05aefd03bfbe1cb1f95f8d8fae899206af99da 100644 (file)
@@ -938,10 +938,11 @@ static int set_brightness(int value)
        /* SPLV laptop */
        if (hotk->methods->brightness_set) {
                if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set,
-                                   value, NULL))
+                                   value, NULL)) {
                        printk(KERN_WARNING
                               "Asus ACPI: Error changing brightness\n");
                        ret = -EIO;
+               }
                goto out;
        }
 
@@ -953,10 +954,11 @@ static int set_brightness(int value)
                                              hotk->methods->brightness_down,
                                              NULL, NULL);
                (value > 0) ? value-- : value++;
-               if (ACPI_FAILURE(status))
+               if (ACPI_FAILURE(status)) {
                        printk(KERN_WARNING
                               "Asus ACPI: Error changing brightness\n");
                        ret = -EIO;
+               }
        }
 out:
        return ret;
index d071ce05632265176cb9434524725fdc976728fb..097083cac4135c7d413cc9d5932dd6cf55c7f269 100644 (file)
@@ -840,6 +840,14 @@ static struct dmi_system_id __initdata compal_dmi_table[] = {
                },
                .callback = dmi_check_cb
        },
+       {
+               .ident = "Dell Mini 1012",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
+               },
+               .callback = dmi_check_cb
+       },
        {
                .ident = "Dell Inspiron 11z",
                .matches = {
@@ -1092,5 +1100,6 @@ MODULE_ALIAS("dmi:*:rnJHL90:rvrREFERENCE:*");
 MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron910:*");
 MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1010:*");
 MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1011:*");
+MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1012:*");
 MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1110:*");
 MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1210:*");
index b41ed5cab3e793105ede42b1e2d7199c04dd6c25..4413975912e036d71961a3430aa00be964de4b39 100644 (file)
@@ -121,6 +121,13 @@ static struct dmi_system_id __devinitdata dell_blacklist[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1011"),
                },
        },
+       {
+               .ident = "Dell Mini 1012",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
+               },
+       },
        {
                .ident = "Dell Inspiron 11z",
                .matches = {
index afe82e50dfea1b03bf53820cf9f9d2edb76e6355..9024480a82288ec071e26008f616fe2d9556c18b 100644 (file)
@@ -1342,8 +1342,10 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips)
                limits = &ips_lv_limits;
        else if (strstr(boot_cpu_data.x86_model_id, "CPU       U"))
                limits = &ips_ulv_limits;
-       else
+       else {
                dev_info(&ips->dev->dev, "No CPUID match found.\n");
+               goto out;
+       }
 
        rdmsrl(TURBO_POWER_CURRENT_LIMIT, turbo_power);
        tdp = turbo_power & TURBO_TDP_MASK;
@@ -1432,6 +1434,12 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
 
        spin_lock_init(&ips->turbo_status_lock);
 
+       ret = pci_enable_device(dev);
+       if (ret) {
+               dev_err(&dev->dev, "can't enable PCI device, aborting\n");
+               goto error_free;
+       }
+
        if (!pci_resource_start(dev, 0)) {
                dev_err(&dev->dev, "TBAR not assigned, aborting\n");
                ret = -ENXIO;
@@ -1444,11 +1452,6 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
                goto error_free;
        }
 
-       ret = pci_enable_device(dev);
-       if (ret) {
-               dev_err(&dev->dev, "can't enable PCI device, aborting\n");
-               goto error_free;
-       }
 
        ips->regmap = ioremap(pci_resource_start(dev, 0),
                              pci_resource_len(dev, 0));
index 5d6119bed00c6500e62bbf19073d772bc8af9e77..e35ed128bdef439313a107106f36c47e03dc5b7e 100644 (file)
@@ -1911,6 +1911,17 @@ enum {   /* hot key scan codes (derived from ACPI DSDT) */
        TP_ACPI_HOTKEYSCAN_VOLUMEDOWN,
        TP_ACPI_HOTKEYSCAN_MUTE,
        TP_ACPI_HOTKEYSCAN_THINKPAD,
+       TP_ACPI_HOTKEYSCAN_UNK1,
+       TP_ACPI_HOTKEYSCAN_UNK2,
+       TP_ACPI_HOTKEYSCAN_UNK3,
+       TP_ACPI_HOTKEYSCAN_UNK4,
+       TP_ACPI_HOTKEYSCAN_UNK5,
+       TP_ACPI_HOTKEYSCAN_UNK6,
+       TP_ACPI_HOTKEYSCAN_UNK7,
+       TP_ACPI_HOTKEYSCAN_UNK8,
+
+       /* Hotkey keymap size */
+       TPACPI_HOTKEY_MAP_LEN
 };
 
 enum { /* Keys/events available through NVRAM polling */
@@ -3082,6 +3093,8 @@ static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = {
        TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */
 };
 
+typedef u16 tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN];
+
 static int __init hotkey_init(struct ibm_init_struct *iibm)
 {
        /* Requirements for changing the default keymaps:
@@ -3113,9 +3126,17 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
         * If the above is too much to ask, don't change the keymap.
         * Ask the thinkpad-acpi maintainer to do it, instead.
         */
-       static u16 ibm_keycode_map[] __initdata = {
+
+       enum keymap_index {
+               TPACPI_KEYMAP_IBM_GENERIC = 0,
+               TPACPI_KEYMAP_LENOVO_GENERIC,
+       };
+
+       static const tpacpi_keymap_t tpacpi_keymaps[] __initconst = {
+       /* Generic keymap for IBM ThinkPads */
+       [TPACPI_KEYMAP_IBM_GENERIC] = {
                /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
-               KEY_FN_F1,      KEY_FN_F2,      KEY_COFFEE,     KEY_SLEEP,
+               KEY_FN_F1,      KEY_BATTERY,    KEY_COFFEE,     KEY_SLEEP,
                KEY_WLAN,       KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
                KEY_FN_F9,      KEY_FN_F10,     KEY_FN_F11,     KEY_SUSPEND,
 
@@ -3146,11 +3167,13 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
                /* (assignments unknown, please report if found) */
                KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
                KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
-       };
-       static u16 lenovo_keycode_map[] __initdata = {
+               },
+
+       /* Generic keymap for Lenovo ThinkPads */
+       [TPACPI_KEYMAP_LENOVO_GENERIC] = {
                /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
                KEY_FN_F1,      KEY_COFFEE,     KEY_BATTERY,    KEY_SLEEP,
-               KEY_WLAN,       KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
+               KEY_WLAN,       KEY_CAMERA, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
                KEY_FN_F9,      KEY_FN_F10,     KEY_FN_F11,     KEY_SUSPEND,
 
                /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */
@@ -3189,11 +3212,25 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
                /* (assignments unknown, please report if found) */
                KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
                KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
+               },
+       };
+
+       static const struct tpacpi_quirk tpacpi_keymap_qtable[] __initconst = {
+               /* Generic maps (fallback) */
+               {
+                 .vendor = PCI_VENDOR_ID_IBM,
+                 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
+                 .quirks = TPACPI_KEYMAP_IBM_GENERIC,
+               },
+               {
+                 .vendor = PCI_VENDOR_ID_LENOVO,
+                 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
+                 .quirks = TPACPI_KEYMAP_LENOVO_GENERIC,
+               },
        };
 
-#define TPACPI_HOTKEY_MAP_LEN          ARRAY_SIZE(ibm_keycode_map)
-#define TPACPI_HOTKEY_MAP_SIZE         sizeof(ibm_keycode_map)
-#define TPACPI_HOTKEY_MAP_TYPESIZE     sizeof(ibm_keycode_map[0])
+#define TPACPI_HOTKEY_MAP_SIZE         sizeof(tpacpi_keymap_t)
+#define TPACPI_HOTKEY_MAP_TYPESIZE     sizeof(tpacpi_keymap_t[0])
 
        int res, i;
        int status;
@@ -3202,6 +3239,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
        bool tabletsw_state = false;
 
        unsigned long quirks;
+       unsigned long keymap_id;
 
        vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
                        "initializing hotkey subdriver\n");
@@ -3342,7 +3380,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
                goto err_exit;
 
        /* Set up key map */
-
        hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
                                        GFP_KERNEL);
        if (!hotkey_keycode_map) {
@@ -3352,17 +3389,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
                goto err_exit;
        }
 
-       if (tpacpi_is_lenovo()) {
-               dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
-                          "using Lenovo default hot key map\n");
-               memcpy(hotkey_keycode_map, &lenovo_keycode_map,
-                       TPACPI_HOTKEY_MAP_SIZE);
-       } else {
-               dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
-                          "using IBM default hot key map\n");
-               memcpy(hotkey_keycode_map, &ibm_keycode_map,
-                       TPACPI_HOTKEY_MAP_SIZE);
-       }
+       keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable,
+                                       ARRAY_SIZE(tpacpi_keymap_qtable));
+       BUG_ON(keymap_id >= ARRAY_SIZE(tpacpi_keymaps));
+       dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+                  "using keymap number %lu\n", keymap_id);
+
+       memcpy(hotkey_keycode_map, &tpacpi_keymaps[keymap_id],
+               TPACPI_HOTKEY_MAP_SIZE);
 
        input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN);
        tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
@@ -3469,7 +3503,8 @@ static bool hotkey_notify_hotkey(const u32 hkey,
        *send_acpi_ev = true;
        *ignore_acpi_ev = false;
 
-       if (scancode > 0 && scancode < 0x21) {
+       /* HKEY event 0x1001 is scancode 0x00 */
+       if (scancode > 0 && scancode <= TPACPI_HOTKEY_MAP_LEN) {
                scancode--;
                if (!(hotkey_source_mask & (1 << scancode))) {
                        tpacpi_input_send_key_masked(scancode);
@@ -6080,13 +6115,18 @@ static struct backlight_ops ibm_backlight_data = {
 
 /* --------------------------------------------------------------------- */
 
+/*
+ * Call _BCL method of video device.  On some ThinkPads this will
+ * switch the firmware to the ACPI brightness control mode.
+ */
+
 static int __init tpacpi_query_bcl_levels(acpi_handle handle)
 {
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        union acpi_object *obj;
        int rc;
 
-       if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
+       if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) {
                obj = (union acpi_object *)buffer.pointer;
                if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
                        printk(TPACPI_ERR "Unknown _BCL data, "
@@ -6103,55 +6143,22 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle)
        return rc;
 }
 
-static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle,
-                                       u32 lvl, void *context, void **rv)
-{
-       char name[ACPI_PATH_SEGMENT_LENGTH];
-       struct acpi_buffer buffer = { sizeof(name), &name };
-
-       if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
-           !strncmp("_BCL", name, sizeof(name) - 1)) {
-               BUG_ON(!rv || !*rv);
-               **(int **)rv = tpacpi_query_bcl_levels(handle);
-               return AE_CTRL_TERMINATE;
-       } else {
-               return AE_OK;
-       }
-}
 
 /*
  * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map
  */
 static unsigned int __init tpacpi_check_std_acpi_brightness_support(void)
 {
-       int status;
+       acpi_handle video_device;
        int bcl_levels = 0;
-       void *bcl_ptr = &bcl_levels;
-
-       if (!vid_handle)
-               TPACPI_ACPIHANDLE_INIT(vid);
-
-       if (!vid_handle)
-               return 0;
-
-       /*
-        * Search for a _BCL method, and execute it.  This is safe on all
-        * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista
-        * BIOS in ACPI backlight control mode.  We do NOT have to care
-        * about calling the _BCL method in an enabled video device, any
-        * will do for our purposes.
-        */
 
-       status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
-                                    tpacpi_acpi_walk_find_bcl, NULL, NULL,
-                                    &bcl_ptr);
+       tpacpi_acpi_handle_locate("video", ACPI_VIDEO_HID, &video_device);
+       if (video_device)
+               bcl_levels = tpacpi_query_bcl_levels(video_device);
 
-       if (ACPI_SUCCESS(status) && bcl_levels > 2) {
-               tp_features.bright_acpimode = 1;
-               return bcl_levels - 2;
-       }
+       tp_features.bright_acpimode = (bcl_levels > 0);
 
-       return 0;
+       return (bcl_levels > 2) ? (bcl_levels - 2) : 0;
 }
 
 /*
@@ -6244,28 +6251,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
        if (tp_features.bright_unkfw)
                return 1;
 
-       if (tp_features.bright_acpimode) {
-               if (acpi_video_backlight_support()) {
-                       if (brightness_enable > 1) {
-                               printk(TPACPI_NOTICE
-                                      "Standard ACPI backlight interface "
-                                      "available, not loading native one.\n");
-                               return 1;
-                       } else if (brightness_enable == 1) {
-                               printk(TPACPI_NOTICE
-                                      "Backlight control force enabled, even if standard "
-                                      "ACPI backlight interface is available\n");
-                       }
-               } else {
-                       if (brightness_enable > 1) {
-                               printk(TPACPI_NOTICE
-                                      "Standard ACPI backlight interface not "
-                                      "available, thinkpad_acpi native "
-                                      "brightness control enabled\n");
-                       }
-               }
-       }
-
        if (!brightness_enable) {
                dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
                           "brightness support disabled by "
@@ -6273,6 +6258,26 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
                return 1;
        }
 
+       if (acpi_video_backlight_support()) {
+               if (brightness_enable > 1) {
+                       printk(TPACPI_INFO
+                              "Standard ACPI backlight interface "
+                              "available, not loading native one.\n");
+                       return 1;
+               } else if (brightness_enable == 1) {
+                       printk(TPACPI_WARN
+                               "Cannot enable backlight brightness support, "
+                               "ACPI is already handling it.  Refer to the "
+                               "acpi_backlight kernel parameter\n");
+                       return 1;
+               }
+       } else if (tp_features.bright_acpimode && brightness_enable > 1) {
+               printk(TPACPI_NOTICE
+                       "Standard ACPI backlight interface not "
+                       "available, thinkpad_acpi native "
+                       "brightness control enabled\n");
+       }
+
        /*
         * Check for module parameter bogosity, note that we
         * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be
index 95a895dd4f132883aa7dc8c379332aa917863aa0..c8dc392edd57534c18cf45257251f42b49c070c7 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/aer.h>
 #include <asm/dma.h>
index 659a695bdad6474e832c9d4ffbef7648fe45c4d5..2af8fd1131234be29fd612b207da23543c78870b 100644 (file)
 #include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/nwpserial.h>
 
-#include <asm/prom.h>
-
 struct of_serial_info {
        int type;
        int line;
index 544f2e25d0e545f30f959019f4a176bdccb20af8..6381a0282ee79ab3f43e464f19a48a0880faa4bc 100644 (file)
@@ -55,7 +55,12 @@ EXPORT_SYMBOL(sunserial_unregister_minors);
 int sunserial_console_match(struct console *con, struct device_node *dp,
                            struct uart_driver *drv, int line, bool ignore_line)
 {
-       if (!con || of_console_device != dp)
+       if (!con)
+               return 0;
+
+       drv->cons = con;
+
+       if (of_console_device != dp)
                return 0;
 
        if (!ignore_line) {
@@ -69,12 +74,10 @@ int sunserial_console_match(struct console *con, struct device_node *dp,
                        return 0;
        }
 
-       con->index = line;
-       drv->cons = con;
-
-       if (!console_set_on_cmdline)
+       if (!console_set_on_cmdline) {
+               con->index = line;
                add_preferred_console(con->name, line, NULL);
-
+       }
        return 1;
 }
 EXPORT_SYMBOL(sunserial_console_match);
index 59be3efe063621e2fffb7b576e8ea0d8daa10b32..052b3c7fa6a0f644d26c613e67e69ffe00ad05be 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
+#include <linux/sched.h>
 #include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/io.h>
index cdc4dd50d638a51abc240c780989b4433856b27c..8ec83d2dffb75ec23c67d35cce2c5ee272943c1a 100644 (file)
@@ -44,9 +44,9 @@ int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int le
                return -ENOENT;
        }
 
-       read_lock(&current->fs->lock);
+       spin_lock(&current->fs->lock);
        path.mnt = mntget(current->fs->root.mnt);
-       read_unlock(&current->fs->lock);
+       spin_unlock(&current->fs->lock);
 
        path.dentry = d;
 
@@ -91,9 +91,9 @@ int pohmelfs_path_length(struct pohmelfs_inode *pi)
                return -ENOENT;
        }
 
-       read_lock(&current->fs->lock);
+       spin_lock(&current->fs->lock);
        root = dget(current->fs->root.dentry);
-       read_unlock(&current->fs->lock);
+       spin_unlock(&current->fs->lock);
 
        spin_lock(&dcache_lock);
 
index afe21e6eb5443cc8e8056e6f630fbd1c89caf991..1c2c68356ea7ecce8d3983fba656a4faf9cd26ae 100644 (file)
@@ -80,7 +80,10 @@ static void clcdfb_disable(struct clcd_fb *fb)
        /*
         * Disable CLCD clock source.
         */
-       clk_disable(fb->clk);
+       if (fb->clk_enabled) {
+               fb->clk_enabled = false;
+               clk_disable(fb->clk);
+       }
 }
 
 static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
@@ -88,7 +91,10 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
        /*
         * Enable the CLCD clock source.
         */
-       clk_enable(fb->clk);
+       if (!fb->clk_enabled) {
+               fb->clk_enabled = true;
+               clk_enable(fb->clk);
+       }
 
        /*
         * Bring up by first enabling..
index 9e60fd201716020c8506a392ecf76204b3884cb1..a7528b91393676bb1f1affa72f6b78f38206d4c5 100644 (file)
@@ -108,7 +108,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        Node *fmt;
        struct file * interp_file = NULL;
        char iname[BINPRM_BUF_SIZE];
-       char *iname_addr = iname;
+       const char *iname_addr = iname;
        int retval;
        int fd_binary = -1;
 
index aca9d55afb220fddd5998a5d37bfd7a402bb5995..396a9884591f5f6a9cc2e7cfa7c80220bf62ef87 100644 (file)
@@ -16,7 +16,8 @@
 
 static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 {
-       char *cp, *i_name, *i_arg;
+       const char *i_arg, *i_name;
+       char *cp;
        struct file *file;
        char interp[BINPRM_BUF_SIZE];
        int retval;
index 50efa339e051f7b7a5d417160ff528ca94e3adfa..3e7dca279d1c0dff3fdb7e0e2e7d8d236af7d4c9 100644 (file)
@@ -770,11 +770,12 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
                                spin_unlock(lock);
                                /*
                                 * Ensure any pending I/O completes so that
-                                * ll_rw_block() actually writes the current
-                                * contents - it is a noop if I/O is still in
-                                * flight on potentially older contents.
+                                * write_dirty_buffer() actually writes the
+                                * current contents - it is a noop if I/O is
+                                * still in flight on potentially older
+                                * contents.
                                 */
-                               ll_rw_block(SWRITE_SYNC_PLUG, 1, &bh);
+                               write_dirty_buffer(bh, WRITE_SYNC_PLUG);
 
                                /*
                                 * Kick off IO for the previous mapping. Note
@@ -2911,13 +2912,6 @@ int submit_bh(int rw, struct buffer_head * bh)
        BUG_ON(buffer_delay(bh));
        BUG_ON(buffer_unwritten(bh));
 
-       /*
-        * Mask in barrier bit for a write (could be either a WRITE or a
-        * WRITE_SYNC
-        */
-       if (buffer_ordered(bh) && (rw & WRITE))
-               rw |= WRITE_BARRIER;
-
        /*
         * Only clear out a write error when rewriting
         */
@@ -2956,22 +2950,21 @@ EXPORT_SYMBOL(submit_bh);
 
 /**
  * ll_rw_block: low-level access to block devices (DEPRECATED)
- * @rw: whether to %READ or %WRITE or %SWRITE or maybe %READA (readahead)
+ * @rw: whether to %READ or %WRITE or maybe %READA (readahead)
  * @nr: number of &struct buffer_heads in the array
  * @bhs: array of pointers to &struct buffer_head
  *
  * ll_rw_block() takes an array of pointers to &struct buffer_heads, and
  * requests an I/O operation on them, either a %READ or a %WRITE.  The third
- * %SWRITE is like %WRITE only we make sure that the *current* data in buffers
- * are sent to disk. The fourth %READA option is described in the documentation
- * for generic_make_request() which ll_rw_block() calls.
+ * %READA option is described in the documentation for generic_make_request()
+ * which ll_rw_block() calls.
  *
  * This function drops any buffer that it cannot get a lock on (with the
- * BH_Lock state bit) unless SWRITE is required, any buffer that appears to be
- * clean when doing a write request, and any buffer that appears to be
- * up-to-date when doing read request.  Further it marks as clean buffers that
- * are processed for writing (the buffer cache won't assume that they are
- * actually clean until the buffer gets unlocked).
+ * BH_Lock state bit), any buffer that appears to be clean when doing a write
+ * request, and any buffer that appears to be up-to-date when doing read
+ * request.  Further it marks as clean buffers that are processed for
+ * writing (the buffer cache won't assume that they are actually clean
+ * until the buffer gets unlocked).
  *
  * ll_rw_block sets b_end_io to simple completion handler that marks
  * the buffer up-to-date (if approriate), unlocks the buffer and wakes
@@ -2987,20 +2980,13 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
        for (i = 0; i < nr; i++) {
                struct buffer_head *bh = bhs[i];
 
-               if (rw == SWRITE || rw == SWRITE_SYNC || rw == SWRITE_SYNC_PLUG)
-                       lock_buffer(bh);
-               else if (!trylock_buffer(bh))
+               if (!trylock_buffer(bh))
                        continue;
-
-               if (rw == WRITE || rw == SWRITE || rw == SWRITE_SYNC ||
-                   rw == SWRITE_SYNC_PLUG) {
+               if (rw == WRITE) {
                        if (test_clear_buffer_dirty(bh)) {
                                bh->b_end_io = end_buffer_write_sync;
                                get_bh(bh);
-                               if (rw == SWRITE_SYNC)
-                                       submit_bh(WRITE_SYNC, bh);
-                               else
-                                       submit_bh(WRITE, bh);
+                               submit_bh(WRITE, bh);
                                continue;
                        }
                } else {
@@ -3016,12 +3002,25 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
 }
 EXPORT_SYMBOL(ll_rw_block);
 
+void write_dirty_buffer(struct buffer_head *bh, int rw)
+{
+       lock_buffer(bh);
+       if (!test_clear_buffer_dirty(bh)) {
+               unlock_buffer(bh);
+               return;
+       }
+       bh->b_end_io = end_buffer_write_sync;
+       get_bh(bh);
+       submit_bh(rw, bh);
+}
+EXPORT_SYMBOL(write_dirty_buffer);
+
 /*
  * For a data-integrity writeout, we need to wait upon any in-progress I/O
  * and then start new I/O and then wait upon it.  The caller must have a ref on
  * the buffer_head.
  */
-int sync_dirty_buffer(struct buffer_head *bh)
+int __sync_dirty_buffer(struct buffer_head *bh, int rw)
 {
        int ret = 0;
 
@@ -3030,7 +3029,7 @@ int sync_dirty_buffer(struct buffer_head *bh)
        if (test_clear_buffer_dirty(bh)) {
                get_bh(bh);
                bh->b_end_io = end_buffer_write_sync;
-               ret = submit_bh(WRITE_SYNC, bh);
+               ret = submit_bh(rw, bh);
                wait_on_buffer(bh);
                if (buffer_eopnotsupp(bh)) {
                        clear_buffer_eopnotsupp(bh);
@@ -3043,6 +3042,12 @@ int sync_dirty_buffer(struct buffer_head *bh)
        }
        return ret;
 }
+EXPORT_SYMBOL(__sync_dirty_buffer);
+
+int sync_dirty_buffer(struct buffer_head *bh)
+{
+       return __sync_dirty_buffer(bh, WRITE_SYNC);
+}
 EXPORT_SYMBOL(sync_dirty_buffer);
 
 /*
index a53b130b366c738c654a7ec71a3e4b01ee6d8ec7..1e7a33028d33908807d776d05840637cfd7e4f22 100644 (file)
@@ -80,7 +80,7 @@ static struct inode *get_cramfs_inode(struct super_block *sb,
                }
        } else {
                inode = iget_locked(sb, CRAMINO(cramfs_inode));
-               if (inode) {
+               if (inode && (inode->i_state & I_NEW)) {
                        setup_inode(inode, cramfs_inode);
                        unlock_new_inode(inode);
                }
index 4d13bf50b7b159774c592ce886c7fd9208372d2a..83293be4814965373d4c81e5b7d91bc63f3a55c6 100644 (file)
@@ -1332,31 +1332,13 @@ EXPORT_SYMBOL(d_add_ci);
  * d_lookup - search for a dentry
  * @parent: parent dentry
  * @name: qstr of name we wish to find
+ * Returns: dentry, or NULL
  *
- * Searches the children of the parent dentry for the name in question. If
- * the dentry is found its reference count is incremented and the dentry
- * is returned. The caller must use dput to free the entry when it has
- * finished using it. %NULL is returned on failure.
- *
- * __d_lookup is dcache_lock free. The hash list is protected using RCU.
- * Memory barriers are used while updating and doing lockless traversal. 
- * To avoid races with d_move while rename is happening, d_lock is used.
- *
- * Overflows in memcmp(), while d_move, are avoided by keeping the length
- * and name pointer in one structure pointed by d_qstr.
- *
- * rcu_read_lock() and rcu_read_unlock() are used to disable preemption while
- * lookup is going on.
- *
- * The dentry unused LRU is not updated even if lookup finds the required dentry
- * in there. It is updated in places such as prune_dcache, shrink_dcache_sb,
- * select_parent and __dget_locked. This laziness saves lookup from dcache_lock
- * acquisition.
- *
- * d_lookup() is protected against the concurrent renames in some unrelated
- * directory using the seqlockt_t rename_lock.
+ * d_lookup searches the children of the parent dentry for the name in
+ * question. If the dentry is found its reference count is incremented and the
+ * dentry is returned. The caller must use dput to free the entry when it has
+ * finished using it. %NULL is returned if the dentry does not exist.
  */
-
 struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
 {
        struct dentry * dentry = NULL;
@@ -1372,6 +1354,21 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
 }
 EXPORT_SYMBOL(d_lookup);
 
+/*
+ * __d_lookup - search for a dentry (racy)
+ * @parent: parent dentry
+ * @name: qstr of name we wish to find
+ * Returns: dentry, or NULL
+ *
+ * __d_lookup is like d_lookup, however it may (rarely) return a
+ * false-negative result due to unrelated rename activity.
+ *
+ * __d_lookup is slightly faster by avoiding rename_lock read seqlock,
+ * however it must be used carefully, eg. with a following d_lookup in
+ * the case of failure.
+ *
+ * __d_lookup callers must be commented.
+ */
 struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
 {
        unsigned int len = name->len;
@@ -1382,6 +1379,19 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
        struct hlist_node *node;
        struct dentry *dentry;
 
+       /*
+        * The hash list is protected using RCU.
+        *
+        * Take d_lock when comparing a candidate dentry, to avoid races
+        * with d_move().
+        *
+        * It is possible that concurrent renames can mess up our list
+        * walk here and result in missing our dentry, resulting in the
+        * false-negative result. d_lookup() protects against concurrent
+        * renames using rename_lock seqlock.
+        *
+        * See Documentation/vfs/dcache-locking.txt for more details.
+        */
        rcu_read_lock();
        
        hlist_for_each_entry_rcu(dentry, node, head, d_hash) {
@@ -1396,8 +1406,8 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
 
                /*
                 * Recheck the dentry after taking the lock - d_move may have
-                * changed things.  Don't bother checking the hash because we're
-                * about to compare the whole name anyway.
+                * changed things. Don't bother checking the hash because
+                * we're about to compare the whole name anyway.
                 */
                if (dentry->d_parent != parent)
                        goto next;
@@ -1925,7 +1935,7 @@ static int prepend_path(const struct path *path, struct path *root,
        bool slash = false;
        int error = 0;
 
-       spin_lock(&vfsmount_lock);
+       br_read_lock(vfsmount_lock);
        while (dentry != root->dentry || vfsmnt != root->mnt) {
                struct dentry * parent;
 
@@ -1954,7 +1964,7 @@ out:
        if (!error && !slash)
                error = prepend(buffer, buflen, "/", 1);
 
-       spin_unlock(&vfsmount_lock);
+       br_read_unlock(vfsmount_lock);
        return error;
 
 global_root:
@@ -2292,11 +2302,12 @@ int path_is_under(struct path *path1, struct path *path2)
        struct vfsmount *mnt = path1->mnt;
        struct dentry *dentry = path1->dentry;
        int res;
-       spin_lock(&vfsmount_lock);
+
+       br_read_lock(vfsmount_lock);
        if (mnt != path2->mnt) {
                for (;;) {
                        if (mnt->mnt_parent == mnt) {
-                               spin_unlock(&vfsmount_lock);
+                               br_read_unlock(vfsmount_lock);
                                return 0;
                        }
                        if (mnt->mnt_parent == path2->mnt)
@@ -2306,7 +2317,7 @@ int path_is_under(struct path *path1, struct path *path2)
                dentry = mnt->mnt_mountpoint;
        }
        res = is_subdir(dentry, path2->dentry);
-       spin_unlock(&vfsmount_lock);
+       br_read_unlock(vfsmount_lock);
        return res;
 }
 EXPORT_SYMBOL(path_is_under);
index 7761837e4500f0c3fee3c3dd51427dcd6adef82a..2d9455282744bce582e48e0ecec4f4a6d332a28c 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -361,13 +361,13 @@ err:
 /*
  * count() counts the number of strings in array ARGV.
  */
-static int count(char __user * __user * argv, int max)
+static int count(const char __user * const __user * argv, int max)
 {
        int i = 0;
 
        if (argv != NULL) {
                for (;;) {
-                       char __user * p;
+                       const char __user * p;
 
                        if (get_user(p, argv))
                                return -EFAULT;
@@ -387,7 +387,7 @@ static int count(char __user * __user * argv, int max)
  * processes's memory to the new process's stack.  The call to get_user_pages()
  * ensures the destination page is created and not swapped out.
  */
-static int copy_strings(int argc, char __user * __user * argv,
+static int copy_strings(int argc, const char __user *const __user *argv,
                        struct linux_binprm *bprm)
 {
        struct page *kmapped_page = NULL;
@@ -396,7 +396,7 @@ static int copy_strings(int argc, char __user * __user * argv,
        int ret;
 
        while (argc-- > 0) {
-               char __user *str;
+               const char __user *str;
                int len;
                unsigned long pos;
 
@@ -470,12 +470,13 @@ out:
 /*
  * Like copy_strings, but get argv and its values from kernel memory.
  */
-int copy_strings_kernel(int argc,char ** argv, struct linux_binprm *bprm)
+int copy_strings_kernel(int argc, const char *const *argv,
+                       struct linux_binprm *bprm)
 {
        int r;
        mm_segment_t oldfs = get_fs();
        set_fs(KERNEL_DS);
-       r = copy_strings(argc, (char __user * __user *)argv, bprm);
+       r = copy_strings(argc, (const char __user *const  __user *)argv, bprm);
        set_fs(oldfs);
        return r;
 }
@@ -997,7 +998,7 @@ EXPORT_SYMBOL(flush_old_exec);
 void setup_new_exec(struct linux_binprm * bprm)
 {
        int i, ch;
-       char * name;
+       const char *name;
        char tcomm[sizeof(current->comm)];
 
        arch_pick_mmap_layout(current->mm);
@@ -1117,7 +1118,7 @@ int check_unsafe_exec(struct linux_binprm *bprm)
        bprm->unsafe = tracehook_unsafe_exec(p);
 
        n_fs = 1;
-       write_lock(&p->fs->lock);
+       spin_lock(&p->fs->lock);
        rcu_read_lock();
        for (t = next_thread(p); t != p; t = next_thread(t)) {
                if (t->fs == p->fs)
@@ -1134,7 +1135,7 @@ int check_unsafe_exec(struct linux_binprm *bprm)
                        res = 1;
                }
        }
-       write_unlock(&p->fs->lock);
+       spin_unlock(&p->fs->lock);
 
        return res;
 }
@@ -1316,9 +1317,9 @@ EXPORT_SYMBOL(search_binary_handler);
 /*
  * sys_execve() executes a new program.
  */
-int do_execve(char * filename,
-       char __user *__user *argv,
-       char __user *__user *envp,
+int do_execve(const char * filename,
+       const char __user *const __user *argv,
+       const char __user *const __user *envp,
        struct pt_regs * regs)
 {
        struct linux_binprm *bprm;
index 1fa23f6ffba5b39a9921bc6f0b5eac0bfd46fecb..1736f23563888b2f0225a6add77d45c984270231 100644 (file)
@@ -250,7 +250,9 @@ int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
 {
        int i, err = 0;
 
-       ll_rw_block(SWRITE, nr_bhs, bhs);
+       for (i = 0; i < nr_bhs; i++)
+               write_dirty_buffer(bhs[i], WRITE);
+
        for (i = 0; i < nr_bhs; i++) {
                wait_on_buffer(bhs[i]);
                if (buffer_eopnotsupp(bhs[i])) {
index edecd36fed9bdcf7f49411a3bcf2f97283bd077b..a04bdd81c11ca3799d4429d8c5eb3579621e0628 100644 (file)
@@ -20,7 +20,9 @@
 #include <linux/cdev.h>
 #include <linux/fsnotify.h>
 #include <linux/sysctl.h>
+#include <linux/lglock.h>
 #include <linux/percpu_counter.h>
+#include <linux/percpu.h>
 #include <linux/ima.h>
 
 #include <asm/atomic.h>
@@ -32,8 +34,8 @@ struct files_stat_struct files_stat = {
        .max_files = NR_FILE
 };
 
-/* public. Not pretty! */
-__cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock);
+DECLARE_LGLOCK(files_lglock);
+DEFINE_LGLOCK(files_lglock);
 
 /* SLAB cache for file structures */
 static struct kmem_cache *filp_cachep __read_mostly;
@@ -249,7 +251,7 @@ static void __fput(struct file *file)
                cdev_put(inode->i_cdev);
        fops_put(file->f_op);
        put_pid(file->f_owner.pid);
-       file_kill(file);
+       file_sb_list_del(file);
        if (file->f_mode & FMODE_WRITE)
                drop_file_write_access(file);
        file->f_path.dentry = NULL;
@@ -328,41 +330,107 @@ struct file *fget_light(unsigned int fd, int *fput_needed)
        return file;
 }
 
-
 void put_filp(struct file *file)
 {
        if (atomic_long_dec_and_test(&file->f_count)) {
                security_file_free(file);
-               file_kill(file);
+               file_sb_list_del(file);
                file_free(file);
        }
 }
 
-void file_move(struct file *file, struct list_head *list)
+static inline int file_list_cpu(struct file *file)
 {
-       if (!list)
-               return;
-       file_list_lock();
-       list_move(&file->f_u.fu_list, list);
-       file_list_unlock();
+#ifdef CONFIG_SMP
+       return file->f_sb_list_cpu;
+#else
+       return smp_processor_id();
+#endif
+}
+
+/* helper for file_sb_list_add to reduce ifdefs */
+static inline void __file_sb_list_add(struct file *file, struct super_block *sb)
+{
+       struct list_head *list;
+#ifdef CONFIG_SMP
+       int cpu;
+       cpu = smp_processor_id();
+       file->f_sb_list_cpu = cpu;
+       list = per_cpu_ptr(sb->s_files, cpu);
+#else
+       list = &sb->s_files;
+#endif
+       list_add(&file->f_u.fu_list, list);
 }
 
-void file_kill(struct file *file)
+/**
+ * file_sb_list_add - add a file to the sb's file list
+ * @file: file to add
+ * @sb: sb to add it to
+ *
+ * Use this function to associate a file with the superblock of the inode it
+ * refers to.
+ */
+void file_sb_list_add(struct file *file, struct super_block *sb)
+{
+       lg_local_lock(files_lglock);
+       __file_sb_list_add(file, sb);
+       lg_local_unlock(files_lglock);
+}
+
+/**
+ * file_sb_list_del - remove a file from the sb's file list
+ * @file: file to remove
+ * @sb: sb to remove it from
+ *
+ * Use this function to remove a file from its superblock.
+ */
+void file_sb_list_del(struct file *file)
 {
        if (!list_empty(&file->f_u.fu_list)) {
-               file_list_lock();
+               lg_local_lock_cpu(files_lglock, file_list_cpu(file));
                list_del_init(&file->f_u.fu_list);
-               file_list_unlock();
+               lg_local_unlock_cpu(files_lglock, file_list_cpu(file));
        }
 }
 
+#ifdef CONFIG_SMP
+
+/*
+ * These macros iterate all files on all CPUs for a given superblock.
+ * files_lglock must be held globally.
+ */
+#define do_file_list_for_each_entry(__sb, __file)              \
+{                                                              \
+       int i;                                                  \
+       for_each_possible_cpu(i) {                              \
+               struct list_head *list;                         \
+               list = per_cpu_ptr((__sb)->s_files, i);         \
+               list_for_each_entry((__file), list, f_u.fu_list)
+
+#define while_file_list_for_each_entry                         \
+       }                                                       \
+}
+
+#else
+
+#define do_file_list_for_each_entry(__sb, __file)              \
+{                                                              \
+       struct list_head *list;                                 \
+       list = &(sb)->s_files;                                  \
+       list_for_each_entry((__file), list, f_u.fu_list)
+
+#define while_file_list_for_each_entry                         \
+}
+
+#endif
+
 int fs_may_remount_ro(struct super_block *sb)
 {
        struct file *file;
-
        /* Check that no files are currently opened for writing. */
-       file_list_lock();
-       list_for_each_entry(file, &sb->s_files, f_u.fu_list) {
+       lg_global_lock(files_lglock);
+       do_file_list_for_each_entry(sb, file) {
                struct inode *inode = file->f_path.dentry->d_inode;
 
                /* File with pending delete? */
@@ -372,11 +440,11 @@ int fs_may_remount_ro(struct super_block *sb)
                /* Writeable file? */
                if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE))
                        goto too_bad;
-       }
-       file_list_unlock();
+       } while_file_list_for_each_entry;
+       lg_global_unlock(files_lglock);
        return 1; /* Tis' cool bro. */
 too_bad:
-       file_list_unlock();
+       lg_global_unlock(files_lglock);
        return 0;
 }
 
@@ -392,8 +460,8 @@ void mark_files_ro(struct super_block *sb)
        struct file *f;
 
 retry:
-       file_list_lock();
-       list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
+       lg_global_lock(files_lglock);
+       do_file_list_for_each_entry(sb, f) {
                struct vfsmount *mnt;
                if (!S_ISREG(f->f_path.dentry->d_inode->i_mode))
                       continue;
@@ -408,16 +476,13 @@ retry:
                        continue;
                file_release_write(f);
                mnt = mntget(f->f_path.mnt);
-               file_list_unlock();
-               /*
-                * This can sleep, so we can't hold
-                * the file_list_lock() spinlock.
-                */
+               /* This can sleep, so we can't hold the spinlock. */
+               lg_global_unlock(files_lglock);
                mnt_drop_write(mnt);
                mntput(mnt);
                goto retry;
-       }
-       file_list_unlock();
+       } while_file_list_for_each_entry;
+       lg_global_unlock(files_lglock);
 }
 
 void __init files_init(unsigned long mempages)
@@ -437,5 +502,6 @@ void __init files_init(unsigned long mempages)
        if (files_stat.max_files < NR_FILE)
                files_stat.max_files = NR_FILE;
        files_defer_init();
+       lg_lock_init(files_lglock);
        percpu_counter_init(&nr_files, 0);
 } 
index 1ee40eb9a2c05cc1751828af612c6942758b4c72..ed45a9cf5f3de46ae08e90d581a500bed9eb4dbf 100644 (file)
@@ -13,11 +13,11 @@ void set_fs_root(struct fs_struct *fs, struct path *path)
 {
        struct path old_root;
 
-       write_lock(&fs->lock);
+       spin_lock(&fs->lock);
        old_root = fs->root;
        fs->root = *path;
        path_get(path);
-       write_unlock(&fs->lock);
+       spin_unlock(&fs->lock);
        if (old_root.dentry)
                path_put(&old_root);
 }
@@ -30,11 +30,11 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
 {
        struct path old_pwd;
 
-       write_lock(&fs->lock);
+       spin_lock(&fs->lock);
        old_pwd = fs->pwd;
        fs->pwd = *path;
        path_get(path);
-       write_unlock(&fs->lock);
+       spin_unlock(&fs->lock);
 
        if (old_pwd.dentry)
                path_put(&old_pwd);
@@ -51,7 +51,7 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root)
                task_lock(p);
                fs = p->fs;
                if (fs) {
-                       write_lock(&fs->lock);
+                       spin_lock(&fs->lock);
                        if (fs->root.dentry == old_root->dentry
                            && fs->root.mnt == old_root->mnt) {
                                path_get(new_root);
@@ -64,7 +64,7 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root)
                                fs->pwd = *new_root;
                                count++;
                        }
-                       write_unlock(&fs->lock);
+                       spin_unlock(&fs->lock);
                }
                task_unlock(p);
        } while_each_thread(g, p);
@@ -87,10 +87,10 @@ void exit_fs(struct task_struct *tsk)
        if (fs) {
                int kill;
                task_lock(tsk);
-               write_lock(&fs->lock);
+               spin_lock(&fs->lock);
                tsk->fs = NULL;
                kill = !--fs->users;
-               write_unlock(&fs->lock);
+               spin_unlock(&fs->lock);
                task_unlock(tsk);
                if (kill)
                        free_fs_struct(fs);
@@ -104,7 +104,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
        if (fs) {
                fs->users = 1;
                fs->in_exec = 0;
-               rwlock_init(&fs->lock);
+               spin_lock_init(&fs->lock);
                fs->umask = old->umask;
                get_fs_root_and_pwd(old, &fs->root, &fs->pwd);
        }
@@ -121,10 +121,10 @@ int unshare_fs_struct(void)
                return -ENOMEM;
 
        task_lock(current);
-       write_lock(&fs->lock);
+       spin_lock(&fs->lock);
        kill = !--fs->users;
        current->fs = new_fs;
-       write_unlock(&fs->lock);
+       spin_unlock(&fs->lock);
        task_unlock(current);
 
        if (kill)
@@ -143,7 +143,7 @@ EXPORT_SYMBOL(current_umask);
 /* to be mentioned only in INIT_TASK */
 struct fs_struct init_fs = {
        .users          = 1,
-       .lock           = __RW_LOCK_UNLOCKED(init_fs.lock),
+       .lock           = __SPIN_LOCK_UNLOCKED(init_fs.lock),
        .umask          = 0022,
 };
 
@@ -156,14 +156,14 @@ void daemonize_fs_struct(void)
 
                task_lock(current);
 
-               write_lock(&init_fs.lock);
+               spin_lock(&init_fs.lock);
                init_fs.users++;
-               write_unlock(&init_fs.lock);
+               spin_unlock(&init_fs.lock);
 
-               write_lock(&fs->lock);
+               spin_lock(&fs->lock);
                current->fs = &init_fs;
                kill = !--fs->users;
-               write_unlock(&fs->lock);
+               spin_unlock(&fs->lock);
 
                task_unlock(current);
                if (kill)
index 99800e564157ed5d3bb78b6e80c6d7f5b7d32051..6bc9e3a5a693b0fa2d5d8f09349f42b9d44ea72f 100644 (file)
@@ -94,6 +94,7 @@ generic_acl_set(struct dentry *dentry, const char *name, const void *value,
                        if (error < 0)
                                goto failed;
                        inode->i_mode = mode;
+                       inode->i_ctime = CURRENT_TIME;
                        if (error == 0) {
                                posix_acl_release(acl);
                                acl = NULL;
index dd1e55535a4e8a65e4405a2419d1a9bcde389f8c..f7dc9b5f9ef8c80560cb545d937aa9818a3b646f 100644 (file)
@@ -104,7 +104,7 @@ static char *__dentry_name(struct dentry *dentry, char *name)
                __putname(name);
                return NULL;
        }
-       strncpy(name, root, PATH_MAX);
+       strlcpy(name, root, PATH_MAX);
        if (len > p - name) {
                __putname(name);
                return NULL;
@@ -876,7 +876,7 @@ static void *hostfs_follow_link(struct dentry *dentry, struct nameidata *nd)
                char *path = dentry_name(dentry);
                int err = -ENOMEM;
                if (path) {
-                       int err = hostfs_do_readlink(path, link, PATH_MAX);
+                       err = hostfs_do_readlink(path, link, PATH_MAX);
                        if (err == PATH_MAX)
                                err = -E2BIG;
                        __putname(path);
index 6b706bc60a66bbb3cecb7477f2ea72e0a091aa84..a6910e91cee8799196e991c7cab98ad11206cf01 100644 (file)
@@ -9,6 +9,8 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/lglock.h>
+
 struct super_block;
 struct linux_binprm;
 struct path;
@@ -70,7 +72,8 @@ extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
 
 extern void __init mnt_init(void);
 
-extern spinlock_t vfsmount_lock;
+DECLARE_BRLOCK(vfsmount_lock);
+
 
 /*
  * fs_struct.c
@@ -80,6 +83,8 @@ extern void chroot_fs_refs(struct path *, struct path *);
 /*
  * file_table.c
  */
+extern void file_sb_list_add(struct file *f, struct super_block *sb);
+extern void file_sb_list_del(struct file *f);
 extern void mark_files_ro(struct super_block *);
 extern struct file *get_empty_filp(void);
 
index b0435dd0654d16acce790332fbb258ed378a14d3..05a38b9c4c0ecbe749ef73931933c0e089fe15ba 100644 (file)
@@ -254,7 +254,9 @@ __flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count)
 {
        int i;
 
-       ll_rw_block(SWRITE, *batch_count, bhs);
+       for (i = 0; i < *batch_count; i++)
+               write_dirty_buffer(bhs[i], WRITE);
+
        for (i = 0; i < *batch_count; i++) {
                struct buffer_head *bh = bhs[i];
                clear_buffer_jwrite(bh);
index 28a9ddaa0c496f85625ccab2d543fc5e0886872b..95d8c11c929ea3563b72f69e130674d6f49d5162 100644 (file)
@@ -119,7 +119,6 @@ static int journal_write_commit_record(journal_t *journal,
        struct buffer_head *bh;
        journal_header_t *header;
        int ret;
-       int barrier_done = 0;
 
        if (is_journal_aborted(journal))
                return 0;
@@ -137,34 +136,36 @@ static int journal_write_commit_record(journal_t *journal,
 
        JBUFFER_TRACE(descriptor, "write commit block");
        set_buffer_dirty(bh);
+
        if (journal->j_flags & JFS_BARRIER) {
-               set_buffer_ordered(bh);
-               barrier_done = 1;
-       }
-       ret = sync_dirty_buffer(bh);
-       if (barrier_done)
-               clear_buffer_ordered(bh);
-       /* is it possible for another commit to fail at roughly
-        * the same time as this one?  If so, we don't want to
-        * trust the barrier flag in the super, but instead want
-        * to remember if we sent a barrier request
-        */
-       if (ret == -EOPNOTSUPP && barrier_done) {
-               char b[BDEVNAME_SIZE];
+               ret = __sync_dirty_buffer(bh, WRITE_SYNC | WRITE_BARRIER);
 
-               printk(KERN_WARNING
-                       "JBD: barrier-based sync failed on %s - "
-                       "disabling barriers\n",
-                       bdevname(journal->j_dev, b));
-               spin_lock(&journal->j_state_lock);
-               journal->j_flags &= ~JFS_BARRIER;
-               spin_unlock(&journal->j_state_lock);
+               /*
+                * Is it possible for another commit to fail at roughly
+                * the same time as this one?  If so, we don't want to
+                * trust the barrier flag in the super, but instead want
+                * to remember if we sent a barrier request
+                */
+               if (ret == -EOPNOTSUPP) {
+                       char b[BDEVNAME_SIZE];
 
-               /* And try again, without the barrier */
-               set_buffer_uptodate(bh);
-               set_buffer_dirty(bh);
+                       printk(KERN_WARNING
+                               "JBD: barrier-based sync failed on %s - "
+                               "disabling barriers\n",
+                               bdevname(journal->j_dev, b));
+                       spin_lock(&journal->j_state_lock);
+                       journal->j_flags &= ~JFS_BARRIER;
+                       spin_unlock(&journal->j_state_lock);
+
+                       /* And try again, without the barrier */
+                       set_buffer_uptodate(bh);
+                       set_buffer_dirty(bh);
+                       ret = sync_dirty_buffer(bh);
+               }
+       } else {
                ret = sync_dirty_buffer(bh);
        }
+
        put_bh(bh);             /* One for getblk() */
        journal_put_journal_head(descriptor);
 
index f19ce94693d848e60ea9e34164a1c75cb56618ea..2c4b1f109da9e6bc3bcedddd423f02cb84c6bc2f 100644 (file)
@@ -1024,7 +1024,7 @@ void journal_update_superblock(journal_t *journal, int wait)
        if (wait)
                sync_dirty_buffer(bh);
        else
-               ll_rw_block(SWRITE, 1, &bh);
+               write_dirty_buffer(bh, WRITE);
 
 out:
        /* If we have just flushed the log (by marking s_start==0), then
index ad717328343acc9e1c2c66ed758c14d2aaffbe2c..d29018307e2e9cca4b97409036d18f4b9421bcac 100644 (file)
@@ -617,7 +617,7 @@ static void flush_descriptor(journal_t *journal,
        set_buffer_jwrite(bh);
        BUFFER_TRACE(bh, "write");
        set_buffer_dirty(bh);
-       ll_rw_block((write_op == WRITE) ? SWRITE : SWRITE_SYNC_PLUG, 1, &bh);
+       write_dirty_buffer(bh, write_op);
 }
 #endif
 
index 1c23a0f4e8a35021a3c291fa3407b976fdbb34a3..5247e7ffdcb46d400e10681535a5728ef8006ad8 100644 (file)
@@ -255,7 +255,9 @@ __flush_batch(journal_t *journal, int *batch_count)
 {
        int i;
 
-       ll_rw_block(SWRITE, *batch_count, journal->j_chkpt_bhs);
+       for (i = 0; i < *batch_count; i++)
+               write_dirty_buffer(journal->j_chkpt_bhs[i], WRITE);
+
        for (i = 0; i < *batch_count; i++) {
                struct buffer_head *bh = journal->j_chkpt_bhs[i];
                clear_buffer_jwrite(bh);
index f52e5e8049f195ec461bfb8781584722b5da2562..7c068c189d80d713d56705e63c5b5e0bf6982ab9 100644 (file)
@@ -101,7 +101,6 @@ static int journal_submit_commit_record(journal_t *journal,
        struct commit_header *tmp;
        struct buffer_head *bh;
        int ret;
-       int barrier_done = 0;
        struct timespec now = current_kernel_time();
 
        if (is_journal_aborted(journal))
@@ -136,30 +135,22 @@ static int journal_submit_commit_record(journal_t *journal,
        if (journal->j_flags & JBD2_BARRIER &&
            !JBD2_HAS_INCOMPAT_FEATURE(journal,
                                       JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
-               set_buffer_ordered(bh);
-               barrier_done = 1;
-       }
-       ret = submit_bh(WRITE_SYNC_PLUG, bh);
-       if (barrier_done)
-               clear_buffer_ordered(bh);
-
-       /* is it possible for another commit to fail at roughly
-        * the same time as this one?  If so, we don't want to
-        * trust the barrier flag in the super, but instead want
-        * to remember if we sent a barrier request
-        */
-       if (ret == -EOPNOTSUPP && barrier_done) {
-               printk(KERN_WARNING
-                      "JBD2: Disabling barriers on %s, "
-                      "not supported by device\n", journal->j_devname);
-               write_lock(&journal->j_state_lock);
-               journal->j_flags &= ~JBD2_BARRIER;
-               write_unlock(&journal->j_state_lock);
+               ret = submit_bh(WRITE_SYNC_PLUG | WRITE_BARRIER, bh);
+               if (ret == -EOPNOTSUPP) {
+                       printk(KERN_WARNING
+                              "JBD2: Disabling barriers on %s, "
+                              "not supported by device\n", journal->j_devname);
+                       write_lock(&journal->j_state_lock);
+                       journal->j_flags &= ~JBD2_BARRIER;
+                       write_unlock(&journal->j_state_lock);
 
-               /* And try again, without the barrier */
-               lock_buffer(bh);
-               set_buffer_uptodate(bh);
-               clear_buffer_dirty(bh);
+                       /* And try again, without the barrier */
+                       lock_buffer(bh);
+                       set_buffer_uptodate(bh);
+                       clear_buffer_dirty(bh);
+                       ret = submit_bh(WRITE_SYNC_PLUG, bh);
+               }
+       } else {
                ret = submit_bh(WRITE_SYNC_PLUG, bh);
        }
        *cbh = bh;
index ad5866aaf0f9aa88cc114fb915e1888f393ffdbb..0e8014ea6b94ad8985f1b0b842f2cea550578e67 100644 (file)
@@ -1124,7 +1124,7 @@ void jbd2_journal_update_superblock(journal_t *journal, int wait)
                        set_buffer_uptodate(bh);
                }
        } else
-               ll_rw_block(SWRITE, 1, &bh);
+               write_dirty_buffer(bh, WRITE);
 
 out:
        /* If we have just flushed the log (by marking s_start==0), then
index a360b06af2e3b488933cfd5450c9af6b3f3db36f..9ad321fd63fdf73b4d7aa99ee5c78c6edbad9da4 100644 (file)
@@ -625,7 +625,7 @@ static void flush_descriptor(journal_t *journal,
        set_buffer_jwrite(bh);
        BUFFER_TRACE(bh, "write");
        set_buffer_dirty(bh);
-       ll_rw_block((write_op == WRITE) ? SWRITE : SWRITE_SYNC_PLUG, 1, &bh);
+       write_dirty_buffer(bh, write_op);
 }
 #endif
 
index cf4e6cdfd15b5afc091c0f2a060af90450176811..93444747237b98c03d5192870bd9740311da93f7 100644 (file)
@@ -80,6 +80,7 @@ struct mb_cache {
        struct list_head                c_cache_list;
        const char                      *c_name;
        atomic_t                        c_entry_count;
+       int                             c_max_entries;
        int                             c_bucket_bits;
        struct kmem_cache               *c_entry_cache;
        struct list_head                *c_block_hash;
@@ -243,6 +244,12 @@ mb_cache_create(const char *name, int bucket_bits)
        if (!cache->c_entry_cache)
                goto fail2;
 
+       /*
+        * Set an upper limit on the number of cache entries so that the hash
+        * chains won't grow too long.
+        */
+       cache->c_max_entries = bucket_count << 4;
+
        spin_lock(&mb_cache_spinlock);
        list_add(&cache->c_cache_list, &mb_cache_list);
        spin_unlock(&mb_cache_spinlock);
@@ -333,7 +340,6 @@ mb_cache_destroy(struct mb_cache *cache)
        kfree(cache);
 }
 
-
 /*
  * mb_cache_entry_alloc()
  *
@@ -345,17 +351,29 @@ mb_cache_destroy(struct mb_cache *cache)
 struct mb_cache_entry *
 mb_cache_entry_alloc(struct mb_cache *cache, gfp_t gfp_flags)
 {
-       struct mb_cache_entry *ce;
-
-       ce = kmem_cache_alloc(cache->c_entry_cache, gfp_flags);
-       if (ce) {
+       struct mb_cache_entry *ce = NULL;
+
+       if (atomic_read(&cache->c_entry_count) >= cache->c_max_entries) {
+               spin_lock(&mb_cache_spinlock);
+               if (!list_empty(&mb_cache_lru_list)) {
+                       ce = list_entry(mb_cache_lru_list.next,
+                                       struct mb_cache_entry, e_lru_list);
+                       list_del_init(&ce->e_lru_list);
+                       __mb_cache_entry_unhash(ce);
+               }
+               spin_unlock(&mb_cache_spinlock);
+       }
+       if (!ce) {
+               ce = kmem_cache_alloc(cache->c_entry_cache, gfp_flags);
+               if (!ce)
+                       return NULL;
                atomic_inc(&cache->c_entry_count);
                INIT_LIST_HEAD(&ce->e_lru_list);
                INIT_LIST_HEAD(&ce->e_block_list);
                ce->e_cache = cache;
-               ce->e_used = 1 + MB_CACHE_WRITER;
                ce->e_queued = 0;
        }
+       ce->e_used = 1 + MB_CACHE_WRITER;
        return ce;
 }
 
index 17ea76bf2fbee41e9ff8a20616e0523781ed2315..24896e8335658c9c0ce2c81c117cb664b964da70 100644 (file)
@@ -595,15 +595,16 @@ int follow_up(struct path *path)
 {
        struct vfsmount *parent;
        struct dentry *mountpoint;
-       spin_lock(&vfsmount_lock);
+
+       br_read_lock(vfsmount_lock);
        parent = path->mnt->mnt_parent;
        if (parent == path->mnt) {
-               spin_unlock(&vfsmount_lock);
+               br_read_unlock(vfsmount_lock);
                return 0;
        }
        mntget(parent);
        mountpoint = dget(path->mnt->mnt_mountpoint);
-       spin_unlock(&vfsmount_lock);
+       br_read_unlock(vfsmount_lock);
        dput(path->dentry);
        path->dentry = mountpoint;
        mntput(path->mnt);
@@ -685,6 +686,35 @@ static __always_inline void follow_dotdot(struct nameidata *nd)
        follow_mount(&nd->path);
 }
 
+/*
+ * Allocate a dentry with name and parent, and perform a parent
+ * directory ->lookup on it. Returns the new dentry, or ERR_PTR
+ * on error. parent->d_inode->i_mutex must be held. d_lookup must
+ * have verified that no child exists while under i_mutex.
+ */
+static struct dentry *d_alloc_and_lookup(struct dentry *parent,
+                               struct qstr *name, struct nameidata *nd)
+{
+       struct inode *inode = parent->d_inode;
+       struct dentry *dentry;
+       struct dentry *old;
+
+       /* Don't create child dentry for a dead directory. */
+       if (unlikely(IS_DEADDIR(inode)))
+               return ERR_PTR(-ENOENT);
+
+       dentry = d_alloc(parent, name);
+       if (unlikely(!dentry))
+               return ERR_PTR(-ENOMEM);
+
+       old = inode->i_op->lookup(inode, dentry, nd);
+       if (unlikely(old)) {
+               dput(dentry);
+               dentry = old;
+       }
+       return dentry;
+}
+
 /*
  *  It's more convoluted than I'd like it to be, but... it's still fairly
  *  small and for now I'd prefer to have fast path as straight as possible.
@@ -706,9 +736,15 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
                        return err;
        }
 
+       /*
+        * Rename seqlock is not required here because in the off chance
+        * of a false negative due to a concurrent rename, we're going to
+        * do the non-racy lookup, below.
+        */
        dentry = __d_lookup(nd->path.dentry, name);
        if (!dentry)
                goto need_lookup;
+found:
        if (dentry->d_op && dentry->d_op->d_revalidate)
                goto need_revalidate;
 done:
@@ -724,56 +760,28 @@ need_lookup:
        mutex_lock(&dir->i_mutex);
        /*
         * First re-do the cached lookup just in case it was created
-        * while we waited for the directory semaphore..
+        * while we waited for the directory semaphore, or the first
+        * lookup failed due to an unrelated rename.
         *
-        * FIXME! This could use version numbering or similar to
-        * avoid unnecessary cache lookups.
-        *
-        * The "dcache_lock" is purely to protect the RCU list walker
-        * from concurrent renames at this point (we mustn't get false
-        * negatives from the RCU list walk here, unlike the optimistic
-        * fast walk).
-        *
-        * so doing d_lookup() (with seqlock), instead of lockfree __d_lookup
+        * This could use version numbering or similar to avoid unnecessary
+        * cache lookups, but then we'd have to do the first lookup in the
+        * non-racy way. However in the common case here, everything should
+        * be hot in cache, so would it be a big win?
         */
        dentry = d_lookup(parent, name);
-       if (!dentry) {
-               struct dentry *new;
-
-               /* Don't create child dentry for a dead directory. */
-               dentry = ERR_PTR(-ENOENT);
-               if (IS_DEADDIR(dir))
-                       goto out_unlock;
-
-               new = d_alloc(parent, name);
-               dentry = ERR_PTR(-ENOMEM);
-               if (new) {
-                       dentry = dir->i_op->lookup(dir, new, nd);
-                       if (dentry)
-                               dput(new);
-                       else
-                               dentry = new;
-               }
-out_unlock:
+       if (likely(!dentry)) {
+               dentry = d_alloc_and_lookup(parent, name, nd);
                mutex_unlock(&dir->i_mutex);
                if (IS_ERR(dentry))
                        goto fail;
                goto done;
        }
-
        /*
         * Uhhuh! Nasty case: the cache was re-populated while
         * we waited on the semaphore. Need to revalidate.
         */
        mutex_unlock(&dir->i_mutex);
-       if (dentry->d_op && dentry->d_op->d_revalidate) {
-               dentry = do_revalidate(dentry, nd);
-               if (!dentry)
-                       dentry = ERR_PTR(-ENOENT);
-       }
-       if (IS_ERR(dentry))
-               goto fail;
-       goto done;
+       goto found;
 
 need_revalidate:
        dentry = do_revalidate(dentry, nd);
@@ -1130,35 +1138,18 @@ static struct dentry *__lookup_hash(struct qstr *name,
                        goto out;
        }
 
-       dentry = __d_lookup(base, name);
-
-       /* lockess __d_lookup may fail due to concurrent d_move()
-        * in some unrelated directory, so try with d_lookup
+       /*
+        * Don't bother with __d_lookup: callers are for creat as
+        * well as unlink, so a lot of the time it would cost
+        * a double lookup.
         */
-       if (!dentry)
-               dentry = d_lookup(base, name);
+       dentry = d_lookup(base, name);
 
        if (dentry && dentry->d_op && dentry->d_op->d_revalidate)
                dentry = do_revalidate(dentry, nd);
 
-       if (!dentry) {
-               struct dentry *new;
-
-               /* Don't create child dentry for a dead directory. */
-               dentry = ERR_PTR(-ENOENT);
-               if (IS_DEADDIR(inode))
-                       goto out;
-
-               new = d_alloc(base, name);
-               dentry = ERR_PTR(-ENOMEM);
-               if (!new)
-                       goto out;
-               dentry = inode->i_op->lookup(inode, new, nd);
-               if (!dentry)
-                       dentry = new;
-               else
-                       dput(new);
-       }
+       if (!dentry)
+               dentry = d_alloc_and_lookup(base, name, nd);
 out:
        return dentry;
 }
index 2e10cb19c5b02983e159bfe5f8039f3d08f3035d..de402eb6eafbad3df3957ca7b74ee92256c1e8c4 100644 (file)
@@ -11,6 +11,8 @@
 #include <linux/syscalls.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/percpu.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #define HASH_SHIFT ilog2(PAGE_SIZE / sizeof(struct list_head))
 #define HASH_SIZE (1UL << HASH_SHIFT)
 
-/* spinlock for vfsmount related operations, inplace of dcache_lock */
-__cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
-
 static int event;
 static DEFINE_IDA(mnt_id_ida);
 static DEFINE_IDA(mnt_group_ida);
+static DEFINE_SPINLOCK(mnt_id_lock);
 static int mnt_id_start = 0;
 static int mnt_group_start = 1;
 
@@ -55,6 +55,16 @@ static struct rw_semaphore namespace_sem;
 struct kobject *fs_kobj;
 EXPORT_SYMBOL_GPL(fs_kobj);
 
+/*
+ * vfsmount lock may be taken for read to prevent changes to the
+ * vfsmount hash, ie. during mountpoint lookups or walking back
+ * up the tree.
+ *
+ * It should be taken for write in all cases where the vfsmount
+ * tree or hash is modified or when a vfsmount structure is modified.
+ */
+DEFINE_BRLOCK(vfsmount_lock);
+
 static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
 {
        unsigned long tmp = ((unsigned long)mnt / L1_CACHE_BYTES);
@@ -65,18 +75,21 @@ static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
 
 #define MNT_WRITER_UNDERFLOW_LIMIT -(1<<16)
 
-/* allocation is serialized by namespace_sem */
+/*
+ * allocation is serialized by namespace_sem, but we need the spinlock to
+ * serialize with freeing.
+ */
 static int mnt_alloc_id(struct vfsmount *mnt)
 {
        int res;
 
 retry:
        ida_pre_get(&mnt_id_ida, GFP_KERNEL);
-       spin_lock(&vfsmount_lock);
+       spin_lock(&mnt_id_lock);
        res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
        if (!res)
                mnt_id_start = mnt->mnt_id + 1;
-       spin_unlock(&vfsmount_lock);
+       spin_unlock(&mnt_id_lock);
        if (res == -EAGAIN)
                goto retry;
 
@@ -86,11 +99,11 @@ retry:
 static void mnt_free_id(struct vfsmount *mnt)
 {
        int id = mnt->mnt_id;
-       spin_lock(&vfsmount_lock);
+       spin_lock(&mnt_id_lock);
        ida_remove(&mnt_id_ida, id);
        if (mnt_id_start > id)
                mnt_id_start = id;
-       spin_unlock(&vfsmount_lock);
+       spin_unlock(&mnt_id_lock);
 }
 
 /*
@@ -348,7 +361,7 @@ static int mnt_make_readonly(struct vfsmount *mnt)
 {
        int ret = 0;
 
-       spin_lock(&vfsmount_lock);
+       br_write_lock(vfsmount_lock);
        mnt->mnt_flags |= MNT_WRITE_HOLD;
        /*
         * After storing MNT_WRITE_HOLD, we'll read the counters. This store
@@ -382,15 +395,15 @@ static int mnt_make_readonly(struct vfsmount *mnt)
         */
        smp_wmb();
        mnt->mnt_flags &= ~MNT_WRITE_HOLD;
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
        return ret;
 }
 
 static void __mnt_unmake_readonly(struct vfsmount *mnt)
 {
-       spin_lock(&vfsmount_lock);
+       br_write_lock(vfsmount_lock);
        mnt->mnt_flags &= ~MNT_READONLY;
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
 }
 
 void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb)
@@ -414,6 +427,7 @@ void free_vfsmnt(struct vfsmount *mnt)
 /*
  * find the first or last mount at @dentry on vfsmount @mnt depending on
  * @dir. If @dir is set return the first mount else return the last mount.
+ * vfsmount_lock must be held for read or write.
  */
 struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
                              int dir)
@@ -443,10 +457,11 @@ struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
 struct vfsmount *lookup_mnt(struct path *path)
 {
        struct vfsmount *child_mnt;
-       spin_lock(&vfsmount_lock);
+
+       br_read_lock(vfsmount_lock);
        if ((child_mnt = __lookup_mnt(path->mnt, path->dentry, 1)))
                mntget(child_mnt);
-       spin_unlock(&vfsmount_lock);
+       br_read_unlock(vfsmount_lock);
        return child_mnt;
 }
 
@@ -455,6 +470,9 @@ static inline int check_mnt(struct vfsmount *mnt)
        return mnt->mnt_ns == current->nsproxy->mnt_ns;
 }
 
+/*
+ * vfsmount lock must be held for write
+ */
 static void touch_mnt_namespace(struct mnt_namespace *ns)
 {
        if (ns) {
@@ -463,6 +481,9 @@ static void touch_mnt_namespace(struct mnt_namespace *ns)
        }
 }
 
+/*
+ * vfsmount lock must be held for write
+ */
 static void __touch_mnt_namespace(struct mnt_namespace *ns)
 {
        if (ns && ns->event != event) {
@@ -471,6 +492,9 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns)
        }
 }
 
+/*
+ * vfsmount lock must be held for write
+ */
 static void detach_mnt(struct vfsmount *mnt, struct path *old_path)
 {
        old_path->dentry = mnt->mnt_mountpoint;
@@ -482,6 +506,9 @@ static void detach_mnt(struct vfsmount *mnt, struct path *old_path)
        old_path->dentry->d_mounted--;
 }
 
+/*
+ * vfsmount lock must be held for write
+ */
 void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
                        struct vfsmount *child_mnt)
 {
@@ -490,6 +517,9 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
        dentry->d_mounted++;
 }
 
+/*
+ * vfsmount lock must be held for write
+ */
 static void attach_mnt(struct vfsmount *mnt, struct path *path)
 {
        mnt_set_mountpoint(path->mnt, path->dentry, mnt);
@@ -499,7 +529,7 @@ static void attach_mnt(struct vfsmount *mnt, struct path *path)
 }
 
 /*
- * the caller must hold vfsmount_lock
+ * vfsmount lock must be held for write
  */
 static void commit_tree(struct vfsmount *mnt)
 {
@@ -623,39 +653,43 @@ static inline void __mntput(struct vfsmount *mnt)
 void mntput_no_expire(struct vfsmount *mnt)
 {
 repeat:
-       if (atomic_dec_and_lock(&mnt->mnt_count, &vfsmount_lock)) {
-               if (likely(!mnt->mnt_pinned)) {
-                       spin_unlock(&vfsmount_lock);
-                       __mntput(mnt);
-                       return;
-               }
-               atomic_add(mnt->mnt_pinned + 1, &mnt->mnt_count);
-               mnt->mnt_pinned = 0;
-               spin_unlock(&vfsmount_lock);
-               acct_auto_close_mnt(mnt);
-               goto repeat;
+       if (atomic_add_unless(&mnt->mnt_count, -1, 1))
+               return;
+       br_write_lock(vfsmount_lock);
+       if (!atomic_dec_and_test(&mnt->mnt_count)) {
+               br_write_unlock(vfsmount_lock);
+               return;
+       }
+       if (likely(!mnt->mnt_pinned)) {
+               br_write_unlock(vfsmount_lock);
+               __mntput(mnt);
+               return;
        }
+       atomic_add(mnt->mnt_pinned + 1, &mnt->mnt_count);
+       mnt->mnt_pinned = 0;
+       br_write_unlock(vfsmount_lock);
+       acct_auto_close_mnt(mnt);
+       goto repeat;
 }
-
 EXPORT_SYMBOL(mntput_no_expire);
 
 void mnt_pin(struct vfsmount *mnt)
 {
-       spin_lock(&vfsmount_lock);
+       br_write_lock(vfsmount_lock);
        mnt->mnt_pinned++;
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
 }
 
 EXPORT_SYMBOL(mnt_pin);
 
 void mnt_unpin(struct vfsmount *mnt)
 {
-       spin_lock(&vfsmount_lock);
+       br_write_lock(vfsmount_lock);
        if (mnt->mnt_pinned) {
                atomic_inc(&mnt->mnt_count);
                mnt->mnt_pinned--;
        }
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
 }
 
 EXPORT_SYMBOL(mnt_unpin);
@@ -746,12 +780,12 @@ int mnt_had_events(struct proc_mounts *p)
        struct mnt_namespace *ns = p->ns;
        int res = 0;
 
-       spin_lock(&vfsmount_lock);
+       br_read_lock(vfsmount_lock);
        if (p->event != ns->event) {
                p->event = ns->event;
                res = 1;
        }
-       spin_unlock(&vfsmount_lock);
+       br_read_unlock(vfsmount_lock);
 
        return res;
 }
@@ -952,12 +986,12 @@ int may_umount_tree(struct vfsmount *mnt)
        int minimum_refs = 0;
        struct vfsmount *p;
 
-       spin_lock(&vfsmount_lock);
+       br_read_lock(vfsmount_lock);
        for (p = mnt; p; p = next_mnt(p, mnt)) {
                actual_refs += atomic_read(&p->mnt_count);
                minimum_refs += 2;
        }
-       spin_unlock(&vfsmount_lock);
+       br_read_unlock(vfsmount_lock);
 
        if (actual_refs > minimum_refs)
                return 0;
@@ -984,10 +1018,10 @@ int may_umount(struct vfsmount *mnt)
 {
        int ret = 1;
        down_read(&namespace_sem);
-       spin_lock(&vfsmount_lock);
+       br_read_lock(vfsmount_lock);
        if (propagate_mount_busy(mnt, 2))
                ret = 0;
-       spin_unlock(&vfsmount_lock);
+       br_read_unlock(vfsmount_lock);
        up_read(&namespace_sem);
        return ret;
 }
@@ -1003,13 +1037,14 @@ void release_mounts(struct list_head *head)
                if (mnt->mnt_parent != mnt) {
                        struct dentry *dentry;
                        struct vfsmount *m;
-                       spin_lock(&vfsmount_lock);
+
+                       br_write_lock(vfsmount_lock);
                        dentry = mnt->mnt_mountpoint;
                        m = mnt->mnt_parent;
                        mnt->mnt_mountpoint = mnt->mnt_root;
                        mnt->mnt_parent = mnt;
                        m->mnt_ghosts--;
-                       spin_unlock(&vfsmount_lock);
+                       br_write_unlock(vfsmount_lock);
                        dput(dentry);
                        mntput(m);
                }
@@ -1017,6 +1052,10 @@ void release_mounts(struct list_head *head)
        }
 }
 
+/*
+ * vfsmount lock must be held for write
+ * namespace_sem must be held for write
+ */
 void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
 {
        struct vfsmount *p;
@@ -1107,7 +1146,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
        }
 
        down_write(&namespace_sem);
-       spin_lock(&vfsmount_lock);
+       br_write_lock(vfsmount_lock);
        event++;
 
        if (!(flags & MNT_DETACH))
@@ -1119,7 +1158,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
                        umount_tree(mnt, 1, &umount_list);
                retval = 0;
        }
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
        up_write(&namespace_sem);
        release_mounts(&umount_list);
        return retval;
@@ -1231,19 +1270,19 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
                        q = clone_mnt(p, p->mnt_root, flag);
                        if (!q)
                                goto Enomem;
-                       spin_lock(&vfsmount_lock);
+                       br_write_lock(vfsmount_lock);
                        list_add_tail(&q->mnt_list, &res->mnt_list);
                        attach_mnt(q, &path);
-                       spin_unlock(&vfsmount_lock);
+                       br_write_unlock(vfsmount_lock);
                }
        }
        return res;
 Enomem:
        if (res) {
                LIST_HEAD(umount_list);
-               spin_lock(&vfsmount_lock);
+               br_write_lock(vfsmount_lock);
                umount_tree(res, 0, &umount_list);
-               spin_unlock(&vfsmount_lock);
+               br_write_unlock(vfsmount_lock);
                release_mounts(&umount_list);
        }
        return NULL;
@@ -1262,9 +1301,9 @@ void drop_collected_mounts(struct vfsmount *mnt)
 {
        LIST_HEAD(umount_list);
        down_write(&namespace_sem);
-       spin_lock(&vfsmount_lock);
+       br_write_lock(vfsmount_lock);
        umount_tree(mnt, 0, &umount_list);
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
        up_write(&namespace_sem);
        release_mounts(&umount_list);
 }
@@ -1392,7 +1431,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
        if (err)
                goto out_cleanup_ids;
 
-       spin_lock(&vfsmount_lock);
+       br_write_lock(vfsmount_lock);
 
        if (IS_MNT_SHARED(dest_mnt)) {
                for (p = source_mnt; p; p = next_mnt(p, source_mnt))
@@ -1411,7 +1450,8 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
                list_del_init(&child->mnt_hash);
                commit_tree(child);
        }
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
+
        return 0;
 
  out_cleanup_ids:
@@ -1466,10 +1506,10 @@ static int do_change_type(struct path *path, int flag)
                        goto out_unlock;
        }
 
-       spin_lock(&vfsmount_lock);
+       br_write_lock(vfsmount_lock);
        for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
                change_mnt_propagation(m, type);
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
 
  out_unlock:
        up_write(&namespace_sem);
@@ -1513,9 +1553,10 @@ static int do_loopback(struct path *path, char *old_name,
        err = graft_tree(mnt, path);
        if (err) {
                LIST_HEAD(umount_list);
-               spin_lock(&vfsmount_lock);
+
+               br_write_lock(vfsmount_lock);
                umount_tree(mnt, 0, &umount_list);
-               spin_unlock(&vfsmount_lock);
+               br_write_unlock(vfsmount_lock);
                release_mounts(&umount_list);
        }
 
@@ -1568,16 +1609,16 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
        else
                err = do_remount_sb(sb, flags, data, 0);
        if (!err) {
-               spin_lock(&vfsmount_lock);
+               br_write_lock(vfsmount_lock);
                mnt_flags |= path->mnt->mnt_flags & MNT_PROPAGATION_MASK;
                path->mnt->mnt_flags = mnt_flags;
-               spin_unlock(&vfsmount_lock);
+               br_write_unlock(vfsmount_lock);
        }
        up_write(&sb->s_umount);
        if (!err) {
-               spin_lock(&vfsmount_lock);
+               br_write_lock(vfsmount_lock);
                touch_mnt_namespace(path->mnt->mnt_ns);
-               spin_unlock(&vfsmount_lock);
+               br_write_unlock(vfsmount_lock);
        }
        return err;
 }
@@ -1754,7 +1795,7 @@ void mark_mounts_for_expiry(struct list_head *mounts)
                return;
 
        down_write(&namespace_sem);
-       spin_lock(&vfsmount_lock);
+       br_write_lock(vfsmount_lock);
 
        /* extract from the expiration list every vfsmount that matches the
         * following criteria:
@@ -1773,7 +1814,7 @@ void mark_mounts_for_expiry(struct list_head *mounts)
                touch_mnt_namespace(mnt->mnt_ns);
                umount_tree(mnt, 1, &umounts);
        }
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
        up_write(&namespace_sem);
 
        release_mounts(&umounts);
@@ -1830,6 +1871,8 @@ resume:
 /*
  * process a list of expirable mountpoints with the intent of discarding any
  * submounts of a specific parent mountpoint
+ *
+ * vfsmount_lock must be held for write
  */
 static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts)
 {
@@ -2048,9 +2091,9 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
                kfree(new_ns);
                return ERR_PTR(-ENOMEM);
        }
-       spin_lock(&vfsmount_lock);
+       br_write_lock(vfsmount_lock);
        list_add_tail(&new_ns->list, &new_ns->root->mnt_list);
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
 
        /*
         * Second pass: switch the tsk->fs->* elements and mark new vfsmounts
@@ -2244,7 +2287,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
                goto out2; /* not attached */
        /* make sure we can reach put_old from new_root */
        tmp = old.mnt;
-       spin_lock(&vfsmount_lock);
+       br_write_lock(vfsmount_lock);
        if (tmp != new.mnt) {
                for (;;) {
                        if (tmp->mnt_parent == tmp)
@@ -2264,7 +2307,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
        /* mount new_root on / */
        attach_mnt(new.mnt, &root_parent);
        touch_mnt_namespace(current->nsproxy->mnt_ns);
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
        chroot_fs_refs(&root, &new);
        error = 0;
        path_put(&root_parent);
@@ -2279,7 +2322,7 @@ out1:
 out0:
        return error;
 out3:
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
        goto out2;
 }
 
@@ -2326,6 +2369,8 @@ void __init mnt_init(void)
        for (u = 0; u < HASH_SIZE; u++)
                INIT_LIST_HEAD(&mount_hashtable[u]);
 
+       br_lock_init(vfsmount_lock);
+
        err = sysfs_init();
        if (err)
                printk(KERN_WARNING "%s: sysfs_init error: %d\n",
@@ -2344,9 +2389,9 @@ void put_mnt_ns(struct mnt_namespace *ns)
        if (!atomic_dec_and_test(&ns->count))
                return;
        down_write(&namespace_sem);
-       spin_lock(&vfsmount_lock);
+       br_write_lock(vfsmount_lock);
        umount_tree(ns->root, 0, &umount_list);
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
        up_write(&namespace_sem);
        release_mounts(&umount_list);
        kfree(ns);
index 26a510a7be0908023eaa5848002eced097f6e9dc..6c2aad49d7318054b57c22b58c6b4eaa0be50178 100644 (file)
@@ -63,7 +63,6 @@ config NFS_V3_ACL
 config NFS_V4
        bool "NFS client support for NFS version 4"
        depends on NFS_FS
-       select RPCSEC_GSS_KRB5
        help
          This option enables support for version 4 of the NFS protocol
          (RFC 3530) in the kernel's NFS client.
index 29539ceeb745f8d19fa57816127eceed2c5d989d..e257172d438c08afe374c99fe0e7c80af51efe6c 100644 (file)
@@ -140,6 +140,13 @@ nfs_opendir(struct inode *inode, struct file *filp)
 
        /* Call generic open code in order to cache credentials */
        res = nfs_open(inode, filp);
+       if (filp->f_path.dentry == filp->f_path.mnt->mnt_root) {
+               /* This is a mountpoint, so d_revalidate will never
+                * have been called, so we need to refresh the
+                * inode (for close-open consistency) ourselves.
+                */
+               __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+       }
        return res;
 }
 
@@ -1103,7 +1110,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
        if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
                goto no_open_dput;
        /* We can't create new files, or truncate existing ones here */
-       openflags &= ~(O_CREAT|O_TRUNC);
+       openflags &= ~(O_CREAT|O_EXCL|O_TRUNC);
 
        /*
         * Note: we're not holding inode->i_mutex and so may be racing with
index 2d141a74ae82ec722d1efb799de168824b593722..eb51bd6201da0cd361d8265b4c6b0e3edee50ec9 100644 (file)
@@ -323,7 +323,7 @@ nfs_file_fsync(struct file *file, int datasync)
        have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
        if (have_error)
                ret = xchg(&ctx->error, 0);
-       if (!ret)
+       if (!ret && status < 0)
                ret = status;
        return ret;
 }
index 7ffbb98ddec34c405bde993b0df16873162e21b6..089da5b5d20a1621b1142dbf75f415251ea4cb4b 100644 (file)
@@ -2036,7 +2036,8 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
        struct rpc_cred *cred;
        struct nfs4_state *state;
        struct dentry *res;
-       fmode_t fmode = nd->intent.open.flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC);
+       int open_flags = nd->intent.open.flags;
+       fmode_t fmode = open_flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC);
 
        if (nd->flags & LOOKUP_CREATE) {
                attr.ia_mode = nd->intent.open.create_mode;
@@ -2044,8 +2045,9 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
                if (!IS_POSIXACL(dir))
                        attr.ia_mode &= ~current_umask();
        } else {
+               open_flags &= ~O_EXCL;
                attr.ia_valid = 0;
-               BUG_ON(nd->intent.open.flags & O_CREAT);
+               BUG_ON(open_flags & O_CREAT);
        }
 
        cred = rpc_lookup_cred();
@@ -2054,7 +2056,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
        parent = dentry->d_parent;
        /* Protect against concurrent sillydeletes */
        nfs_block_sillyrename(parent);
-       state = nfs4_do_open(dir, &path, fmode, nd->intent.open.flags, &attr, cred);
+       state = nfs4_do_open(dir, &path, fmode, open_flags, &attr, cred);
        put_rpccred(cred);
        if (IS_ERR(state)) {
                if (PTR_ERR(state) == -ENOENT) {
@@ -2273,8 +2275,7 @@ static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct
 out:
        if (page)
                __free_page(page);
-       if (locations)
-               kfree(locations);
+       kfree(locations);
        return status;
 }
 
index ee26316ad1f44eaf276299740c2a579635682fac..ec3966e4706b2f70d8709199f86456392a6e6584 100644 (file)
@@ -655,6 +655,13 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
 
        if (nfss->options & NFS_OPTION_FSCACHE)
                seq_printf(m, ",fsc");
+
+       if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) {
+               if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONE)
+                       seq_printf(m, ",lookupcache=none");
+               else
+                       seq_printf(m, ",lookupcache=pos");
+       }
 }
 
 /*
index 503b9da159a3d3def44ca3cb5d752d1020eb1e50..95932f523aef2b2b7ef4686b8bb4a18383b4a395 100644 (file)
@@ -69,7 +69,6 @@ config NFSD_V4
        depends on NFSD && PROC_FS && EXPERIMENTAL
        select NFSD_V3
        select FS_POSIX_ACL
-       select RPCSEC_GSS_KRB5
        help
          This option enables support in your system's NFS server for
          version 4 of the NFS protocol (RFC 3530).
index 1fa86b9df73b4c885190b6b3bbf95291b7630d4e..922263393c765664f6b5598f4c144093ec9e582c 100644 (file)
@@ -175,24 +175,24 @@ static int nilfs_sync_super(struct nilfs_sb_info *sbi, int flag)
 {
        struct the_nilfs *nilfs = sbi->s_nilfs;
        int err;
-       int barrier_done = 0;
 
-       if (nilfs_test_opt(sbi, BARRIER)) {
-               set_buffer_ordered(nilfs->ns_sbh[0]);
-               barrier_done = 1;
-       }
  retry:
        set_buffer_dirty(nilfs->ns_sbh[0]);
-       err = sync_dirty_buffer(nilfs->ns_sbh[0]);
-       if (err == -EOPNOTSUPP && barrier_done) {
-               nilfs_warning(sbi->s_super, __func__,
-                             "barrier-based sync failed. "
-                             "disabling barriers\n");
-               nilfs_clear_opt(sbi, BARRIER);
-               barrier_done = 0;
-               clear_buffer_ordered(nilfs->ns_sbh[0]);
-               goto retry;
+
+       if (nilfs_test_opt(sbi, BARRIER)) {
+               err = __sync_dirty_buffer(nilfs->ns_sbh[0],
+                                         WRITE_SYNC | WRITE_BARRIER);
+               if (err == -EOPNOTSUPP) {
+                       nilfs_warning(sbi->s_super, __func__,
+                                     "barrier-based sync failed. "
+                                     "disabling barriers\n");
+                       nilfs_clear_opt(sbi, BARRIER);
+                       goto retry;
+               }
+       } else {
+               err = sync_dirty_buffer(nilfs->ns_sbh[0]);
        }
+
        if (unlikely(err)) {
                printk(KERN_ERR
                       "NILFS: unable to write superblock (err=%d)\n", err);
@@ -400,9 +400,10 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno)
        list_add(&sbi->s_list, &nilfs->ns_supers);
        up_write(&nilfs->ns_super_sem);
 
+       err = -ENOMEM;
        sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size);
        if (!sbi->s_ifile)
-               return -ENOMEM;
+               goto delist;
 
        down_read(&nilfs->ns_segctor_sem);
        err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp,
@@ -433,6 +434,7 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno)
        nilfs_mdt_destroy(sbi->s_ifile);
        sbi->s_ifile = NULL;
 
+ delist:
        down_write(&nilfs->ns_super_sem);
        list_del_init(&sbi->s_list);
        up_write(&nilfs->ns_super_sem);
index 37de1f062d81146126e75870b04d03a7640e38d1..6af1c0073e9ec8a871a9fe51d42e69d1daaf6cf7 100644 (file)
@@ -608,11 +608,11 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs,
                return -EINVAL;
        }
 
-       if (swp) {
+       if (!valid[!swp])
                printk(KERN_WARNING "NILFS warning: broken superblock. "
                       "using spare superblock.\n");
+       if (swp)
                nilfs_swap_super_block(nilfs);
-       }
 
        nilfs->ns_sbwcount = 0;
        nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
index 630715f9f73d0e9ae4370a339eb5163a8bb55ca0..d74e1983e8dc478145dc8da369c0479bb947d8c2 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -675,7 +675,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
        f->f_path.mnt = mnt;
        f->f_pos = 0;
        f->f_op = fops_get(inode->i_fop);
-       file_move(f, &inode->i_sb->s_files);
+       file_sb_list_add(f, inode->i_sb);
 
        error = security_dentry_open(f, cred);
        if (error)
@@ -721,7 +721,7 @@ cleanup_all:
                        mnt_drop_write(mnt);
                }
        }
-       file_kill(f);
+       file_sb_list_del(f);
        f->f_path.dentry = NULL;
        f->f_path.mnt = NULL;
 cleanup_file:
index 5cc564a83149a5fc311b57d87793febbdcfd4f27..8066b8dd748f6800a09694ee62c2a0b33c97d20a 100644 (file)
@@ -126,6 +126,9 @@ static int do_make_slave(struct vfsmount *mnt)
        return 0;
 }
 
+/*
+ * vfsmount lock must be held for write
+ */
 void change_mnt_propagation(struct vfsmount *mnt, int type)
 {
        if (type == MS_SHARED) {
@@ -270,12 +273,12 @@ int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry,
                prev_src_mnt  = child;
        }
 out:
-       spin_lock(&vfsmount_lock);
+       br_write_lock(vfsmount_lock);
        while (!list_empty(&tmp_list)) {
                child = list_first_entry(&tmp_list, struct vfsmount, mnt_hash);
                umount_tree(child, 0, &umount_list);
        }
-       spin_unlock(&vfsmount_lock);
+       br_write_unlock(vfsmount_lock);
        release_mounts(&umount_list);
        return ret;
 }
@@ -296,6 +299,8 @@ static inline int do_refcount_check(struct vfsmount *mnt, int count)
  * other mounts its parent propagates to.
  * Check if any of these mounts that **do not have submounts**
  * have more references than 'refcnt'. If so return busy.
+ *
+ * vfsmount lock must be held for read or write
  */
 int propagate_mount_busy(struct vfsmount *mnt, int refcnt)
 {
@@ -353,6 +358,8 @@ static void __propagate_umount(struct vfsmount *mnt)
  * collect all mounts that receive propagation from the mount in @list,
  * and return these additional mounts in the same list.
  * @list: the list of mounts to be unmounted.
+ *
+ * vfsmount lock must be held for write
  */
 int propagate_umount(struct list_head *list)
 {
index ae35413dcbe1322a0ace18dbff0688138f585764..caa758377d66b8ba5530d029635d8cdfa98048ba 100644 (file)
@@ -83,6 +83,7 @@ void reiserfs_evict_inode(struct inode *inode)
        dquot_drop(inode);
        inode->i_blocks = 0;
        reiserfs_write_unlock_once(inode->i_sb, depth);
+       return;
 
 no_delete:
        end_writeback(inode);
index 1ec952b1f036fb30266cc8fea1e7b3795444fd37..812e2c05aa29eeda01bf94323234cdf260344353 100644 (file)
@@ -2311,7 +2311,7 @@ static int journal_read_transaction(struct super_block *sb,
        /* flush out the real blocks */
        for (i = 0; i < get_desc_trans_len(desc); i++) {
                set_buffer_dirty(real_blocks[i]);
-               ll_rw_block(SWRITE, 1, real_blocks + i);
+               write_dirty_buffer(real_blocks[i], WRITE);
        }
        for (i = 0; i < get_desc_trans_len(desc); i++) {
                wait_on_buffer(real_blocks[i]);
index 9674ab2c8718c3f1061f3556e6ec3e9b479cb8a9..8819e3a7ff203fb521b537672d16d5e2d4cea80d 100644 (file)
@@ -54,7 +54,22 @@ static struct super_block *alloc_super(struct file_system_type *type)
                        s = NULL;
                        goto out;
                }
+#ifdef CONFIG_SMP
+               s->s_files = alloc_percpu(struct list_head);
+               if (!s->s_files) {
+                       security_sb_free(s);
+                       kfree(s);
+                       s = NULL;
+                       goto out;
+               } else {
+                       int i;
+
+                       for_each_possible_cpu(i)
+                               INIT_LIST_HEAD(per_cpu_ptr(s->s_files, i));
+               }
+#else
                INIT_LIST_HEAD(&s->s_files);
+#endif
                INIT_LIST_HEAD(&s->s_instances);
                INIT_HLIST_HEAD(&s->s_anon);
                INIT_LIST_HEAD(&s->s_inodes);
@@ -108,6 +123,9 @@ out:
  */
 static inline void destroy_super(struct super_block *s)
 {
+#ifdef CONFIG_SMP
+       free_percpu(s->s_files);
+#endif
        security_sb_free(s);
        kfree(s->s_subtype);
        kfree(s->s_options);
index 048484fb10d28f12722052955abb043ecc0ac096..46f7a807bbc1ec8313af3df1a4c08c2afb3498eb 100644 (file)
@@ -114,10 +114,8 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
        
        ubh_mark_buffer_dirty (USPI_UBH(uspi));
        ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
-       if (sb->s_flags & MS_SYNCHRONOUS) {
-               ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
-               ubh_wait_on_buffer (UCPI_UBH(ucpi));
-       }
+       if (sb->s_flags & MS_SYNCHRONOUS)
+               ubh_sync_block(UCPI_UBH(ucpi));
        sb->s_dirt = 1;
        
        unlock_super (sb);
@@ -207,10 +205,8 @@ do_more:
 
        ubh_mark_buffer_dirty (USPI_UBH(uspi));
        ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
-       if (sb->s_flags & MS_SYNCHRONOUS) {
-               ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
-               ubh_wait_on_buffer (UCPI_UBH(ucpi));
-       }
+       if (sb->s_flags & MS_SYNCHRONOUS)
+               ubh_sync_block(UCPI_UBH(ucpi));
 
        if (overflow) {
                fragment += count;
@@ -558,10 +554,8 @@ static u64 ufs_add_fragments(struct inode *inode, u64 fragment,
        
        ubh_mark_buffer_dirty (USPI_UBH(uspi));
        ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
-       if (sb->s_flags & MS_SYNCHRONOUS) {
-               ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
-               ubh_wait_on_buffer (UCPI_UBH(ucpi));
-       }
+       if (sb->s_flags & MS_SYNCHRONOUS)
+               ubh_sync_block(UCPI_UBH(ucpi));
        sb->s_dirt = 1;
 
        UFSD("EXIT, fragment %llu\n", (unsigned long long)fragment);
@@ -680,10 +674,8 @@ cg_found:
 succed:
        ubh_mark_buffer_dirty (USPI_UBH(uspi));
        ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
-       if (sb->s_flags & MS_SYNCHRONOUS) {
-               ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
-               ubh_wait_on_buffer (UCPI_UBH(ucpi));
-       }
+       if (sb->s_flags & MS_SYNCHRONOUS)
+               ubh_sync_block(UCPI_UBH(ucpi));
        sb->s_dirt = 1;
 
        result += cgno * uspi->s_fpg;
index 428017e018fe63268b216b9ff2fce6cd83d547b8..2eabf04af3de12e98d0fbf812879825e7247e619 100644 (file)
@@ -113,10 +113,8 @@ void ufs_free_inode (struct inode * inode)
 
        ubh_mark_buffer_dirty (USPI_UBH(uspi));
        ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
-       if (sb->s_flags & MS_SYNCHRONOUS) {
-               ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
-               ubh_wait_on_buffer (UCPI_UBH(ucpi));
-       }
+       if (sb->s_flags & MS_SYNCHRONOUS)
+               ubh_sync_block(UCPI_UBH(ucpi));
        
        sb->s_dirt = 1;
        unlock_super (sb);
@@ -156,10 +154,8 @@ static void ufs2_init_inodes_chunk(struct super_block *sb,
 
        fs32_add(sb, &ucg->cg_u.cg_u2.cg_initediblk, uspi->s_inopb);
        ubh_mark_buffer_dirty(UCPI_UBH(ucpi));
-       if (sb->s_flags & MS_SYNCHRONOUS) {
-               ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
-               ubh_wait_on_buffer(UCPI_UBH(ucpi));
-       }
+       if (sb->s_flags & MS_SYNCHRONOUS)
+               ubh_sync_block(UCPI_UBH(ucpi));
 
        UFSD("EXIT\n");
 }
@@ -290,10 +286,8 @@ cg_found:
        }
        ubh_mark_buffer_dirty (USPI_UBH(uspi));
        ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
-       if (sb->s_flags & MS_SYNCHRONOUS) {
-               ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
-               ubh_wait_on_buffer (UCPI_UBH(ucpi));
-       }
+       if (sb->s_flags & MS_SYNCHRONOUS)
+               ubh_sync_block(UCPI_UBH(ucpi));
        sb->s_dirt = 1;
 
        inode->i_ino = cg * uspi->s_ipg + bit;
index 34d5cb1353204ea8a2a7cf348750d66f4519613d..a58f9155fc9a7baea4169efec7529434035d8458 100644 (file)
@@ -243,10 +243,8 @@ static int ufs_trunc_indirect(struct inode *inode, u64 offset, void *p)
                ubh_bforget(ind_ubh);
                ind_ubh = NULL;
        }
-       if (IS_SYNC(inode) && ind_ubh && ubh_buffer_dirty(ind_ubh)) {
-               ubh_ll_rw_block(SWRITE, ind_ubh);
-               ubh_wait_on_buffer (ind_ubh);
-       }
+       if (IS_SYNC(inode) && ind_ubh && ubh_buffer_dirty(ind_ubh))
+               ubh_sync_block(ind_ubh);
        ubh_brelse (ind_ubh);
        
        UFSD("EXIT: ino %lu\n", inode->i_ino);
@@ -307,10 +305,8 @@ static int ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p)
                ubh_bforget(dind_bh);
                dind_bh = NULL;
        }
-       if (IS_SYNC(inode) && dind_bh && ubh_buffer_dirty(dind_bh)) {
-               ubh_ll_rw_block(SWRITE, dind_bh);
-               ubh_wait_on_buffer (dind_bh);
-       }
+       if (IS_SYNC(inode) && dind_bh && ubh_buffer_dirty(dind_bh))
+               ubh_sync_block(dind_bh);
        ubh_brelse (dind_bh);
        
        UFSD("EXIT: ino %lu\n", inode->i_ino);
@@ -367,10 +363,8 @@ static int ufs_trunc_tindirect(struct inode *inode)
                ubh_bforget(tind_bh);
                tind_bh = NULL;
        }
-       if (IS_SYNC(inode) && tind_bh && ubh_buffer_dirty(tind_bh)) {
-               ubh_ll_rw_block(SWRITE, tind_bh);
-               ubh_wait_on_buffer (tind_bh);
-       }
+       if (IS_SYNC(inode) && tind_bh && ubh_buffer_dirty(tind_bh))
+               ubh_sync_block(tind_bh);
        ubh_brelse (tind_bh);
        
        UFSD("EXIT: ino %lu\n", inode->i_ino);
index 85a7fc9e4a4e345161a1c8a8a26e0eebcb834aae..d2c36d53fe66e8a827d2f232309bc11d7df0afec 100644 (file)
@@ -113,21 +113,17 @@ void ubh_mark_buffer_uptodate (struct ufs_buffer_head * ubh, int flag)
        }
 }
 
-void ubh_ll_rw_block(int rw, struct ufs_buffer_head *ubh)
+void ubh_sync_block(struct ufs_buffer_head *ubh)
 {
-       if (!ubh)
-               return;
+       if (ubh) {
+               unsigned i;
 
-       ll_rw_block(rw, ubh->count, ubh->bh);
-}
+               for (i = 0; i < ubh->count; i++)
+                       write_dirty_buffer(ubh->bh[i], WRITE);
 
-void ubh_wait_on_buffer (struct ufs_buffer_head * ubh)
-{
-       unsigned i;
-       if (!ubh)
-               return;
-       for ( i = 0; i < ubh->count; i++ )
-               wait_on_buffer (ubh->bh[i]);
+               for (i = 0; i < ubh->count; i++)
+                       wait_on_buffer(ubh->bh[i]);
+       }
 }
 
 void ubh_bforget (struct ufs_buffer_head * ubh)
index 0466036912f1adb41ccf85eb2d3dbd81b669ef4e..9f8775ce381c403647e84d1df9d45ae78c80a573 100644 (file)
@@ -269,8 +269,7 @@ extern void ubh_brelse (struct ufs_buffer_head *);
 extern void ubh_brelse_uspi (struct ufs_sb_private_info *);
 extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *);
 extern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *, int);
-extern void ubh_ll_rw_block(int, struct ufs_buffer_head *);
-extern void ubh_wait_on_buffer (struct ufs_buffer_head *);
+extern void ubh_sync_block(struct ufs_buffer_head *);
 extern void ubh_bforget (struct ufs_buffer_head *);
 extern int  ubh_buffer_dirty (struct ufs_buffer_head *);
 #define ubh_ubhcpymem(mem,ubh,size) _ubh_ubhcpymem_(uspi,mem,ubh,size)
index df84e3b04555f495356dfb15e74dfcd3806b1523..d89dec864d42547b84708e3502bf81f98108e76f 100644 (file)
@@ -23,8 +23,10 @@ asmlinkage long sys_vfork(struct pt_regs *regs);
 #endif
 
 #ifndef sys_execve
-asmlinkage long sys_execve(char __user *filename, char __user * __user *argv,
-                       char __user * __user *envp, struct pt_regs *regs);
+asmlinkage long sys_execve(const char __user *filename,
+                          const char __user *const __user *argv,
+                          const char __user *const __user *envp,
+                          struct pt_regs *regs);
 #endif
 
 #ifndef sys_mmap2
index ca16c3801a1e7c26332efd842be95c4299bcd1b4..be33b3affc8ada39fdaaf78bb2deefaca8385615 100644 (file)
@@ -150,6 +150,7 @@ struct clcd_fb {
        u16                     off_cntl;
        u32                     clcd_cntl;
        u32                     cmap[16];
+       bool                    clk_enabled;
 };
 
 static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
index c809e286d213df3cb1d63caa7f6b97b82162c34a..a065612fc928768268cf0352c91c34dc3f7c448a 100644 (file)
@@ -50,8 +50,8 @@ struct linux_binprm{
        int unsafe;             /* how unsafe this exec is (mask of LSM_UNSAFE_*) */
        unsigned int per_clear; /* bits to clear in current->personality */
        int argc, envc;
-       char * filename;        /* Name of binary as seen by procps */
-       char * interp;          /* Name of the binary really executed. Most
+       const char * filename;  /* Name of binary as seen by procps */
+       const char * interp;    /* Name of the binary really executed. Most
                                   of the time same as filename, but could be
                                   different for binfmt_{misc,script} */
        unsigned interp_flags;
@@ -126,7 +126,8 @@ extern int setup_arg_pages(struct linux_binprm * bprm,
                           unsigned long stack_top,
                           int executable_stack);
 extern int bprm_mm_init(struct linux_binprm *bprm);
-extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm);
+extern int copy_strings_kernel(int argc, const char *const *argv,
+                              struct linux_binprm *bprm);
 extern int prepare_bprm_creds(struct linux_binprm *bprm);
 extern void install_exec_creds(struct linux_binprm *bprm);
 extern void do_coredump(long signr, int exit_code, struct pt_regs *regs);
index 43e649a72529afa8282f7da2029ab8e6759f0a97..ec94c12f21da5ab9d8098f7afbdf59d2cc7886b7 100644 (file)
@@ -32,7 +32,6 @@ enum bh_state_bits {
        BH_Delay,       /* Buffer is not yet allocated on disk */
        BH_Boundary,    /* Block is followed by a discontiguity */
        BH_Write_EIO,   /* I/O error on write */
-       BH_Ordered,     /* ordered write */
        BH_Eopnotsupp,  /* operation not supported (barrier) */
        BH_Unwritten,   /* Buffer is allocated on disk but not written */
        BH_Quiet,       /* Buffer Error Prinks to be quiet */
@@ -125,7 +124,6 @@ BUFFER_FNS(Async_Write, async_write)
 BUFFER_FNS(Delay, delay)
 BUFFER_FNS(Boundary, boundary)
 BUFFER_FNS(Write_EIO, write_io_error)
-BUFFER_FNS(Ordered, ordered)
 BUFFER_FNS(Eopnotsupp, eopnotsupp)
 BUFFER_FNS(Unwritten, unwritten)
 
@@ -183,6 +181,8 @@ void unlock_buffer(struct buffer_head *bh);
 void __lock_buffer(struct buffer_head *bh);
 void ll_rw_block(int, int, struct buffer_head * bh[]);
 int sync_dirty_buffer(struct buffer_head *bh);
+int __sync_dirty_buffer(struct buffer_head *bh, int rw);
+void write_dirty_buffer(struct buffer_head *bh, int rw);
 int submit_bh(int, struct buffer_head *);
 void write_boundary_block(struct block_device *bdev,
                        sector_t bblock, unsigned blocksize);
index 9a96b4d83fc126a92adb9c87f7f1e5ae62bc0056..76041b6147582ef62eb0daedafbf1771a8e844c6 100644 (file)
@@ -125,9 +125,6 @@ struct inodes_stat_t {
  *                     block layer could (in theory) choose to ignore this
  *                     request if it runs into resource problems.
  * WRITE               A normal async write. Device will be plugged.
- * SWRITE              Like WRITE, but a special case for ll_rw_block() that
- *                     tells it to lock the buffer first. Normally a buffer
- *                     must be locked before doing IO.
  * WRITE_SYNC_PLUG     Synchronous write. Identical to WRITE, but passes down
  *                     the hint that someone will be waiting on this IO
  *                     shortly. The device must still be unplugged explicitly,
@@ -138,9 +135,6 @@ struct inodes_stat_t {
  *                     immediately after submission. The write equivalent
  *                     of READ_SYNC.
  * WRITE_ODIRECT_PLUG  Special case write for O_DIRECT only.
- * SWRITE_SYNC
- * SWRITE_SYNC_PLUG    Like WRITE_SYNC/WRITE_SYNC_PLUG, but locks the buffer.
- *                     See SWRITE.
  * WRITE_BARRIER       Like WRITE_SYNC, but tells the block layer that all
  *                     previously submitted writes must be safely on storage
  *                     before this one is started. Also guarantees that when
@@ -155,7 +149,6 @@ struct inodes_stat_t {
 #define READ                   0
 #define WRITE                  RW_MASK
 #define READA                  RWA_MASK
-#define SWRITE                 (WRITE | READA)
 
 #define READ_SYNC              (READ | REQ_SYNC | REQ_UNPLUG)
 #define READ_META              (READ | REQ_META)
@@ -165,8 +158,6 @@ struct inodes_stat_t {
 #define WRITE_META             (WRITE | REQ_META)
 #define WRITE_BARRIER          (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG | \
                                 REQ_HARDBARRIER)
-#define SWRITE_SYNC_PLUG       (SWRITE | REQ_SYNC | REQ_NOIDLE)
-#define SWRITE_SYNC            (SWRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG)
 
 /*
  * These aren't really reads or writes, they pass down information about
@@ -929,6 +920,9 @@ struct file {
 #define f_vfsmnt       f_path.mnt
        const struct file_operations    *f_op;
        spinlock_t              f_lock;  /* f_ep_links, f_flags, no IRQ */
+#ifdef CONFIG_SMP
+       int                     f_sb_list_cpu;
+#endif
        atomic_long_t           f_count;
        unsigned int            f_flags;
        fmode_t                 f_mode;
@@ -953,9 +947,6 @@ struct file {
        unsigned long f_mnt_write_state;
 #endif
 };
-extern spinlock_t files_lock;
-#define file_list_lock() spin_lock(&files_lock);
-#define file_list_unlock() spin_unlock(&files_lock);
 
 #define get_file(x)    atomic_long_inc(&(x)->f_count)
 #define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1)
@@ -1346,7 +1337,11 @@ struct super_block {
 
        struct list_head        s_inodes;       /* all inodes */
        struct hlist_head       s_anon;         /* anonymous dentries for (nfs) exporting */
+#ifdef CONFIG_SMP
+       struct list_head __percpu *s_files;
+#else
        struct list_head        s_files;
+#endif
        /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */
        struct list_head        s_dentry_lru;   /* unused dentry lru */
        int                     s_nr_dentry_unused;     /* # of dentry on lru */
@@ -2197,8 +2192,6 @@ static inline void insert_inode_hash(struct inode *inode) {
        __insert_inode_hash(inode, inode->i_ino);
 }
 
-extern void file_move(struct file *f, struct list_head *list);
-extern void file_kill(struct file *f);
 #ifdef CONFIG_BLOCK
 extern void submit_bio(int, struct bio *);
 extern int bdev_read_only(struct block_device *);
index eca3d5202138f68bb30dd1a308aaf4e121171663..a42b5bf02f8bcfec3ea20ecef765df3f4d690250 100644 (file)
@@ -5,7 +5,7 @@
 
 struct fs_struct {
        int users;
-       rwlock_t lock;
+       spinlock_t lock;
        int umask;
        int in_exec;
        struct path root, pwd;
@@ -23,29 +23,29 @@ extern int unshare_fs_struct(void);
 
 static inline void get_fs_root(struct fs_struct *fs, struct path *root)
 {
-       read_lock(&fs->lock);
+       spin_lock(&fs->lock);
        *root = fs->root;
        path_get(root);
-       read_unlock(&fs->lock);
+       spin_unlock(&fs->lock);
 }
 
 static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd)
 {
-       read_lock(&fs->lock);
+       spin_lock(&fs->lock);
        *pwd = fs->pwd;
        path_get(pwd);
-       read_unlock(&fs->lock);
+       spin_unlock(&fs->lock);
 }
 
 static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root,
                                       struct path *pwd)
 {
-       read_lock(&fs->lock);
+       spin_lock(&fs->lock);
        *root = fs->root;
        path_get(root);
        *pwd = fs->pwd;
        path_get(pwd);
-       read_unlock(&fs->lock);
+       spin_unlock(&fs->lock);
 }
 
 #endif /* _LINUX_FS_STRUCT_H */
diff --git a/include/linux/lglock.h b/include/linux/lglock.h
new file mode 100644 (file)
index 0000000..b288cb7
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Specialised local-global spinlock. Can only be declared as global variables
+ * to avoid overhead and keep things simple (and we don't want to start using
+ * these inside dynamically allocated structures).
+ *
+ * "local/global locks" (lglocks) can be used to:
+ *
+ * - Provide fast exclusive access to per-CPU data, with exclusive access to
+ *   another CPU's data allowed but possibly subject to contention, and to
+ *   provide very slow exclusive access to all per-CPU data.
+ * - Or to provide very fast and scalable read serialisation, and to provide
+ *   very slow exclusive serialisation of data (not necessarily per-CPU data).
+ *
+ * Brlocks are also implemented as a short-hand notation for the latter use
+ * case.
+ *
+ * Copyright 2009, 2010, Nick Piggin, Novell Inc.
+ */
+#ifndef __LINUX_LGLOCK_H
+#define __LINUX_LGLOCK_H
+
+#include <linux/spinlock.h>
+#include <linux/lockdep.h>
+#include <linux/percpu.h>
+
+/* can make br locks by using local lock for read side, global lock for write */
+#define br_lock_init(name)     name##_lock_init()
+#define br_read_lock(name)     name##_local_lock()
+#define br_read_unlock(name)   name##_local_unlock()
+#define br_write_lock(name)    name##_global_lock_online()
+#define br_write_unlock(name)  name##_global_unlock_online()
+
+#define DECLARE_BRLOCK(name)   DECLARE_LGLOCK(name)
+#define DEFINE_BRLOCK(name)    DEFINE_LGLOCK(name)
+
+
+#define lg_lock_init(name)     name##_lock_init()
+#define lg_local_lock(name)    name##_local_lock()
+#define lg_local_unlock(name)  name##_local_unlock()
+#define lg_local_lock_cpu(name, cpu)   name##_local_lock_cpu(cpu)
+#define lg_local_unlock_cpu(name, cpu) name##_local_unlock_cpu(cpu)
+#define lg_global_lock(name)   name##_global_lock()
+#define lg_global_unlock(name) name##_global_unlock()
+#define lg_global_lock_online(name) name##_global_lock_online()
+#define lg_global_unlock_online(name) name##_global_unlock_online()
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+#define LOCKDEP_INIT_MAP lockdep_init_map
+
+#define DEFINE_LGLOCK_LOCKDEP(name)                                    \
+ struct lock_class_key name##_lock_key;                                        \
+ struct lockdep_map name##_lock_dep_map;                               \
+ EXPORT_SYMBOL(name##_lock_dep_map)
+
+#else
+#define LOCKDEP_INIT_MAP(a, b, c, d)
+
+#define DEFINE_LGLOCK_LOCKDEP(name)
+#endif
+
+
+#define DECLARE_LGLOCK(name)                                           \
+ extern void name##_lock_init(void);                                   \
+ extern void name##_local_lock(void);                                  \
+ extern void name##_local_unlock(void);                                        \
+ extern void name##_local_lock_cpu(int cpu);                           \
+ extern void name##_local_unlock_cpu(int cpu);                         \
+ extern void name##_global_lock(void);                                 \
+ extern void name##_global_unlock(void);                               \
+ extern void name##_global_lock_online(void);                          \
+ extern void name##_global_unlock_online(void);                                \
+
+#define DEFINE_LGLOCK(name)                                            \
+                                                                       \
+ DEFINE_PER_CPU(arch_spinlock_t, name##_lock);                         \
+ DEFINE_LGLOCK_LOCKDEP(name);                                          \
+                                                                       \
+ void name##_lock_init(void) {                                         \
+       int i;                                                          \
+       LOCKDEP_INIT_MAP(&name##_lock_dep_map, #name, &name##_lock_key, 0); \
+       for_each_possible_cpu(i) {                                      \
+               arch_spinlock_t *lock;                                  \
+               lock = &per_cpu(name##_lock, i);                        \
+               *lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;     \
+       }                                                               \
+ }                                                                     \
+ EXPORT_SYMBOL(name##_lock_init);                                      \
+                                                                       \
+ void name##_local_lock(void) {                                                \
+       arch_spinlock_t *lock;                                          \
+       preempt_disable();                                              \
+       rwlock_acquire_read(&name##_lock_dep_map, 0, 0, _THIS_IP_);     \
+       lock = &__get_cpu_var(name##_lock);                             \
+       arch_spin_lock(lock);                                           \
+ }                                                                     \
+ EXPORT_SYMBOL(name##_local_lock);                                     \
+                                                                       \
+ void name##_local_unlock(void) {                                      \
+       arch_spinlock_t *lock;                                          \
+       rwlock_release(&name##_lock_dep_map, 1, _THIS_IP_);             \
+       lock = &__get_cpu_var(name##_lock);                             \
+       arch_spin_unlock(lock);                                         \
+       preempt_enable();                                               \
+ }                                                                     \
+ EXPORT_SYMBOL(name##_local_unlock);                                   \
+                                                                       \
+ void name##_local_lock_cpu(int cpu) {                                 \
+       arch_spinlock_t *lock;                                          \
+       preempt_disable();                                              \
+       rwlock_acquire_read(&name##_lock_dep_map, 0, 0, _THIS_IP_);     \
+       lock = &per_cpu(name##_lock, cpu);                              \
+       arch_spin_lock(lock);                                           \
+ }                                                                     \
+ EXPORT_SYMBOL(name##_local_lock_cpu);                                 \
+                                                                       \
+ void name##_local_unlock_cpu(int cpu) {                               \
+       arch_spinlock_t *lock;                                          \
+       rwlock_release(&name##_lock_dep_map, 1, _THIS_IP_);             \
+       lock = &per_cpu(name##_lock, cpu);                              \
+       arch_spin_unlock(lock);                                         \
+       preempt_enable();                                               \
+ }                                                                     \
+ EXPORT_SYMBOL(name##_local_unlock_cpu);                               \
+                                                                       \
+ void name##_global_lock_online(void) {                                        \
+       int i;                                                          \
+       preempt_disable();                                              \
+       rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_);           \
+       for_each_online_cpu(i) {                                        \
+               arch_spinlock_t *lock;                                  \
+               lock = &per_cpu(name##_lock, i);                        \
+               arch_spin_lock(lock);                                   \
+       }                                                               \
+ }                                                                     \
+ EXPORT_SYMBOL(name##_global_lock_online);                             \
+                                                                       \
+ void name##_global_unlock_online(void) {                              \
+       int i;                                                          \
+       rwlock_release(&name##_lock_dep_map, 1, _RET_IP_);              \
+       for_each_online_cpu(i) {                                        \
+               arch_spinlock_t *lock;                                  \
+               lock = &per_cpu(name##_lock, i);                        \
+               arch_spin_unlock(lock);                                 \
+       }                                                               \
+       preempt_enable();                                               \
+ }                                                                     \
+ EXPORT_SYMBOL(name##_global_unlock_online);                           \
+                                                                       \
+ void name##_global_lock(void) {                                       \
+       int i;                                                          \
+       preempt_disable();                                              \
+       rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_);           \
+       for_each_online_cpu(i) {                                        \
+               arch_spinlock_t *lock;                                  \
+               lock = &per_cpu(name##_lock, i);                        \
+               arch_spin_lock(lock);                                   \
+       }                                                               \
+ }                                                                     \
+ EXPORT_SYMBOL(name##_global_lock);                                    \
+                                                                       \
+ void name##_global_unlock(void) {                                     \
+       int i;                                                          \
+       rwlock_release(&name##_lock_dep_map, 1, _RET_IP_);              \
+       for_each_online_cpu(i) {                                        \
+               arch_spinlock_t *lock;                                  \
+               lock = &per_cpu(name##_lock, i);                        \
+               arch_spin_unlock(lock);                                 \
+       }                                                               \
+       preempt_enable();                                               \
+ }                                                                     \
+ EXPORT_SYMBOL(name##_global_unlock);
+#endif
index ce160d68f5e706fb3c157940e68ccac3627dccef..1e2a6db2d7dd03466bf850dc5011860c23e8f9c9 100644 (file)
@@ -2109,7 +2109,9 @@ extern void daemonize(const char *, ...);
 extern int allow_signal(int);
 extern int disallow_signal(int);
 
-extern int do_execve(char *, char __user * __user *, char __user * __user *, struct pt_regs *);
+extern int do_execve(const char *,
+                    const char __user * const __user *,
+                    const char __user * const __user *, struct pt_regs *);
 extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *);
 struct task_struct *fork_idle(int);
 
index ae0a5286f558f334859a6d5a2163c18bcc974c3e..92e52a1e6af3fd8478bb451f04d34a3c63b1625f 100644 (file)
@@ -213,6 +213,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  * @dma_alignment: SPI controller constraint on DMA buffers alignment.
  * @mode_bits: flags understood by this controller driver
  * @flags: other constraints relevant to this driver
+ * @bus_lock_spinlock: spinlock for SPI bus locking
+ * @bus_lock_mutex: mutex for SPI bus locking
+ * @bus_lock_flag: indicates that the SPI bus is locked for exclusive use
  * @setup: updates the device mode and clocking records used by a
  *     device's SPI controller; protocol code may call this.  This
  *     must fail if an unrecognized or unsupported mode is requested.
index 6e5d19788634f751ab18e980c2cee847bb7d3560..e6319d18a55d93066ac49b39ecd05de5e9be0424 100644 (file)
@@ -820,7 +820,7 @@ asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags,
                                  u64 mask, int fd,
                                  const char  __user *pathname);
 
-int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
+int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]);
 
 
 asmlinkage long sys_perf_event_open(
index 1437da3ddc629b7dc285e7cb4ce11e2b5400de7a..67d64e6efe7a8c95d775b6418d2c1c8d728d667d 100644 (file)
@@ -329,6 +329,13 @@ struct tty_struct {
        struct tty_port *port;
 };
 
+/* Each of a tty's open files has private_data pointing to tty_file_private */
+struct tty_file_private {
+       struct tty_struct *tty;
+       struct file *file;
+       struct list_head list;
+};
+
 /* tty magic number */
 #define TTY_MAGIC              0x5401
 
@@ -458,6 +465,7 @@ extern void proc_clear_tty(struct task_struct *p);
 extern struct tty_struct *get_current_tty(void);
 extern void tty_default_fops(struct file_operations *fops);
 extern struct tty_struct *alloc_tty_struct(void);
+extern void tty_add_file(struct tty_struct *tty, struct file *file);
 extern void free_tty_struct(struct tty_struct *tty);
 extern void initialize_tty_struct(struct tty_struct *tty,
                struct tty_driver *driver, int idx);
@@ -470,6 +478,7 @@ extern struct tty_struct *tty_pair_get_tty(struct tty_struct *tty);
 extern struct tty_struct *tty_pair_get_pty(struct tty_struct *tty);
 
 extern struct mutex tty_mutex;
+extern spinlock_t tty_files_lock;
 
 extern void tty_write_unlock(struct tty_struct *tty);
 extern int tty_write_lock(struct tty_struct *tty, int ndelay);
index 6a664c3f7c1e426dd0b74129ce9cf81cb07fefa0..7dc97d12253c1bdc494b939e5e856b1b1fa6fc2c 100644 (file)
@@ -1707,6 +1707,7 @@ struct snd_emu10k1 {
        unsigned int card_type;                 /* EMU10K1_CARD_* */
        unsigned int ecard_ctrl;                /* ecard control bits */
        unsigned long dma_mask;                 /* PCI DMA mask */
+       unsigned int delay_pcm_irq;             /* in samples */
        int max_cache_pages;                    /* max memory size / PAGE_SIZE */
        struct snd_dma_buffer silent_page;      /* silent page */
        struct snd_dma_buffer ptb_pages;        /* page table pages */
index 2b108538d0d95684be2048fcc80a7acf484970c4..3098a38f3ae1b6a980da5e645b7c093e799721bf 100644 (file)
@@ -24,10 +24,11 @@ static int __init no_initrd(char *str)
 
 __setup("noinitrd", no_initrd);
 
-static int __init do_linuxrc(void * shell)
+static int __init do_linuxrc(void *_shell)
 {
-       static char *argv[] = { "linuxrc", NULL, };
-       extern char * envp_init[];
+       static const char *argv[] = { "linuxrc", NULL, };
+       extern const char *envp_init[];
+       const char *shell = _shell;
 
        sys_close(old_fd);sys_close(root_fd);
        sys_setsid();
index 22d61cb06f98ab6fc31333213477197e93394416..94ab488039aab1dde97d442f785046475f09c978 100644 (file)
@@ -197,8 +197,8 @@ static int __init set_reset_devices(char *str)
 
 __setup("reset_devices", set_reset_devices);
 
-static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
-char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
+static const char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
+const char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
 static const char *panic_later, *panic_param;
 
 extern const struct obs_kernel_param __setup_start[], __setup_end[];
@@ -809,7 +809,7 @@ static void __init do_pre_smp_initcalls(void)
                do_one_initcall(*fn);
 }
 
-static void run_init_process(char *init_filename)
+static void run_init_process(const char *init_filename)
 {
        argv_init[0] = init_filename;
        kernel_execve(init_filename, argv_init, envp_init);
index c438f545a3217eca47dcae2ff98618467971a9f7..be775f7e81e08809dea392cd3a4dd1488a7e6cd9 100644 (file)
@@ -255,7 +255,14 @@ extern void kdb_ps1(const struct task_struct *p);
 extern void kdb_print_nameval(const char *name, unsigned long val);
 extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info);
 extern void kdb_meminfo_proc_show(void);
+#ifdef CONFIG_KALLSYMS
 extern const char *kdb_walk_kallsyms(loff_t *pos);
+#else /* ! CONFIG_KALLSYMS */
+static inline const char *kdb_walk_kallsyms(loff_t *pos)
+{
+       return NULL;
+}
+#endif /* ! CONFIG_KALLSYMS */
 extern char *kdb_getstr(char *, size_t, char *);
 
 /* Defines for kdb_symbol_print */
index 45344d5c53dd3b3daf3397f0a26eb34d7584625c..6b2485dcb0504ef8af79ca79a3de1e9d1f556023 100644 (file)
@@ -82,8 +82,8 @@ static char *kdb_name_table[100];     /* arbitrary size */
 int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab)
 {
        int ret = 0;
-       unsigned long symbolsize;
-       unsigned long offset;
+       unsigned long symbolsize = 0;
+       unsigned long offset = 0;
 #define knt1_size 128          /* must be >= kallsyms table size */
        char *knt1 = NULL;
 
index 671ed56e0a490a56ed4e8dc15aa6624d60ebaadf..03120229db2802929065a210930e41c7fa701ba0 100644 (file)
@@ -1386,8 +1386,7 @@ static int wait_task_stopped(struct wait_opts *wo,
        if (!unlikely(wo->wo_flags & WNOWAIT))
                *p_code = 0;
 
-       /* don't need the RCU readlock here as we're holding a spinlock */
-       uid = __task_cred(p)->uid;
+       uid = task_uid(p);
 unlock_sig:
        spin_unlock_irq(&p->sighand->siglock);
        if (!exit_code)
@@ -1460,7 +1459,7 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p)
        }
        if (!unlikely(wo->wo_flags & WNOWAIT))
                p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
-       uid = __task_cred(p)->uid;
+       uid = task_uid(p);
        spin_unlock_irq(&p->sighand->siglock);
 
        pid = task_pid_vnr(p);
index 98b450876f93878b437bbbc6efe6abd1c4028b29..856eac3ec52eb1a11fa6405d3e870da796c778ee 100644 (file)
@@ -752,13 +752,13 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
        struct fs_struct *fs = current->fs;
        if (clone_flags & CLONE_FS) {
                /* tsk->fs is already what we want */
-               write_lock(&fs->lock);
+               spin_lock(&fs->lock);
                if (fs->in_exec) {
-                       write_unlock(&fs->lock);
+                       spin_unlock(&fs->lock);
                        return -EAGAIN;
                }
                fs->users++;
-               write_unlock(&fs->lock);
+               spin_unlock(&fs->lock);
                return 0;
        }
        tsk->fs = copy_fs_struct(fs);
@@ -1676,13 +1676,13 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
 
                if (new_fs) {
                        fs = current->fs;
-                       write_lock(&fs->lock);
+                       spin_lock(&fs->lock);
                        current->fs = new_fs;
                        if (--fs->users)
                                new_fs = NULL;
                        else
                                new_fs = fs;
-                       write_unlock(&fs->lock);
+                       spin_unlock(&fs->lock);
                }
 
                if (new_mm) {
index 6e9b19667a8d2fdff6ac3c0bf76d32d8c1fc4d87..9cd0591c96a21acf825861c7672533c0273ae25e 100644 (file)
@@ -153,7 +153,9 @@ static int ____call_usermodehelper(void *data)
                        goto fail;
        }
 
-       retval = kernel_execve(sub_info->path, sub_info->argv, sub_info->envp);
+       retval = kernel_execve(sub_info->path,
+                              (const char *const *)sub_info->argv,
+                              (const char *const *)sub_info->envp);
 
        /* Exec failed? */
 fail:
index dfaa0f4e9789f5e8f395ac1dee7975c1abffdc1d..080b09a57a8fab1a4565757d13bb7a4fdb74b74a 100644 (file)
@@ -2325,7 +2325,10 @@ static int shmem_show_options(struct seq_file *seq, struct vfsmount *vfs)
 
 static void shmem_put_super(struct super_block *sb)
 {
-       kfree(sb->s_fs_info);
+       struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
+
+       percpu_counter_destroy(&sbinfo->used_blocks);
+       kfree(sbinfo);
        sb->s_fs_info = NULL;
 }
 
@@ -2367,7 +2370,8 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
 #endif
 
        spin_lock_init(&sbinfo->stat_lock);
-       percpu_counter_init(&sbinfo->used_blocks, 0);
+       if (percpu_counter_init(&sbinfo->used_blocks, 0))
+               goto failed;
        sbinfo->free_inodes = sbinfo->max_inodes;
 
        sb->s_maxbytes = SHMEM_MAX_BYTES;
index 1ae654391442049083fae7040d5d1e5568f2b424..3721fbb9a83c3c7761c05ae39d8acab21b6f6b66 100644 (file)
@@ -3143,7 +3143,7 @@ pull:
                        put_page(skb_shinfo(skb)->frags[0].page);
                        memmove(skb_shinfo(skb)->frags,
                                skb_shinfo(skb)->frags + 1,
-                               --skb_shinfo(skb)->nr_frags);
+                               --skb_shinfo(skb)->nr_frags * sizeof(skb_frag_t));
                }
        }
 
index 6bccba31d13208d03f042002f5808c3396c1f37f..51d6c31679757f58e62368a42edba16d9bfc4d09 100644 (file)
@@ -735,6 +735,7 @@ static void get_counters(const struct xt_table_info *t,
                if (cpu == curcpu)
                        continue;
                i = 0;
+               local_bh_disable();
                xt_info_wrlock(cpu);
                xt_entry_foreach(iter, t->entries[cpu], t->size) {
                        ADD_COUNTER(counters[i], iter->counters.bcnt,
@@ -742,6 +743,7 @@ static void get_counters(const struct xt_table_info *t,
                        ++i;
                }
                xt_info_wrunlock(cpu);
+               local_bh_enable();
        }
        put_cpu();
 }
index c439721b165a6369acd1bd2ea1d64d4b0580b1bb..97b64b22c41214858d6ddb1fb9cf8e292468e23d 100644 (file)
@@ -909,6 +909,7 @@ get_counters(const struct xt_table_info *t,
                if (cpu == curcpu)
                        continue;
                i = 0;
+               local_bh_disable();
                xt_info_wrlock(cpu);
                xt_entry_foreach(iter, t->entries[cpu], t->size) {
                        ADD_COUNTER(counters[i], iter->counters.bcnt,
@@ -916,6 +917,7 @@ get_counters(const struct xt_table_info *t,
                        ++i; /* macro does multi eval of i */
                }
                xt_info_wrunlock(cpu);
+               local_bh_enable();
        }
        put_cpu();
 }
index 5359ef4daac5230e4c691c2100d8016dcb69e102..29a7bca29e3fddec24a55ea2e6ca228bc7a452ba 100644 (file)
@@ -922,6 +922,7 @@ get_counters(const struct xt_table_info *t,
                if (cpu == curcpu)
                        continue;
                i = 0;
+               local_bh_disable();
                xt_info_wrlock(cpu);
                xt_entry_foreach(iter, t->entries[cpu], t->size) {
                        ADD_COUNTER(counters[i], iter->counters.bcnt,
@@ -929,6 +930,7 @@ get_counters(const struct xt_table_info *t,
                        ++i;
                }
                xt_info_wrunlock(cpu);
+               local_bh_enable();
        }
        put_cpu();
 }
index 8f2d0400cf8ae616ad4283a6d846d8fa4b684d40..d126365ac0463bc075d62446562a8d9f07d548a2 100644 (file)
@@ -2580,7 +2580,7 @@ ctl_table ipv6_route_table_template[] = {
                .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_elasticity,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
-               .proc_handler   =       proc_dointvec_jiffies,
+               .proc_handler   =       proc_dointvec,
        },
        {
                .procname       =       "mtu_expires",
@@ -2594,7 +2594,7 @@ ctl_table ipv6_route_table_template[] = {
                .data           =       &init_net.ipv6.sysctl.ip6_rt_min_advmss,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
-               .proc_handler   =       proc_dointvec_jiffies,
+               .proc_handler   =       proc_dointvec,
        },
        {
                .procname       =       "gc_min_interval_ms",
index 2cbf380377d5e009fa972d85af18ded9971a5248..8648a9922aabace0231de8eec18b88e30239fd5f 100644 (file)
@@ -1406,7 +1406,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
        struct netlink_sock *nlk = nlk_sk(sk);
        int noblock = flags&MSG_DONTWAIT;
        size_t copied;
-       struct sk_buff *skb;
+       struct sk_buff *skb, *frag __maybe_unused = NULL;
        int err;
 
        if (flags&MSG_OOB)
@@ -1441,21 +1441,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
                        kfree_skb(skb);
                        skb = compskb;
                } else {
-                       /*
-                        * Before setting frag_list to NULL, we must get a
-                        * private copy of skb if shared (because of MSG_PEEK)
-                        */
-                       if (skb_shared(skb)) {
-                               struct sk_buff *nskb;
-
-                               nskb = pskb_copy(skb, GFP_KERNEL);
-                               kfree_skb(skb);
-                               skb = nskb;
-                               err = -ENOMEM;
-                               if (!skb)
-                                       goto out;
-                       }
-                       kfree_skb(skb_shinfo(skb)->frag_list);
+                       frag = skb_shinfo(skb)->frag_list;
                        skb_shinfo(skb)->frag_list = NULL;
                }
        }
@@ -1492,6 +1478,10 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
        if (flags & MSG_TRUNC)
                copied = skb->len;
 
+#ifdef CONFIG_COMPAT_NETLINK_MESSAGES
+       skb_shinfo(skb)->frag_list = frag;
+#endif
+
        skb_free_datagram(sk, skb);
 
        if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2)
index 8406c66549909c763a6b2ae3d7594ea5aeceb361..c2ed90a4c0b428a984c7329e1af0f8d3957a0ae4 100644 (file)
@@ -152,21 +152,24 @@ static int tcf_gact(struct sk_buff *skb, struct tc_action *a, struct tcf_result
 static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
        unsigned char *b = skb_tail_pointer(skb);
-       struct tc_gact opt;
        struct tcf_gact *gact = a->priv;
+       struct tc_gact opt = {
+               .index   = gact->tcf_index,
+               .refcnt  = gact->tcf_refcnt - ref,
+               .bindcnt = gact->tcf_bindcnt - bind,
+               .action  = gact->tcf_action,
+       };
        struct tcf_t t;
 
-       opt.index = gact->tcf_index;
-       opt.refcnt = gact->tcf_refcnt - ref;
-       opt.bindcnt = gact->tcf_bindcnt - bind;
-       opt.action = gact->tcf_action;
        NLA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt);
 #ifdef CONFIG_GACT_PROB
        if (gact->tcfg_ptype) {
-               struct tc_gact_p p_opt;
-               p_opt.paction = gact->tcfg_paction;
-               p_opt.pval = gact->tcfg_pval;
-               p_opt.ptype = gact->tcfg_ptype;
+               struct tc_gact_p p_opt = {
+                       .paction = gact->tcfg_paction,
+                       .pval    = gact->tcfg_pval,
+                       .ptype   = gact->tcfg_ptype,
+               };
+
                NLA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt);
        }
 #endif
index 11f195af2da0732aaf362380928e298f7f35a199..0c311be9282798ea6b27d1109f482bfdb20c7dac 100644 (file)
@@ -219,15 +219,16 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, i
 {
        unsigned char *b = skb_tail_pointer(skb);
        struct tcf_mirred *m = a->priv;
-       struct tc_mirred opt;
+       struct tc_mirred opt = {
+               .index   = m->tcf_index,
+               .action  = m->tcf_action,
+               .refcnt  = m->tcf_refcnt - ref,
+               .bindcnt = m->tcf_bindcnt - bind,
+               .eaction = m->tcfm_eaction,
+               .ifindex = m->tcfm_ifindex,
+       };
        struct tcf_t t;
 
-       opt.index = m->tcf_index;
-       opt.action = m->tcf_action;
-       opt.refcnt = m->tcf_refcnt - ref;
-       opt.bindcnt = m->tcf_bindcnt - bind;
-       opt.eaction = m->tcfm_eaction;
-       opt.ifindex = m->tcfm_ifindex;
        NLA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt);
        t.install = jiffies_to_clock_t(jiffies - m->tcf_tm.install);
        t.lastuse = jiffies_to_clock_t(jiffies - m->tcf_tm.lastuse);
index 509a2d53a99d483980d33ab4b71460d209cac0dc..186eb837e600da750dd3347f96f033478d131b76 100644 (file)
@@ -272,19 +272,19 @@ static int tcf_nat_dump(struct sk_buff *skb, struct tc_action *a,
 {
        unsigned char *b = skb_tail_pointer(skb);
        struct tcf_nat *p = a->priv;
-       struct tc_nat opt;
+       struct tc_nat opt = {
+               .old_addr = p->old_addr,
+               .new_addr = p->new_addr,
+               .mask     = p->mask,
+               .flags    = p->flags,
+
+               .index    = p->tcf_index,
+               .action   = p->tcf_action,
+               .refcnt   = p->tcf_refcnt - ref,
+               .bindcnt  = p->tcf_bindcnt - bind,
+       };
        struct tcf_t t;
 
-       opt.old_addr = p->old_addr;
-       opt.new_addr = p->new_addr;
-       opt.mask = p->mask;
-       opt.flags = p->flags;
-
-       opt.index = p->tcf_index;
-       opt.action = p->tcf_action;
-       opt.refcnt = p->tcf_refcnt - ref;
-       opt.bindcnt = p->tcf_bindcnt - bind;
-
        NLA_PUT(skb, TCA_NAT_PARMS, sizeof(opt), &opt);
        t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
        t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
index 4a1d640b0cf16d842a26e3de807df2d937752cc8..97e84f3ee77563fb14aa7b8e0faf2db476a81501 100644 (file)
@@ -164,13 +164,14 @@ static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
 {
        unsigned char *b = skb_tail_pointer(skb);
        struct tcf_defact *d = a->priv;
-       struct tc_defact opt;
+       struct tc_defact opt = {
+               .index   = d->tcf_index,
+               .refcnt  = d->tcf_refcnt - ref,
+               .bindcnt = d->tcf_bindcnt - bind,
+               .action  = d->tcf_action,
+       };
        struct tcf_t t;
 
-       opt.index = d->tcf_index;
-       opt.refcnt = d->tcf_refcnt - ref;
-       opt.bindcnt = d->tcf_bindcnt - bind;
-       opt.action = d->tcf_action;
        NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
        NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata);
        t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
index e9607fe55b58006af76880c8e5364a16c3cebdbd..66cbf4eb8855452477ec0f459d69cd6db2559ce7 100644 (file)
@@ -159,13 +159,14 @@ static inline int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
 {
        unsigned char *b = skb_tail_pointer(skb);
        struct tcf_skbedit *d = a->priv;
-       struct tc_skbedit opt;
+       struct tc_skbedit opt = {
+               .index   = d->tcf_index,
+               .refcnt  = d->tcf_refcnt - ref,
+               .bindcnt = d->tcf_bindcnt - bind,
+               .action  = d->tcf_action,
+       };
        struct tcf_t t;
 
-       opt.index = d->tcf_index;
-       opt.refcnt = d->tcf_refcnt - ref;
-       opt.bindcnt = d->tcf_bindcnt - bind;
-       opt.action = d->tcf_action;
        NLA_PUT(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt);
        if (d->flags & SKBEDIT_F_PRIORITY)
                NLA_PUT(skb, TCA_SKBEDIT_PRIORITY, sizeof(d->priority),
index 443c161eb8bdd0dd4c988a9bab0d6d387fe2f0e3..3376d7657185324adf2afef79984369bd16984ff 100644 (file)
@@ -18,10 +18,11 @@ config SUNRPC_XPRT_RDMA
          If unsure, say N.
 
 config RPCSEC_GSS_KRB5
-       tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)"
-       depends on SUNRPC && EXPERIMENTAL
+       tristate
+       depends on SUNRPC && CRYPTO
+       prompt "Secure RPC: Kerberos V mechanism" if !(NFS_V4 || NFSD_V4)
+       default y
        select SUNRPC_GSS
-       select CRYPTO
        select CRYPTO_MD5
        select CRYPTO_DES
        select CRYPTO_CBC
@@ -34,7 +35,7 @@ config RPCSEC_GSS_KRB5
          available from http://linux-nfs.org/.  In addition, user-space
          Kerberos support should be installed.
 
-         If unsure, say N.
+         If unsure, say Y.
 
 config RPCSEC_GSS_SPKM3
        tristate "Secure RPC: SPKM3 mechanism (EXPERIMENTAL)"
index e5e28d1946a41a852a558caa83ca49c68265bed7..2ac3f6e8adffaf74a7480961997bb9fb97201e98 100644 (file)
@@ -249,6 +249,8 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
        req->rl_nchunks = nchunks;
 
        BUG_ON(nchunks == 0);
+       BUG_ON((r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR)
+              && (nchunks > 3));
 
        /*
         * finish off header. If write, marshal discrim and nchunks.
index 27015c6d8eb58311ed88264e86313fc3879ad0c2..5f4c7b3bc7114c597703c2739a427815c3be741c 100644 (file)
@@ -650,10 +650,22 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
        ep->rep_attr.cap.max_send_wr = cdata->max_requests;
        switch (ia->ri_memreg_strategy) {
        case RPCRDMA_FRMR:
-               /* Add room for frmr register and invalidate WRs */
-               ep->rep_attr.cap.max_send_wr *= 3;
-               if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr)
-                       return -EINVAL;
+               /* Add room for frmr register and invalidate WRs.
+                * 1. FRMR reg WR for head
+                * 2. FRMR invalidate WR for head
+                * 3. FRMR reg WR for pagelist
+                * 4. FRMR invalidate WR for pagelist
+                * 5. FRMR reg WR for tail
+                * 6. FRMR invalidate WR for tail
+                * 7. The RDMA_SEND WR
+                */
+               ep->rep_attr.cap.max_send_wr *= 7;
+               if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr) {
+                       cdata->max_requests = devattr.max_qp_wr / 7;
+                       if (!cdata->max_requests)
+                               return -EINVAL;
+                       ep->rep_attr.cap.max_send_wr = cdata->max_requests * 7;
+               }
                break;
        case RPCRDMA_MEMWINDOWS_ASYNC:
        case RPCRDMA_MEMWINDOWS:
@@ -1490,7 +1502,7 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
        memset(&frmr_wr, 0, sizeof frmr_wr);
        frmr_wr.opcode = IB_WR_FAST_REG_MR;
        frmr_wr.send_flags = 0;                 /* unsignaled */
-       frmr_wr.wr.fast_reg.iova_start = (unsigned long)seg1->mr_dma;
+       frmr_wr.wr.fast_reg.iova_start = seg1->mr_dma;
        frmr_wr.wr.fast_reg.page_list = seg1->mr_chunk.rl_mw->r.frmr.fr_pgl;
        frmr_wr.wr.fast_reg.page_list_len = i;
        frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
index 49a62f0c4b87dc7f5a92223a7ecf67699e246e37..b6309db5622689deaf1c76a6acb1f6a09a02602c 100644 (file)
@@ -1305,10 +1305,11 @@ static void xs_tcp_state_change(struct sock *sk)
        if (!(xprt = xprt_from_sock(sk)))
                goto out;
        dprintk("RPC:       xs_tcp_state_change client %p...\n", xprt);
-       dprintk("RPC:       state %x conn %d dead %d zapped %d\n",
+       dprintk("RPC:       state %x conn %d dead %d zapped %d sk_shutdown %d\n",
                        sk->sk_state, xprt_connected(xprt),
                        sock_flag(sk, SOCK_DEAD),
-                       sock_flag(sk, SOCK_ZAPPED));
+                       sock_flag(sk, SOCK_ZAPPED),
+                       sk->sk_shutdown);
 
        switch (sk->sk_state) {
        case TCP_ESTABLISHED:
@@ -1779,10 +1780,25 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt, struct sock_xprt *tra
 {
        unsigned int state = transport->inet->sk_state;
 
-       if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED)
-               return;
-       if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT))
-               return;
+       if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED) {
+               /* we don't need to abort the connection if the socket
+                * hasn't undergone a shutdown
+                */
+               if (transport->inet->sk_shutdown == 0)
+                       return;
+               dprintk("RPC:       %s: TCP_CLOSEd and sk_shutdown set to %d\n",
+                               __func__, transport->inet->sk_shutdown);
+       }
+       if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT)) {
+               /* we don't need to abort the connection if the socket
+                * hasn't undergone a shutdown
+                */
+               if (transport->inet->sk_shutdown == 0)
+                       return;
+               dprintk("RPC:       %s: ESTABLISHED/SYN_SENT "
+                               "sk_shutdown set to %d\n",
+                               __func__, transport->inet->sk_shutdown);
+       }
        xs_abort_connection(xprt, transport);
 }
 
index ba59983aaffee6e3d7f7a0afb241f92d787b152d..b14ed4b1f27c3bd70f5837c2f032baf11a88e9a1 100644 (file)
@@ -2504,7 +2504,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
        if (p->dir > XFRM_POLICY_OUT)
                return NULL;
 
-       xp = xfrm_policy_alloc(net, GFP_KERNEL);
+       xp = xfrm_policy_alloc(net, GFP_ATOMIC);
        if (xp == NULL) {
                *dir = -ENOBUFS;
                return NULL;
index d5666d3cc21b5a4e240e20924c63cd610236bef7..f73e2c2042185fff2d079dbdb3f4b8b828371e72 100644 (file)
@@ -607,8 +607,8 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
        return error;
 }
 
-static int apparmor_task_setrlimit(unsigned int resource,
-                                  struct rlimit *new_rlim)
+static int apparmor_task_setrlimit(struct task_struct *task,
+               unsigned int resource, struct rlimit *new_rlim)
 {
        struct aa_profile *profile = aa_current_profile();
        int error = 0;
index 96bab9469d487fb8bc66c4724f14c51bf86b295a..19358dc14605bae1422ae00226291751695ba44c 100644 (file)
@@ -62,19 +62,14 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
        int deleted, connected;
        int error = 0;
 
-       /* Get the root we want to resolve too */
+       /* Get the root we want to resolve too, released below */
        if (flags & PATH_CHROOT_REL) {
                /* resolve paths relative to chroot */
-               read_lock(&current->fs->lock);
-               root = current->fs->root;
-               /* released below */
-               path_get(&root);
-               read_unlock(&current->fs->lock);
+               get_fs_root(current->fs, &root);
        } else {
                /* resolve paths relative to namespace */
                root.mnt = current->nsproxy->mnt_ns->root;
                root.dentry = root.mnt->mnt_root;
-               /* released below */
                path_get(&root);
        }
 
index 4e015996dd4d6d316cbbef4c9fafb2c2e48c9e34..9d172e6e330c9fd7906a8a2e5754713f80dfb433 100644 (file)
@@ -40,7 +40,7 @@
  *
  * Warn if that happens, once per boot.
  */
-static void warn_setuid_and_fcaps_mixed(char *fname)
+static void warn_setuid_and_fcaps_mixed(const char *fname)
 {
        static int warned;
        if (!warned) {
index 42043f96e54f69d0d2cb2ab1f063a7e638d0786f..4796ddd4e721ae454a02563d713aa235870ece02 100644 (file)
@@ -2170,8 +2170,9 @@ static inline void flush_unauthorized_files(const struct cred *cred,
 
        tty = get_current_tty();
        if (tty) {
-               file_list_lock();
+               spin_lock(&tty_files_lock);
                if (!list_empty(&tty->tty_files)) {
+                       struct tty_file_private *file_priv;
                        struct inode *inode;
 
                        /* Revalidate access to controlling tty.
@@ -2179,14 +2180,16 @@ static inline void flush_unauthorized_files(const struct cred *cred,
                           than using file_has_perm, as this particular open
                           file may belong to another process and we are only
                           interested in the inode-based check here. */
-                       file = list_first_entry(&tty->tty_files, struct file, f_u.fu_list);
+                       file_priv = list_first_entry(&tty->tty_files,
+                                               struct tty_file_private, list);
+                       file = file_priv->file;
                        inode = file->f_path.dentry->d_inode;
                        if (inode_has_perm(cred, inode,
                                           FILE__READ | FILE__WRITE, NULL)) {
                                drop_tty = 1;
                        }
                }
-               file_list_unlock();
+               spin_unlock(&tty_files_lock);
                tty_kref_put(tty);
        }
        /* Reset controlling tty. */
index a3b2a6479246deca30152bbb7f84e049634f2662..134fc6c2e08dc01eeda84a730545b0532f0588fe 100644 (file)
@@ -978,6 +978,10 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
 {
        if (substream->runtime->trigger_master != substream)
                return 0;
+       /* some drivers might use hw_ptr to recover from the pause -
+          update the hw_ptr now */
+       if (push)
+               snd_pcm_update_hw_ptr(substream);
        /* The jiffies check in snd_pcm_update_hw_ptr*() is done by
         * a delta betwen the current jiffies, this gives a large enough
         * delta, effectively to skip the check once.
index 4203782d7cb79bec7e7bf47157b32ee04de1efee..aff8387c45cf2e2955d71ee0ca3446808402feaa 100644 (file)
@@ -52,6 +52,7 @@ static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64};
 static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
 static int enable_ir[SNDRV_CARDS];
 static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
+static uint delay_pcm_irq[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard.");
@@ -73,6 +74,8 @@ module_param_array(enable_ir, bool, NULL, 0444);
 MODULE_PARM_DESC(enable_ir, "Enable IR.");
 module_param_array(subsystem, uint, NULL, 0444);
 MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
+module_param_array(delay_pcm_irq, uint, NULL, 0444);
+MODULE_PARM_DESC(delay_pcm_irq, "Delay PCM interrupt by specified number of samples (default 0).");
 /*
  * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value  Model:SB0400
  */
@@ -127,6 +130,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
                                      &emu)) < 0)
                goto error;
        card->private_data = emu;
+       emu->delay_pcm_irq = delay_pcm_irq[dev] & 0x1f;
        if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0)
                goto error;
        if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0)
index 55b83ef73c630e83b2d098a45cce1f570923df7f..622bace148e3c4e5e4de3efa1936b56245004c69 100644 (file)
@@ -332,7 +332,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
                evoice->epcm->ccca_start_addr = start_addr + ccis;
                if (extra) {
                        start_addr += ccis;
-                       end_addr += ccis;
+                       end_addr += ccis + emu->delay_pcm_irq;
                }
                if (stereo && !extra) {
                        snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK);
@@ -360,7 +360,9 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
        /* Assumption that PT is already 0 so no harm overwriting */
        snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
        snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
-       snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24));
+       snd_emu10k1_ptr_write(emu, PSST, voice,
+                       (start_addr + (extra ? emu->delay_pcm_irq : 0)) |
+                       (send_amount[2] << 24));
        if (emu->card_capabilities->emu_model)
                pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */
        else 
@@ -732,6 +734,23 @@ static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu, struct snd_
        snd_emu10k1_ptr_write(emu, IP, voice, 0);
 }
 
+static inline void snd_emu10k1_playback_mangle_extra(struct snd_emu10k1 *emu,
+               struct snd_emu10k1_pcm *epcm,
+               struct snd_pcm_substream *substream,
+               struct snd_pcm_runtime *runtime)
+{
+       unsigned int ptr, period_pos;
+
+       /* try to sychronize the current position for the interrupt
+          source voice */
+       period_pos = runtime->status->hw_ptr - runtime->hw_ptr_interrupt;
+       period_pos %= runtime->period_size;
+       ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->extra->number);
+       ptr &= ~0x00ffffff;
+       ptr |= epcm->ccca_start_addr + period_pos;
+       snd_emu10k1_ptr_write(emu, CCCA, epcm->extra->number, ptr);
+}
+
 static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
                                        int cmd)
 {
@@ -753,6 +772,8 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
                /* follow thru */
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
        case SNDRV_PCM_TRIGGER_RESUME:
+               if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE)
+                       snd_emu10k1_playback_mangle_extra(emu, epcm, substream, runtime);
                mix = &emu->pcm_mixer[substream->number];
                snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix);
                snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix);
@@ -869,8 +890,9 @@ static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream *
 #endif
        /*
        printk(KERN_DEBUG
-              "ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n",
-              ptr, runtime->buffer_size, runtime->period_size);
+              "ptr = 0x%lx, buffer_size = 0x%lx, period_size = 0x%lx\n",
+              (long)ptr, (long)runtime->buffer_size,
+              (long)runtime->period_size);
        */
        return ptr;
 }
index ffb1ddb8dc28ea1d3fbdf574d0c4efbef9772c98..957a311514c8ed9fe34586b518aa463ec279dddd 100644 (file)
@@ -310,8 +310,10 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
        if (snd_BUG_ON(!hdr))
                return NULL;
 
+       idx = runtime->period_size >= runtime->buffer_size ?
+                                       (emu->delay_pcm_irq * 2) : 0;
        mutex_lock(&hdr->block_mutex);
-       blk = search_empty(emu, runtime->dma_bytes);
+       blk = search_empty(emu, runtime->dma_bytes + idx);
        if (blk == NULL) {
                mutex_unlock(&hdr->block_mutex);
                return NULL;
index 31b5d9eeba68655db32a631160bcf95049b4f1d0..c424952a734e0e48546518fe6b47ccbf959e9aee 100644 (file)
@@ -3049,6 +3049,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
                      CXT5066_DELL_LAPTOP),
        SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
+       SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTO),
        SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
        SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
index 2cd1ae809e4677a84834654bcdafa3e07ddaf06a..a4dd04524e4391ce7d47f76196b6eeca5e6e9f85 100644 (file)
@@ -19030,6 +19030,7 @@ static int patch_alc888(struct hda_codec *codec)
 /*
  * ALC680 support
  */
+#define ALC680_DIGIN_NID       ALC880_DIGIN_NID
 #define ALC680_DIGOUT_NID      ALC880_DIGOUT_NID
 #define alc680_modes           alc260_modes
 
@@ -19044,23 +19045,93 @@ static hda_nid_t alc680_adc_nids[3] = {
        0x07, 0x08, 0x09
 };
 
+/*
+ * Analog capture ADC cgange
+ */
+static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
+                                     struct hda_codec *codec,
+                                     unsigned int stream_tag,
+                                     unsigned int format,
+                                     struct snd_pcm_substream *substream)
+{
+       struct alc_spec *spec = codec->spec;
+       struct auto_pin_cfg *cfg = &spec->autocfg;
+       unsigned int pre_mic, pre_line;
+
+       pre_mic  = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]);
+       pre_line = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_LINE]);
+
+       spec->cur_adc_stream_tag = stream_tag;
+       spec->cur_adc_format = format;
+
+       if (pre_mic || pre_line) {
+               if (pre_mic)
+                       snd_hda_codec_setup_stream(codec, 0x08, stream_tag, 0,
+                                                                       format);
+               else
+                       snd_hda_codec_setup_stream(codec, 0x09, stream_tag, 0,
+                                                                       format);
+       } else
+               snd_hda_codec_setup_stream(codec, 0x07, stream_tag, 0, format);
+       return 0;
+}
+
+static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
+                                     struct hda_codec *codec,
+                                     struct snd_pcm_substream *substream)
+{
+       snd_hda_codec_cleanup_stream(codec, 0x07);
+       snd_hda_codec_cleanup_stream(codec, 0x08);
+       snd_hda_codec_cleanup_stream(codec, 0x09);
+       return 0;
+}
+
+static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
+       .substreams = 1, /* can be overridden */
+       .channels_min = 2,
+       .channels_max = 2,
+       /* NID is set in alc_build_pcms */
+       .ops = {
+               .prepare = alc680_capture_pcm_prepare,
+               .cleanup = alc680_capture_pcm_cleanup
+       },
+};
+
 static struct snd_kcontrol_new alc680_base_mixer[] = {
        /* output mixer control */
        HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT),
        { }
 };
 
-static struct snd_kcontrol_new alc680_capture_mixer[] = {
-       HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
+static struct hda_bind_ctls alc680_bind_cap_vol = {
+       .ops = &snd_hda_bind_vol,
+       .values = {
+               HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
+               HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
+               HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
+               0
+       },
+};
+
+static struct hda_bind_ctls alc680_bind_cap_switch = {
+       .ops = &snd_hda_bind_sw,
+       .values = {
+               HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
+               HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
+               HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
+               0
+       },
+};
+
+static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
+       HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
+       HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
        { } /* end */
 };
 
@@ -19068,25 +19139,73 @@ static struct snd_kcontrol_new alc680_capture_mixer[] = {
  * generic initialization of ADC, input mixers and output mixers
  */
 static struct hda_verb alc680_init_verbs[] = {
-       /* Unmute DAC0-1 and set vol = 0 */
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 
        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+
+       {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT   | AC_USRSP_EN},
+       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT  | AC_USRSP_EN},
+
        { }
 };
 
+/* toggle speaker-output according to the hp-jack state */
+static void alc680_base_setup(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+
+       spec->autocfg.hp_pins[0] = 0x16;
+       spec->autocfg.speaker_pins[0] = 0x14;
+       spec->autocfg.speaker_pins[1] = 0x15;
+       spec->autocfg.input_pins[AUTO_PIN_MIC] = 0x18;
+       spec->autocfg.input_pins[AUTO_PIN_LINE] = 0x19;
+}
+
+static void alc680_rec_autoswitch(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       struct auto_pin_cfg *cfg = &spec->autocfg;
+       unsigned int present;
+       hda_nid_t new_adc;
+
+       present = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]);
+
+       new_adc = present ? 0x8 : 0x7;
+       __snd_hda_codec_cleanup_stream(codec, !present ? 0x8 : 0x7, 1);
+       snd_hda_codec_setup_stream(codec, new_adc,
+                                  spec->cur_adc_stream_tag, 0,
+                                  spec->cur_adc_format);
+
+}
+
+static void alc680_unsol_event(struct hda_codec *codec,
+                                          unsigned int res)
+{
+       if ((res >> 26) == ALC880_HP_EVENT)
+               alc_automute_amp(codec);
+       if ((res >> 26) == ALC880_MIC_EVENT)
+               alc680_rec_autoswitch(codec);
+}
+
+static void alc680_inithook(struct hda_codec *codec)
+{
+       alc_automute_amp(codec);
+       alc680_rec_autoswitch(codec);
+}
+
 /* create input playback/capture controls for the given pin */
 static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
                                    const char *ctlname, int idx)
@@ -19197,13 +19316,7 @@ static void alc680_auto_init_hp_out(struct hda_codec *codec)
 #define alc680_pcm_analog_capture      alc880_pcm_analog_capture
 #define alc680_pcm_analog_alt_capture  alc880_pcm_analog_alt_capture
 #define alc680_pcm_digital_playback    alc880_pcm_digital_playback
-
-static struct hda_input_mux alc680_capture_source = {
-       .num_items = 1,
-       .items = {
-               { "Mic", 0x0 },
-       },
-};
+#define alc680_pcm_digital_capture     alc880_pcm_digital_capture
 
 /*
  * BIOS auto configuration
@@ -19218,6 +19331,7 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
                                           alc680_ignore);
        if (err < 0)
                return err;
+
        if (!spec->autocfg.line_outs) {
                if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
                        spec->multiout.max_channels = 2;
@@ -19239,8 +19353,6 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
                add_mixer(spec, spec->kctls.list);
 
        add_verb(spec, alc680_init_verbs);
-       spec->num_mux_defs = 1;
-       spec->input_mux = &alc680_capture_source;
 
        err = alc_auto_add_mic_boost(codec);
        if (err < 0)
@@ -19279,17 +19391,17 @@ static struct snd_pci_quirk alc680_cfg_tbl[] = {
 static struct alc_config_preset alc680_presets[] = {
        [ALC680_BASE] = {
                .mixers = { alc680_base_mixer },
-               .cap_mixer =  alc680_capture_mixer,
+               .cap_mixer =  alc680_master_capture_mixer,
                .init_verbs = { alc680_init_verbs },
                .num_dacs = ARRAY_SIZE(alc680_dac_nids),
                .dac_nids = alc680_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc680_adc_nids),
-               .adc_nids = alc680_adc_nids,
-               .hp_nid = 0x04,
                .dig_out_nid = ALC680_DIGOUT_NID,
                .num_channel_mode = ARRAY_SIZE(alc680_modes),
                .channel_mode = alc680_modes,
-               .input_mux = &alc680_capture_source,
+               .unsol_event = alc680_unsol_event,
+               .setup = alc680_base_setup,
+               .init_hook = alc680_inithook,
+
        },
 };
 
@@ -19333,9 +19445,9 @@ static int patch_alc680(struct hda_codec *codec)
                setup_preset(codec, &alc680_presets[board_config]);
 
        spec->stream_analog_playback = &alc680_pcm_analog_playback;
-       spec->stream_analog_capture = &alc680_pcm_analog_capture;
-       spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture;
+       spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
        spec->stream_digital_playback = &alc680_pcm_digital_playback;
+       spec->stream_digital_capture = &alc680_pcm_digital_capture;
 
        if (!spec->adc_nids) {
                spec->adc_nids = alc680_adc_nids;
index f64fb7d988cb57f63876bbc92f0b94d93beb9cfe..ad5202efd7a9e270523cc517e487c6e1997027e3 100644 (file)
@@ -1224,15 +1224,14 @@ static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip)
                    firmware.firmware.ASIC, firmware.firmware.CODEC,
                    firmware.firmware.AUXDSP, firmware.firmware.PROG);
 
+       if (!chip)
+               return 1;
+
        for (i = 0; i < FIRMWARE_VERSIONS; i++) {
                if (!memcmp(&firmware_versions[i], &firmware, sizeof(firmware)))
-                       break;
-       }
-       if (i >= FIRMWARE_VERSIONS)
-               return 0; /* no match */
+                       return 1; /* OK */
 
-       if (!chip)
-               return 1; /* OK */
+       }
 
        snd_printdd("Writing Firmware\n");
        if (!chip->fw_entry) {
index 4e212ed62ea609be9e1b3d45a5ac3fb6efea1a38..f8154e661524c64e1098f318d447ba7bfcda3616 100644 (file)
@@ -178,13 +178,6 @@ static int wm8776_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        case SND_SOC_DAIFMT_LEFT_J:
                iface |= 0x0001;
                break;
-               /* FIXME: CHECK A/B */
-       case SND_SOC_DAIFMT_DSP_A:
-               iface |= 0x0003;
-               break;
-       case SND_SOC_DAIFMT_DSP_B:
-               iface |= 0x0007;
-               break;
        default:
                return -EINVAL;
        }