From 24b6a174250e165ccb98250b65d4938650f6c6d6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 6 Sep 2010 23:53:47 +0100 Subject: [PATCH] --- yaml --- r: 210698 b: refs/heads/master c: 551402a30efa45560e23c22a7aa04453861602c3 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/ia64/include/asm/compat.h | 2 +- trunk/arch/ia64/kernel/fsys.S | 46 +-- trunk/arch/m68k/include/asm/unistd.h | 5 +- trunk/arch/m68k/kernel/entry.S | 3 - trunk/arch/m68knommu/kernel/syscalltable.S | 3 - trunk/arch/mips/include/asm/compat.h | 2 +- trunk/arch/mn10300/kernel/mn10300-serial.c | 22 +- trunk/arch/parisc/include/asm/compat.h | 2 +- trunk/arch/powerpc/include/asm/compat.h | 2 +- trunk/arch/s390/include/asm/compat.h | 2 +- trunk/arch/sparc/include/asm/compat.h | 2 +- trunk/arch/tile/include/asm/compat.h | 2 +- trunk/arch/x86/ia32/ia32entry.S | 22 +- trunk/arch/x86/include/asm/compat.h | 2 +- trunk/drivers/gpu/drm/drm_crtc_helper.c | 2 +- trunk/drivers/hid/hid-core.c | 4 +- trunk/drivers/hid/hid-ids.h | 4 - trunk/drivers/hid/hid-mosart.c | 1 - trunk/drivers/hid/hid-topseed.c | 1 - trunk/drivers/hid/usbhid/hid-core.c | 8 +- trunk/drivers/hid/usbhid/hid-quirks.c | 4 - trunk/drivers/hid/usbhid/hiddev.c | 2 +- trunk/drivers/hid/usbhid/usbhid.h | 1 - trunk/drivers/mtd/nand/bf5xx_nand.c | 9 +- trunk/drivers/mtd/nand/mxc_nand.c | 47 ++- trunk/drivers/mtd/nand/pxa3xx_nand.c | 6 - trunk/drivers/mtd/onenand/samsung.c | 16 +- trunk/drivers/net/ll_temac_main.c | 1 - trunk/drivers/net/ll_temac_mdio.c | 1 - trunk/drivers/serial/mpc52xx_uart.c | 1 - trunk/drivers/spi/amba-pl022.c | 16 +- trunk/drivers/spi/dw_spi.c | 24 +- trunk/drivers/spi/spi.c | 9 +- trunk/drivers/spi/spi_s3c64xx.c | 37 +- trunk/fs/9p/vfs_dir.c | 6 +- trunk/fs/9p/vfs_inode.c | 9 +- trunk/fs/9p/vfs_super.c | 20 +- trunk/fs/aio.c | 3 - trunk/fs/cifs/Kconfig | 2 + trunk/fs/cifs/asn1.c | 6 +- trunk/fs/cifs/cifsencrypt.c | 418 +++++++++++++++++---- trunk/fs/cifs/cifsglob.h | 25 +- trunk/fs/cifs/cifspdu.h | 7 +- trunk/fs/cifs/cifsproto.h | 13 +- trunk/fs/cifs/cifssmb.c | 13 +- trunk/fs/cifs/connect.c | 71 ++-- trunk/fs/cifs/inode.c | 30 +- trunk/fs/cifs/netmisc.c | 22 +- trunk/fs/cifs/ntlmssp.h | 13 + trunk/fs/cifs/sess.c | 132 +++++-- trunk/fs/cifs/transport.c | 6 +- trunk/fs/nfs/Kconfig | 1 - trunk/fs/nfs/client.c | 2 +- trunk/fs/nfs/file.c | 4 + trunk/fs/nfs/super.c | 8 - trunk/fs/nfsd/Kconfig | 1 - trunk/include/linux/compat.h | 3 - trunk/include/linux/gpio.h | 1 - trunk/include/linux/quotaops.h | 10 +- trunk/include/linux/spi/dw_spi.h | 2 - trunk/include/linux/sunrpc/clnt.h | 2 +- trunk/kernel/compat.c | 21 -- trunk/kernel/sched_fair.c | 6 +- trunk/net/9p/client.c | 7 +- trunk/net/sunrpc/auth.c | 2 +- trunk/net/sunrpc/auth_gss/auth_gss.c | 9 +- trunk/net/sunrpc/auth_gss/gss_krb5_mech.c | 10 +- trunk/net/sunrpc/auth_gss/gss_spkm3_mech.c | 5 +- trunk/net/sunrpc/clnt.c | 116 +++--- trunk/net/sunrpc/rpc_pipe.c | 20 +- 71 files changed, 805 insertions(+), 534 deletions(-) diff --git a/[refs] b/[refs] index 7112af346836..a12c69624c4c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9c03f1622af051004416dd3e24d8a0fa31e34178 +refs/heads/master: 551402a30efa45560e23c22a7aa04453861602c3 diff --git a/trunk/arch/ia64/include/asm/compat.h b/trunk/arch/ia64/include/asm/compat.h index 9301a2821615..f90edc85b509 100644 --- a/trunk/arch/ia64/include/asm/compat.h +++ b/trunk/arch/ia64/include/asm/compat.h @@ -199,7 +199,7 @@ ptr_to_compat(void __user *uptr) } static __inline__ void __user * -arch_compat_alloc_user_space (long len) +compat_alloc_user_space (long len) { struct pt_regs *regs = task_pt_regs(current); return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len); diff --git a/trunk/arch/ia64/kernel/fsys.S b/trunk/arch/ia64/kernel/fsys.S index 471a1e783aca..3567d54f8cee 100644 --- a/trunk/arch/ia64/kernel/fsys.S +++ b/trunk/arch/ia64/kernel/fsys.S @@ -424,26 +424,14 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP #ifdef CONFIG_SMP - // __ticket_spin_trylock(r31) - ld4 r17=[r31] - mov r8=EINVAL // default to EINVAL - ;; - extr r9=r17,17,15 - ;; - xor r18=r17,r9 - adds r19=1,r17 - ;; - extr.u r18=r18,0,15 + mov r17=1 ;; - cmp.eq p0,p7=0,r18 -(p7) br.cond.spnt.many .lock_contention - mov.m ar.ccv=r17 - ;; - cmpxchg4.acq r9=[r31],r19,ar.ccv + cmpxchg4.acq r18=[r31],r17,ar.ccv // try to acquire the lock + mov r8=EINVAL // default to EINVAL ;; - cmp4.eq p0,p7=r9,r17 -(p7) br.cond.spnt.many .lock_contention ld8 r3=[r2] // re-read current->blocked now that we hold the lock + cmp4.ne p6,p0=r18,r0 +(p6) br.cond.spnt.many .lock_contention ;; #else ld8 r3=[r2] // re-read current->blocked now that we hold the lock @@ -502,17 +490,7 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set (p6) br.cond.spnt.few 1b // yes -> retry #ifdef CONFIG_SMP - // __ticket_spin_unlock(r31) - adds r31=2,r31 - ;; - ld2.bias r2=[r31] - mov r3=65534 - ;; - adds r2=2,r2 - ;; - and r3=r3,r2 - ;; - st2.rel [r31]=r3 + st4.rel [r31]=r0 // release the lock #endif SSM_PSR_I(p0, p9, r31) ;; @@ -534,17 +512,7 @@ EX(.fail_efault, (p15) st8 [r34]=r3) .sig_pending: #ifdef CONFIG_SMP - // __ticket_spin_unlock(r31) - adds r31=2,r31 - ;; - ld2.bias r2=[r31] - mov r3=65534 - ;; - adds r2=2,r2 - ;; - and r3=r3,r2 - ;; - st2.rel [r31]=r3 + st4.rel [r31]=r0 // release the lock #endif SSM_PSR_I(p0, p9, r17) ;; diff --git a/trunk/arch/m68k/include/asm/unistd.h b/trunk/arch/m68k/include/asm/unistd.h index b43b36beafe3..60b15d0aa072 100644 --- a/trunk/arch/m68k/include/asm/unistd.h +++ b/trunk/arch/m68k/include/asm/unistd.h @@ -340,13 +340,10 @@ #define __NR_set_thread_area 334 #define __NR_atomic_cmpxchg_32 335 #define __NR_atomic_barrier 336 -#define __NR_fanotify_init 337 -#define __NR_fanotify_mark 338 -#define __NR_prlimit64 339 #ifdef __KERNEL__ -#define NR_syscalls 340 +#define NR_syscalls 337 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/arch/m68k/kernel/entry.S b/trunk/arch/m68k/kernel/entry.S index 6360c437dcf5..2391bdff0996 100644 --- a/trunk/arch/m68k/kernel/entry.S +++ b/trunk/arch/m68k/kernel/entry.S @@ -765,7 +765,4 @@ sys_call_table: .long sys_set_thread_area .long sys_atomic_cmpxchg_32 /* 335 */ .long sys_atomic_barrier - .long sys_fanotify_init - .long sys_fanotify_mark - .long sys_prlimit64 diff --git a/trunk/arch/m68knommu/kernel/syscalltable.S b/trunk/arch/m68knommu/kernel/syscalltable.S index 79b1ed198c07..b30b3eb197a5 100644 --- a/trunk/arch/m68knommu/kernel/syscalltable.S +++ b/trunk/arch/m68knommu/kernel/syscalltable.S @@ -355,9 +355,6 @@ ENTRY(sys_call_table) .long sys_set_thread_area .long sys_atomic_cmpxchg_32 /* 335 */ .long sys_atomic_barrier - .long sys_fanotify_init - .long sys_fanotify_mark - .long sys_prlimit64 .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall diff --git a/trunk/arch/mips/include/asm/compat.h b/trunk/arch/mips/include/asm/compat.h index dbc51065df5b..613f6912dfc1 100644 --- a/trunk/arch/mips/include/asm/compat.h +++ b/trunk/arch/mips/include/asm/compat.h @@ -145,7 +145,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static inline void __user *arch_compat_alloc_user_space(long len) +static inline void __user *compat_alloc_user_space(long len) { struct pt_regs *regs = (struct pt_regs *) ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1; diff --git a/trunk/arch/mn10300/kernel/mn10300-serial.c b/trunk/arch/mn10300/kernel/mn10300-serial.c index db509dd80565..9d49073e827a 100644 --- a/trunk/arch/mn10300/kernel/mn10300-serial.c +++ b/trunk/arch/mn10300/kernel/mn10300-serial.c @@ -156,17 +156,17 @@ struct mn10300_serial_port mn10300_serial_port_sif0 = { ._intr = &SC0ICR, ._rxb = &SC0RXB, ._txb = &SC0TXB, - .rx_name = "ttySM0:Rx", - .tx_name = "ttySM0:Tx", + .rx_name = "ttySM0/Rx", + .tx_name = "ttySM0/Tx", #ifdef CONFIG_MN10300_TTYSM0_TIMER8 - .tm_name = "ttySM0:Timer8", + .tm_name = "ttySM0/Timer8", ._tmxmd = &TM8MD, ._tmxbr = &TM8BR, ._tmicr = &TM8ICR, .tm_irq = TM8IRQ, .div_timer = MNSCx_DIV_TIMER_16BIT, #else /* CONFIG_MN10300_TTYSM0_TIMER2 */ - .tm_name = "ttySM0:Timer2", + .tm_name = "ttySM0/Timer2", ._tmxmd = &TM2MD, ._tmxbr = (volatile u16 *) &TM2BR, ._tmicr = &TM2ICR, @@ -209,17 +209,17 @@ struct mn10300_serial_port mn10300_serial_port_sif1 = { ._intr = &SC1ICR, ._rxb = &SC1RXB, ._txb = &SC1TXB, - .rx_name = "ttySM1:Rx", - .tx_name = "ttySM1:Tx", + .rx_name = "ttySM1/Rx", + .tx_name = "ttySM1/Tx", #ifdef CONFIG_MN10300_TTYSM1_TIMER9 - .tm_name = "ttySM1:Timer9", + .tm_name = "ttySM1/Timer9", ._tmxmd = &TM9MD, ._tmxbr = &TM9BR, ._tmicr = &TM9ICR, .tm_irq = TM9IRQ, .div_timer = MNSCx_DIV_TIMER_16BIT, #else /* CONFIG_MN10300_TTYSM1_TIMER3 */ - .tm_name = "ttySM1:Timer3", + .tm_name = "ttySM1/Timer3", ._tmxmd = &TM3MD, ._tmxbr = (volatile u16 *) &TM3BR, ._tmicr = &TM3ICR, @@ -260,9 +260,9 @@ struct mn10300_serial_port mn10300_serial_port_sif2 = { .uart.lock = __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif2.uart.lock), .name = "ttySM2", - .rx_name = "ttySM2:Rx", - .tx_name = "ttySM2:Tx", - .tm_name = "ttySM2:Timer10", + .rx_name = "ttySM2/Rx", + .tx_name = "ttySM2/Tx", + .tm_name = "ttySM2/Timer10", ._iobase = &SC2CTR, ._control = &SC2CTR, ._status = &SC2STR, diff --git a/trunk/arch/parisc/include/asm/compat.h b/trunk/arch/parisc/include/asm/compat.h index efa0b60c63fe..02b77baa5da6 100644 --- a/trunk/arch/parisc/include/asm/compat.h +++ b/trunk/arch/parisc/include/asm/compat.h @@ -147,7 +147,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static __inline__ void __user *arch_compat_alloc_user_space(long len) +static __inline__ void __user *compat_alloc_user_space(long len) { struct pt_regs *regs = ¤t->thread.regs; return (void __user *)regs->gr[30]; diff --git a/trunk/arch/powerpc/include/asm/compat.h b/trunk/arch/powerpc/include/asm/compat.h index a11d4eac4f97..396d21a80058 100644 --- a/trunk/arch/powerpc/include/asm/compat.h +++ b/trunk/arch/powerpc/include/asm/compat.h @@ -134,7 +134,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static inline void __user *arch_compat_alloc_user_space(long len) +static inline void __user *compat_alloc_user_space(long len) { struct pt_regs *regs = current->thread.regs; unsigned long usp = regs->gpr[1]; diff --git a/trunk/arch/s390/include/asm/compat.h b/trunk/arch/s390/include/asm/compat.h index a875c2f542e1..104f2007f097 100644 --- a/trunk/arch/s390/include/asm/compat.h +++ b/trunk/arch/s390/include/asm/compat.h @@ -181,7 +181,7 @@ static inline int is_compat_task(void) #endif -static inline void __user *arch_compat_alloc_user_space(long len) +static inline void __user *compat_alloc_user_space(long len) { unsigned long stack; diff --git a/trunk/arch/sparc/include/asm/compat.h b/trunk/arch/sparc/include/asm/compat.h index 6f57325bb883..5016f76ea98a 100644 --- a/trunk/arch/sparc/include/asm/compat.h +++ b/trunk/arch/sparc/include/asm/compat.h @@ -167,7 +167,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static inline void __user *arch_compat_alloc_user_space(long len) +static inline void __user *compat_alloc_user_space(long len) { struct pt_regs *regs = current_thread_info()->kregs; unsigned long usp = regs->u_regs[UREG_I6]; diff --git a/trunk/arch/tile/include/asm/compat.h b/trunk/arch/tile/include/asm/compat.h index 345d81ce44bb..5a34da6cdd79 100644 --- a/trunk/arch/tile/include/asm/compat.h +++ b/trunk/arch/tile/include/asm/compat.h @@ -195,7 +195,7 @@ static inline unsigned long ptr_to_compat_reg(void __user *uptr) return (long)(int)(long __force)uptr; } -static inline void __user *arch_compat_alloc_user_space(long len) +static inline void __user *compat_alloc_user_space(long len) { struct pt_regs *regs = task_pt_regs(current); return (void __user *)regs->sp - len; diff --git a/trunk/arch/x86/ia32/ia32entry.S b/trunk/arch/x86/ia32/ia32entry.S index 518bb99c3394..b86feabed69b 100644 --- a/trunk/arch/x86/ia32/ia32entry.S +++ b/trunk/arch/x86/ia32/ia32entry.S @@ -50,12 +50,7 @@ /* * Reload arg registers from stack in case ptrace changed them. * We don't reload %eax because syscall_trace_enter() returned - * the %rax value we should see. Instead, we just truncate that - * value to 32 bits again as we did on entry from user mode. - * If it's a new value set by user_regset during entry tracing, - * this matches the normal truncation of the user-mode value. - * If it's -1 to make us punt the syscall, then (u32)-1 is still - * an appropriately invalid value. + * the value it wants us to use in the table lookup. */ .macro LOAD_ARGS32 offset, _r9=0 .if \_r9 @@ -65,7 +60,6 @@ movl \offset+48(%rsp),%edx movl \offset+56(%rsp),%esi movl \offset+64(%rsp),%edi - movl %eax,%eax /* zero extension */ .endm .macro CFI_STARTPROC32 simple @@ -159,7 +153,7 @@ ENTRY(ia32_sysenter_target) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) CFI_REMEMBER_STATE jnz sysenter_tracesys - cmpq $(IA32_NR_syscalls-1),%rax + cmpl $(IA32_NR_syscalls-1),%eax ja ia32_badsys sysenter_do_call: IA32_ARG_FIXUP @@ -201,7 +195,7 @@ sysexit_from_sys_call: movl $AUDIT_ARCH_I386,%edi /* 1st arg: audit arch */ call audit_syscall_entry movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall number */ - cmpq $(IA32_NR_syscalls-1),%rax + cmpl $(IA32_NR_syscalls-1),%eax ja ia32_badsys movl %ebx,%edi /* reload 1st syscall arg */ movl RCX-ARGOFFSET(%rsp),%esi /* reload 2nd syscall arg */ @@ -254,7 +248,7 @@ sysenter_tracesys: call syscall_trace_enter LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST - cmpq $(IA32_NR_syscalls-1),%rax + cmpl $(IA32_NR_syscalls-1),%eax ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */ jmp sysenter_do_call CFI_ENDPROC @@ -320,7 +314,7 @@ ENTRY(ia32_cstar_target) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) CFI_REMEMBER_STATE jnz cstar_tracesys - cmpq $IA32_NR_syscalls-1,%rax + cmpl $IA32_NR_syscalls-1,%eax ja ia32_badsys cstar_do_call: IA32_ARG_FIXUP 1 @@ -373,7 +367,7 @@ cstar_tracesys: LOAD_ARGS32 ARGOFFSET, 1 /* reload args from stack in case ptrace changed it */ RESTORE_REST xchgl %ebp,%r9d - cmpq $(IA32_NR_syscalls-1),%rax + cmpl $(IA32_NR_syscalls-1),%eax ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */ jmp cstar_do_call END(ia32_cstar_target) @@ -431,7 +425,7 @@ ENTRY(ia32_syscall) orl $TS_COMPAT,TI_status(%r10) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) jnz ia32_tracesys - cmpq $(IA32_NR_syscalls-1),%rax + cmpl $(IA32_NR_syscalls-1),%eax ja ia32_badsys ia32_do_call: IA32_ARG_FIXUP @@ -450,7 +444,7 @@ ia32_tracesys: call syscall_trace_enter LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST - cmpq $(IA32_NR_syscalls-1),%rax + cmpl $(IA32_NR_syscalls-1),%eax ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ jmp ia32_do_call END(ia32_syscall) diff --git a/trunk/arch/x86/include/asm/compat.h b/trunk/arch/x86/include/asm/compat.h index 1d9cd27c2920..306160e58b48 100644 --- a/trunk/arch/x86/include/asm/compat.h +++ b/trunk/arch/x86/include/asm/compat.h @@ -205,7 +205,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static inline void __user *arch_compat_alloc_user_space(long len) +static inline void __user *compat_alloc_user_space(long len) { struct pt_regs *regs = task_pt_regs(current); return (void __user *)regs->sp - len; diff --git a/trunk/drivers/gpu/drm/drm_crtc_helper.c b/trunk/drivers/gpu/drm/drm_crtc_helper.c index d2ab01e90a96..4238a19c36db 100644 --- a/trunk/drivers/gpu/drm/drm_crtc_helper.c +++ b/trunk/drivers/gpu/drm/drm_crtc_helper.c @@ -104,7 +104,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, connector->funcs->force(connector); } else { connector->status = connector->funcs->detect(connector); - drm_helper_hpd_irq_event(dev); + drm_kms_helper_poll_enable(dev); } if (connector->status == connector_status_disconnected) { diff --git a/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c index 3f7292486024..0c52899be964 100644 --- a/trunk/drivers/hid/hid-core.c +++ b/trunk/drivers/hid/hid-core.c @@ -1285,11 +1285,8 @@ static const struct hid_device_id hid_blacklist[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, @@ -1581,6 +1578,7 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) }, { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) }, { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT)}, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)}, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)}, { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, diff --git a/trunk/drivers/hid/hid-ids.h b/trunk/drivers/hid/hid-ids.h index 765a4f53eb5c..85c6d13c9ffa 100644 --- a/trunk/drivers/hid/hid-ids.h +++ b/trunk/drivers/hid/hid-ids.h @@ -105,7 +105,6 @@ #define USB_VENDOR_ID_ASUS 0x0486 #define USB_DEVICE_ID_ASUS_T91MT 0x0185 -#define USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO 0x0186 #define USB_VENDOR_ID_ASUSTEK 0x0b05 #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 @@ -129,7 +128,6 @@ #define USB_VENDOR_ID_BTC 0x046e #define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 -#define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577 #define USB_VENDOR_ID_CANDO 0x2087 #define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 @@ -151,7 +149,6 @@ #define USB_VENDOR_ID_CHICONY 0x04f2 #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 -#define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d #define USB_VENDOR_ID_CIDC 0x1677 @@ -510,7 +507,6 @@ #define USB_VENDOR_ID_UCLOGIC 0x5543 #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 #define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 -#define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001 #define USB_VENDOR_ID_VERNIER 0x08f7 #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 diff --git a/trunk/drivers/hid/hid-mosart.c b/trunk/drivers/hid/hid-mosart.c index ac5421d568f1..e91437c18906 100644 --- a/trunk/drivers/hid/hid-mosart.c +++ b/trunk/drivers/hid/hid-mosart.c @@ -239,7 +239,6 @@ static void mosart_remove(struct hid_device *hdev) static const struct hid_device_id mosart_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, { } }; MODULE_DEVICE_TABLE(hid, mosart_devices); diff --git a/trunk/drivers/hid/hid-topseed.c b/trunk/drivers/hid/hid-topseed.c index 956ed9ac19d4..5771f851f856 100644 --- a/trunk/drivers/hid/hid-topseed.c +++ b/trunk/drivers/hid/hid-topseed.c @@ -64,7 +64,6 @@ static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi, static const struct hid_device_id ts_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, { } }; diff --git a/trunk/drivers/hid/usbhid/hid-core.c b/trunk/drivers/hid/usbhid/hid-core.c index 599041a7f670..b729c0286679 100644 --- a/trunk/drivers/hid/usbhid/hid-core.c +++ b/trunk/drivers/hid/usbhid/hid-core.c @@ -828,7 +828,6 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co } } else { int skipped_report_id = 0; - int report_id = buf[0]; if (buf[0] == 0x0) { /* Don't send the Report ID */ buf++; @@ -838,7 +837,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), HID_REQ_SET_REPORT, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - ((report_type + 1) << 8) | report_id, + ((report_type + 1) << 8) | *buf, interface->desc.bInterfaceNumber, buf, count, USB_CTRL_SET_TIMEOUT); /* count also the report id, if this was a numbered report. */ @@ -1446,11 +1445,6 @@ static const struct hid_device_id hid_usb_table[] = { { } }; -struct usb_interface *usbhid_find_interface(int minor) -{ - return usb_find_interface(&hid_driver, minor); -} - static struct hid_driver hid_usb_driver = { .name = "generic-usb", .id_table = hid_usb_table, diff --git a/trunk/drivers/hid/usbhid/hid-quirks.c b/trunk/drivers/hid/usbhid/hid-quirks.c index 70da3181c8a0..2643d3147621 100644 --- a/trunk/drivers/hid/usbhid/hid-quirks.c +++ b/trunk/drivers/hid/usbhid/hid-quirks.c @@ -33,7 +33,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, @@ -70,7 +69,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, @@ -79,8 +77,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE }, - { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT }, - { 0, 0 } }; diff --git a/trunk/drivers/hid/usbhid/hiddev.c b/trunk/drivers/hid/usbhid/hiddev.c index 681e620eb95b..0a29c51114aa 100644 --- a/trunk/drivers/hid/usbhid/hiddev.c +++ b/trunk/drivers/hid/usbhid/hiddev.c @@ -270,7 +270,7 @@ static int hiddev_open(struct inode *inode, struct file *file) struct hiddev *hiddev; int res; - intf = usbhid_find_interface(iminor(inode)); + intf = usb_find_interface(&hiddev_driver, iminor(inode)); if (!intf) return -ENODEV; hid = usb_get_intfdata(intf); diff --git a/trunk/drivers/hid/usbhid/usbhid.h b/trunk/drivers/hid/usbhid/usbhid.h index 89d2e847dcc6..693fd3e720df 100644 --- a/trunk/drivers/hid/usbhid/usbhid.h +++ b/trunk/drivers/hid/usbhid/usbhid.h @@ -42,7 +42,6 @@ void usbhid_submit_report (struct hid_device *hid, struct hid_report *report, unsigned char dir); int usbhid_get_power(struct hid_device *hid); void usbhid_put_power(struct hid_device *hid); -struct usb_interface *usbhid_find_interface(int minor); /* iofl flags */ #define HID_CTRL_RUNNING 1 diff --git a/trunk/drivers/mtd/nand/bf5xx_nand.c b/trunk/drivers/mtd/nand/bf5xx_nand.c index 6fbeefa3a766..a382e3dd0a5d 100644 --- a/trunk/drivers/mtd/nand/bf5xx_nand.c +++ b/trunk/drivers/mtd/nand/bf5xx_nand.c @@ -682,6 +682,7 @@ static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info) static int __devexit bf5xx_nand_remove(struct platform_device *pdev) { struct bf5xx_nand_info *info = to_nand_info(pdev); + struct mtd_info *mtd = NULL; platform_set_drvdata(pdev, NULL); @@ -689,7 +690,11 @@ static int __devexit bf5xx_nand_remove(struct platform_device *pdev) * and their partitions, then go through freeing the * resources used */ - nand_release(&info->mtd); + mtd = &info->mtd; + if (mtd) { + nand_release(mtd); + kfree(mtd); + } peripheral_free_list(bfin_nfc_pin_req); bf5xx_nand_dma_remove(info); @@ -705,7 +710,7 @@ static int bf5xx_nand_scan(struct mtd_info *mtd) struct nand_chip *chip = mtd->priv; int ret; - ret = nand_scan_ident(mtd, 1, NULL); + ret = nand_scan_ident(mtd, 1); if (ret) return ret; diff --git a/trunk/drivers/mtd/nand/mxc_nand.c b/trunk/drivers/mtd/nand/mxc_nand.c index b2828e84d243..fcf8ceb277d4 100644 --- a/trunk/drivers/mtd/nand/mxc_nand.c +++ b/trunk/drivers/mtd/nand/mxc_nand.c @@ -67,9 +67,7 @@ #define NFC_V1_V2_CONFIG1_BIG (1 << 5) #define NFC_V1_V2_CONFIG1_RST (1 << 6) #define NFC_V1_V2_CONFIG1_CE (1 << 7) -#define NFC_V2_CONFIG1_ONE_CYCLE (1 << 8) -#define NFC_V2_CONFIG1_PPB(x) (((x) & 0x3) << 9) -#define NFC_V2_CONFIG1_FP_INT (1 << 11) +#define NFC_V1_V2_CONFIG1_ONE_CYCLE (1 << 8) #define NFC_V1_V2_CONFIG2_INT (1 << 15) @@ -404,16 +402,16 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host) /* Wait for operation to complete */ wait_op_done(host, true); - memcpy(host->data_buf, host->main_area0, 16); - if (this->options & NAND_BUSWIDTH_16) { + void __iomem *main_buf = host->main_area0; /* compress the ID info */ - host->data_buf[1] = host->data_buf[2]; - host->data_buf[2] = host->data_buf[4]; - host->data_buf[3] = host->data_buf[6]; - host->data_buf[4] = host->data_buf[8]; - host->data_buf[5] = host->data_buf[10]; + writeb(readb(main_buf + 2), main_buf + 1); + writeb(readb(main_buf + 4), main_buf + 2); + writeb(readb(main_buf + 6), main_buf + 3); + writeb(readb(main_buf + 8), main_buf + 4); + writeb(readb(main_buf + 10), main_buf + 5); } + memcpy(host->data_buf, host->main_area0, 16); } static uint16_t get_dev_status_v3(struct mxc_nand_host *host) @@ -731,30 +729,27 @@ static void preset_v1_v2(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - uint16_t config1 = 0; - - if (nand_chip->ecc.mode == NAND_ECC_HW) - config1 |= NFC_V1_V2_CONFIG1_ECC_EN; - - if (nfc_is_v21()) - config1 |= NFC_V2_CONFIG1_FP_INT; - - if (!cpu_is_mx21()) - config1 |= NFC_V1_V2_CONFIG1_INT_MSK; + uint16_t tmp; + + /* enable interrupt, disable spare enable */ + tmp = readw(NFC_V1_V2_CONFIG1); + tmp &= ~NFC_V1_V2_CONFIG1_INT_MSK; + tmp &= ~NFC_V1_V2_CONFIG1_SP_EN; + if (nand_chip->ecc.mode == NAND_ECC_HW) { + tmp |= NFC_V1_V2_CONFIG1_ECC_EN; + } else { + tmp &= ~NFC_V1_V2_CONFIG1_ECC_EN; + } if (nfc_is_v21() && mtd->writesize) { - uint16_t pages_per_block = mtd->erasesize / mtd->writesize; - host->eccsize = get_eccsize(mtd); if (host->eccsize == 4) - config1 |= NFC_V2_CONFIG1_ECC_MODE_4; - - config1 |= NFC_V2_CONFIG1_PPB(ffs(pages_per_block) - 6); + tmp |= NFC_V2_CONFIG1_ECC_MODE_4; } else { host->eccsize = 1; } - writew(config1, NFC_V1_V2_CONFIG1); + writew(tmp, NFC_V1_V2_CONFIG1); /* preset operation */ /* Unlock the internal RAM Buffer */ diff --git a/trunk/drivers/mtd/nand/pxa3xx_nand.c b/trunk/drivers/mtd/nand/pxa3xx_nand.c index 4d01cda68844..4d89f3780207 100644 --- a/trunk/drivers/mtd/nand/pxa3xx_nand.c +++ b/trunk/drivers/mtd/nand/pxa3xx_nand.c @@ -1320,7 +1320,6 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) goto fail_free_irq; } -#ifdef CONFIG_MTD_PARTITIONS if (mtd_has_cmdlinepart()) { static const char *probes[] = { "cmdlinepart", NULL }; struct mtd_partition *parts; @@ -1333,9 +1332,6 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) } return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); -#else - return 0; -#endif fail_free_irq: free_irq(irq, info); @@ -1368,9 +1364,7 @@ static int pxa3xx_nand_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); del_mtd_device(mtd); -#ifdef CONFIG_MTD_PARTITIONS del_mtd_partitions(mtd); -#endif irq = platform_get_irq(pdev, 0); if (irq >= 0) free_irq(irq, info); diff --git a/trunk/drivers/mtd/onenand/samsung.c b/trunk/drivers/mtd/onenand/samsung.c index a460f1b748c2..cb443af3d45f 100644 --- a/trunk/drivers/mtd/onenand/samsung.c +++ b/trunk/drivers/mtd/onenand/samsung.c @@ -554,13 +554,14 @@ static int s5pc110_dma_ops(void *dst, void *src, size_t count, int direction) do { status = readl(base + S5PC110_DMA_TRANS_STATUS); - if (status & S5PC110_DMA_TRANS_STATUS_TE) { - writel(S5PC110_DMA_TRANS_CMD_TEC, - base + S5PC110_DMA_TRANS_CMD); - return -EIO; - } } while (!(status & S5PC110_DMA_TRANS_STATUS_TD)); + if (status & S5PC110_DMA_TRANS_STATUS_TE) { + writel(S5PC110_DMA_TRANS_CMD_TEC, base + S5PC110_DMA_TRANS_CMD); + writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD); + return -EIO; + } + writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD); return 0; @@ -570,12 +571,13 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area, unsigned char *buffer, int offset, size_t count) { struct onenand_chip *this = mtd->priv; + void __iomem *bufferram; void __iomem *p; void *buf = (void *) buffer; dma_addr_t dma_src, dma_dst; int err; - p = this->base + area; + p = bufferram = this->base + area; if (ONENAND_CURRENT_BUFFERRAM(this)) { if (area == ONENAND_DATARAM) p += this->writesize; @@ -619,7 +621,7 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area, normal: if (count != mtd->writesize) { /* Copy the bufferram to memory to prevent unaligned access */ - memcpy(this->page_buf, p, mtd->writesize); + memcpy(this->page_buf, bufferram, mtd->writesize); p = this->page_buf + offset; } diff --git a/trunk/drivers/net/ll_temac_main.c b/trunk/drivers/net/ll_temac_main.c index 87f0a93b165c..bdf2149e5296 100644 --- a/trunk/drivers/net/ll_temac_main.c +++ b/trunk/drivers/net/ll_temac_main.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include /* needed for sizeof(tcphdr) */ diff --git a/trunk/drivers/net/ll_temac_mdio.c b/trunk/drivers/net/ll_temac_mdio.c index 8cf9d4f56bb2..5ae28c975b38 100644 --- a/trunk/drivers/net/ll_temac_mdio.c +++ b/trunk/drivers/net/ll_temac_mdio.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/serial/mpc52xx_uart.c b/trunk/drivers/serial/mpc52xx_uart.c index c4399e23565a..8dedb266f143 100644 --- a/trunk/drivers/serial/mpc52xx_uart.c +++ b/trunk/drivers/serial/mpc52xx_uart.c @@ -500,7 +500,6 @@ static int __init mpc512x_psc_fifoc_init(void) psc_fifoc = of_iomap(np, 0); if (!psc_fifoc) { pr_err("%s: Can't map FIFOC\n", __func__); - of_node_put(np); return -ENODEV; } diff --git a/trunk/drivers/spi/amba-pl022.c b/trunk/drivers/spi/amba-pl022.c index 4c37c4e28647..acd35d1ebd12 100644 --- a/trunk/drivers/spi/amba-pl022.c +++ b/trunk/drivers/spi/amba-pl022.c @@ -503,9 +503,8 @@ static void giveback(struct pl022 *pl022) msg->state = NULL; if (msg->complete) msg->complete(msg->context); - /* This message is completed, so let's turn off the clocks! */ + /* This message is completed, so let's turn off the clock! */ clk_disable(pl022->clk); - amba_pclk_disable(pl022->adev); } /** @@ -1140,10 +1139,9 @@ static void pump_messages(struct work_struct *work) /* Setup the SPI using the per chip configuration */ pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); /* - * We enable the clocks here, then the clocks will be disabled when + * We enable the clock here, then the clock will be disabled when * giveback() is called in each method (poll/interrupt/DMA) */ - amba_pclk_enable(pl022->adev); clk_enable(pl022->clk); restore_state(pl022); flush(pl022); @@ -1788,9 +1786,11 @@ pl022_probe(struct amba_device *adev, struct amba_id *id) } /* Disable SSP */ + clk_enable(pl022->clk); writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); load_ssp_default_config(pl022); + clk_disable(pl022->clk); status = request_irq(adev->irq[0], pl022_interrupt_handler, 0, "pl022", pl022); @@ -1818,8 +1818,6 @@ pl022_probe(struct amba_device *adev, struct amba_id *id) goto err_spi_register; } dev_dbg(dev, "probe succeded\n"); - /* Disable the silicon block pclk and clock it when needed */ - amba_pclk_disable(adev); return 0; err_spi_register: @@ -1881,9 +1879,9 @@ static int pl022_suspend(struct amba_device *adev, pm_message_t state) return status; } - amba_pclk_enable(adev); + clk_enable(pl022->clk); load_ssp_default_config(pl022); - amba_pclk_disable(adev); + clk_disable(pl022->clk); dev_dbg(&adev->dev, "suspended\n"); return 0; } @@ -1983,7 +1981,7 @@ static int __init pl022_init(void) return amba_driver_register(&pl022_driver); } -subsys_initcall(pl022_init); +module_init(pl022_init); static void __exit pl022_exit(void) { diff --git a/trunk/drivers/spi/dw_spi.c b/trunk/drivers/spi/dw_spi.c index 56247853c298..d256cb00604c 100644 --- a/trunk/drivers/spi/dw_spi.c +++ b/trunk/drivers/spi/dw_spi.c @@ -181,6 +181,10 @@ static void flush(struct dw_spi *dws) wait_till_not_busy(dws); } +static void null_cs_control(u32 command) +{ +} + static int null_writer(struct dw_spi *dws) { u8 n_bytes = dws->n_bytes; @@ -318,7 +322,7 @@ static void giveback(struct dw_spi *dws) struct spi_transfer, transfer_list); - if (!last_transfer->cs_change && dws->cs_control) + if (!last_transfer->cs_change) dws->cs_control(MRST_SPI_DEASSERT); msg->state = NULL; @@ -392,11 +396,6 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws) static irqreturn_t dw_spi_irq(int irq, void *dev_id) { struct dw_spi *dws = dev_id; - u16 irq_status, irq_mask = 0x3f; - - irq_status = dw_readw(dws, isr) & irq_mask; - if (!irq_status) - return IRQ_NONE; if (!dws->cur_msg) { spi_mask_intr(dws, SPI_INT_TXEI); @@ -545,13 +544,13 @@ static void pump_transfers(unsigned long data) */ if (dws->cs_control) { if (dws->rx && dws->tx) - chip->tmode = SPI_TMOD_TR; + chip->tmode = 0x00; else if (dws->rx) - chip->tmode = SPI_TMOD_RO; + chip->tmode = 0x02; else - chip->tmode = SPI_TMOD_TO; + chip->tmode = 0x01; - cr0 &= ~SPI_TMOD_MASK; + cr0 &= ~(0x3 << SPI_MODE_OFFSET); cr0 |= (chip->tmode << SPI_TMOD_OFFSET); } @@ -700,6 +699,9 @@ static int dw_spi_setup(struct spi_device *spi) chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); if (!chip) return -ENOMEM; + + chip->cs_control = null_cs_control; + chip->enable_dma = 0; } /* @@ -881,7 +883,7 @@ int __devinit dw_spi_add_host(struct dw_spi *dws) dws->dma_inited = 0; dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60); - ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, + ret = request_irq(dws->irq, dw_spi_irq, 0, "dw_spi", dws); if (ret < 0) { dev_err(&master->dev, "can not get IRQ\n"); diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index 0bcf4c1601a2..a9e5c79ae52a 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -554,9 +554,11 @@ int spi_register_master(struct spi_master *master) EXPORT_SYMBOL_GPL(spi_register_master); -static int __unregister(struct device *dev, void *null) +static int __unregister(struct device *dev, void *master_dev) { - spi_unregister_device(to_spi_device(dev)); + /* note: before about 2.6.14-rc1 this would corrupt memory: */ + if (dev != master_dev) + spi_unregister_device(to_spi_device(dev)); return 0; } @@ -574,7 +576,8 @@ void spi_unregister_master(struct spi_master *master) { int dummy; - dummy = device_for_each_child(&master->dev, NULL, __unregister); + dummy = device_for_each_child(master->dev.parent, &master->dev, + __unregister); device_unregister(&master->dev); } EXPORT_SYMBOL_GPL(spi_unregister_master); diff --git a/trunk/drivers/spi/spi_s3c64xx.c b/trunk/drivers/spi/spi_s3c64xx.c index c3038da2648a..97365815a729 100644 --- a/trunk/drivers/spi/spi_s3c64xx.c +++ b/trunk/drivers/spi/spi_s3c64xx.c @@ -200,9 +200,6 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) val = readl(regs + S3C64XX_SPI_STATUS); } while (TX_FIFO_LVL(val, sci) && loops--); - if (loops == 0) - dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n"); - /* Flush RxFIFO*/ loops = msecs_to_loops(1); do { @@ -213,9 +210,6 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) break; } while (loops--); - if (loops == 0) - dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n"); - val = readl(regs + S3C64XX_SPI_CH_CFG); val &= ~S3C64XX_SPI_CH_SW_RST; writel(val, regs + S3C64XX_SPI_CH_CFG); @@ -326,17 +320,16 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd, /* millisecs to xfer 'len' bytes @ 'cur_speed' */ ms = xfer->len * 8 * 1000 / sdd->cur_speed; - ms += 10; /* some tolerance */ + ms += 5; /* some tolerance */ if (dma_mode) { val = msecs_to_jiffies(ms) + 10; val = wait_for_completion_timeout(&sdd->xfer_completion, val); } else { - u32 status; val = msecs_to_loops(ms); do { - status = readl(regs + S3C64XX_SPI_STATUS); - } while (RX_FIFO_LVL(status, sci) < xfer->len && --val); + val = readl(regs + S3C64XX_SPI_STATUS); + } while (RX_FIFO_LVL(val, sci) < xfer->len && --val); } if (!val) @@ -454,8 +447,8 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) writel(val, regs + S3C64XX_SPI_CLK_CFG); } -static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id, - int size, enum s3c2410_dma_buffresult res) +void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id, + int size, enum s3c2410_dma_buffresult res) { struct s3c64xx_spi_driver_data *sdd = buf_id; unsigned long flags; @@ -474,8 +467,8 @@ static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id, spin_unlock_irqrestore(&sdd->lock, flags); } -static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id, - int size, enum s3c2410_dma_buffresult res) +void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id, + int size, enum s3c2410_dma_buffresult res) { struct s3c64xx_spi_driver_data *sdd = buf_id; unsigned long flags; @@ -515,9 +508,8 @@ static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd, list_for_each_entry(xfer, &msg->transfers, transfer_list) { if (xfer->tx_buf != NULL) { - xfer->tx_dma = dma_map_single(dev, - (void *)xfer->tx_buf, xfer->len, - DMA_TO_DEVICE); + xfer->tx_dma = dma_map_single(dev, xfer->tx_buf, + xfer->len, DMA_TO_DEVICE); if (dma_mapping_error(dev, xfer->tx_dma)) { dev_err(dev, "dma_map_single Tx failed\n"); xfer->tx_dma = XFER_DMAADDR_INVALID; @@ -927,13 +919,6 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) return -ENODEV; } - sci = pdev->dev.platform_data; - if (!sci->src_clk_name) { - dev_err(&pdev->dev, - "Board init must call s3c64xx_spi_set_info()\n"); - return -EINVAL; - } - /* Check for availability of necessary resource */ dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); @@ -961,6 +946,8 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) return -ENOMEM; } + sci = pdev->dev.platform_data; + platform_set_drvdata(pdev, master); sdd = spi_master_get_devdata(master); @@ -1183,7 +1170,7 @@ static int __init s3c64xx_spi_init(void) { return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe); } -subsys_initcall(s3c64xx_spi_init); +module_init(s3c64xx_spi_init); static void __exit s3c64xx_spi_exit(void) { diff --git a/trunk/fs/9p/vfs_dir.c b/trunk/fs/9p/vfs_dir.c index 899f168fd19c..16c8a2a98c1b 100644 --- a/trunk/fs/9p/vfs_dir.c +++ b/trunk/fs/9p/vfs_dir.c @@ -292,11 +292,9 @@ int v9fs_dir_release(struct inode *inode, struct file *filp) fid = filp->private_data; P9_DPRINTK(P9_DEBUG_VFS, - "v9fs_dir_release: inode: %p filp: %p fid: %d\n", - inode, filp, fid ? fid->fid : -1); + "inode: %p filp: %p fid: %d\n", inode, filp, fid->fid); filemap_write_and_wait(inode->i_mapping); - if (fid) - p9_client_clunk(fid); + p9_client_clunk(fid); return 0; } diff --git a/trunk/fs/9p/vfs_inode.c b/trunk/fs/9p/vfs_inode.c index 9e670d527646..c7c23eab9440 100644 --- a/trunk/fs/9p/vfs_inode.c +++ b/trunk/fs/9p/vfs_inode.c @@ -730,10 +730,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int mode, P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); goto error; } - if (v9ses->cache) - dentry->d_op = &v9fs_cached_dentry_operations; - else - dentry->d_op = &v9fs_dentry_operations; + dentry->d_op = &v9fs_cached_dentry_operations; d_instantiate(dentry, inode); err = v9fs_fid_add(dentry, fid); if (err < 0) @@ -1131,7 +1128,6 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb); generic_fillattr(dentry->d_inode, stat); - p9stat_free(st); kfree(st); return 0; } @@ -1493,7 +1489,6 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) retval = strnlen(buffer, buflen); done: - p9stat_free(st); kfree(st); return retval; } @@ -1947,7 +1942,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotu = { .unlink = v9fs_vfs_unlink, .mkdir = v9fs_vfs_mkdir, .rmdir = v9fs_vfs_rmdir, - .mknod = v9fs_vfs_mknod, + .mknod = v9fs_vfs_mknod_dotl, .rename = v9fs_vfs_rename, .getattr = v9fs_vfs_getattr, .setattr = v9fs_vfs_setattr, diff --git a/trunk/fs/9p/vfs_super.c b/trunk/fs/9p/vfs_super.c index 1d12ba0ed3db..f9311077de68 100644 --- a/trunk/fs/9p/vfs_super.c +++ b/trunk/fs/9p/vfs_super.c @@ -122,10 +122,6 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, fid = v9fs_session_init(v9ses, dev_name, data); if (IS_ERR(fid)) { retval = PTR_ERR(fid); - /* - * we need to call session_close to tear down some - * of the data structure setup by session_init - */ goto close_session; } @@ -148,6 +144,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, retval = -ENOMEM; goto release_sb; } + sb->s_root = root; if (v9fs_proto_dotl(v9ses)) { @@ -155,7 +152,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, st = p9_client_getattr_dotl(fid, P9_STATS_BASIC); if (IS_ERR(st)) { retval = PTR_ERR(st); - goto release_sb; + goto clunk_fid; } v9fs_stat2inode_dotl(st, root->d_inode); @@ -165,7 +162,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, st = p9_client_stat(fid); if (IS_ERR(st)) { retval = PTR_ERR(st); - goto release_sb; + goto clunk_fid; } root->d_inode->i_ino = v9fs_qid2ino(&st->qid); @@ -177,24 +174,19 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, v9fs_fid_add(root, fid); - P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n"); +P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n"); simple_set_mnt(mnt, sb); return 0; clunk_fid: p9_client_clunk(fid); + close_session: v9fs_session_close(v9ses); kfree(v9ses); return retval; + release_sb: - /* - * we will do the session_close and root dentry release - * in the below call. But we need to clunk fid, because we haven't - * attached the fid to dentry so it won't get clunked - * automatically. - */ - p9_client_clunk(fid); deactivate_locked_super(sb); return retval; } diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c index 1320b2a05fb2..3006b5bc33d6 100644 --- a/trunk/fs/aio.c +++ b/trunk/fs/aio.c @@ -1659,9 +1659,6 @@ long do_io_submit(aio_context_t ctx_id, long nr, if (unlikely(nr < 0)) return -EINVAL; - if (unlikely(nr > LONG_MAX/sizeof(*iocbpp))) - nr = LONG_MAX/sizeof(*iocbpp); - if (unlikely(!access_ok(VERIFY_READ, iocbpp, (nr*sizeof(*iocbpp))))) return -EFAULT; diff --git a/trunk/fs/cifs/Kconfig b/trunk/fs/cifs/Kconfig index 917b7d449bb2..0da1debd499d 100644 --- a/trunk/fs/cifs/Kconfig +++ b/trunk/fs/cifs/Kconfig @@ -2,6 +2,8 @@ config CIFS tristate "CIFS support (advanced network filesystem, SMBFS successor)" depends on INET select NLS + select CRYPTO_MD5 + select CRYPTO_ARC4 help This is the client VFS module for the Common Internet File System (CIFS) protocol which is the successor to the Server Message Block diff --git a/trunk/fs/cifs/asn1.c b/trunk/fs/cifs/asn1.c index cfd1ce34e0bc..21f0fbd86989 100644 --- a/trunk/fs/cifs/asn1.c +++ b/trunk/fs/cifs/asn1.c @@ -597,13 +597,13 @@ decode_negTokenInit(unsigned char *security_blob, int length, if (compare_oid(oid, oidlen, MSKRB5_OID, MSKRB5_OID_LEN)) server->sec_mskerberos = true; - else if (compare_oid(oid, oidlen, KRB5U2U_OID, + if (compare_oid(oid, oidlen, KRB5U2U_OID, KRB5U2U_OID_LEN)) server->sec_kerberosu2u = true; - else if (compare_oid(oid, oidlen, KRB5_OID, + if (compare_oid(oid, oidlen, KRB5_OID, KRB5_OID_LEN)) server->sec_kerberos = true; - else if (compare_oid(oid, oidlen, NTLMSSP_OID, + if (compare_oid(oid, oidlen, NTLMSSP_OID, NTLMSSP_OID_LEN)) server->sec_ntlmssp = true; diff --git a/trunk/fs/cifs/cifsencrypt.c b/trunk/fs/cifs/cifsencrypt.c index 35042d8f7338..709f2296bdb4 100644 --- a/trunk/fs/cifs/cifsencrypt.c +++ b/trunk/fs/cifs/cifsencrypt.c @@ -27,6 +27,7 @@ #include "md5.h" #include "cifs_unicode.h" #include "cifsproto.h" +#include "ntlmssp.h" #include #include @@ -42,21 +43,43 @@ extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24); static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, - const struct mac_key *key, char *signature) + struct TCP_Server_Info *server, char *signature) { - struct MD5Context context; + int rc; - if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL)) + if (cifs_pdu == NULL || server == NULL || signature == NULL) return -EINVAL; - cifs_MD5_init(&context); - cifs_MD5_update(&context, (char *)&key->data, key->len); - cifs_MD5_update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length); + if (!server->ntlmssp.sdescmd5) { + cERROR(1, + "cifs_calculate_signature: can't generate signature\n"); + return -1; + } - cifs_MD5_final(signature, &context); - return 0; + rc = crypto_shash_init(&server->ntlmssp.sdescmd5->shash); + if (rc) { + cERROR(1, "cifs_calculate_signature: oould not init md5\n"); + return rc; + } + + if (server->secType == RawNTLMSSP) + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, + server->session_key.data.ntlmv2.key, + CIFS_NTLMV2_SESSKEY_SIZE); + else + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, + (char *)&server->session_key.data, + server->session_key.len); + + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, + cifs_pdu->Protocol, cifs_pdu->smb_buf_length); + + rc = crypto_shash_final(&server->ntlmssp.sdescmd5->shash, signature); + + return rc; } + int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, __u32 *pexpected_response_sequence_number) { @@ -78,8 +101,7 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, server->sequence_number++; spin_unlock(&GlobalMid_Lock); - rc = cifs_calculate_signature(cifs_pdu, &server->mac_signing_key, - smb_signature); + rc = cifs_calculate_signature(cifs_pdu, server, smb_signature); if (rc) memset(cifs_pdu->Signature.SecuritySignature, 0, 8); else @@ -89,21 +111,39 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, } static int cifs_calc_signature2(const struct kvec *iov, int n_vec, - const struct mac_key *key, char *signature) + struct TCP_Server_Info *server, char *signature) { - struct MD5Context context; int i; + int rc; - if ((iov == NULL) || (signature == NULL) || (key == NULL)) + if (iov == NULL || server == NULL || signature == NULL) return -EINVAL; - cifs_MD5_init(&context); - cifs_MD5_update(&context, (char *)&key->data, key->len); + if (!server->ntlmssp.sdescmd5) { + cERROR(1, "cifs_calc_signature2: can't generate signature\n"); + return -1; + } + + rc = crypto_shash_init(&server->ntlmssp.sdescmd5->shash); + if (rc) { + cERROR(1, "cifs_calc_signature2: oould not init md5\n"); + return rc; + } + + if (server->secType == RawNTLMSSP) + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, + server->session_key.data.ntlmv2.key, + CIFS_NTLMV2_SESSKEY_SIZE); + else + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, + (char *)&server->session_key.data, + server->session_key.len); + for (i = 0; i < n_vec; i++) { if (iov[i].iov_len == 0) continue; if (iov[i].iov_base == NULL) { - cERROR(1, "null iovec entry"); + cERROR(1, "cifs_calc_signature2: null iovec entry"); return -EIO; } /* The first entry includes a length field (which does not get @@ -111,18 +151,18 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec, if (i == 0) { if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ break; /* nothing to sign or corrupt header */ - cifs_MD5_update(&context, iov[0].iov_base+4, - iov[0].iov_len-4); + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, + iov[i].iov_base + 4, iov[i].iov_len - 4); } else - cifs_MD5_update(&context, iov[i].iov_base, iov[i].iov_len); + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, + iov[i].iov_base, iov[i].iov_len); } - cifs_MD5_final(signature, &context); + rc = crypto_shash_final(&server->ntlmssp.sdescmd5->shash, signature); - return 0; + return rc; } - int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, __u32 *pexpected_response_sequence_number) { @@ -145,8 +185,7 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, server->sequence_number++; spin_unlock(&GlobalMid_Lock); - rc = cifs_calc_signature2(iov, n_vec, &server->mac_signing_key, - smb_signature); + rc = cifs_calc_signature2(iov, n_vec, server, smb_signature); if (rc) memset(cifs_pdu->Signature.SecuritySignature, 0, 8); else @@ -156,14 +195,14 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, } int cifs_verify_signature(struct smb_hdr *cifs_pdu, - const struct mac_key *mac_key, + struct TCP_Server_Info *server, __u32 expected_sequence_number) { - unsigned int rc; + int rc; char server_response_sig[8]; char what_we_think_sig_should_be[20]; - if ((cifs_pdu == NULL) || (mac_key == NULL)) + if (cifs_pdu == NULL || server == NULL) return -EINVAL; if (cifs_pdu->Command == SMB_COM_NEGOTIATE) @@ -192,7 +231,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, cpu_to_le32(expected_sequence_number); cifs_pdu->Signature.Sequence.Reserved = 0; - rc = cifs_calculate_signature(cifs_pdu, mac_key, + rc = cifs_calculate_signature(cifs_pdu, server, what_we_think_sig_should_be); if (rc) @@ -209,7 +248,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, } /* We fill in key by putting in 40 byte array which was allocated by caller */ -int cifs_calculate_mac_key(struct mac_key *key, const char *rn, +int cifs_calculate_session_key(struct session_key *key, const char *rn, const char *password) { char temp_key[16]; @@ -267,38 +306,52 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, { int rc = 0; int len; - char nt_hash[16]; - struct HMACMD5Context *pctxt; + char nt_hash[CIFS_NTHASH_SIZE]; wchar_t *user; wchar_t *domain; + wchar_t *server; - pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL); - - if (pctxt == NULL) - return -ENOMEM; + if (!ses->server->ntlmssp.sdeschmacmd5) { + cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); + return -1; + } /* calculate md4 hash of password */ E_md4hash(ses->password, nt_hash); - /* convert Domainname to unicode and uppercase */ - hmac_md5_init_limK_to_64(nt_hash, 16, pctxt); + crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, nt_hash, + CIFS_NTHASH_SIZE); + + rc = crypto_shash_init(&ses->server->ntlmssp.sdeschmacmd5->shash); + if (rc) { + cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n"); + return rc; + } /* convert ses->userName to unicode and uppercase */ len = strlen(ses->userName); user = kmalloc(2 + (len * 2), GFP_KERNEL); - if (user == NULL) + if (user == NULL) { + cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n"); + rc = -ENOMEM; goto calc_exit_2; + } len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); UniStrupr(user); - hmac_md5_update((char *)user, 2*len, pctxt); + + crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, + (char *)user, 2 * len); /* convert ses->domainName to unicode and uppercase */ if (ses->domainName) { len = strlen(ses->domainName); domain = kmalloc(2 + (len * 2), GFP_KERNEL); - if (domain == NULL) + if (domain == NULL) { + cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure"); + rc = -ENOMEM; goto calc_exit_1; + } len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, nls_cp); /* the following line was removed since it didn't work well @@ -306,65 +359,292 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, Maybe converting the domain name earlier makes sense */ /* UniStrupr(domain); */ - hmac_md5_update((char *)domain, 2*len, pctxt); + crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, + (char *)domain, 2 * len); kfree(domain); + } else if (ses->serverName) { + len = strlen(ses->serverName); + + server = kmalloc(2 + (len * 2), GFP_KERNEL); + if (server == NULL) { + cERROR(1, "calc_ntlmv2_hash: server mem alloc failure"); + rc = -ENOMEM; + goto calc_exit_1; + } + len = cifs_strtoUCS((__le16 *)server, ses->serverName, len, + nls_cp); + /* the following line was removed since it didn't work well + with lower cased domain name that passed as an option. + Maybe converting the domain name earlier makes sense */ + /* UniStrupr(domain); */ + + crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, + (char *)server, 2 * len); + + kfree(server); } + + rc = crypto_shash_final(&ses->server->ntlmssp.sdeschmacmd5->shash, + ses->server->ntlmv2_hash); + calc_exit_1: kfree(user); calc_exit_2: /* BB FIXME what about bytes 24 through 40 of the signing key? compare with the NTLM example */ - hmac_md5_final(ses->server->ntlmv2_hash, pctxt); - kfree(pctxt); return rc; } -void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, - const struct nls_table *nls_cp) +static int +find_domain_name(struct cifsSesInfo *ses) +{ + int rc = 0; + unsigned int attrsize; + unsigned int type; + unsigned char *blobptr; + struct ntlmssp2_name *attrptr; + + if (ses->server->tiblob) { + blobptr = ses->server->tiblob; + attrptr = (struct ntlmssp2_name *) blobptr; + + while ((type = attrptr->type) != 0) { + blobptr += 2; /* advance attr type */ + attrsize = attrptr->length; + blobptr += 2; /* advance attr size */ + if (type == NTLMSSP_AV_NB_DOMAIN_NAME) { + if (!ses->domainName) { + ses->domainName = + kmalloc(attrptr->length + 1, + GFP_KERNEL); + if (!ses->domainName) + return -ENOMEM; + cifs_from_ucs2(ses->domainName, + (__le16 *)blobptr, + attrptr->length, + attrptr->length, + load_nls_default(), false); + } + } + blobptr += attrsize; /* advance attr value */ + attrptr = (struct ntlmssp2_name *) blobptr; + } + } else { + ses->server->tilen = 2 * sizeof(struct ntlmssp2_name); + ses->server->tiblob = kmalloc(ses->server->tilen, GFP_KERNEL); + if (!ses->server->tiblob) { + ses->server->tilen = 0; + cERROR(1, "Challenge target info allocation failure"); + return -ENOMEM; + } + memset(ses->server->tiblob, 0x0, ses->server->tilen); + attrptr = (struct ntlmssp2_name *) ses->server->tiblob; + attrptr->type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE); + } + + return rc; +} + +static int +CalcNTLMv2_response(const struct TCP_Server_Info *server, + char *v2_session_response) { int rc; + + if (!server->ntlmssp.sdeschmacmd5) { + cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); + return -1; + } + + crypto_shash_setkey(server->ntlmssp.hmacmd5, server->ntlmv2_hash, + CIFS_HMAC_MD5_HASH_SIZE); + + rc = crypto_shash_init(&server->ntlmssp.sdeschmacmd5->shash); + if (rc) { + cERROR(1, "CalcNTLMv2_response: could not init hmacmd5"); + return rc; + } + + memcpy(v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, + server->cryptKey, CIFS_SERVER_CHALLENGE_SIZE); + crypto_shash_update(&server->ntlmssp.sdeschmacmd5->shash, + v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, + sizeof(struct ntlmv2_resp) - CIFS_SERVER_CHALLENGE_SIZE); + + if (server->tilen) + crypto_shash_update(&server->ntlmssp.sdeschmacmd5->shash, + server->tiblob, server->tilen); + + rc = crypto_shash_final(&server->ntlmssp.sdeschmacmd5->shash, + v2_session_response); + + return rc; +} + +int +setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, + const struct nls_table *nls_cp) +{ + int rc = 0; struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf; - struct HMACMD5Context context; buf->blob_signature = cpu_to_le32(0x00000101); buf->reserved = 0; buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); buf->reserved2 = 0; - buf->names[0].type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE); - buf->names[0].length = 0; - buf->names[1].type = 0; - buf->names[1].length = 0; + + if (!ses->domainName) { + rc = find_domain_name(ses); + if (rc) { + cERROR(1, "could not get domain/server name rc %d", rc); + return rc; + } + } /* calculate buf->ntlmv2_hash */ rc = calc_ntlmv2_hash(ses, nls_cp); - if (rc) + if (rc) { cERROR(1, "could not get v2 hash rc %d", rc); - CalcNTLMv2_response(ses, resp_buf); + return rc; + } + rc = CalcNTLMv2_response(ses->server, resp_buf); + if (rc) { + cERROR(1, "could not get v2 hash rc %d", rc); + return rc; + } + + if (!ses->server->ntlmssp.sdeschmacmd5) { + cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); + return -1; + } + + crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, + ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); - /* now calculate the MAC key for NTLMv2 */ - hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); - hmac_md5_update(resp_buf, 16, &context); - hmac_md5_final(ses->server->mac_signing_key.data.ntlmv2.key, &context); + rc = crypto_shash_init(&ses->server->ntlmssp.sdeschmacmd5->shash); + if (rc) { + cERROR(1, "setup_ntlmv2_rsp: could not init hmacmd5\n"); + return rc; + } - memcpy(&ses->server->mac_signing_key.data.ntlmv2.resp, resp_buf, - sizeof(struct ntlmv2_resp)); - ses->server->mac_signing_key.len = 16 + sizeof(struct ntlmv2_resp); + crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, + resp_buf, CIFS_HMAC_MD5_HASH_SIZE); + + rc = crypto_shash_final(&ses->server->ntlmssp.sdeschmacmd5->shash, + ses->server->session_key.data.ntlmv2.key); + + memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf, + sizeof(struct ntlmv2_resp)); + ses->server->session_key.len = 16 + sizeof(struct ntlmv2_resp); + + return rc; } -void CalcNTLMv2_response(const struct cifsSesInfo *ses, - char *v2_session_response) +int +calc_seckey(struct TCP_Server_Info *server) { - struct HMACMD5Context context; - /* rest of v2 struct already generated */ - memcpy(v2_session_response + 8, ses->server->cryptKey, 8); - hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); + int rc; + unsigned char sec_key[CIFS_NTLMV2_SESSKEY_SIZE]; + struct crypto_blkcipher *tfm_arc4; + struct scatterlist sgin, sgout; + struct blkcipher_desc desc; + + get_random_bytes(sec_key, CIFS_NTLMV2_SESSKEY_SIZE); + + tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", + 0, CRYPTO_ALG_ASYNC); + if (!tfm_arc4 || IS_ERR(tfm_arc4)) { + cERROR(1, "could not allocate " "master crypto API arc4\n"); + return 1; + } - hmac_md5_update(v2_session_response+8, - sizeof(struct ntlmv2_resp) - 8, &context); + desc.tfm = tfm_arc4; - hmac_md5_final(v2_session_response, &context); -/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */ + crypto_blkcipher_setkey(tfm_arc4, + server->session_key.data.ntlmv2.key, CIFS_CPHTXT_SIZE); + sg_init_one(&sgin, sec_key, CIFS_CPHTXT_SIZE); + sg_init_one(&sgout, server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE); + rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE); + + if (!rc) + memcpy(server->session_key.data.ntlmv2.key, + sec_key, CIFS_NTLMV2_SESSKEY_SIZE); + + crypto_free_blkcipher(tfm_arc4); + + return 0; +} + +void +cifs_crypto_shash_release(struct TCP_Server_Info *server) +{ + if (server->ntlmssp.md5) + crypto_free_shash(server->ntlmssp.md5); + + if (server->ntlmssp.hmacmd5) + crypto_free_shash(server->ntlmssp.hmacmd5); + + kfree(server->ntlmssp.sdeschmacmd5); + + kfree(server->ntlmssp.sdescmd5); +} + +int +cifs_crypto_shash_allocate(struct TCP_Server_Info *server) +{ + int rc; + unsigned int size; + + server->ntlmssp.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); + if (!server->ntlmssp.hmacmd5 || + IS_ERR(server->ntlmssp.hmacmd5)) { + cERROR(1, "could not allocate crypto hmacmd5\n"); + return 1; + } + + server->ntlmssp.md5 = crypto_alloc_shash("md5", 0, 0); + if (!server->ntlmssp.md5 || IS_ERR(server->ntlmssp.md5)) { + cERROR(1, "could not allocate crypto md5\n"); + rc = 1; + goto cifs_crypto_shash_allocate_ret1; + } + + size = sizeof(struct shash_desc) + + crypto_shash_descsize(server->ntlmssp.hmacmd5); + server->ntlmssp.sdeschmacmd5 = kmalloc(size, GFP_KERNEL); + if (!server->ntlmssp.sdeschmacmd5) { + cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n"); + rc = -ENOMEM; + goto cifs_crypto_shash_allocate_ret2; + } + server->ntlmssp.sdeschmacmd5->shash.tfm = server->ntlmssp.hmacmd5; + server->ntlmssp.sdeschmacmd5->shash.flags = 0x0; + + + size = sizeof(struct shash_desc) + + crypto_shash_descsize(server->ntlmssp.md5); + server->ntlmssp.sdescmd5 = kmalloc(size, GFP_KERNEL); + if (!server->ntlmssp.sdescmd5) { + cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n"); + rc = -ENOMEM; + goto cifs_crypto_shash_allocate_ret3; + } + server->ntlmssp.sdescmd5->shash.tfm = server->ntlmssp.md5; + server->ntlmssp.sdescmd5->shash.flags = 0x0; + + return 0; + +cifs_crypto_shash_allocate_ret3: + kfree(server->ntlmssp.sdeschmacmd5); + +cifs_crypto_shash_allocate_ret2: + crypto_free_shash(server->ntlmssp.md5); + +cifs_crypto_shash_allocate_ret1: + crypto_free_shash(server->ntlmssp.hmacmd5); + + return rc; } diff --git a/trunk/fs/cifs/cifsglob.h b/trunk/fs/cifs/cifsglob.h index 0cdfb8c32ac6..c9d0cfc086eb 100644 --- a/trunk/fs/cifs/cifsglob.h +++ b/trunk/fs/cifs/cifsglob.h @@ -25,6 +25,9 @@ #include #include "cifs_fs_sb.h" #include "cifsacl.h" +#include +#include + /* * The sizes of various internal tables and strings */ @@ -97,7 +100,7 @@ enum protocolEnum { /* Netbios frames protocol not supported at this time */ }; -struct mac_key { +struct session_key { unsigned int len; union { char ntlm[CIFS_SESS_KEY_SIZE + 16]; @@ -120,6 +123,21 @@ struct cifs_cred { struct cifs_ace *aces; }; +struct sdesc { + struct shash_desc shash; + char ctx[]; +}; + +struct ntlmssp_auth { + __u32 client_flags; + __u32 server_flags; + unsigned char ciphertext[CIFS_CPHTXT_SIZE]; + struct crypto_shash *hmacmd5; + struct crypto_shash *md5; + struct sdesc *sdeschmacmd5; + struct sdesc *sdescmd5; +}; + /* ***************************************************************** * Except the CIFS PDUs themselves all the @@ -182,11 +200,14 @@ struct TCP_Server_Info { /* 16th byte of RFC1001 workstation name is always null */ char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; __u32 sequence_number; /* needed for CIFS PDU signature */ - struct mac_key mac_signing_key; + struct session_key session_key; char ntlmv2_hash[16]; unsigned long lstrp; /* when we got last response from this server */ u16 dialect; /* dialect index that server chose */ /* extended security flavors that server supports */ + unsigned int tilen; /* length of the target info blob */ + unsigned char *tiblob; /* target info blob in challenge response */ + struct ntlmssp_auth ntlmssp; /* various keys, ciphers, flags */ bool sec_kerberos; /* supports plain Kerberos */ bool sec_mskerberos; /* supports legacy MS Kerberos */ bool sec_kerberosu2u; /* supports U2U Kerberos */ diff --git a/trunk/fs/cifs/cifspdu.h b/trunk/fs/cifs/cifspdu.h index 14d036d8db11..320e0fd0ba7b 100644 --- a/trunk/fs/cifs/cifspdu.h +++ b/trunk/fs/cifs/cifspdu.h @@ -134,6 +134,12 @@ * Size of the session key (crypto key encrypted with the password */ #define CIFS_SESS_KEY_SIZE (24) +#define CIFS_CLIENT_CHALLENGE_SIZE (8) +#define CIFS_SERVER_CHALLENGE_SIZE (8) +#define CIFS_HMAC_MD5_HASH_SIZE (16) +#define CIFS_CPHTXT_SIZE (16) +#define CIFS_NTLMV2_SESSKEY_SIZE (16) +#define CIFS_NTHASH_SIZE (16) /* * Maximum user name length @@ -663,7 +669,6 @@ struct ntlmv2_resp { __le64 time; __u64 client_chal; /* random */ __u32 reserved2; - struct ntlmssp2_name names[2]; /* array of name entries could follow ending in minimum 4 byte struct */ } __attribute__((packed)); diff --git a/trunk/fs/cifs/cifsproto.h b/trunk/fs/cifs/cifsproto.h index 1d60c655e3e0..1378d9133844 100644 --- a/trunk/fs/cifs/cifsproto.h +++ b/trunk/fs/cifs/cifsproto.h @@ -87,9 +87,8 @@ extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); extern int decode_negTokenInit(unsigned char *security_blob, int length, struct TCP_Server_Info *server); extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); -extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port); extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, - const unsigned short int port); + unsigned short int port); extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr); extern void header_assemble(struct smb_hdr *, char /* command */ , const struct cifsTconInfo *, int /* length of @@ -362,13 +361,15 @@ extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *); extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, __u32 *); extern int cifs_verify_signature(struct smb_hdr *, - const struct mac_key *mac_key, + struct TCP_Server_Info *server, __u32 expected_sequence_number); -extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn, +extern int cifs_calculate_session_key(struct session_key *key, const char *rn, const char *pass); -extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); -extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, +extern int setup_ntlmv2_rsp(struct cifsSesInfo *, char *, const struct nls_table *); +extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); +extern void cifs_crypto_shash_release(struct TCP_Server_Info *); +extern int calc_seckey(struct TCP_Server_Info *); #ifdef CONFIG_CIFS_WEAK_PW_HASH extern void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt, char *lnm_session_key); diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index c65c3419dd37..4bda920d1f75 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -604,11 +604,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) else rc = -EINVAL; - if (server->sec_kerberos || server->sec_mskerberos) - server->secType = Kerberos; - else if (server->sec_ntlmssp) - server->secType = RawNTLMSSP; - else + if (server->secType == Kerberos) { + if (!server->sec_kerberos && + !server->sec_mskerberos) + rc = -EOPNOTSUPP; + } else if (server->secType == RawNTLMSSP) { + if (!server->sec_ntlmssp) + rc = -EOPNOTSUPP; + } else rc = -EOPNOTSUPP; } } else diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 67dad54fbfa1..ec0ea4a43bdb 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -400,9 +400,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) cFYI(1, "call to reconnect done"); csocket = server->ssocket; continue; - } else if (length == -ERESTARTSYS || - length == -EAGAIN || - length == -EINTR) { + } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) { msleep(1); /* minimum sleep to prevent looping allowing socket to clear and app threads to set tcpStatus CifsNeedReconnect if server hung */ @@ -416,6 +414,18 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) } else continue; } else if (length <= 0) { + if (server->tcpStatus == CifsNew) { + cFYI(1, "tcp session abend after SMBnegprot"); + /* some servers kill the TCP session rather than + returning an SMB negprot error, in which + case reconnecting here is not going to help, + and so simply return error to mount */ + break; + } + if (!try_to_freeze() && (length == -EINTR)) { + cFYI(1, "cifsd thread killed"); + break; + } cFYI(1, "Reconnect after unexpected peek error %d", length); cifs_reconnect(server); @@ -456,19 +466,27 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) an error on SMB negprot response */ cFYI(1, "Negative RFC1002 Session Response Error 0x%x)", pdu_length); - /* give server a second to clean up */ - msleep(1000); - /* always try 445 first on reconnect since we get NACK - * on some if we ever connected to port 139 (the NACK - * is since we do not begin with RFC1001 session - * initialize frame) - */ - cifs_set_port((struct sockaddr *) - &server->addr.sockAddr, CIFS_PORT); - cifs_reconnect(server); - csocket = server->ssocket; - wake_up(&server->response_q); - continue; + if (server->tcpStatus == CifsNew) { + /* if nack on negprot (rather than + ret of smb negprot error) reconnecting + not going to help, ret error to mount */ + break; + } else { + /* give server a second to + clean up before reconnect attempt */ + msleep(1000); + /* always try 445 first on reconnect + since we get NACK on some if we ever + connected to port 139 (the NACK is + since we do not begin with RFC1001 + session initialize frame) */ + server->addr.sockAddr.sin_port = + htons(CIFS_PORT); + cifs_reconnect(server); + csocket = server->ssocket; + wake_up(&server->response_q); + continue; + } } else if (temp != (char) 0) { cERROR(1, "Unknown RFC 1002 frame"); cifs_dump_mem(" Received Data: ", (char *)smb_buffer, @@ -504,7 +522,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) total_read += length) { length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, pdu_length - total_read, 0); - if (server->tcpStatus == CifsExiting) { + if ((server->tcpStatus == CifsExiting) || + (length == -EINTR)) { /* then will exit */ reconnect = 2; break; @@ -515,9 +534,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) /* Now we will reread sock */ reconnect = 1; break; - } else if (length == -ERESTARTSYS || - length == -EAGAIN || - length == -EINTR) { + } else if ((length == -ERESTARTSYS) || + (length == -EAGAIN)) { msleep(1); /* minimum sleep to prevent looping, allowing socket to clear and app threads to set tcpStatus @@ -1690,6 +1708,7 @@ cifs_put_smb_ses(struct cifsSesInfo *ses) CIFSSMBLogoff(xid, ses); _FreeXid(xid); } + cifs_crypto_shash_release(server); sesInfoFree(ses); cifs_put_tcp_session(server); } @@ -1769,13 +1788,23 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) ses->linux_uid = volume_info->linux_uid; ses->overrideSecFlg = volume_info->secFlg; + rc = cifs_crypto_shash_allocate(server); + if (rc) { + cERROR(1, "could not setup hash structures rc %d", rc); + goto get_ses_fail; + } + server->tilen = 0; + server->tiblob = NULL; + mutex_lock(&ses->session_mutex); rc = cifs_negotiate_protocol(xid, ses); if (!rc) rc = cifs_setup_session(xid, ses, volume_info->local_nls); mutex_unlock(&ses->session_mutex); - if (rc) + if (rc) { + cifs_crypto_shash_release(ses->server); goto get_ses_fail; + } /* success, put it on the list */ write_lock(&cifs_tcp_ses_lock); diff --git a/trunk/fs/cifs/inode.c b/trunk/fs/cifs/inode.c index 93f77d438d3c..86a164f08a74 100644 --- a/trunk/fs/cifs/inode.c +++ b/trunk/fs/cifs/inode.c @@ -1462,17 +1462,28 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry, { char *fromName = NULL; char *toName = NULL; - struct cifs_sb_info *cifs_sb; + struct cifs_sb_info *cifs_sb_source; + struct cifs_sb_info *cifs_sb_target; struct cifsTconInfo *tcon; FILE_UNIX_BASIC_INFO *info_buf_source = NULL; FILE_UNIX_BASIC_INFO *info_buf_target; int xid, rc, tmprc; - cifs_sb = CIFS_SB(source_dir->i_sb); - tcon = cifs_sb->tcon; + cifs_sb_target = CIFS_SB(target_dir->i_sb); + cifs_sb_source = CIFS_SB(source_dir->i_sb); + tcon = cifs_sb_source->tcon; xid = GetXid(); + /* + * BB: this might be allowed if same server, but different share. + * Consider adding support for this + */ + if (tcon != cifs_sb_target->tcon) { + rc = -EXDEV; + goto cifs_rename_exit; + } + /* * we already have the rename sem so we do not need to * grab it again here to protect the path integrity @@ -1508,16 +1519,17 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry, info_buf_target = info_buf_source + 1; tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName, info_buf_source, - cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & + cifs_sb_source->local_nls, + cifs_sb_source->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (tmprc != 0) goto unlink_target; - tmprc = CIFSSMBUnixQPathInfo(xid, tcon, toName, - info_buf_target, - cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & + tmprc = CIFSSMBUnixQPathInfo(xid, tcon, + toName, info_buf_target, + cifs_sb_target->local_nls, + /* remap based on source sb */ + cifs_sb_source->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (tmprc == 0 && (info_buf_source->UniqueId == diff --git a/trunk/fs/cifs/netmisc.c b/trunk/fs/cifs/netmisc.c index 9aad47a2d62f..f97851119e6c 100644 --- a/trunk/fs/cifs/netmisc.c +++ b/trunk/fs/cifs/netmisc.c @@ -206,28 +206,24 @@ cifs_convert_address(struct sockaddr *dst, const char *src, int len) } int -cifs_set_port(struct sockaddr *addr, const unsigned short int port) +cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, + const unsigned short int port) { - switch (addr->sa_family) { + if (!cifs_convert_address(dst, src, len)) + return 0; + + switch (dst->sa_family) { case AF_INET: - ((struct sockaddr_in *)addr)->sin_port = htons(port); + ((struct sockaddr_in *)dst)->sin_port = htons(port); break; case AF_INET6: - ((struct sockaddr_in6 *)addr)->sin6_port = htons(port); + ((struct sockaddr_in6 *)dst)->sin6_port = htons(port); break; default: return 0; } - return 1; -} -int -cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, - const unsigned short int port) -{ - if (!cifs_convert_address(dst, src, len)) - return 0; - return cifs_set_port(dst, port); + return 1; } /***************************************************************************** diff --git a/trunk/fs/cifs/ntlmssp.h b/trunk/fs/cifs/ntlmssp.h index 49c9a4e75319..1db0f0746a5b 100644 --- a/trunk/fs/cifs/ntlmssp.h +++ b/trunk/fs/cifs/ntlmssp.h @@ -61,6 +61,19 @@ #define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000 #define NTLMSSP_NEGOTIATE_56 0x80000000 +/* Define AV Pair Field IDs */ +#define NTLMSSP_AV_EOL 0 +#define NTLMSSP_AV_NB_COMPUTER_NAME 1 +#define NTLMSSP_AV_NB_DOMAIN_NAME 2 +#define NTLMSSP_AV_DNS_COMPUTER_NAME 3 +#define NTLMSSP_AV_DNS_DOMAIN_NAME 4 +#define NTLMSSP_AV_DNS_TREE_NAME 5 +#define NTLMSSP_AV_FLAGS 6 +#define NTLMSSP_AV_TIMESTAMP 7 +#define NTLMSSP_AV_RESTRICTION 8 +#define NTLMSSP_AV_TARGET_NAME 9 +#define NTLMSSP_AV_CHANNEL_BINDINGS 10 + /* Although typedefs are not commonly used for structure definitions */ /* in the Linux kernel, in this particular case they are useful */ /* to more closely match the standards document for NTLMSSP from */ diff --git a/trunk/fs/cifs/sess.c b/trunk/fs/cifs/sess.c index 0a57cb7db5dd..795095f4eac6 100644 --- a/trunk/fs/cifs/sess.c +++ b/trunk/fs/cifs/sess.c @@ -383,6 +383,9 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft, static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, struct cifsSesInfo *ses) { + unsigned int tioffset; /* challeng message target info area */ + unsigned int tilen; /* challeng message target info area length */ + CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; if (blob_len < sizeof(CHALLENGE_MESSAGE)) { @@ -405,6 +408,20 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, /* BB spec says that if AvId field of MsvAvTimestamp is populated then we must set the MIC field of the AUTHENTICATE_MESSAGE */ + ses->server->ntlmssp.server_flags = le32_to_cpu(pblob->NegotiateFlags); + + tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset); + tilen = cpu_to_le16(pblob->TargetInfoArray.Length); + ses->server->tilen = tilen; + if (tilen) { + ses->server->tiblob = kmalloc(tilen, GFP_KERNEL); + if (!ses->server->tiblob) { + cERROR(1, "Challenge target info allocation failure"); + return -ENOMEM; + } + memcpy(ses->server->tiblob, bcc_ptr + tioffset, tilen); + } + return 0; } @@ -425,12 +442,13 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, /* BB is NTLMV2 session security format easier to use here? */ flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM; + NTLMSSP_NEGOTIATE_NTLM; if (ses->server->secMode & - (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) - flags |= NTLMSSP_NEGOTIATE_SIGN; - if (ses->server->secMode & SECMODE_SIGN_REQUIRED) - flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { + flags |= NTLMSSP_NEGOTIATE_SIGN | + NTLMSSP_NEGOTIATE_KEY_XCH | + NTLMSSP_NEGOTIATE_EXTENDED_SEC; + } sec_blob->NegotiateFlags |= cpu_to_le32(flags); @@ -451,10 +469,12 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, struct cifsSesInfo *ses, const struct nls_table *nls_cp, bool first) { + int rc; + unsigned int size; AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; __u32 flags; unsigned char *tmp; - char ntlm_session_key[CIFS_SESS_KEY_SIZE]; + struct ntlmv2_resp ntlmv2_response = {}; memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); sec_blob->MessageType = NtLmAuthenticate; @@ -477,19 +497,25 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, sec_blob->LmChallengeResponse.Length = 0; sec_blob->LmChallengeResponse.MaximumLength = 0; - /* calculate session key, BB what about adding similar ntlmv2 path? */ - SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key); - if (first) - cifs_calculate_mac_key(&ses->server->mac_signing_key, - ntlm_session_key, ses->password); - - memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE); sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); - sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE); - sec_blob->NtChallengeResponse.MaximumLength = - cpu_to_le16(CIFS_SESS_KEY_SIZE); + rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp); + if (rc) { + cERROR(1, "error rc: %d during ntlmssp ntlmv2 setup", rc); + goto setup_ntlmv2_ret; + } + size = sizeof(struct ntlmv2_resp); + memcpy(tmp, (char *)&ntlmv2_response, size); + tmp += size; + if (ses->server->tilen > 0) { + memcpy(tmp, ses->server->tiblob, ses->server->tilen); + tmp += ses->server->tilen; + } else + ses->server->tilen = 0; - tmp += CIFS_SESS_KEY_SIZE; + sec_blob->NtChallengeResponse.Length = cpu_to_le16(size + + ses->server->tilen); + sec_blob->NtChallengeResponse.MaximumLength = + cpu_to_le16(size + ses->server->tilen); if (ses->domainName == NULL) { sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); @@ -501,7 +527,6 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, len = cifs_strtoUCS((__le16 *)tmp, ses->domainName, MAX_USERNAME_SIZE, nls_cp); len *= 2; /* unicode is 2 bytes each */ - len += 2; /* trailing null */ sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); sec_blob->DomainName.Length = cpu_to_le16(len); sec_blob->DomainName.MaximumLength = cpu_to_le16(len); @@ -518,7 +543,6 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, len = cifs_strtoUCS((__le16 *)tmp, ses->userName, MAX_USERNAME_SIZE, nls_cp); len *= 2; /* unicode is 2 bytes each */ - len += 2; /* trailing null */ sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer); sec_blob->UserName.Length = cpu_to_le16(len); sec_blob->UserName.MaximumLength = cpu_to_le16(len); @@ -530,9 +554,26 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, sec_blob->WorkstationName.MaximumLength = 0; tmp += 2; - sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); - sec_blob->SessionKey.Length = 0; - sec_blob->SessionKey.MaximumLength = 0; + if ((ses->server->ntlmssp.server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && + !calc_seckey(ses->server)) { + memcpy(tmp, ses->server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE); + sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); + sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE); + sec_blob->SessionKey.MaximumLength = + cpu_to_le16(CIFS_CPHTXT_SIZE); + tmp += CIFS_CPHTXT_SIZE; + } else { + sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); + sec_blob->SessionKey.Length = 0; + sec_blob->SessionKey.MaximumLength = 0; + } + + ses->server->sequence_number = 0; + +setup_ntlmv2_ret: + if (ses->server->tilen > 0) + kfree(ses->server->tiblob); + return tmp - pbuffer; } @@ -546,15 +587,14 @@ static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB, return; } -static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB, +static int setup_ntlmssp_auth_req(char *ntlmsspblob, struct cifsSesInfo *ses, const struct nls_table *nls, bool first_time) { int bloblen; - bloblen = build_ntlmssp_auth_blob(&pSMB->req.SecurityBlob[0], ses, nls, + bloblen = build_ntlmssp_auth_blob(ntlmsspblob, ses, nls, first_time); - pSMB->req.SecurityBlobLength = cpu_to_le16(bloblen); return bloblen; } @@ -690,7 +730,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, if (first_time) /* should this be moved into common code with similar ntlmv2 path? */ - cifs_calculate_mac_key(&ses->server->mac_signing_key, + cifs_calculate_session_key(&ses->server->session_key, ntlm_session_key, ses->password); /* copy session key */ @@ -729,12 +769,21 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, cpu_to_le16(sizeof(struct ntlmv2_resp)); /* calculate session key */ - setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); + rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); + if (rc) { + kfree(v2_sess_key); + goto ssetup_exit; + } /* FIXME: calculate MAC key */ memcpy(bcc_ptr, (char *)v2_sess_key, sizeof(struct ntlmv2_resp)); bcc_ptr += sizeof(struct ntlmv2_resp); kfree(v2_sess_key); + if (ses->server->tilen > 0) { + memcpy(bcc_ptr, ses->server->tiblob, + ses->server->tilen); + bcc_ptr += ses->server->tilen; + } if (ses->capabilities & CAP_UNICODE) { if (iov[0].iov_len % 2) { *bcc_ptr = 0; @@ -765,15 +814,15 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, } /* bail out if key is too long */ if (msg->sesskey_len > - sizeof(ses->server->mac_signing_key.data.krb5)) { + sizeof(ses->server->session_key.data.krb5)) { cERROR(1, "Kerberos signing key too long (%u bytes)", msg->sesskey_len); rc = -EOVERFLOW; goto ssetup_exit; } if (first_time) { - ses->server->mac_signing_key.len = msg->sesskey_len; - memcpy(ses->server->mac_signing_key.data.krb5, + ses->server->session_key.len = msg->sesskey_len; + memcpy(ses->server->session_key.data.krb5, msg->data, msg->sesskey_len); } pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; @@ -815,12 +864,28 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, if (phase == NtLmNegotiate) { setup_ntlmssp_neg_req(pSMB, ses); iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); + iov[1].iov_base = &pSMB->req.SecurityBlob[0]; } else if (phase == NtLmAuthenticate) { int blob_len; - blob_len = setup_ntlmssp_auth_req(pSMB, ses, - nls_cp, - first_time); + char *ntlmsspblob; + + ntlmsspblob = kmalloc(5 * + sizeof(struct _AUTHENTICATE_MESSAGE), + GFP_KERNEL); + if (!ntlmsspblob) { + cERROR(1, "Can't allocate NTLMSSP"); + rc = -ENOMEM; + goto ssetup_exit; + } + + blob_len = setup_ntlmssp_auth_req(ntlmsspblob, + ses, + nls_cp, + first_time); iov[1].iov_len = blob_len; + iov[1].iov_base = ntlmsspblob; + pSMB->req.SecurityBlobLength = + cpu_to_le16(blob_len); /* Make sure that we tell the server that we are using the uid that it just gave us back on the response (challenge) */ @@ -830,7 +895,6 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, rc = -ENOSYS; goto ssetup_exit; } - iov[1].iov_base = &pSMB->req.SecurityBlob[0]; /* unicode strings must be word aligned */ if ((iov[0].iov_len + iov[1].iov_len) % 2) { *bcc_ptr = 0; diff --git a/trunk/fs/cifs/transport.c b/trunk/fs/cifs/transport.c index 82f78c4d6978..e0588cdf4cc5 100644 --- a/trunk/fs/cifs/transport.c +++ b/trunk/fs/cifs/transport.c @@ -543,7 +543,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))) { rc = cifs_verify_signature(midQ->resp_buf, - &ses->server->mac_signing_key, + ses->server, midQ->sequence_number+1); if (rc) { cERROR(1, "Unexpected SMB signature"); @@ -731,7 +731,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))) { rc = cifs_verify_signature(out_buf, - &ses->server->mac_signing_key, + ses->server, midQ->sequence_number+1); if (rc) { cERROR(1, "Unexpected SMB signature"); @@ -981,7 +981,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))) { rc = cifs_verify_signature(out_buf, - &ses->server->mac_signing_key, + ses->server, midQ->sequence_number+1); if (rc) { cERROR(1, "Unexpected SMB signature"); diff --git a/trunk/fs/nfs/Kconfig b/trunk/fs/nfs/Kconfig index f7e13db613cb..6c2aad49d731 100644 --- a/trunk/fs/nfs/Kconfig +++ b/trunk/fs/nfs/Kconfig @@ -63,7 +63,6 @@ config NFS_V3_ACL config NFS_V4 bool "NFS client support for NFS version 4" depends on NFS_FS - select SUNRPC_GSS help This option enables support for version 4 of the NFS protocol (RFC 3530) in the kernel's NFS client. diff --git a/trunk/fs/nfs/client.c b/trunk/fs/nfs/client.c index e7340729af89..4e7df2adb212 100644 --- a/trunk/fs/nfs/client.c +++ b/trunk/fs/nfs/client.c @@ -275,7 +275,7 @@ static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1, sin1->sin6_scope_id != sin2->sin6_scope_id) return 0; - return ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr); + return ipv6_addr_equal(&sin1->sin6_addr, &sin1->sin6_addr); } #else /* !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) */ static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1, diff --git a/trunk/fs/nfs/file.c b/trunk/fs/nfs/file.c index 05bf3c0dc751..eb51bd6201da 100644 --- a/trunk/fs/nfs/file.c +++ b/trunk/fs/nfs/file.c @@ -723,6 +723,10 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl) default: BUG(); } + if (res < 0) + dprintk(KERN_WARNING "%s: VFS is out of sync with lock manager" + " - error %d!\n", + __func__, res); return res; } diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index f4cbf0c306c6..ec3966e4706b 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -431,15 +431,7 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) goto out_err; error = server->nfs_client->rpc_ops->statfs(server, fh, &res); - if (unlikely(error == -ESTALE)) { - struct dentry *pd_dentry; - pd_dentry = dget_parent(dentry); - if (pd_dentry != NULL) { - nfs_zap_caches(pd_dentry->d_inode); - dput(pd_dentry); - } - } nfs_free_fattr(res.fattr); if (error < 0) goto out_err; diff --git a/trunk/fs/nfsd/Kconfig b/trunk/fs/nfsd/Kconfig index 4264377552e2..95932f523aef 100644 --- a/trunk/fs/nfsd/Kconfig +++ b/trunk/fs/nfsd/Kconfig @@ -69,7 +69,6 @@ config NFSD_V4 depends on NFSD && PROC_FS && EXPERIMENTAL select NFSD_V3 select FS_POSIX_ACL - select SUNRPC_GSS help This option enables support in your system's NFS server for version 4 of the NFS protocol (RFC 3530). diff --git a/trunk/include/linux/compat.h b/trunk/include/linux/compat.h index 5778b559d59c..9ddc8780e8db 100644 --- a/trunk/include/linux/compat.h +++ b/trunk/include/linux/compat.h @@ -360,8 +360,5 @@ extern ssize_t compat_rw_copy_check_uvector(int type, const struct compat_iovec __user *uvector, unsigned long nr_segs, unsigned long fast_segs, struct iovec *fast_pointer, struct iovec **ret_pointer); - -extern void __user *compat_alloc_user_space(unsigned long len); - #endif /* CONFIG_COMPAT */ #endif /* _LINUX_COMPAT_H */ diff --git a/trunk/include/linux/gpio.h b/trunk/include/linux/gpio.h index e41f7dd1ae67..03f616b78cfa 100644 --- a/trunk/include/linux/gpio.h +++ b/trunk/include/linux/gpio.h @@ -13,7 +13,6 @@ #include struct device; -struct gpio_chip; /* * Some platforms don't support the GPIO programming interface. diff --git a/trunk/include/linux/quotaops.h b/trunk/include/linux/quotaops.h index d1a9193960f1..d50ba858cfe0 100644 --- a/trunk/include/linux/quotaops.h +++ b/trunk/include/linux/quotaops.h @@ -274,14 +274,8 @@ static inline int dquot_alloc_space(struct inode *inode, qsize_t nr) int ret; ret = dquot_alloc_space_nodirty(inode, nr); - if (!ret) { - /* - * Mark inode fully dirty. Since we are allocating blocks, inode - * would become fully dirty soon anyway and it reportedly - * reduces inode_lock contention. - */ - mark_inode_dirty(inode); - } + if (!ret) + mark_inode_dirty_sync(inode); return ret; } diff --git a/trunk/include/linux/spi/dw_spi.h b/trunk/include/linux/spi/dw_spi.h index c91302f3a257..cc813f95a2f2 100644 --- a/trunk/include/linux/spi/dw_spi.h +++ b/trunk/include/linux/spi/dw_spi.h @@ -14,9 +14,7 @@ #define SPI_MODE_OFFSET 6 #define SPI_SCPH_OFFSET 6 #define SPI_SCOL_OFFSET 7 - #define SPI_TMOD_OFFSET 8 -#define SPI_TMOD_MASK (0x3 << SPI_TMOD_OFFSET) #define SPI_TMOD_TR 0x0 /* xmit & recv */ #define SPI_TMOD_TO 0x1 /* xmit only */ #define SPI_TMOD_RO 0x2 /* recv only */ diff --git a/trunk/include/linux/sunrpc/clnt.h b/trunk/include/linux/sunrpc/clnt.h index 85f38a63f098..569dc722a600 100644 --- a/trunk/include/linux/sunrpc/clnt.h +++ b/trunk/include/linux/sunrpc/clnt.h @@ -30,7 +30,7 @@ struct rpc_inode; * The high-level client handle */ struct rpc_clnt { - atomic_t cl_count; /* Number of references */ + struct kref cl_kref; /* Number of references */ struct list_head cl_clients; /* Global list of clients */ struct list_head cl_tasks; /* List of tasks */ spinlock_t cl_lock; /* spinlock */ diff --git a/trunk/kernel/compat.c b/trunk/kernel/compat.c index c9e2ec0b34a8..e167efce8423 100644 --- a/trunk/kernel/compat.c +++ b/trunk/kernel/compat.c @@ -1126,24 +1126,3 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info) return 0; } - -/* - * Allocate user-space memory for the duration of a single system call, - * in order to marshall parameters inside a compat thunk. - */ -void __user *compat_alloc_user_space(unsigned long len) -{ - void __user *ptr; - - /* If len would occupy more than half of the entire compat space... */ - if (unlikely(len > (((compat_uptr_t)~0) >> 1))) - return NULL; - - ptr = arch_compat_alloc_user_space(len); - - if (unlikely(!access_ok(VERIFY_WRITE, ptr, len))) - return NULL; - - return ptr; -} -EXPORT_SYMBOL_GPL(compat_alloc_user_space); diff --git a/trunk/kernel/sched_fair.c b/trunk/kernel/sched_fair.c index a171138a9402..9b5b4f86b742 100644 --- a/trunk/kernel/sched_fair.c +++ b/trunk/kernel/sched_fair.c @@ -54,13 +54,13 @@ enum sched_tunable_scaling sysctl_sched_tunable_scaling * Minimal preemption granularity for CPU-bound tasks: * (default: 2 msec * (1 + ilog(ncpus)), units: nanoseconds) */ -unsigned int sysctl_sched_min_granularity = 750000ULL; -unsigned int normalized_sysctl_sched_min_granularity = 750000ULL; +unsigned int sysctl_sched_min_granularity = 2000000ULL; +unsigned int normalized_sysctl_sched_min_granularity = 2000000ULL; /* * is kept at sysctl_sched_latency / sysctl_sched_min_granularity */ -static unsigned int sched_nr_latency = 8; +static unsigned int sched_nr_latency = 3; /* * After fork, child runs first. If set to 0 (default) then diff --git a/trunk/net/9p/client.c b/trunk/net/9p/client.c index 9eb72505308f..dc6f2f26d023 100644 --- a/trunk/net/9p/client.c +++ b/trunk/net/9p/client.c @@ -331,10 +331,8 @@ static void p9_tag_cleanup(struct p9_client *c) } } - if (c->tagpool) { - p9_idpool_put(0, c->tagpool); /* free reserved tag 0 */ + if (c->tagpool) p9_idpool_destroy(c->tagpool); - } /* free requests associated with tags */ for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) { @@ -946,7 +944,6 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, int16_t nwqids, count; err = 0; - wqids = NULL; clnt = oldfid->clnt; if (clone) { fid = p9_fid_create(clnt); @@ -997,11 +994,9 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, else fid->qid = oldfid->qid; - kfree(wqids); return fid; clunk_fid: - kfree(wqids); p9_client_clunk(fid); fid = NULL; diff --git a/trunk/net/sunrpc/auth.c b/trunk/net/sunrpc/auth.c index e9eaaf7d43c1..36cb66022a27 100644 --- a/trunk/net/sunrpc/auth.c +++ b/trunk/net/sunrpc/auth.c @@ -38,7 +38,7 @@ static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = { static LIST_HEAD(cred_unused); static unsigned long number_cred_unused; -#define MAX_HASHTABLE_BITS (14) +#define MAX_HASHTABLE_BITS (10) static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp) { unsigned long num; diff --git a/trunk/net/sunrpc/auth_gss/auth_gss.c b/trunk/net/sunrpc/auth_gss/auth_gss.c index 12c485982814..dcfc66bab2bb 100644 --- a/trunk/net/sunrpc/auth_gss/auth_gss.c +++ b/trunk/net/sunrpc/auth_gss/auth_gss.c @@ -745,18 +745,17 @@ gss_pipe_release(struct inode *inode) struct rpc_inode *rpci = RPC_I(inode); struct gss_upcall_msg *gss_msg; -restart: spin_lock(&inode->i_lock); - list_for_each_entry(gss_msg, &rpci->in_downcall, list) { + while (!list_empty(&rpci->in_downcall)) { - if (!list_empty(&gss_msg->msg.list)) - continue; + gss_msg = list_entry(rpci->in_downcall.next, + struct gss_upcall_msg, list); gss_msg->msg.errno = -EPIPE; atomic_inc(&gss_msg->count); __gss_unhash_msg(gss_msg); spin_unlock(&inode->i_lock); gss_release_msg(gss_msg); - goto restart; + spin_lock(&inode->i_lock); } spin_unlock(&inode->i_lock); diff --git a/trunk/net/sunrpc/auth_gss/gss_krb5_mech.c b/trunk/net/sunrpc/auth_gss/gss_krb5_mech.c index 778e5dfc5144..032644610524 100644 --- a/trunk/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/trunk/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -237,7 +237,6 @@ get_key(const void *p, const void *end, if (!supported_gss_krb5_enctype(alg)) { printk(KERN_WARNING "gss_kerberos_mech: unsupported " "encryption key algorithm %d\n", alg); - p = ERR_PTR(-EINVAL); goto out_err; } p = simple_get_netobj(p, end, &key); @@ -283,19 +282,15 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx) ctx->enctype = ENCTYPE_DES_CBC_RAW; ctx->gk5e = get_gss_krb5_enctype(ctx->enctype); - if (ctx->gk5e == NULL) { - p = ERR_PTR(-EINVAL); + if (ctx->gk5e == NULL) goto out_err; - } /* The downcall format was designed before we completely understood * the uses of the context fields; so it includes some stuff we * just give some minimal sanity-checking, and some we ignore * completely (like the next twenty bytes): */ - if (unlikely(p + 20 > end || p + 20 < p)) { - p = ERR_PTR(-EFAULT); + if (unlikely(p + 20 > end || p + 20 < p)) goto out_err; - } p += 20; p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); if (IS_ERR(p)) @@ -624,7 +619,6 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, if (ctx->seq_send64 != ctx->seq_send) { dprintk("%s: seq_send64 %lx, seq_send %x overflow?\n", __func__, (long unsigned)ctx->seq_send64, ctx->seq_send); - p = ERR_PTR(-EINVAL); goto out_err; } p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype)); diff --git a/trunk/net/sunrpc/auth_gss/gss_spkm3_mech.c b/trunk/net/sunrpc/auth_gss/gss_spkm3_mech.c index adade3d313f2..dc3f1f5ed865 100644 --- a/trunk/net/sunrpc/auth_gss/gss_spkm3_mech.c +++ b/trunk/net/sunrpc/auth_gss/gss_spkm3_mech.c @@ -100,7 +100,6 @@ gss_import_sec_context_spkm3(const void *p, size_t len, if (version != 1) { dprintk("RPC: unknown spkm3 token format: " "obsolete nfs-utils?\n"); - p = ERR_PTR(-EINVAL); goto out_err_free_ctx; } @@ -136,10 +135,8 @@ gss_import_sec_context_spkm3(const void *p, size_t len, if (IS_ERR(p)) goto out_err_free_intg_alg; - if (p != end) { - p = ERR_PTR(-EFAULT); + if (p != end) goto out_err_free_intg_key; - } ctx_id->internal_ctx_id = ctx; diff --git a/trunk/net/sunrpc/clnt.c b/trunk/net/sunrpc/clnt.c index fa5549079d79..2388d83b68ff 100644 --- a/trunk/net/sunrpc/clnt.c +++ b/trunk/net/sunrpc/clnt.c @@ -226,7 +226,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru goto out_no_principal; } - atomic_set(&clnt->cl_count, 1); + kref_init(&clnt->cl_kref); err = rpc_setup_pipedir(clnt, program->pipe_dir_name); if (err < 0) @@ -390,14 +390,14 @@ rpc_clone_client(struct rpc_clnt *clnt) if (new->cl_principal == NULL) goto out_no_principal; } - atomic_set(&new->cl_count, 1); + kref_init(&new->cl_kref); err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); if (err != 0) goto out_no_path; if (new->cl_auth) atomic_inc(&new->cl_auth->au_count); xprt_get(clnt->cl_xprt); - atomic_inc(&clnt->cl_count); + kref_get(&clnt->cl_kref); rpc_register_client(new); rpciod_up(); return new; @@ -465,8 +465,10 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client); * Free an RPC client */ static void -rpc_free_client(struct rpc_clnt *clnt) +rpc_free_client(struct kref *kref) { + struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref); + dprintk("RPC: destroying %s client for %s\n", clnt->cl_protname, clnt->cl_server); if (!IS_ERR(clnt->cl_path.dentry)) { @@ -493,10 +495,12 @@ rpc_free_client(struct rpc_clnt *clnt) * Free an RPC client */ static void -rpc_free_auth(struct rpc_clnt *clnt) +rpc_free_auth(struct kref *kref) { + struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref); + if (clnt->cl_auth == NULL) { - rpc_free_client(clnt); + rpc_free_client(kref); return; } @@ -505,11 +509,10 @@ rpc_free_auth(struct rpc_clnt *clnt) * release remaining GSS contexts. This mechanism ensures * that it can do so safely. */ - atomic_inc(&clnt->cl_count); + kref_init(kref); rpcauth_release(clnt->cl_auth); clnt->cl_auth = NULL; - if (atomic_dec_and_test(&clnt->cl_count)) - rpc_free_client(clnt); + kref_put(kref, rpc_free_client); } /* @@ -522,8 +525,7 @@ rpc_release_client(struct rpc_clnt *clnt) if (list_empty(&clnt->cl_tasks)) wake_up(&destroy_wait); - if (atomic_dec_and_test(&clnt->cl_count)) - rpc_free_auth(clnt); + kref_put(&clnt->cl_kref, rpc_free_auth); } /** @@ -586,7 +588,7 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt) if (clnt != NULL) { rpc_task_release_client(task); task->tk_client = clnt; - atomic_inc(&clnt->cl_count); + kref_get(&clnt->cl_kref); if (clnt->cl_softrtry) task->tk_flags |= RPC_TASK_SOFT; /* Add to the client's list of all tasks */ @@ -929,7 +931,7 @@ call_reserveresult(struct rpc_task *task) task->tk_status = 0; if (status >= 0) { if (task->tk_rqstp) { - task->tk_action = call_refresh; + task->tk_action = call_allocate; return; } @@ -964,54 +966,13 @@ call_reserveresult(struct rpc_task *task) } /* - * 2. Bind and/or refresh the credentials - */ -static void -call_refresh(struct rpc_task *task) -{ - dprint_status(task); - - task->tk_action = call_refreshresult; - task->tk_status = 0; - task->tk_client->cl_stats->rpcauthrefresh++; - rpcauth_refreshcred(task); -} - -/* - * 2a. Process the results of a credential refresh - */ -static void -call_refreshresult(struct rpc_task *task) -{ - int status = task->tk_status; - - dprint_status(task); - - task->tk_status = 0; - task->tk_action = call_allocate; - if (status >= 0 && rpcauth_uptodatecred(task)) - return; - switch (status) { - case -EACCES: - rpc_exit(task, -EACCES); - return; - case -ENOMEM: - rpc_exit(task, -ENOMEM); - return; - case -ETIMEDOUT: - rpc_delay(task, 3*HZ); - } - task->tk_action = call_refresh; -} - -/* - * 2b. Allocate the buffer. For details, see sched.c:rpc_malloc. + * 2. Allocate the buffer. For details, see sched.c:rpc_malloc. * (Note: buffer memory is freed in xprt_release). */ static void call_allocate(struct rpc_task *task) { - unsigned int slack = task->tk_rqstp->rq_cred->cr_auth->au_cslack; + unsigned int slack = task->tk_client->cl_auth->au_cslack; struct rpc_rqst *req = task->tk_rqstp; struct rpc_xprt *xprt = task->tk_xprt; struct rpc_procinfo *proc = task->tk_msg.rpc_proc; @@ -1019,7 +980,7 @@ call_allocate(struct rpc_task *task) dprint_status(task); task->tk_status = 0; - task->tk_action = call_bind; + task->tk_action = call_refresh; if (req->rq_buffer) return; @@ -1056,6 +1017,47 @@ call_allocate(struct rpc_task *task) rpc_exit(task, -ERESTARTSYS); } +/* + * 2a. Bind and/or refresh the credentials + */ +static void +call_refresh(struct rpc_task *task) +{ + dprint_status(task); + + task->tk_action = call_refreshresult; + task->tk_status = 0; + task->tk_client->cl_stats->rpcauthrefresh++; + rpcauth_refreshcred(task); +} + +/* + * 2b. Process the results of a credential refresh + */ +static void +call_refreshresult(struct rpc_task *task) +{ + int status = task->tk_status; + + dprint_status(task); + + task->tk_status = 0; + task->tk_action = call_bind; + if (status >= 0 && rpcauth_uptodatecred(task)) + return; + switch (status) { + case -EACCES: + rpc_exit(task, -EACCES); + return; + case -ENOMEM: + rpc_exit(task, -ENOMEM); + return; + case -ETIMEDOUT: + rpc_delay(task, 3*HZ); + } + task->tk_action = call_refresh; +} + static inline int rpc_task_need_encode(struct rpc_task *task) { diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index 8c8eef2b8f26..95ccbcf45d3e 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -48,7 +48,7 @@ static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, return; do { msg = list_entry(head->next, struct rpc_pipe_msg, list); - list_del_init(&msg->list); + list_del(&msg->list); msg->errno = err; destroy_msg(msg); } while (!list_empty(head)); @@ -208,7 +208,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp) if (msg != NULL) { spin_lock(&inode->i_lock); msg->errno = -EAGAIN; - list_del_init(&msg->list); + list_del(&msg->list); spin_unlock(&inode->i_lock); rpci->ops->destroy_msg(msg); } @@ -268,7 +268,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) if (res < 0 || msg->len == msg->copied) { filp->private_data = NULL; spin_lock(&inode->i_lock); - list_del_init(&msg->list); + list_del(&msg->list); spin_unlock(&inode->i_lock); rpci->ops->destroy_msg(msg); } @@ -371,23 +371,21 @@ rpc_show_info(struct seq_file *m, void *v) static int rpc_info_open(struct inode *inode, struct file *file) { - struct rpc_clnt *clnt = NULL; + struct rpc_clnt *clnt; int ret = single_open(file, rpc_show_info, NULL); if (!ret) { struct seq_file *m = file->private_data; - - spin_lock(&file->f_path.dentry->d_lock); - if (!d_unhashed(file->f_path.dentry)) - clnt = RPC_I(inode)->private; - if (clnt != NULL && atomic_inc_not_zero(&clnt->cl_count)) { - spin_unlock(&file->f_path.dentry->d_lock); + mutex_lock(&inode->i_mutex); + clnt = RPC_I(inode)->private; + if (clnt) { + kref_get(&clnt->cl_kref); m->private = clnt; } else { - spin_unlock(&file->f_path.dentry->d_lock); single_release(inode, file); ret = -EINVAL; } + mutex_unlock(&inode->i_mutex); } return ret; }