From 3562ef245ec7a804048ca6fae0afd7cdd061394a Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 21 Jun 2011 15:01:53 +0200 Subject: [PATCH] --- yaml --- r: 254066 b: refs/heads/master c: 50bc03ab5c7529fdfe4e01621efca7d26439ea00 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/power/devices.txt | 67 +++++-- trunk/Documentation/power/runtime_pm.txt | 5 + trunk/arch/arm/boot/compressed/head.S | 14 +- trunk/arch/arm/include/asm/assembler.h | 4 - .../arch/arm/include/asm/entry-macro-multi.S | 2 - trunk/arch/arm/kernel/module.c | 13 +- trunk/arch/arm/kernel/smp.c | 6 +- trunk/arch/arm/mach-h720x/Kconfig | 2 - trunk/arch/arm/mm/proc-v7.S | 16 +- trunk/arch/arm/plat-iop/cp6.c | 1 - trunk/arch/mn10300/include/asm/uaccess.h | 1 - trunk/arch/s390/Kconfig | 1 - trunk/arch/s390/kernel/smp.c | 4 +- trunk/arch/s390/oprofile/init.c | 8 +- trunk/arch/x86/pci/acpi.c | 2 +- trunk/block/blk-throttle.c | 4 +- trunk/block/cfq-iosched.c | 16 +- trunk/block/genhd.c | 79 ++++---- trunk/drivers/ata/libata-core.c | 6 +- trunk/drivers/ata/libata-scsi.c | 6 - trunk/drivers/ata/pata_marvell.c | 3 - trunk/drivers/ata/sata_dwc_460ex.c | 2 +- trunk/drivers/base/power/clock_ops.c | 4 +- trunk/drivers/base/power/main.c | 28 +-- trunk/drivers/gpu/drm/i915/i915_gem.c | 10 +- .../gpu/drm/i915/i915_gem_execbuffer.c | 4 + trunk/drivers/gpu/drm/i915/i915_irq.c | 1 - trunk/drivers/gpu/drm/i915/i915_reg.h | 1 - trunk/drivers/gpu/drm/i915/i915_suspend.c | 5 - trunk/drivers/gpu/drm/i915/intel_display.c | 3 +- trunk/drivers/gpu/drm/radeon/evergreen.c | 4 +- trunk/drivers/gpu/drm/radeon/radeon.h | 1 - .../drivers/gpu/drm/radeon/radeon_atombios.c | 36 ---- trunk/drivers/hid/hid-multitouch.c | 5 +- trunk/drivers/infiniband/hw/cxgb4/cm.c | 46 +---- trunk/drivers/infiniband/hw/cxgb4/cq.c | 4 - trunk/drivers/infiniband/hw/cxgb4/mem.c | 2 +- trunk/drivers/infiniband/hw/cxgb4/qp.c | 5 +- trunk/drivers/infiniband/hw/qib/qib_iba7322.c | 25 +-- trunk/drivers/infiniband/hw/qib/qib_intr.c | 6 +- trunk/drivers/pci/pci-driver.c | 4 +- trunk/drivers/pci/pci.c | 2 +- trunk/drivers/pci/probe.c | 2 +- trunk/drivers/rtc/rtc-vt8500.c | 45 ++++- trunk/drivers/target/loopback/tcm_loop.c | 13 +- trunk/drivers/target/target_core_configfs.c | 24 +-- trunk/drivers/target/target_core_device.c | 5 +- trunk/drivers/target/target_core_pr.c | 6 +- trunk/drivers/target/target_core_tmr.c | 8 +- trunk/drivers/target/target_core_transport.c | 6 +- trunk/drivers/target/tcm_fc/tcm_fc.h | 2 +- trunk/drivers/target/tcm_fc/tfc_cmd.c | 64 +++---- trunk/drivers/target/tcm_fc/tfc_io.c | 2 +- trunk/drivers/target/tcm_fc/tfc_sess.c | 4 +- trunk/drivers/tty/serial/mrst_max3110.c | 5 +- trunk/drivers/usb/core/driver.c | 6 +- trunk/fs/block_dev.c | 14 +- trunk/fs/btrfs/ctree.h | 1 + trunk/fs/cifs/Kconfig | 2 +- trunk/fs/cifs/cifs_fs_sb.h | 1 - trunk/fs/cifs/cifsfs.c | 156 ++++++++------- trunk/fs/cifs/cifsproto.h | 8 +- trunk/fs/cifs/connect.c | 88 ++++----- trunk/fs/cifs/smbencrypt.c | 6 +- trunk/fs/ext4/ext4_extents.h | 9 +- trunk/fs/ext4/extents.c | 42 ++-- trunk/fs/ext4/inode.c | 2 +- trunk/fs/ext4/mballoc.c | 8 +- trunk/fs/ext4/move_extent.c | 10 +- trunk/fs/ext4/super.c | 15 +- trunk/fs/jbd2/checkpoint.c | 28 ++- trunk/fs/jbd2/commit.c | 33 ++-- trunk/fs/jbd2/journal.c | 91 ++++++--- trunk/fs/jbd2/transaction.c | 69 ++++--- trunk/fs/jfs/file.c | 6 +- trunk/fs/jfs/jfs_imap.c | 12 +- trunk/fs/jfs/jfs_incore.h | 3 +- trunk/fs/jfs/resize.c | 2 +- trunk/fs/lockd/clntproc.c | 8 +- trunk/fs/nfs/inode.c | 6 +- trunk/fs/nfs/internal.h | 11 -- trunk/fs/nfs/nfs4filelayout.c | 21 +- trunk/fs/nfs/nfs4proc.c | 45 ++--- trunk/fs/nfs/nfs4xdr.c | 26 ++- trunk/fs/nfs/objlayout/objio_osd.c | 4 +- trunk/fs/nfs/objlayout/objlayout.c | 2 +- trunk/fs/nfs/pagelist.c | 3 +- trunk/fs/nfs/pnfs.c | 44 ++--- trunk/fs/nfs/pnfs.h | 1 - trunk/fs/nfs/pnfs_dev.c | 17 +- trunk/fs/omfs/file.c | 1 + trunk/include/linux/blk_types.h | 2 +- trunk/include/linux/blktrace_api.h | 3 +- trunk/include/linux/device.h | 4 +- trunk/include/linux/jbd2.h | 2 + trunk/include/linux/nfs_page.h | 3 - trunk/include/linux/nfs_xdr.h | 1 + trunk/include/linux/pm.h | 3 +- trunk/include/linux/sunrpc/sched.h | 3 +- trunk/include/sound/soc.h | 3 +- trunk/include/trace/events/ext4.h | 179 ++++++++++-------- trunk/init/calibrate.c | 14 +- trunk/kernel/power/user.c | 4 +- trunk/kernel/time/alarmtimer.c | 158 +++++++--------- trunk/mm/memory_hotplug.c | 4 +- trunk/net/sunrpc/auth_gss/auth_gss.c | 4 +- trunk/net/sunrpc/clnt.c | 5 +- trunk/net/sunrpc/sched.c | 1 - trunk/security/keys/request_key.c | 3 +- trunk/sound/pci/asihpi/asihpi.c | 1 + trunk/sound/pci/hda/patch_realtek.c | 13 +- trunk/sound/pci/hda/patch_via.c | 35 +--- trunk/sound/soc/codecs/wm8991.c | 1 + trunk/sound/soc/imx/Kconfig | 7 + trunk/sound/soc/imx/imx-pcm-dma-mx2.c | 2 - trunk/sound/soc/imx/imx-ssi.c | 2 +- trunk/sound/soc/pxa/pxa2xx-pcm.c | 4 +- trunk/sound/soc/soc-cache.c | 3 + 119 files changed, 869 insertions(+), 1042 deletions(-) diff --git a/[refs] b/[refs] index ecf5356bccad..7d2a7e81ca26 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: edcda265225b90c8700b21758fffcba61d19e046 +refs/heads/master: 50bc03ab5c7529fdfe4e01621efca7d26439ea00 diff --git a/trunk/Documentation/power/devices.txt b/trunk/Documentation/power/devices.txt index 64565aac6e40..88880839ece4 100644 --- a/trunk/Documentation/power/devices.txt +++ b/trunk/Documentation/power/devices.txt @@ -520,20 +520,59 @@ Support for power domains is provided through the pwr_domain field of struct device. This field is a pointer to an object of type struct dev_power_domain, defined in include/linux/pm.h, providing a set of power management callbacks analogous to the subsystem-level and device driver callbacks that are executed -for the given device during all power transitions, instead of the respective -subsystem-level callbacks. Specifically, if a device's pm_domain pointer is -not NULL, the ->suspend() callback from the object pointed to by it will be -executed instead of its subsystem's (e.g. bus type's) ->suspend() callback and -anlogously for all of the remaining callbacks. In other words, power management -domain callbacks, if defined for the given device, always take precedence over -the callbacks provided by the device's subsystem (e.g. bus type). - -The support for device power management domains is only relevant to platforms -needing to use the same device driver power management callbacks in many -different power domain configurations and wanting to avoid incorporating the -support for power domains into subsystem-level callbacks, for example by -modifying the platform bus type. Other platforms need not implement it or take -it into account in any way. +for the given device during all power transitions, in addition to the respective +subsystem-level callbacks. Specifically, the power domain "suspend" callbacks +(i.e. ->runtime_suspend(), ->suspend(), ->freeze(), ->poweroff(), etc.) are +executed after the analogous subsystem-level callbacks, while the power domain +"resume" callbacks (i.e. ->runtime_resume(), ->resume(), ->thaw(), ->restore, +etc.) are executed before the analogous subsystem-level callbacks. Error codes +returned by the "suspend" and "resume" power domain callbacks are ignored. + +Power domain ->runtime_idle() callback is executed before the subsystem-level +->runtime_idle() callback and the result returned by it is not ignored. Namely, +if it returns error code, the subsystem-level ->runtime_idle() callback will not +be called and the helper function rpm_idle() executing it will return error +code. This mechanism is intended to help platforms where saving device state +is a time consuming operation and should only be carried out if all devices +in the power domain are idle, before turning off the shared power resource(s). +Namely, the power domain ->runtime_idle() callback may return error code until +the pm_runtime_idle() helper (or its asychronous version) has been called for +all devices in the power domain (it is recommended that the returned error code +be -EBUSY in those cases), preventing the subsystem-level ->runtime_idle() +callback from being run prematurely. + +The support for device power domains is only relevant to platforms needing to +use the same subsystem-level (e.g. platform bus type) and device driver power +management callbacks in many different power domain configurations and wanting +to avoid incorporating the support for power domains into the subsystem-level +callbacks. The other platforms need not implement it or take it into account +in any way. + + +System Devices +-------------- +System devices (sysdevs) follow a slightly different API, which can be found in + + include/linux/sysdev.h + drivers/base/sys.c + +System devices will be suspended with interrupts disabled, and after all other +devices have been suspended. On resume, they will be resumed before any other +devices, and also with interrupts disabled. These things occur in special +"sysdev_driver" phases, which affect only system devices. + +Thus, after the suspend_noirq (or freeze_noirq or poweroff_noirq) phase, when +the non-boot CPUs are all offline and IRQs are disabled on the remaining online +CPU, then a sysdev_driver.suspend phase is carried out, and the system enters a +sleep state (or a system image is created). During resume (or after the image +has been created or loaded) a sysdev_driver.resume phase is carried out, IRQs +are enabled on the only online CPU, the non-boot CPUs are enabled, and the +resume_noirq (or thaw_noirq or restore_noirq) phase begins. + +Code to actually enter and exit the system-wide low power state sometimes +involves hardware details that are only known to the boot firmware, and +may leave a CPU running software (from SRAM or flash memory) that monitors +the system and manages its wakeup sequence. Device Low Power (suspend) States diff --git a/trunk/Documentation/power/runtime_pm.txt b/trunk/Documentation/power/runtime_pm.txt index 22accb3eb40e..654097b130b4 100644 --- a/trunk/Documentation/power/runtime_pm.txt +++ b/trunk/Documentation/power/runtime_pm.txt @@ -566,6 +566,11 @@ to do this is: pm_runtime_set_active(dev); pm_runtime_enable(dev); +The PM core always increments the run-time usage counter before calling the +->prepare() callback and decrements it after calling the ->complete() callback. +Hence disabling run-time PM temporarily like this will not cause any run-time +suspend callbacks to be lost. + 7. Generic subsystem callbacks Subsystems may wish to conserve code space by using the set of generic power diff --git a/trunk/arch/arm/boot/compressed/head.S b/trunk/arch/arm/boot/compressed/head.S index 940b20178107..942fad97e447 100644 --- a/trunk/arch/arm/boot/compressed/head.S +++ b/trunk/arch/arm/boot/compressed/head.S @@ -597,8 +597,6 @@ __common_mmu_cache_on: sub pc, lr, r0, lsr #32 @ properly flush pipeline #endif -#define PROC_ENTRY_SIZE (4*5) - /* * Here follow the relocatable cache support functions for the * various processors. This is a generic hook for locating an @@ -626,7 +624,7 @@ call_cache_fn: adr r12, proc_types ARM( addeq pc, r12, r3 ) @ call cache function THUMB( addeq r12, r3 ) THUMB( moveq pc, r12 ) @ call cache function - add r12, r12, #PROC_ENTRY_SIZE + add r12, r12, #4*5 b 1b /* @@ -796,16 +794,6 @@ proc_types: .size proc_types, . - proc_types - /* - * If you get a "non-constant expression in ".if" statement" - * error from the assembler on this line, check that you have - * not accidentally written a "b" instruction where you should - * have written W(b). - */ - .if (. - proc_types) % PROC_ENTRY_SIZE != 0 - .error "The size of one or more proc_types entries is wrong." - .endif - /* * Turn off the Cache and MMU. ARMv3 does not support * reading the control register, but ARMv4 does. diff --git a/trunk/arch/arm/include/asm/assembler.h b/trunk/arch/arm/include/asm/assembler.h index 65c3f2474f5e..bc2d2d75f706 100644 --- a/trunk/arch/arm/include/asm/assembler.h +++ b/trunk/arch/arm/include/asm/assembler.h @@ -13,9 +13,6 @@ * Do not include any C declarations in this file - it is included by * assembler source. */ -#ifndef __ASM_ASSEMBLER_H__ -#define __ASM_ASSEMBLER_H__ - #ifndef __ASSEMBLY__ #error "Only include this from assembly code" #endif @@ -293,4 +290,3 @@ .macro ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f usracc ldr, \reg, \ptr, \inc, \cond, \rept, \abort .endm -#endif /* __ASM_ASSEMBLER_H__ */ diff --git a/trunk/arch/arm/include/asm/entry-macro-multi.S b/trunk/arch/arm/include/asm/entry-macro-multi.S index 2da8547de6d6..ec0bbf79c71f 100644 --- a/trunk/arch/arm/include/asm/entry-macro-multi.S +++ b/trunk/arch/arm/include/asm/entry-macro-multi.S @@ -1,5 +1,3 @@ -#include - /* * Interrupt handling. Preserves r7, r8, r9 */ diff --git a/trunk/arch/arm/kernel/module.c b/trunk/arch/arm/kernel/module.c index 016d6a0830a3..fee7c36349eb 100644 --- a/trunk/arch/arm/kernel/module.c +++ b/trunk/arch/arm/kernel/module.c @@ -193,17 +193,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, offset -= 0x02000000; offset += sym->st_value - loc; - /* - * For function symbols, only Thumb addresses are - * allowed (no interworking). - * - * For non-function symbols, the destination - * has no specific ARM/Thumb disposition, so - * the branch is resolved under the assumption - * that interworking is not required. - */ - if ((ELF32_ST_TYPE(sym->st_info) == STT_FUNC && - !(offset & 1)) || + /* only Thumb addresses allowed (no interworking) */ + if (!(offset & 1) || offset <= (s32)0xff000000 || offset >= (s32)0x01000000) { pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index e7f92a4321f3..344e52b16c8c 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -318,13 +318,9 @@ asmlinkage void __cpuinit secondary_start_kernel(void) smp_store_cpu_info(cpu); /* - * OK, now it's safe to let the boot CPU continue. Wait for - * the CPU migration code to notice that the CPU is online - * before we continue. + * OK, now it's safe to let the boot CPU continue */ set_cpu_online(cpu, true); - while (!cpu_active(cpu)) - cpu_relax(); /* * OK, it's off to the idle thread for us diff --git a/trunk/arch/arm/mach-h720x/Kconfig b/trunk/arch/arm/mach-h720x/Kconfig index abf356c02343..9b6982efbd22 100644 --- a/trunk/arch/arm/mach-h720x/Kconfig +++ b/trunk/arch/arm/mach-h720x/Kconfig @@ -6,14 +6,12 @@ config ARCH_H7201 bool "gms30c7201" depends on ARCH_H720X select CPU_H7201 - select ZONE_DMA help Say Y here if you are using the Hynix GMS30C7201 Reference Board config ARCH_H7202 bool "hms30c7202" select CPU_H7202 - select ZONE_DMA depends on ARCH_H720X help Say Y here if you are using the Hynix HMS30C7202 Reference Board diff --git a/trunk/arch/arm/mm/proc-v7.S b/trunk/arch/arm/mm/proc-v7.S index 089c0b5e454f..3c3867850a30 100644 --- a/trunk/arch/arm/mm/proc-v7.S +++ b/trunk/arch/arm/mm/proc-v7.S @@ -210,21 +210,19 @@ cpu_v7_name: /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */ .globl cpu_v7_suspend_size -.equ cpu_v7_suspend_size, 4 * 9 +.equ cpu_v7_suspend_size, 4 * 8 #ifdef CONFIG_PM_SLEEP ENTRY(cpu_v7_do_suspend) stmfd sp!, {r4 - r11, lr} mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID mrc p15, 0, r5, c13, c0, 1 @ Context ID - mrc p15, 0, r6, c13, c0, 3 @ User r/o thread ID - stmia r0!, {r4 - r6} mrc p15, 0, r6, c3, c0, 0 @ Domain ID mrc p15, 0, r7, c2, c0, 0 @ TTB 0 mrc p15, 0, r8, c2, c0, 1 @ TTB 1 mrc p15, 0, r9, c1, c0, 0 @ Control register mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register mrc p15, 0, r11, c1, c0, 2 @ Co-processor access control - stmia r0, {r6 - r11} + stmia r0, {r4 - r11} ldmfd sp!, {r4 - r11, pc} ENDPROC(cpu_v7_do_suspend) @@ -232,11 +230,9 @@ ENTRY(cpu_v7_do_resume) mov ip, #0 mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache - ldmia r0!, {r4 - r6} + ldmia r0, {r4 - r11} mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID mcr p15, 0, r5, c13, c0, 1 @ Context ID - mcr p15, 0, r6, c13, c0, 3 @ User r/o thread ID - ldmia r0, {r6 - r11} mcr p15, 0, r6, c3, c0, 0 @ Domain ID mcr p15, 0, r7, c2, c0, 0 @ TTB 0 mcr p15, 0, r8, c2, c0, 1 @ TTB 1 @@ -422,9 +418,9 @@ ENTRY(v7_processor_functions) .word cpu_v7_dcache_clean_area .word cpu_v7_switch_mm .word cpu_v7_set_pte_ext - .word cpu_v7_suspend_size - .word cpu_v7_do_suspend - .word cpu_v7_do_resume + .word 0 + .word 0 + .word 0 .size v7_processor_functions, . - v7_processor_functions .section ".rodata" diff --git a/trunk/arch/arm/plat-iop/cp6.c b/trunk/arch/arm/plat-iop/cp6.c index bab73e2c79db..9612a87e2a88 100644 --- a/trunk/arch/arm/plat-iop/cp6.c +++ b/trunk/arch/arm/plat-iop/cp6.c @@ -18,7 +18,6 @@ */ #include #include -#include static int cp6_trap(struct pt_regs *regs, unsigned int instr) { diff --git a/trunk/arch/mn10300/include/asm/uaccess.h b/trunk/arch/mn10300/include/asm/uaccess.h index 780560b330d9..3d6e60dad9d9 100644 --- a/trunk/arch/mn10300/include/asm/uaccess.h +++ b/trunk/arch/mn10300/include/asm/uaccess.h @@ -15,7 +15,6 @@ * User space memory access functions */ #include -#include #include #include diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index c03fef7a9c22..90d77bd078f5 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -579,7 +579,6 @@ config S390_GUEST def_bool y prompt "s390 guest support for KVM (EXPERIMENTAL)" depends on 64BIT && EXPERIMENTAL - select VIRTUALIZATION select VIRTIO select VIRTIO_RING select VIRTIO_CONSOLE diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 1d55c95f617c..52420d2785b3 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -262,7 +262,7 @@ void smp_ctl_set_bit(int cr, int bit) memset(&parms.orvals, 0, sizeof(parms.orvals)); memset(&parms.andvals, 0xff, sizeof(parms.andvals)); - parms.orvals[cr] = 1UL << bit; + parms.orvals[cr] = 1 << bit; on_each_cpu(smp_ctl_bit_callback, &parms, 1); } EXPORT_SYMBOL(smp_ctl_set_bit); @@ -276,7 +276,7 @@ void smp_ctl_clear_bit(int cr, int bit) memset(&parms.orvals, 0, sizeof(parms.orvals)); memset(&parms.andvals, 0xff, sizeof(parms.andvals)); - parms.andvals[cr] = ~(1UL << bit); + parms.andvals[cr] = ~(1L << bit); on_each_cpu(smp_ctl_bit_callback, &parms, 1); } EXPORT_SYMBOL(smp_ctl_clear_bit); diff --git a/trunk/arch/s390/oprofile/init.c b/trunk/arch/s390/oprofile/init.c index 0e358c2cffeb..5995e9bc72d9 100644 --- a/trunk/arch/s390/oprofile/init.c +++ b/trunk/arch/s390/oprofile/init.c @@ -25,7 +25,7 @@ extern void s390_backtrace(struct pt_regs * const regs, unsigned int depth); #include "hwsampler.h" -#define DEFAULT_INTERVAL 4127518 +#define DEFAULT_INTERVAL 4096 #define DEFAULT_SDBT_BLOCKS 1 #define DEFAULT_SDB_BLOCKS 511 @@ -151,12 +151,6 @@ static int oprofile_hwsampler_init(struct oprofile_operations *ops) if (oprofile_max_interval == 0) return -ENODEV; - /* The initial value should be sane */ - if (oprofile_hw_interval < oprofile_min_interval) - oprofile_hw_interval = oprofile_min_interval; - if (oprofile_hw_interval > oprofile_max_interval) - oprofile_hw_interval = oprofile_max_interval; - if (oprofile_timer_init(ops)) return -ENODEV; diff --git a/trunk/arch/x86/pci/acpi.c b/trunk/arch/x86/pci/acpi.c index 68c3c1395202..0972315c3860 100644 --- a/trunk/arch/x86/pci/acpi.c +++ b/trunk/arch/x86/pci/acpi.c @@ -188,7 +188,7 @@ static bool resource_contains(struct resource *res, resource_size_t point) return false; } -static void coalesce_windows(struct pci_root_info *info, unsigned long type) +static void coalesce_windows(struct pci_root_info *info, int type) { int i, j; struct resource *res1, *res2; diff --git a/trunk/block/blk-throttle.c b/trunk/block/blk-throttle.c index 3689f833afdc..a62be8d0dc1b 100644 --- a/trunk/block/blk-throttle.c +++ b/trunk/block/blk-throttle.c @@ -927,7 +927,7 @@ static int throtl_dispatch(struct request_queue *q) bio_list_init(&bio_list_on_stack); - throtl_log(td, "dispatch nr_queued=%d read=%u write=%u", + throtl_log(td, "dispatch nr_queued=%lu read=%u write=%u", total_nr_queued(td), td->nr_queued[READ], td->nr_queued[WRITE]); @@ -1204,7 +1204,7 @@ int blk_throtl_bio(struct request_queue *q, struct bio **biop) } queue_bio: - throtl_log_tg(td, tg, "[%c] bio. bdisp=%llu sz=%u bps=%llu" + throtl_log_tg(td, tg, "[%c] bio. bdisp=%u sz=%u bps=%llu" " iodisp=%u iops=%u queued=%d/%d", rw == READ ? 'R' : 'W', tg->bytes_disp[rw], bio->bi_size, tg->bps[rw], diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index f3799432676d..3c7b537bf908 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -988,10 +988,9 @@ static void cfq_group_served(struct cfq_data *cfqd, struct cfq_group *cfqg, cfq_log_cfqg(cfqd, cfqg, "served: vt=%llu min_vt=%llu", cfqg->vdisktime, st->min_vdisktime); - cfq_log_cfqq(cfqq->cfqd, cfqq, - "sl_used=%u disp=%u charge=%u iops=%u sect=%lu", - used_sl, cfqq->slice_dispatch, charge, - iops_mode(cfqd), cfqq->nr_sectors); + cfq_log_cfqq(cfqq->cfqd, cfqq, "sl_used=%u disp=%u charge=%u iops=%u" + " sect=%u", used_sl, cfqq->slice_dispatch, charge, + iops_mode(cfqd), cfqq->nr_sectors); cfq_blkiocg_update_timeslice_used(&cfqg->blkg, used_sl, unaccounted_sl); cfq_blkiocg_set_start_empty_time(&cfqg->blkg); @@ -2024,8 +2023,8 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) */ if (sample_valid(cic->ttime_samples) && (cfqq->slice_end - jiffies < cic->ttime_mean)) { - cfq_log_cfqq(cfqd, cfqq, "Not idling. think_time:%lu", - cic->ttime_mean); + cfq_log_cfqq(cfqd, cfqq, "Not idling. think_time:%d", + cic->ttime_mean); return; } @@ -2773,11 +2772,8 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd, smp_wmb(); cic->key = cfqd_dead_key(cfqd); - if (rcu_dereference(ioc->ioc_data) == cic) { - spin_lock(&ioc->lock); + if (ioc->ioc_data == cic) rcu_assign_pointer(ioc->ioc_data, NULL); - spin_unlock(&ioc->lock); - } if (cic->cfqq[BLK_RW_ASYNC]) { cfq_exit_cfqq(cfqd, cic->cfqq[BLK_RW_ASYNC]); diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index 3608289c8ecd..95822ae25cfe 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -1371,7 +1371,6 @@ struct disk_events { struct gendisk *disk; /* the associated disk */ spinlock_t lock; - struct mutex block_mutex; /* protects blocking */ int block; /* event blocking depth */ unsigned int pending; /* events already sent out */ unsigned int clearing; /* events being cleared */ @@ -1415,44 +1414,22 @@ static unsigned long disk_events_poll_jiffies(struct gendisk *disk) return msecs_to_jiffies(intv_msecs); } -/** - * disk_block_events - block and flush disk event checking - * @disk: disk to block events for - * - * On return from this function, it is guaranteed that event checking - * isn't in progress and won't happen until unblocked by - * disk_unblock_events(). Events blocking is counted and the actual - * unblocking happens after the matching number of unblocks are done. - * - * Note that this intentionally does not block event checking from - * disk_clear_events(). - * - * CONTEXT: - * Might sleep. - */ -void disk_block_events(struct gendisk *disk) +static void __disk_block_events(struct gendisk *disk, bool sync) { struct disk_events *ev = disk->ev; unsigned long flags; bool cancel; - if (!ev) - return; - - /* - * Outer mutex ensures that the first blocker completes canceling - * the event work before further blockers are allowed to finish. - */ - mutex_lock(&ev->block_mutex); - spin_lock_irqsave(&ev->lock, flags); cancel = !ev->block++; spin_unlock_irqrestore(&ev->lock, flags); - if (cancel) - cancel_delayed_work_sync(&disk->ev->dwork); - - mutex_unlock(&ev->block_mutex); + if (cancel) { + if (sync) + cancel_delayed_work_sync(&disk->ev->dwork); + else + cancel_delayed_work(&disk->ev->dwork); + } } static void __disk_unblock_events(struct gendisk *disk, bool check_now) @@ -1483,6 +1460,27 @@ static void __disk_unblock_events(struct gendisk *disk, bool check_now) spin_unlock_irqrestore(&ev->lock, flags); } +/** + * disk_block_events - block and flush disk event checking + * @disk: disk to block events for + * + * On return from this function, it is guaranteed that event checking + * isn't in progress and won't happen until unblocked by + * disk_unblock_events(). Events blocking is counted and the actual + * unblocking happens after the matching number of unblocks are done. + * + * Note that this intentionally does not block event checking from + * disk_clear_events(). + * + * CONTEXT: + * Might sleep. + */ +void disk_block_events(struct gendisk *disk) +{ + if (disk->ev) + __disk_block_events(disk, true); +} + /** * disk_unblock_events - unblock disk event checking * @disk: disk to unblock events for @@ -1510,18 +1508,10 @@ void disk_unblock_events(struct gendisk *disk) */ void disk_check_events(struct gendisk *disk) { - struct disk_events *ev = disk->ev; - unsigned long flags; - - if (!ev) - return; - - spin_lock_irqsave(&ev->lock, flags); - if (!ev->block) { - cancel_delayed_work(&ev->dwork); - queue_delayed_work(system_nrt_wq, &ev->dwork, 0); + if (disk->ev) { + __disk_block_events(disk, false); + __disk_unblock_events(disk, true); } - spin_unlock_irqrestore(&ev->lock, flags); } EXPORT_SYMBOL_GPL(disk_check_events); @@ -1556,7 +1546,7 @@ unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask) spin_unlock_irq(&ev->lock); /* uncondtionally schedule event check and wait for it to finish */ - disk_block_events(disk); + __disk_block_events(disk, true); queue_delayed_work(system_nrt_wq, &ev->dwork, 0); flush_delayed_work(&ev->dwork); __disk_unblock_events(disk, false); @@ -1674,7 +1664,7 @@ static ssize_t disk_events_poll_msecs_store(struct device *dev, if (intv < 0 && intv != -1) return -EINVAL; - disk_block_events(disk); + __disk_block_events(disk, true); disk->ev->poll_msecs = intv; __disk_unblock_events(disk, true); @@ -1760,7 +1750,6 @@ static void disk_add_events(struct gendisk *disk) INIT_LIST_HEAD(&ev->node); ev->disk = disk; spin_lock_init(&ev->lock); - mutex_init(&ev->block_mutex); ev->block = 1; ev->poll_msecs = -1; INIT_DELAYED_WORK(&ev->dwork, disk_events_workfn); @@ -1781,7 +1770,7 @@ static void disk_del_events(struct gendisk *disk) if (!disk->ev) return; - disk_block_events(disk); + __disk_block_events(disk, true); mutex_lock(&disk_events_mutex); list_del_init(&disk->ev->node); diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 000d03ae6653..736bee5dafeb 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -4143,9 +4143,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { * Devices which choke on SETXFER. Applies only if both the * device and controller are SATA. */ - { "PIONEER DVD-RW DVRTD08", NULL, ATA_HORKAGE_NOSETXFER }, - { "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER }, - { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, + { "PIONEER DVD-RW DVRTD08", "1.00", ATA_HORKAGE_NOSETXFER }, + { "PIONEER DVD-RW DVR-212D", "1.28", ATA_HORKAGE_NOSETXFER }, + { "PIONEER DVD-RW DVR-216D", "1.08", ATA_HORKAGE_NOSETXFER }, /* End Marker */ { } diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index 927f968e99d9..d51f9795c064 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -3797,12 +3797,6 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc); */ int ata_sas_port_start(struct ata_port *ap) { - /* - * the port is marked as frozen at allocation time, but if we don't - * have new eh, we won't thaw it - */ - if (!ap->ops->error_handler) - ap->pflags &= ~ATA_PFLAG_FROZEN; return 0; } EXPORT_SYMBOL_GPL(ata_sas_port_start); diff --git a/trunk/drivers/ata/pata_marvell.c b/trunk/drivers/ata/pata_marvell.c index 5d7f58a7e34d..75a6a0c0094f 100644 --- a/trunk/drivers/ata/pata_marvell.c +++ b/trunk/drivers/ata/pata_marvell.c @@ -161,9 +161,6 @@ static const struct pci_device_id marvell_pci_tbl[] = { { PCI_DEVICE(0x11AB, 0x6121), }, { PCI_DEVICE(0x11AB, 0x6123), }, { PCI_DEVICE(0x11AB, 0x6145), }, - { PCI_DEVICE(0x1B4B, 0x91A0), }, - { PCI_DEVICE(0x1B4B, 0x91A4), }, - { } /* terminate list */ }; diff --git a/trunk/drivers/ata/sata_dwc_460ex.c b/trunk/drivers/ata/sata_dwc_460ex.c index dc88a39e7db8..1c4b3aa4c7c4 100644 --- a/trunk/drivers/ata/sata_dwc_460ex.c +++ b/trunk/drivers/ata/sata_dwc_460ex.c @@ -389,7 +389,7 @@ static void sata_dwc_tf_dump(struct ata_taskfile *tf) /* * Function: get_burst_length_encode * arguments: datalength: length in bytes of data - * returns value to be programmed in register corresponding to data length + * returns value to be programmed in register corrresponding to data length * This value is effectively the log(base 2) of the length */ static int get_burst_length_encode(int datalength) diff --git a/trunk/drivers/base/power/clock_ops.c b/trunk/drivers/base/power/clock_ops.c index ad367c4139b1..eaa8a854af03 100644 --- a/trunk/drivers/base/power/clock_ops.c +++ b/trunk/drivers/base/power/clock_ops.c @@ -387,7 +387,7 @@ static int pm_runtime_clk_notify(struct notifier_block *nb, clknb = container_of(nb, struct pm_clk_notifier_block, nb); switch (action) { - case BUS_NOTIFY_BIND_DRIVER: + case BUS_NOTIFY_ADD_DEVICE: if (clknb->con_ids[0]) { for (con_id = clknb->con_ids; *con_id; con_id++) enable_clock(dev, *con_id); @@ -395,7 +395,7 @@ static int pm_runtime_clk_notify(struct notifier_block *nb, enable_clock(dev, NULL); } break; - case BUS_NOTIFY_UNBOUND_DRIVER: + case BUS_NOTIFY_DEL_DEVICE: if (clknb->con_ids[0]) { for (con_id = clknb->con_ids; *con_id; con_id++) disable_clock(dev, *con_id); diff --git a/trunk/drivers/base/power/main.c b/trunk/drivers/base/power/main.c index 06f09bf89cb2..aa6320207745 100644 --- a/trunk/drivers/base/power/main.c +++ b/trunk/drivers/base/power/main.c @@ -57,8 +57,7 @@ static int async_error; */ void device_pm_init(struct device *dev) { - dev->power.is_prepared = false; - dev->power.is_suspended = false; + dev->power.in_suspend = false; init_completion(&dev->power.completion); complete_all(&dev->power.completion); dev->power.wakeup = NULL; @@ -92,7 +91,7 @@ void device_pm_add(struct device *dev) pr_debug("PM: Adding info for %s:%s\n", dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); mutex_lock(&dpm_list_mtx); - if (dev->parent && dev->parent->power.is_prepared) + if (dev->parent && dev->parent->power.in_suspend) dev_warn(dev, "parent %s should not be sleeping\n", dev_name(dev->parent)); list_add_tail(&dev->power.entry, &dpm_list); @@ -512,14 +511,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) dpm_wait(dev->parent, async); device_lock(dev); - /* - * This is a fib. But we'll allow new children to be added below - * a resumed device, even if the device hasn't been completed yet. - */ - dev->power.is_prepared = false; - - if (!dev->power.is_suspended) - goto Unlock; + dev->power.in_suspend = false; if (dev->pwr_domain) { pm_dev_dbg(dev, state, "power domain "); @@ -556,9 +548,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) } End: - dev->power.is_suspended = false; - - Unlock: device_unlock(dev); complete_all(&dev->power.completion); @@ -681,7 +670,7 @@ void dpm_complete(pm_message_t state) struct device *dev = to_device(dpm_prepared_list.prev); get_device(dev); - dev->power.is_prepared = false; + dev->power.in_suspend = false; list_move(&dev->power.entry, &list); mutex_unlock(&dpm_list_mtx); @@ -846,11 +835,11 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) device_lock(dev); if (async_error) - goto Unlock; + goto End; if (pm_wakeup_pending()) { async_error = -EBUSY; - goto Unlock; + goto End; } if (dev->pwr_domain) { @@ -888,9 +877,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) } End: - dev->power.is_suspended = !error; - - Unlock: device_unlock(dev); complete_all(&dev->power.completion); @@ -1056,7 +1042,7 @@ int dpm_prepare(pm_message_t state) put_device(dev); break; } - dev->power.is_prepared = true; + dev->power.in_suspend = true; if (!list_empty(&dev->power.entry)) list_move_tail(&dev->power.entry, &dpm_prepared_list); put_device(dev); diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index c6389de53161..94c84d744100 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -1219,12 +1219,12 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ret = i915_gem_object_bind_to_gtt(obj, 0, true); if (ret) goto unlock; - - ret = i915_gem_object_set_to_gtt_domain(obj, write); - if (ret) - goto unlock; } + ret = i915_gem_object_set_to_gtt_domain(obj, write); + if (ret) + goto unlock; + if (obj->tiling_mode == I915_TILING_NONE) ret = i915_gem_object_put_fence(obj); else @@ -2926,6 +2926,8 @@ i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj) */ wmb(); + i915_gem_release_mmap(obj); + old_write_domain = obj->base.write_domain; obj->base.write_domain = 0; diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 4934cf84c320..20a4cc5b818f 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -187,6 +187,10 @@ i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) i915_gem_clflush_object(obj); + /* blow away mappings if mapped through GTT */ + if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_GTT) + i915_gem_release_mmap(obj); + if (obj->base.pending_write_domain) cd->flips |= atomic_read(&obj->pending_flip); diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index ae2b49969b99..9e34a1abeb61 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -1749,7 +1749,6 @@ void ironlake_irq_preinstall(struct drm_device *dev) * happens. */ I915_WRITE(GEN6_BLITTER_HWSTAM, ~GEN6_BLITTER_USER_INTERRUPT); - I915_WRITE(GEN6_BSD_HWSTAM, ~GEN6_BSD_USER_INTERRUPT); } /* XXX hotplug from PCH */ diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 5d5def756c9e..2f967af8e62e 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -531,7 +531,6 @@ #define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE 0 #define GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR (1 << 3) -#define GEN6_BSD_HWSTAM 0x12098 #define GEN6_BSD_IMR 0x120a8 #define GEN6_BSD_USER_INTERRUPT (1 << 12) diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c index e8152d23d5b6..60a94d2b5264 100644 --- a/trunk/drivers/gpu/drm/i915/i915_suspend.c +++ b/trunk/drivers/gpu/drm/i915/i915_suspend.c @@ -678,7 +678,6 @@ void i915_save_display(struct drm_device *dev) } /* VGA state */ - mutex_lock(&dev->struct_mutex); dev_priv->saveVGA0 = I915_READ(VGA0); dev_priv->saveVGA1 = I915_READ(VGA1); dev_priv->saveVGA_PD = I915_READ(VGA_PD); @@ -688,7 +687,6 @@ void i915_save_display(struct drm_device *dev) dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); i915_save_vga(dev); - mutex_unlock(&dev->struct_mutex); } void i915_restore_display(struct drm_device *dev) @@ -782,8 +780,6 @@ void i915_restore_display(struct drm_device *dev) I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); else I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); - - mutex_lock(&dev->struct_mutex); I915_WRITE(VGA0, dev_priv->saveVGA0); I915_WRITE(VGA1, dev_priv->saveVGA1); I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); @@ -791,7 +787,6 @@ void i915_restore_display(struct drm_device *dev) udelay(150); i915_restore_vga(dev); - mutex_unlock(&dev->struct_mutex); } int i915_save_state(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index aa43e7be6053..81a9059b6a94 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -4687,7 +4687,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, I915_WRITE(DSPCNTR(plane), dspcntr); POSTING_READ(DSPCNTR(plane)); - intel_enable_plane(dev_priv, plane, pipe); ret = intel_pipe_set_base(crtc, x, y, old_fb); @@ -5218,6 +5217,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, I915_WRITE(DSPCNTR(plane), dspcntr); POSTING_READ(DSPCNTR(plane)); + if (!HAS_PCH_SPLIT(dev)) + intel_enable_plane(dev_priv, plane, pipe); ret = intel_pipe_set_base(crtc, x, y, old_fb); diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index 12d2fdc52414..445af7981637 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -2013,9 +2013,9 @@ static void evergreen_gpu_init(struct radeon_device *rdev) rdev->config.evergreen.tile_config |= (3 << 0); break; } - /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */ + /* num banks is 8 on all fusion asics */ if (rdev->flags & RADEON_IS_IGP) - rdev->config.evergreen.tile_config |= 1 << 4; + rdev->config.evergreen.tile_config |= 8 << 4; else rdev->config.evergreen.tile_config |= ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; diff --git a/trunk/drivers/gpu/drm/radeon/radeon.h b/trunk/drivers/gpu/drm/radeon/radeon.h index ef0e0e016914..27f45579e64b 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon.h +++ b/trunk/drivers/gpu/drm/radeon/radeon.h @@ -179,7 +179,6 @@ void radeon_pm_resume(struct radeon_device *rdev); void radeon_combios_get_power_modes(struct radeon_device *rdev); void radeon_atombios_get_power_modes(struct radeon_device *rdev); void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type); -int radeon_atom_get_max_vddc(struct radeon_device *rdev, u16 *voltage); void rs690_pm_info(struct radeon_device *rdev); extern int rv6xx_get_temp(struct radeon_device *rdev); extern int rv770_get_temp(struct radeon_device *rdev); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c index bf2b61584cdb..1e725d9f767f 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c @@ -2320,14 +2320,6 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, le16_to_cpu(clock_info->r600.usVDDC); } - /* patch up vddc if necessary */ - if (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage == 0xff01) { - u16 vddc; - - if (radeon_atom_get_max_vddc(rdev, &vddc) == 0) - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc; - } - if (rdev->flags & RADEON_IS_IGP) { /* skip invalid modes */ if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) @@ -2638,35 +2630,7 @@ void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 v atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } -int radeon_atom_get_max_vddc(struct radeon_device *rdev, - u16 *voltage) -{ - union set_voltage args; - int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); - u8 frev, crev; - - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) - return -EINVAL; - - switch (crev) { - case 1: - return -EINVAL; - case 2: - args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE; - args.v2.ucVoltageMode = 0; - args.v2.usVoltageLevel = 0; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - - *voltage = le16_to_cpu(args.v2.usVoltageLevel); - break; - default: - DRM_ERROR("Unknown table version %d, %d\n", frev, crev); - return -EINVAL; - } - return 0; -} void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) { diff --git a/trunk/drivers/hid/hid-multitouch.c b/trunk/drivers/hid/hid-multitouch.c index 0b2dcd0ee591..386765654cf6 100644 --- a/trunk/drivers/hid/hid-multitouch.c +++ b/trunk/drivers/hid/hid-multitouch.c @@ -271,6 +271,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, } return 1; case HID_DG_CONTACTID: + if (!td->maxcontacts) + td->maxcontacts = MT_DEFAULT_MAXCONTACT; input_mt_init_slots(hi->input, td->maxcontacts); td->last_slot_field = usage->hid; td->last_field_index = field->index; @@ -547,9 +549,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) if (ret) goto fail; - if (!td->maxcontacts) - td->maxcontacts = MT_DEFAULT_MAXCONTACT; - td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), GFP_KERNEL); if (!td->slots) { diff --git a/trunk/drivers/infiniband/hw/cxgb4/cm.c b/trunk/drivers/infiniband/hw/cxgb4/cm.c index 31fb44085c9b..f660cd04ec2f 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/cm.c +++ b/trunk/drivers/infiniband/hw/cxgb4/cm.c @@ -1463,9 +1463,9 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) struct c4iw_qp_attributes attrs; int disconnect = 1; int release = 0; + int abort = 0; struct tid_info *t = dev->rdev.lldi.tids; unsigned int tid = GET_TID(hdr); - int ret; ep = lookup_tid(t, tid); PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); @@ -1501,12 +1501,10 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) start_ep_timer(ep); __state_set(&ep->com, CLOSING); attrs.next_state = C4IW_QP_STATE_CLOSING; - ret = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, + abort = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); - if (ret != -ECONNRESET) { - peer_close_upcall(ep); - disconnect = 1; - } + peer_close_upcall(ep); + disconnect = 1; break; case ABORTING: disconnect = 0; @@ -2111,16 +2109,15 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp) break; } + mutex_unlock(&ep->com.mutex); if (close) { - if (abrupt) { - close_complete_upcall(ep); - ret = send_abort(ep, NULL, gfp); - } else + if (abrupt) + ret = abort_connection(ep, NULL, gfp); + else ret = send_halfclose(ep, gfp); if (ret) fatal = 1; } - mutex_unlock(&ep->com.mutex); if (fatal) release_ep_resources(ep); return ret; @@ -2304,31 +2301,6 @@ static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb) return 0; } -static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb) -{ - struct cpl_abort_req_rss *req = cplhdr(skb); - struct c4iw_ep *ep; - struct tid_info *t = dev->rdev.lldi.tids; - unsigned int tid = GET_TID(req); - - ep = lookup_tid(t, tid); - if (is_neg_adv_abort(req->status)) { - PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep, - ep->hwtid); - kfree_skb(skb); - return 0; - } - PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid, - ep->com.state); - - /* - * Wake up any threads in rdma_init() or rdma_fini(). - */ - c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET); - sched(dev, skb); - return 0; -} - /* * Most upcalls from the T4 Core go to sched() to * schedule the processing on a work queue. @@ -2345,7 +2317,7 @@ c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS] = { [CPL_PASS_ESTABLISH] = sched, [CPL_PEER_CLOSE] = sched, [CPL_CLOSE_CON_RPL] = sched, - [CPL_ABORT_REQ_RSS] = peer_abort_intr, + [CPL_ABORT_REQ_RSS] = sched, [CPL_RDMA_TERMINATE] = sched, [CPL_FW4_ACK] = sched, [CPL_SET_TCB_RPL] = set_tcb_rpl, diff --git a/trunk/drivers/infiniband/hw/cxgb4/cq.c b/trunk/drivers/infiniband/hw/cxgb4/cq.c index 1720dc790d13..8d8f8add6fcd 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/cq.c +++ b/trunk/drivers/infiniband/hw/cxgb4/cq.c @@ -801,10 +801,6 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries, if (ucontext) { memsize = roundup(memsize, PAGE_SIZE); hwentries = memsize / sizeof *chp->cq.queue; - while (hwentries > T4_MAX_IQ_SIZE) { - memsize -= PAGE_SIZE; - hwentries = memsize / sizeof *chp->cq.queue; - } } chp->cq.size = hwentries; chp->cq.memsize = memsize; diff --git a/trunk/drivers/infiniband/hw/cxgb4/mem.c b/trunk/drivers/infiniband/hw/cxgb4/mem.c index 0347eed4a167..273ffe49525a 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/mem.c +++ b/trunk/drivers/infiniband/hw/cxgb4/mem.c @@ -625,7 +625,7 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, mhp->attr.perms = c4iw_ib_to_tpt_access(acc); mhp->attr.va_fbo = virt; mhp->attr.page_size = shift - 12; - mhp->attr.len = length; + mhp->attr.len = (u32) length; err = register_mem(rhp, php, mhp, shift); if (err) diff --git a/trunk/drivers/infiniband/hw/cxgb4/qp.c b/trunk/drivers/infiniband/hw/cxgb4/qp.c index a41578e48c7b..3b773b05a898 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/qp.c +++ b/trunk/drivers/infiniband/hw/cxgb4/qp.c @@ -1207,8 +1207,11 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, c4iw_get_ep(&qhp->ep->com); } ret = rdma_fini(rhp, qhp, ep); - if (ret) + if (ret) { + if (internal) + c4iw_get_ep(&qhp->ep->com); goto err; + } break; case C4IW_QP_STATE_TERMINATE: set_state(qhp, C4IW_QP_STATE_TERMINATE); diff --git a/trunk/drivers/infiniband/hw/qib/qib_iba7322.c b/trunk/drivers/infiniband/hw/qib/qib_iba7322.c index 8ec5237031a0..9f53e68a096a 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/trunk/drivers/infiniband/hw/qib/qib_iba7322.c @@ -469,8 +469,6 @@ static u8 ib_rate_to_delay[IB_RATE_120_GBPS + 1] = { #define IB_7322_LT_STATE_RECOVERIDLE 0x0f #define IB_7322_LT_STATE_CFGENH 0x10 #define IB_7322_LT_STATE_CFGTEST 0x11 -#define IB_7322_LT_STATE_CFGWAITRMTTEST 0x12 -#define IB_7322_LT_STATE_CFGWAITENH 0x13 /* link state machine states from IBC */ #define IB_7322_L_STATE_DOWN 0x0 @@ -500,10 +498,8 @@ static const u8 qib_7322_physportstate[0x20] = { IB_PHYSPORTSTATE_LINK_ERR_RECOVER, [IB_7322_LT_STATE_CFGENH] = IB_PHYSPORTSTATE_CFG_ENH, [IB_7322_LT_STATE_CFGTEST] = IB_PHYSPORTSTATE_CFG_TRAIN, - [IB_7322_LT_STATE_CFGWAITRMTTEST] = - IB_PHYSPORTSTATE_CFG_TRAIN, - [IB_7322_LT_STATE_CFGWAITENH] = - IB_PHYSPORTSTATE_CFG_WAIT_ENH, + [0x12] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x13] = IB_PHYSPORTSTATE_CFG_WAIT_ENH, [0x14] = IB_PHYSPORTSTATE_CFG_TRAIN, [0x15] = IB_PHYSPORTSTATE_CFG_TRAIN, [0x16] = IB_PHYSPORTSTATE_CFG_TRAIN, @@ -1696,9 +1692,7 @@ static void handle_serdes_issues(struct qib_pportdata *ppd, u64 ibcst) break; } - if (((ibclt >= IB_7322_LT_STATE_CFGTEST && - ibclt <= IB_7322_LT_STATE_CFGWAITENH) || - ibclt == IB_7322_LT_STATE_LINKUP) && + if (ibclt == IB_7322_LT_STATE_CFGTEST && (ibcst & SYM_MASK(IBCStatusA_0, LinkSpeedQDR))) { force_h1(ppd); ppd->cpspec->qdr_reforce = 1; @@ -7307,17 +7301,12 @@ static void ibsd_wr_allchans(struct qib_pportdata *ppd, int addr, unsigned data, static void serdes_7322_los_enable(struct qib_pportdata *ppd, int enable) { u64 data = qib_read_kreg_port(ppd, krp_serdesctrl); - u8 state = SYM_FIELD(data, IBSerdesCtrl_0, RXLOSEN); - - if (enable && !state) { - printk(KERN_INFO QIB_DRV_NAME " IB%u:%u Turning LOS on\n", - ppd->dd->unit, ppd->port); + printk(KERN_INFO QIB_DRV_NAME " IB%u:%u Turning LOS %s\n", + ppd->dd->unit, ppd->port, (enable ? "on" : "off")); + if (enable) data |= SYM_MASK(IBSerdesCtrl_0, RXLOSEN); - } else if (!enable && state) { - printk(KERN_INFO QIB_DRV_NAME " IB%u:%u Turning LOS off\n", - ppd->dd->unit, ppd->port); + else data &= ~SYM_MASK(IBSerdesCtrl_0, RXLOSEN); - } qib_write_kreg_port(ppd, krp_serdesctrl, data); } diff --git a/trunk/drivers/infiniband/hw/qib/qib_intr.c b/trunk/drivers/infiniband/hw/qib/qib_intr.c index 6ae57d23004a..a693c56ec8a6 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_intr.c +++ b/trunk/drivers/infiniband/hw/qib/qib_intr.c @@ -96,12 +96,8 @@ void qib_handle_e_ibstatuschanged(struct qib_pportdata *ppd, u64 ibcs) * states, or if it transitions from any of the up (INIT or better) * states into any of the down states (except link recovery), then * call the chip-specific code to take appropriate actions. - * - * ppd->lflags could be 0 if this is the first time the interrupt - * handlers has been called but the link is already up. */ - if (lstate >= IB_PORT_INIT && - (!ppd->lflags || (ppd->lflags & QIBL_LINKDOWN)) && + if (lstate >= IB_PORT_INIT && (ppd->lflags & QIBL_LINKDOWN) && ltstate == IB_PHYSPORTSTATE_LINKUP) { /* transitioned to UP */ if (dd->f_ib_updown(ppd, 1, ibcs)) diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 46767c53917a..135df164a4c1 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -624,7 +624,7 @@ static int pci_pm_prepare(struct device *dev) * system from the sleep state, we'll have to prevent it from signaling * wake-up. */ - pm_runtime_get_sync(dev); + pm_runtime_resume(dev); if (drv && drv->pm && drv->pm->prepare) error = drv->pm->prepare(dev); @@ -638,8 +638,6 @@ static void pci_pm_complete(struct device *dev) if (drv && drv->pm && drv->pm->complete) drv->pm->complete(dev); - - pm_runtime_put_sync(dev); } #else /* !CONFIG_PM_SLEEP */ diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 2c5b9b991279..5f10c23dff94 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -3284,7 +3284,7 @@ static int pci_set_vga_state_arch(struct pci_dev *dev, bool decode, * @dev: the PCI device * @decode: true = enable decoding, false = disable decoding * @command_bits: PCI_COMMAND_IO and/or PCI_COMMAND_MEMORY - * @flags: traverse ancestors and change bridges + * @change_bridge_flags: traverse ancestors and change bridges * CHANGE_BRIDGE_ONLY / CHANGE_BRIDGE */ int pci_set_vga_state(struct pci_dev *dev, bool decode, diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index bafb3c3d4a89..48849ffdd672 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -168,7 +168,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN; if (type == pci_bar_io) { l &= PCI_BASE_ADDRESS_IO_MASK; - mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT; + mask = PCI_BASE_ADDRESS_IO_MASK & IO_SPACE_LIMIT; } else { l &= PCI_BASE_ADDRESS_MEM_MASK; mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; diff --git a/trunk/drivers/rtc/rtc-vt8500.c b/trunk/drivers/rtc/rtc-vt8500.c index efd6066b5cd2..b8bc862903ae 100644 --- a/trunk/drivers/rtc/rtc-vt8500.c +++ b/trunk/drivers/rtc/rtc-vt8500.c @@ -78,6 +78,7 @@ struct vt8500_rtc { void __iomem *regbase; struct resource *res; int irq_alarm; + int irq_hz; struct rtc_device *rtc; spinlock_t lock; /* Protects this structure */ }; @@ -99,6 +100,10 @@ static irqreturn_t vt8500_rtc_irq(int irq, void *dev_id) if (isr & 1) events |= RTC_AF | RTC_IRQF; + /* Only second/minute interrupts are supported */ + if (isr & 2) + events |= RTC_UF | RTC_IRQF; + rtc_update_irq(vt8500_rtc->rtc, 1, events); return IRQ_HANDLED; @@ -194,12 +199,27 @@ static int vt8500_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } +static int vt8500_update_irq_enable(struct device *dev, unsigned int enabled) +{ + struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev); + unsigned long tmp = readl(vt8500_rtc->regbase + VT8500_RTC_CR); + + if (enabled) + tmp |= VT8500_RTC_CR_SM_SEC | VT8500_RTC_CR_SM_ENABLE; + else + tmp &= ~VT8500_RTC_CR_SM_ENABLE; + + writel(tmp, vt8500_rtc->regbase + VT8500_RTC_CR); + return 0; +} + static const struct rtc_class_ops vt8500_rtc_ops = { .read_time = vt8500_rtc_read_time, .set_time = vt8500_rtc_set_time, .read_alarm = vt8500_rtc_read_alarm, .set_alarm = vt8500_rtc_set_alarm, .alarm_irq_enable = vt8500_alarm_irq_enable, + .update_irq_enable = vt8500_update_irq_enable, }; static int __devinit vt8500_rtc_probe(struct platform_device *pdev) @@ -228,6 +248,13 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) goto err_free; } + vt8500_rtc->irq_hz = platform_get_irq(pdev, 1); + if (vt8500_rtc->irq_hz < 0) { + dev_err(&pdev->dev, "No 1Hz IRQ resource defined\n"); + ret = -ENXIO; + goto err_free; + } + vt8500_rtc->res = request_mem_region(vt8500_rtc->res->start, resource_size(vt8500_rtc->res), "vt8500-rtc"); @@ -245,8 +272,9 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) goto err_release; } - /* Enable RTC and set it to 24-hour mode */ - writel(VT8500_RTC_CR_ENABLE | VT8500_RTC_CR_24H, + /* Enable the second/minute interrupt generation and enable RTC */ + writel(VT8500_RTC_CR_ENABLE | VT8500_RTC_CR_24H + | VT8500_RTC_CR_SM_ENABLE | VT8500_RTC_CR_SM_SEC, vt8500_rtc->regbase + VT8500_RTC_CR); vt8500_rtc->rtc = rtc_device_register("vt8500-rtc", &pdev->dev, @@ -258,16 +286,26 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) goto err_unmap; } + ret = request_irq(vt8500_rtc->irq_hz, vt8500_rtc_irq, 0, + "rtc 1Hz", vt8500_rtc); + if (ret < 0) { + dev_err(&pdev->dev, "can't get irq %i, err %d\n", + vt8500_rtc->irq_hz, ret); + goto err_unreg; + } + ret = request_irq(vt8500_rtc->irq_alarm, vt8500_rtc_irq, 0, "rtc alarm", vt8500_rtc); if (ret < 0) { dev_err(&pdev->dev, "can't get irq %i, err %d\n", vt8500_rtc->irq_alarm, ret); - goto err_unreg; + goto err_free_hz; } return 0; +err_free_hz: + free_irq(vt8500_rtc->irq_hz, vt8500_rtc); err_unreg: rtc_device_unregister(vt8500_rtc->rtc); err_unmap: @@ -285,6 +323,7 @@ static int __devexit vt8500_rtc_remove(struct platform_device *pdev) struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev); free_irq(vt8500_rtc->irq_alarm, vt8500_rtc); + free_irq(vt8500_rtc->irq_hz, vt8500_rtc); rtc_device_unregister(vt8500_rtc->rtc); diff --git a/trunk/drivers/target/loopback/tcm_loop.c b/trunk/drivers/target/loopback/tcm_loop.c index 70c2e7fa6664..dee2a2c909f5 100644 --- a/trunk/drivers/target/loopback/tcm_loop.c +++ b/trunk/drivers/target/loopback/tcm_loop.c @@ -386,7 +386,7 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc) */ se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, (void *)tl_tmr, TMR_LUN_RESET); - if (IS_ERR(se_cmd->se_tmr_req)) + if (!se_cmd->se_tmr_req) goto release; /* * Locate the underlying TCM struct se_lun from sc->device->lun @@ -1017,7 +1017,6 @@ static int tcm_loop_make_nexus( struct se_portal_group *se_tpg; struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba; struct tcm_loop_nexus *tl_nexus; - int ret = -ENOMEM; if (tl_tpg->tl_hba->tl_nexus) { printk(KERN_INFO "tl_tpg->tl_hba->tl_nexus already exists\n"); @@ -1034,10 +1033,8 @@ static int tcm_loop_make_nexus( * Initialize the struct se_session pointer */ tl_nexus->se_sess = transport_init_session(); - if (IS_ERR(tl_nexus->se_sess)) { - ret = PTR_ERR(tl_nexus->se_sess); + if (!tl_nexus->se_sess) goto out; - } /* * Since we are running in 'demo mode' this call with generate a * struct se_node_acl for the tcm_loop struct se_portal_group with the SCSI @@ -1063,7 +1060,7 @@ static int tcm_loop_make_nexus( out: kfree(tl_nexus); - return ret; + return -ENOMEM; } static int tcm_loop_drop_nexus( @@ -1143,7 +1140,7 @@ static ssize_t tcm_loop_tpg_store_nexus( * the fabric protocol_id set in tcm_loop_make_scsi_hba(), and call * tcm_loop_make_nexus() */ - if (strlen(page) >= TL_WWN_ADDR_LEN) { + if (strlen(page) > TL_WWN_ADDR_LEN) { printk(KERN_ERR "Emulated NAA Sas Address: %s, exceeds" " max: %d\n", page, TL_WWN_ADDR_LEN); return -EINVAL; @@ -1324,7 +1321,7 @@ struct se_wwn *tcm_loop_make_scsi_hba( return ERR_PTR(-EINVAL); check_len: - if (strlen(name) >= TL_WWN_ADDR_LEN) { + if (strlen(name) > TL_WWN_ADDR_LEN) { printk(KERN_ERR "Emulated NAA %s Address: %s, exceeds" " max: %d\n", name, tcm_loop_dump_proto_id(tl_hba), TL_WWN_ADDR_LEN); diff --git a/trunk/drivers/target/target_core_configfs.c b/trunk/drivers/target/target_core_configfs.c index 25c1f49a7d8b..ee6fad979b50 100644 --- a/trunk/drivers/target/target_core_configfs.c +++ b/trunk/drivers/target/target_core_configfs.c @@ -304,7 +304,7 @@ struct target_fabric_configfs *target_fabric_configfs_init( printk(KERN_ERR "Unable to locate passed fabric name\n"); return NULL; } - if (strlen(name) >= TARGET_FABRIC_NAME_SIZE) { + if (strlen(name) > TARGET_FABRIC_NAME_SIZE) { printk(KERN_ERR "Passed name: %s exceeds TARGET_FABRIC" "_NAME_SIZE\n", name); return NULL; @@ -312,7 +312,7 @@ struct target_fabric_configfs *target_fabric_configfs_init( tf = kzalloc(sizeof(struct target_fabric_configfs), GFP_KERNEL); if (!(tf)) - return NULL; + return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&tf->tf_list); atomic_set(&tf->tf_access_cnt, 0); @@ -851,7 +851,7 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial( return -EOPNOTSUPP; } - if (strlen(page) >= INQUIRY_VPD_SERIAL_LEN) { + if ((strlen(page) + 1) > INQUIRY_VPD_SERIAL_LEN) { printk(KERN_ERR "Emulated VPD Unit Serial exceeds" " INQUIRY_VPD_SERIAL_LEN: %d\n", INQUIRY_VPD_SERIAL_LEN); return -EOVERFLOW; @@ -917,7 +917,7 @@ static ssize_t target_core_dev_wwn_show_attr_vpd_protocol_identifier( transport_dump_vpd_proto_id(vpd, buf, VPD_TMP_BUF_SIZE); - if ((len + strlen(buf) >= PAGE_SIZE)) + if ((len + strlen(buf) > PAGE_SIZE)) break; len += sprintf(page+len, "%s", buf); @@ -962,19 +962,19 @@ static ssize_t target_core_dev_wwn_show_attr_##_name( \ \ memset(buf, 0, VPD_TMP_BUF_SIZE); \ transport_dump_vpd_assoc(vpd, buf, VPD_TMP_BUF_SIZE); \ - if ((len + strlen(buf) >= PAGE_SIZE)) \ + if ((len + strlen(buf) > PAGE_SIZE)) \ break; \ len += sprintf(page+len, "%s", buf); \ \ memset(buf, 0, VPD_TMP_BUF_SIZE); \ transport_dump_vpd_ident_type(vpd, buf, VPD_TMP_BUF_SIZE); \ - if ((len + strlen(buf) >= PAGE_SIZE)) \ + if ((len + strlen(buf) > PAGE_SIZE)) \ break; \ len += sprintf(page+len, "%s", buf); \ \ memset(buf, 0, VPD_TMP_BUF_SIZE); \ transport_dump_vpd_ident(vpd, buf, VPD_TMP_BUF_SIZE); \ - if ((len + strlen(buf) >= PAGE_SIZE)) \ + if ((len + strlen(buf) > PAGE_SIZE)) \ break; \ len += sprintf(page+len, "%s", buf); \ } \ @@ -1299,7 +1299,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts( &i_buf[0] : "", pr_reg->pr_res_key, pr_reg->pr_res_generation); - if ((len + strlen(buf) >= PAGE_SIZE)) + if ((len + strlen(buf) > PAGE_SIZE)) break; len += sprintf(page+len, "%s", buf); @@ -1496,7 +1496,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( ret = -ENOMEM; goto out; } - if (strlen(i_port) >= PR_APTPL_MAX_IPORT_LEN) { + if (strlen(i_port) > PR_APTPL_MAX_IPORT_LEN) { printk(KERN_ERR "APTPL metadata initiator_node=" " exceeds PR_APTPL_MAX_IPORT_LEN: %d\n", PR_APTPL_MAX_IPORT_LEN); @@ -1510,7 +1510,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( ret = -ENOMEM; goto out; } - if (strlen(isid) >= PR_REG_ISID_LEN) { + if (strlen(isid) > PR_REG_ISID_LEN) { printk(KERN_ERR "APTPL metadata initiator_isid" "= exceeds PR_REG_ISID_LEN: %d\n", PR_REG_ISID_LEN); @@ -1571,7 +1571,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( ret = -ENOMEM; goto out; } - if (strlen(t_port) >= PR_APTPL_MAX_TPORT_LEN) { + if (strlen(t_port) > PR_APTPL_MAX_TPORT_LEN) { printk(KERN_ERR "APTPL metadata target_node=" " exceeds PR_APTPL_MAX_TPORT_LEN: %d\n", PR_APTPL_MAX_TPORT_LEN); @@ -3052,7 +3052,7 @@ static struct config_group *target_core_call_addhbatotarget( int ret; memset(buf, 0, TARGET_CORE_NAME_MAX_LEN); - if (strlen(name) >= TARGET_CORE_NAME_MAX_LEN) { + if (strlen(name) > TARGET_CORE_NAME_MAX_LEN) { printk(KERN_ERR "Passed *name strlen(): %d exceeds" " TARGET_CORE_NAME_MAX_LEN: %d\n", (int)strlen(name), TARGET_CORE_NAME_MAX_LEN); diff --git a/trunk/drivers/target/target_core_device.c b/trunk/drivers/target/target_core_device.c index ba698ea62bb2..8407f9ca2b31 100644 --- a/trunk/drivers/target/target_core_device.c +++ b/trunk/drivers/target/target_core_device.c @@ -192,7 +192,7 @@ int transport_get_lun_for_tmr( &SE_NODE_ACL(se_sess)->device_list[unpacked_lun]; if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { se_lun = se_cmd->se_lun = se_tmr->tmr_lun = deve->se_lun; - dev = se_lun->lun_se_dev; + dev = se_tmr->tmr_dev = se_lun->lun_se_dev; se_cmd->pr_res_key = deve->pr_res_key; se_cmd->orig_fe_lun = unpacked_lun; se_cmd->se_orig_obj_ptr = SE_LUN(se_cmd)->lun_se_dev; @@ -216,7 +216,6 @@ int transport_get_lun_for_tmr( se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; return -1; } - se_tmr->tmr_dev = dev; spin_lock(&dev->se_tmr_lock); list_add_tail(&se_tmr->tmr_list, &dev->dev_tmr_list); @@ -1431,7 +1430,7 @@ struct se_lun_acl *core_dev_init_initiator_node_lun_acl( struct se_lun_acl *lacl; struct se_node_acl *nacl; - if (strlen(initiatorname) >= TRANSPORT_IQN_LEN) { + if (strlen(initiatorname) > TRANSPORT_IQN_LEN) { printk(KERN_ERR "%s InitiatorName exceeds maximum size.\n", TPG_TFO(tpg)->get_fabric_name()); *ret = -EOVERFLOW; diff --git a/trunk/drivers/target/target_core_pr.c b/trunk/drivers/target/target_core_pr.c index b662db3a320b..a79f518ca6e2 100644 --- a/trunk/drivers/target/target_core_pr.c +++ b/trunk/drivers/target/target_core_pr.c @@ -1916,7 +1916,7 @@ static int __core_scsi3_update_aptpl_buf( pr_reg->pr_res_mapped_lun); } - if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { + if ((len + strlen(tmp) > pr_aptpl_buf_len)) { printk(KERN_ERR "Unable to update renaming" " APTPL metadata\n"); spin_unlock(&T10_RES(su_dev)->registration_lock); @@ -1934,7 +1934,7 @@ static int __core_scsi3_update_aptpl_buf( TPG_TFO(tpg)->tpg_get_tag(tpg), lun->lun_sep->sep_rtpi, lun->unpacked_lun, reg_count); - if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { + if ((len + strlen(tmp) > pr_aptpl_buf_len)) { printk(KERN_ERR "Unable to update renaming" " APTPL metadata\n"); spin_unlock(&T10_RES(su_dev)->registration_lock); @@ -1986,7 +1986,7 @@ static int __core_scsi3_write_aptpl_to_file( memset(iov, 0, sizeof(struct iovec)); memset(path, 0, 512); - if (strlen(&wwn->unit_serial[0]) >= 512) { + if (strlen(&wwn->unit_serial[0]) > 512) { printk(KERN_ERR "WWN value for struct se_device does not fit" " into path buffer\n"); return -1; diff --git a/trunk/drivers/target/target_core_tmr.c b/trunk/drivers/target/target_core_tmr.c index 179063d81cdd..59b8b9c5ad72 100644 --- a/trunk/drivers/target/target_core_tmr.c +++ b/trunk/drivers/target/target_core_tmr.c @@ -75,16 +75,10 @@ void core_tmr_release_req( { struct se_device *dev = tmr->tmr_dev; - if (!dev) { - kmem_cache_free(se_tmr_req_cache, tmr); - return; - } - spin_lock(&dev->se_tmr_lock); list_del(&tmr->tmr_list); - spin_unlock(&dev->se_tmr_lock); - kmem_cache_free(se_tmr_req_cache, tmr); + spin_unlock(&dev->se_tmr_lock); } static void core_tmr_handle_tas_abort( diff --git a/trunk/drivers/target/target_core_transport.c b/trunk/drivers/target/target_core_transport.c index 4b9b7169bdd9..4dafeb8b5638 100644 --- a/trunk/drivers/target/target_core_transport.c +++ b/trunk/drivers/target/target_core_transport.c @@ -536,13 +536,13 @@ EXPORT_SYMBOL(transport_register_session); void transport_deregister_session_configfs(struct se_session *se_sess) { struct se_node_acl *se_nacl; - unsigned long flags; + /* * Used by struct se_node_acl's under ConfigFS to locate active struct se_session */ se_nacl = se_sess->se_node_acl; if ((se_nacl)) { - spin_lock_irqsave(&se_nacl->nacl_sess_lock, flags); + spin_lock_irq(&se_nacl->nacl_sess_lock); list_del(&se_sess->sess_acl_list); /* * If the session list is empty, then clear the pointer. @@ -556,7 +556,7 @@ void transport_deregister_session_configfs(struct se_session *se_sess) se_nacl->acl_sess_list.prev, struct se_session, sess_acl_list); } - spin_unlock_irqrestore(&se_nacl->nacl_sess_lock, flags); + spin_unlock_irq(&se_nacl->nacl_sess_lock); } } EXPORT_SYMBOL(transport_deregister_session_configfs); diff --git a/trunk/drivers/target/tcm_fc/tcm_fc.h b/trunk/drivers/target/tcm_fc/tcm_fc.h index 7b82f1b7fef8..defff32b7880 100644 --- a/trunk/drivers/target/tcm_fc/tcm_fc.h +++ b/trunk/drivers/target/tcm_fc/tcm_fc.h @@ -144,7 +144,7 @@ enum ft_cmd_state { */ struct ft_cmd { enum ft_cmd_state state; - u32 lun; /* LUN from request */ + u16 lun; /* LUN from request */ struct ft_sess *sess; /* session held for cmd */ struct fc_seq *seq; /* sequence in exchange mgr */ struct se_cmd se_cmd; /* Local TCM I/O descriptor */ diff --git a/trunk/drivers/target/tcm_fc/tfc_cmd.c b/trunk/drivers/target/tcm_fc/tfc_cmd.c index b2a106729d49..c056a1132ae1 100644 --- a/trunk/drivers/target/tcm_fc/tfc_cmd.c +++ b/trunk/drivers/target/tcm_fc/tfc_cmd.c @@ -94,6 +94,29 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller) 16, 4, cmd->cdb, MAX_COMMAND_SIZE, 0); } +/* + * Get LUN from CDB. + */ +static int ft_get_lun_for_cmd(struct ft_cmd *cmd, u8 *lunp) +{ + u64 lun; + + lun = lunp[1]; + switch (lunp[0] >> 6) { + case 0: + break; + case 1: + lun |= (lunp[0] & 0x3f) << 8; + break; + default: + return -1; + } + if (lun >= TRANSPORT_MAX_LUNS_PER_TPG) + return -1; + cmd->lun = lun; + return transport_get_lun_for_cmd(&cmd->se_cmd, NULL, lun); +} + static void ft_queue_cmd(struct ft_sess *sess, struct ft_cmd *cmd) { struct se_queue_obj *qobj; @@ -395,7 +418,6 @@ static void ft_send_tm(struct ft_cmd *cmd) { struct se_tmr_req *tmr; struct fcp_cmnd *fcp; - struct ft_sess *sess; u8 tm_func; fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp)); @@ -403,6 +425,13 @@ static void ft_send_tm(struct ft_cmd *cmd) switch (fcp->fc_tm_flags) { case FCP_TMF_LUN_RESET: tm_func = TMR_LUN_RESET; + if (ft_get_lun_for_cmd(cmd, fcp->fc_lun) < 0) { + ft_dump_cmd(cmd, __func__); + transport_send_check_condition_and_sense(&cmd->se_cmd, + cmd->se_cmd.scsi_sense_reason, 0); + ft_sess_put(cmd->sess); + return; + } break; case FCP_TMF_TGT_RESET: tm_func = TMR_TARGET_WARM_RESET; @@ -434,36 +463,6 @@ static void ft_send_tm(struct ft_cmd *cmd) return; } cmd->se_cmd.se_tmr_req = tmr; - - switch (fcp->fc_tm_flags) { - case FCP_TMF_LUN_RESET: - cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun); - if (transport_get_lun_for_tmr(&cmd->se_cmd, cmd->lun) < 0) { - /* - * Make sure to clean up newly allocated TMR request - * since "unable to handle TMR request because failed - * to get to LUN" - */ - FT_TM_DBG("Failed to get LUN for TMR func %d, " - "se_cmd %p, unpacked_lun %d\n", - tm_func, &cmd->se_cmd, cmd->lun); - ft_dump_cmd(cmd, __func__); - sess = cmd->sess; - transport_send_check_condition_and_sense(&cmd->se_cmd, - cmd->se_cmd.scsi_sense_reason, 0); - transport_generic_free_cmd(&cmd->se_cmd, 0, 1, 0); - ft_sess_put(sess); - return; - } - break; - case FCP_TMF_TGT_RESET: - case FCP_TMF_CLR_TASK_SET: - case FCP_TMF_ABT_TASK_SET: - case FCP_TMF_CLR_ACA: - break; - default: - return; - } transport_generic_handle_tmr(&cmd->se_cmd); } @@ -636,8 +635,7 @@ static void ft_send_cmd(struct ft_cmd *cmd) fc_seq_exch(cmd->seq)->lp->tt.seq_set_resp(cmd->seq, ft_recv_seq, cmd); - cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun); - ret = transport_get_lun_for_cmd(&cmd->se_cmd, NULL, cmd->lun); + ret = ft_get_lun_for_cmd(cmd, fcp->fc_lun); if (ret < 0) { ft_dump_cmd(cmd, __func__); transport_send_check_condition_and_sense(&cmd->se_cmd, diff --git a/trunk/drivers/target/tcm_fc/tfc_io.c b/trunk/drivers/target/tcm_fc/tfc_io.c index 8c4a24077d9d..4c3c0efbe13f 100644 --- a/trunk/drivers/target/tcm_fc/tfc_io.c +++ b/trunk/drivers/target/tcm_fc/tfc_io.c @@ -203,7 +203,7 @@ int ft_queue_data_in(struct se_cmd *se_cmd) /* XXX For now, initiator will retry */ if (printk_ratelimit()) printk(KERN_ERR "%s: Failed to send frame %p, " - "xid <0x%x>, remaining %zu, " + "xid <0x%x>, remaining <0x%x>, " "lso_max <0x%x>\n", __func__, fp, ep->xid, remaining, lport->lso_max); diff --git a/trunk/drivers/target/tcm_fc/tfc_sess.c b/trunk/drivers/target/tcm_fc/tfc_sess.c index 7491e21cc6ae..a3bd57f2ea32 100644 --- a/trunk/drivers/target/tcm_fc/tfc_sess.c +++ b/trunk/drivers/target/tcm_fc/tfc_sess.c @@ -229,7 +229,7 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id, return NULL; sess->se_sess = transport_init_session(); - if (IS_ERR(sess->se_sess)) { + if (!sess->se_sess) { kfree(sess); return NULL; } @@ -332,7 +332,7 @@ void ft_sess_close(struct se_session *se_sess) lport = sess->tport->lport; port_id = sess->port_id; if (port_id == -1) { - mutex_unlock(&ft_lport_lock); + mutex_lock(&ft_lport_lock); return; } FT_SESS_DBG("port_id %x\n", port_id); diff --git a/trunk/drivers/tty/serial/mrst_max3110.c b/trunk/drivers/tty/serial/mrst_max3110.c index a764bf99743b..1bd28450ca40 100644 --- a/trunk/drivers/tty/serial/mrst_max3110.c +++ b/trunk/drivers/tty/serial/mrst_max3110.c @@ -421,6 +421,7 @@ static int max3110_main_thread(void *_max) int ret = 0; struct circ_buf *xmit = &max->con_xmit; + init_waitqueue_head(wq); pr_info(PR_FMT "start main thread\n"); do { @@ -822,7 +823,7 @@ static int __devinit serial_m3110_probe(struct spi_device *spi) res = RC_TAG; ret = max3110_write_then_read(max, (u8 *)&res, (u8 *)&res, 2, 0); if (ret < 0 || res == 0 || res == 0xffff) { - dev_dbg(&spi->dev, "MAX3111 deemed not present (conf reg %04x)", + printk(KERN_ERR "MAX3111 deemed not present (conf reg %04x)", res); ret = -ENODEV; goto err_get_page; @@ -837,8 +838,6 @@ static int __devinit serial_m3110_probe(struct spi_device *spi) max->con_xmit.head = 0; max->con_xmit.tail = 0; - init_waitqueue_head(&max->wq); - max->main_thread = kthread_run(max3110_main_thread, max, "max3110_main"); if (IS_ERR(max->main_thread)) { diff --git a/trunk/drivers/usb/core/driver.c b/trunk/drivers/usb/core/driver.c index aa3cc465a601..e35a17687c05 100644 --- a/trunk/drivers/usb/core/driver.c +++ b/trunk/drivers/usb/core/driver.c @@ -375,7 +375,7 @@ static int usb_unbind_interface(struct device *dev) * Just re-enable it without affecting the endpoint toggles. */ usb_enable_interface(udev, intf, false); - } else if (!error && !intf->dev.power.is_prepared) { + } else if (!error && !intf->dev.power.in_suspend) { r = usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); if (r < 0) @@ -960,7 +960,7 @@ void usb_rebind_intf(struct usb_interface *intf) } /* Try to rebind the interface */ - if (!intf->dev.power.is_prepared) { + if (!intf->dev.power.in_suspend) { intf->needs_binding = 0; rc = device_attach(&intf->dev); if (rc < 0) @@ -1107,7 +1107,7 @@ static int usb_resume_interface(struct usb_device *udev, if (intf->condition == USB_INTERFACE_UNBOUND) { /* Carry out a deferred switch to altsetting 0 */ - if (intf->needs_altsetting0 && !intf->dev.power.is_prepared) { + if (intf->needs_altsetting0 && !intf->dev.power.in_suspend) { usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); intf->needs_altsetting0 = 0; diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 610e8e0b04b8..1a2421f908f0 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -762,19 +762,7 @@ static struct block_device *bd_start_claiming(struct block_device *bdev, if (!disk) return ERR_PTR(-ENXIO); - /* - * Normally, @bdev should equal what's returned from bdget_disk() - * if partno is 0; however, some drivers (floppy) use multiple - * bdev's for the same physical device and @bdev may be one of the - * aliases. Keep @bdev if partno is 0. This means claimer - * tracking is broken for those devices but it has always been that - * way. - */ - if (partno) - whole = bdget_disk(disk, 0); - else - whole = bdgrab(bdev); - + whole = bdget_disk(disk, 0); module_put(disk->fops->owner); put_disk(disk); if (!whole) diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index f30ac05dbda7..300628795fdb 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -19,6 +19,7 @@ #ifndef __BTRFS_CTREE__ #define __BTRFS_CTREE__ +#include #include #include #include diff --git a/trunk/fs/cifs/Kconfig b/trunk/fs/cifs/Kconfig index f66cc1625150..53ed1ad2c112 100644 --- a/trunk/fs/cifs/Kconfig +++ b/trunk/fs/cifs/Kconfig @@ -156,6 +156,6 @@ config CIFS_ACL config CIFS_NFSD_EXPORT bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)" - depends on CIFS && EXPERIMENTAL && BROKEN + depends on CIFS && EXPERIMENTAL help Allows NFS server to export a CIFS mounted share (nfsd over cifs) diff --git a/trunk/fs/cifs/cifs_fs_sb.h b/trunk/fs/cifs/cifs_fs_sb.h index 7260e11e21f8..ffb1459dc6ec 100644 --- a/trunk/fs/cifs/cifs_fs_sb.h +++ b/trunk/fs/cifs/cifs_fs_sb.h @@ -42,7 +42,6 @@ #define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ #define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */ #define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */ -#define CIFS_MOUNT_POSIXACL 0x100000 /* mirror of MS_POSIXACL in mnt_cifs_flags */ struct cifs_sb_info { struct rb_root tlink_tree; diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index 35f9154615fa..2f0c58646c10 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -104,7 +104,8 @@ cifs_sb_deactive(struct super_block *sb) } static int -cifs_read_super(struct super_block *sb) +cifs_read_super(struct super_block *sb, struct smb_vol *volume_info, + const char *devname, int silent) { struct inode *inode; struct cifs_sb_info *cifs_sb; @@ -112,16 +113,22 @@ cifs_read_super(struct super_block *sb) cifs_sb = CIFS_SB(sb); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIXACL) - sb->s_flags |= MS_POSIXACL; + spin_lock_init(&cifs_sb->tlink_tree_lock); + cifs_sb->tlink_tree = RB_ROOT; - if (cifs_sb_master_tcon(cifs_sb)->ses->capabilities & CAP_LARGE_FILES) - sb->s_maxbytes = MAX_LFS_FILESIZE; - else - sb->s_maxbytes = MAX_NON_LFS; + rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); + if (rc) + return rc; + + cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; - /* BB FIXME fix time_gran to be larger for LANMAN sessions */ - sb->s_time_gran = 100; + rc = cifs_mount(sb, cifs_sb, volume_info, devname); + + if (rc) { + if (!silent) + cERROR(1, "cifs_mount failed w/return code = %d", rc); + goto out_mount_failed; + } sb->s_magic = CIFS_MAGIC_NUMBER; sb->s_op = &cifs_super_ops; @@ -163,14 +170,37 @@ cifs_read_super(struct super_block *sb) if (inode) iput(inode); + cifs_umount(sb, cifs_sb); + +out_mount_failed: + bdi_destroy(&cifs_sb->bdi); return rc; } -static void cifs_kill_sb(struct super_block *sb) +static void +cifs_put_super(struct super_block *sb) { - struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - kill_anon_super(sb); - cifs_umount(cifs_sb); + int rc = 0; + struct cifs_sb_info *cifs_sb; + + cFYI(1, "In cifs_put_super"); + cifs_sb = CIFS_SB(sb); + if (cifs_sb == NULL) { + cFYI(1, "Empty cifs superblock info passed to unmount"); + return; + } + + rc = cifs_umount(sb, cifs_sb); + if (rc) + cERROR(1, "cifs_umount failed with return code %d", rc); + if (cifs_sb->mountdata) { + kfree(cifs_sb->mountdata); + cifs_sb->mountdata = NULL; + } + + unload_nls(cifs_sb->local_nls); + bdi_destroy(&cifs_sb->bdi); + kfree(cifs_sb); } static int @@ -518,6 +548,7 @@ static int cifs_drop_inode(struct inode *inode) } static const struct super_operations cifs_super_ops = { + .put_super = cifs_put_super, .statfs = cifs_statfs, .alloc_inode = cifs_alloc_inode, .destroy_inode = cifs_destroy_inode, @@ -554,7 +585,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) full_path = cifs_build_path_to_root(vol, cifs_sb, cifs_sb_master_tcon(cifs_sb)); if (full_path == NULL) - return ERR_PTR(-ENOMEM); + return NULL; cFYI(1, "Get root dentry for %s", full_path); @@ -583,7 +614,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) dchild = d_alloc(dparent, &name); if (dchild == NULL) { dput(dparent); - dparent = ERR_PTR(-ENOMEM); + dparent = NULL; goto out; } } @@ -601,7 +632,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) if (rc) { dput(dchild); dput(dparent); - dparent = ERR_PTR(rc); + dparent = NULL; goto out; } alias = d_materialise_unique(dchild, inode); @@ -609,7 +640,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) dput(dchild); if (IS_ERR(alias)) { dput(dparent); - dparent = ERR_PTR(-EINVAL); /* XXX */ + dparent = NULL; goto out; } dchild = alias; @@ -629,13 +660,6 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) return dparent; } -static int cifs_set_super(struct super_block *sb, void *data) -{ - struct cifs_mnt_data *mnt_data = data; - sb->s_fs_info = mnt_data->cifs_sb; - return set_anon_super(sb, NULL); -} - static struct dentry * cifs_do_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) @@ -656,73 +680,75 @@ cifs_do_mount(struct file_system_type *fs_type, cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); if (cifs_sb == NULL) { root = ERR_PTR(-ENOMEM); - goto out_nls; - } - - cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL); - if (cifs_sb->mountdata == NULL) { - root = ERR_PTR(-ENOMEM); - goto out_cifs_sb; + goto out; } cifs_setup_cifs_sb(volume_info, cifs_sb); - rc = cifs_mount(cifs_sb, volume_info); - if (rc) { - if (!(flags & MS_SILENT)) - cERROR(1, "cifs_mount failed w/return code = %d", rc); - root = ERR_PTR(rc); - goto out_mountdata; - } - mnt_data.vol = volume_info; mnt_data.cifs_sb = cifs_sb; mnt_data.flags = flags; - sb = sget(fs_type, cifs_match_super, cifs_set_super, &mnt_data); + sb = sget(fs_type, cifs_match_super, set_anon_super, &mnt_data); if (IS_ERR(sb)) { root = ERR_CAST(sb); - cifs_umount(cifs_sb); - goto out; + goto out_cifs_sb; } - if (sb->s_root) { + if (sb->s_fs_info) { cFYI(1, "Use existing superblock"); - cifs_umount(cifs_sb); - } else { - sb->s_flags = flags; - /* BB should we make this contingent on mount parm? */ - sb->s_flags |= MS_NODIRATIME | MS_NOATIME; - - rc = cifs_read_super(sb); - if (rc) { - root = ERR_PTR(rc); - goto out_super; - } + goto out_shared; + } + + /* + * Copy mount params for use in submounts. Better to do + * the copy here and deal with the error before cleanup gets + * complicated post-mount. + */ + cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL); + if (cifs_sb->mountdata == NULL) { + root = ERR_PTR(-ENOMEM); + goto out_super; + } + + sb->s_flags = flags; + /* BB should we make this contingent on mount parm? */ + sb->s_flags |= MS_NODIRATIME | MS_NOATIME; + sb->s_fs_info = cifs_sb; - sb->s_flags |= MS_ACTIVE; + rc = cifs_read_super(sb, volume_info, dev_name, + flags & MS_SILENT ? 1 : 0); + if (rc) { + root = ERR_PTR(rc); + goto out_super; } + sb->s_flags |= MS_ACTIVE; + root = cifs_get_root(volume_info, sb); - if (IS_ERR(root)) + if (root == NULL) goto out_super; cFYI(1, "dentry root is: %p", root); goto out; +out_shared: + root = cifs_get_root(volume_info, sb); + if (root) + cFYI(1, "dentry root is: %p", root); + goto out; + out_super: + kfree(cifs_sb->mountdata); deactivate_locked_super(sb); -out: - cifs_cleanup_volume_info(&volume_info); - return root; -out_mountdata: - kfree(cifs_sb->mountdata); out_cifs_sb: + unload_nls(cifs_sb->local_nls); kfree(cifs_sb); -out_nls: - unload_nls(volume_info->local_nls); - goto out; + +out: + cifs_cleanup_volume_info(&volume_info); + return root; } static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, @@ -811,7 +837,7 @@ struct file_system_type cifs_fs_type = { .owner = THIS_MODULE, .name = "cifs", .mount = cifs_do_mount, - .kill_sb = cifs_kill_sb, + .kill_sb = kill_anon_super, /* .fs_flags */ }; const struct inode_operations cifs_dir_inode_ops = { diff --git a/trunk/fs/cifs/cifsproto.h b/trunk/fs/cifs/cifsproto.h index 257f312ede42..953f84413c77 100644 --- a/trunk/fs/cifs/cifsproto.h +++ b/trunk/fs/cifs/cifsproto.h @@ -157,8 +157,9 @@ extern int cifs_match_super(struct super_block *, void *); extern void cifs_cleanup_volume_info(struct smb_vol **pvolume_info); extern int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, const char *devname); -extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *); -extern void cifs_umount(struct cifs_sb_info *); +extern int cifs_mount(struct super_block *, struct cifs_sb_info *, + struct smb_vol *, const char *); +extern int cifs_umount(struct super_block *, struct cifs_sb_info *); extern void cifs_dfs_release_automount_timer(void); void cifs_proc_init(void); void cifs_proc_clean(void); @@ -217,8 +218,7 @@ extern int get_dfs_path(int xid, struct cifs_ses *pSesInfo, struct dfs_info3_param **preferrals, int remap); extern void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, - struct smb_vol *vol); + struct super_block *sb, struct smb_vol *vol); extern int CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData); extern int SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 7f540df52527..12cf72dd0c42 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -2546,7 +2546,7 @@ ip_connect(struct TCP_Server_Info *server) } void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, struct smb_vol *vol_info) + struct super_block *sb, struct smb_vol *vol_info) { /* if we are reconnecting then should we check to see if * any requested capabilities changed locally e.g. via @@ -2600,23 +2600,22 @@ void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, cap &= ~CIFS_UNIX_POSIX_ACL_CAP; else if (CIFS_UNIX_POSIX_ACL_CAP & cap) { cFYI(1, "negotiated posix acl support"); - if (cifs_sb) - cifs_sb->mnt_cifs_flags |= - CIFS_MOUNT_POSIXACL; + if (sb) + sb->s_flags |= MS_POSIXACL; } if (vol_info && vol_info->posix_paths == 0) cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { cFYI(1, "negotiate posix pathnames"); - if (cifs_sb) - cifs_sb->mnt_cifs_flags |= + if (sb) + CIFS_SB(sb)->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; } - if (cifs_sb && (cifs_sb->rsize > 127 * 1024)) { + if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { - cifs_sb->rsize = 127 * 1024; + CIFS_SB(sb)->rsize = 127 * 1024; cFYI(DBG2, "larger reads not supported by srv"); } } @@ -2663,9 +2662,6 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, { INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); - spin_lock_init(&cifs_sb->tlink_tree_lock); - cifs_sb->tlink_tree = RB_ROOT; - if (pvolume_info->rsize > CIFSMaxBufSize) { cERROR(1, "rsize %d too large, using MaxBufSize", pvolume_info->rsize); @@ -2754,21 +2750,21 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, /* * When the server supports very large writes via POSIX extensions, we can - * allow up to 2^24-1, minus the size of a WRITE_AND_X header, not including - * the RFC1001 length. + * allow up to 2^24 - PAGE_CACHE_SIZE. * * Note that this might make for "interesting" allocation problems during - * writeback however as we have to allocate an array of pointers for the - * pages. A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096. + * writeback however (as we have to allocate an array of pointers for the + * pages). A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096. */ -#define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ) + 4) +#define CIFS_MAX_WSIZE ((1<<24) - PAGE_CACHE_SIZE) /* - * When the server doesn't allow large posix writes, only allow a wsize of - * 128k minus the size of the WRITE_AND_X header. That allows for a write up - * to the maximum size described by RFC1002. + * When the server doesn't allow large posix writes, default to a wsize of + * 128k - PAGE_CACHE_SIZE -- one page less than the largest frame size + * described in RFC1001. This allows space for the header without going over + * that by default. */ -#define CIFS_MAX_RFC1002_WSIZE (128 * 1024 - sizeof(WRITE_REQ) + 4) +#define CIFS_MAX_RFC1001_WSIZE (128 * 1024 - PAGE_CACHE_SIZE) /* * The default wsize is 1M. find_get_pages seems to return a maximum of 256 @@ -2787,18 +2783,11 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) /* can server support 24-bit write sizes? (via UNIX extensions) */ if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP)) - wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1002_WSIZE); + wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1001_WSIZE); - /* - * no CAP_LARGE_WRITE_X or is signing enabled without CAP_UNIX set? - * Limit it to max buffer offered by the server, minus the size of the - * WRITEX header, not including the 4 byte RFC1001 length. - */ - if (!(server->capabilities & CAP_LARGE_WRITE_X) || - (!(server->capabilities & CAP_UNIX) && - (server->sec_mode & (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)))) - wsize = min_t(unsigned int, wsize, - server->maxBuf - sizeof(WRITE_REQ) + 4); + /* no CAP_LARGE_WRITE_X? Limit it to 16 bits */ + if (!(server->capabilities & CAP_LARGE_WRITE_X)) + wsize = min_t(unsigned int, wsize, USHRT_MAX); /* hard limit of CIFS_MAX_WSIZE */ wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); @@ -2948,11 +2937,7 @@ int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, if (volume_info->nullauth) { cFYI(1, "null user"); - volume_info->username = kzalloc(1, GFP_KERNEL); - if (volume_info->username == NULL) { - rc = -ENOMEM; - goto out; - } + volume_info->username = ""; } else if (volume_info->username) { /* BB fixme parse for domain name here */ cFYI(1, "Username: %s", volume_info->username); @@ -2986,7 +2971,8 @@ int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, } int -cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) +cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, + struct smb_vol *volume_info, const char *devname) { int rc = 0; int xid; @@ -2997,13 +2983,6 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) struct tcon_link *tlink; #ifdef CONFIG_CIFS_DFS_UPCALL int referral_walks_count = 0; - - rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); - if (rc) - return rc; - - cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; - try_mount_again: /* cleanup activities if we're chasing a referral */ if (referral_walks_count) { @@ -3028,7 +3007,6 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) srvTcp = cifs_get_tcp_session(volume_info); if (IS_ERR(srvTcp)) { rc = PTR_ERR(srvTcp); - bdi_destroy(&cifs_sb->bdi); goto out; } @@ -3040,6 +3018,14 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) goto mount_fail_check; } + if (pSesInfo->capabilities & CAP_LARGE_FILES) + sb->s_maxbytes = MAX_LFS_FILESIZE; + else + sb->s_maxbytes = MAX_NON_LFS; + + /* BB FIXME fix time_gran to be larger for LANMAN sessions */ + sb->s_time_gran = 100; + /* search for existing tcon to this server share */ tcon = cifs_get_tcon(pSesInfo, volume_info); if (IS_ERR(tcon)) { @@ -3052,7 +3038,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) if (tcon->ses->capabilities & CAP_UNIX) { /* reset of caps checks mount to see if unix extensions disabled for just this mount */ - reset_cifs_unix_caps(xid, tcon, cifs_sb, volume_info); + reset_cifs_unix_caps(xid, tcon, sb, volume_info); if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && (le64_to_cpu(tcon->fsUnixInfo.Capability) & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) { @@ -3175,7 +3161,6 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) cifs_put_smb_ses(pSesInfo); else cifs_put_tcp_session(srvTcp); - bdi_destroy(&cifs_sb->bdi); goto out; } @@ -3350,8 +3335,8 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses, return rc; } -void -cifs_umount(struct cifs_sb_info *cifs_sb) +int +cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) { struct rb_root *root = &cifs_sb->tlink_tree; struct rb_node *node; @@ -3372,10 +3357,7 @@ cifs_umount(struct cifs_sb_info *cifs_sb) } spin_unlock(&cifs_sb->tlink_tree_lock); - bdi_destroy(&cifs_sb->bdi); - kfree(cifs_sb->mountdata); - unload_nls(cifs_sb->local_nls); - kfree(cifs_sb); + return 0; } int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses) diff --git a/trunk/fs/cifs/smbencrypt.c b/trunk/fs/cifs/smbencrypt.c index 1c5b770c3141..1525d5e662b6 100644 --- a/trunk/fs/cifs/smbencrypt.c +++ b/trunk/fs/cifs/smbencrypt.c @@ -90,10 +90,12 @@ smbhash(unsigned char *out, const unsigned char *in, unsigned char *key) sg_init_one(&sgout, out, 8); rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, 8); - if (rc) + if (rc) { cERROR(1, "could not encrypt crypt key rc: %d\n", rc); + crypto_free_blkcipher(tfm_des); + goto smbhash_err; + } - crypto_free_blkcipher(tfm_des); smbhash_err: return rc; } diff --git a/trunk/fs/ext4/ext4_extents.h b/trunk/fs/ext4/ext4_extents.h index 095c36f3b612..2e29abb30f76 100644 --- a/trunk/fs/ext4/ext4_extents.h +++ b/trunk/fs/ext4/ext4_extents.h @@ -125,7 +125,7 @@ struct ext4_ext_path { * positive retcode - signal for ext4_ext_walk_space(), see below * callback must return valid extent (passed or newly created) */ -typedef int (*ext_prepare_callback)(struct inode *, ext4_lblk_t, +typedef int (*ext_prepare_callback)(struct inode *, struct ext4_ext_path *, struct ext4_ext_cache *, struct ext4_extent *, void *); @@ -133,11 +133,8 @@ typedef int (*ext_prepare_callback)(struct inode *, ext4_lblk_t, #define EXT_BREAK 1 #define EXT_REPEAT 2 -/* - * Maximum number of logical blocks in a file; ext4_extent's ee_block is - * __le32. - */ -#define EXT_MAX_BLOCKS 0xffffffff +/* Maximum logical block in a file; ext4_extent's ee_block is __le32 */ +#define EXT_MAX_BLOCK 0xffffffff /* * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an diff --git a/trunk/fs/ext4/extents.c b/trunk/fs/ext4/extents.c index f815cc81e7a2..5199bac7fc62 100644 --- a/trunk/fs/ext4/extents.c +++ b/trunk/fs/ext4/extents.c @@ -1408,7 +1408,7 @@ static int ext4_ext_search_right(struct inode *inode, /* * ext4_ext_next_allocated_block: - * returns allocated block in subsequent extent or EXT_MAX_BLOCKS. + * returns allocated block in subsequent extent or EXT_MAX_BLOCK. * NOTE: it considers block number from index entry as * allocated block. Thus, index entries have to be consistent * with leaves. @@ -1422,7 +1422,7 @@ ext4_ext_next_allocated_block(struct ext4_ext_path *path) depth = path->p_depth; if (depth == 0 && path->p_ext == NULL) - return EXT_MAX_BLOCKS; + return EXT_MAX_BLOCK; while (depth >= 0) { if (depth == path->p_depth) { @@ -1439,12 +1439,12 @@ ext4_ext_next_allocated_block(struct ext4_ext_path *path) depth--; } - return EXT_MAX_BLOCKS; + return EXT_MAX_BLOCK; } /* * ext4_ext_next_leaf_block: - * returns first allocated block from next leaf or EXT_MAX_BLOCKS + * returns first allocated block from next leaf or EXT_MAX_BLOCK */ static ext4_lblk_t ext4_ext_next_leaf_block(struct inode *inode, struct ext4_ext_path *path) @@ -1456,7 +1456,7 @@ static ext4_lblk_t ext4_ext_next_leaf_block(struct inode *inode, /* zero-tree has no leaf blocks at all */ if (depth == 0) - return EXT_MAX_BLOCKS; + return EXT_MAX_BLOCK; /* go to index block */ depth--; @@ -1469,7 +1469,7 @@ static ext4_lblk_t ext4_ext_next_leaf_block(struct inode *inode, depth--; } - return EXT_MAX_BLOCKS; + return EXT_MAX_BLOCK; } /* @@ -1677,13 +1677,13 @@ static unsigned int ext4_ext_check_overlap(struct inode *inode, */ if (b2 < b1) { b2 = ext4_ext_next_allocated_block(path); - if (b2 == EXT_MAX_BLOCKS) + if (b2 == EXT_MAX_BLOCK) goto out; } /* check for wrap through zero on extent logical start block*/ if (b1 + len1 < b1) { - len1 = EXT_MAX_BLOCKS - b1; + len1 = EXT_MAX_BLOCK - b1; newext->ee_len = cpu_to_le16(len1); ret = 1; } @@ -1767,7 +1767,7 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, fex = EXT_LAST_EXTENT(eh); next = ext4_ext_next_leaf_block(inode, path); if (le32_to_cpu(newext->ee_block) > le32_to_cpu(fex->ee_block) - && next != EXT_MAX_BLOCKS) { + && next != EXT_MAX_BLOCK) { ext_debug("next leaf block - %d\n", next); BUG_ON(npath != NULL); npath = ext4_ext_find_extent(inode, next, NULL); @@ -1887,7 +1887,7 @@ static int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block, BUG_ON(func == NULL); BUG_ON(inode == NULL); - while (block < last && block != EXT_MAX_BLOCKS) { + while (block < last && block != EXT_MAX_BLOCK) { num = last - block; /* find extent for this block */ down_read(&EXT4_I(inode)->i_data_sem); @@ -1958,7 +1958,7 @@ static int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block, err = -EIO; break; } - err = func(inode, next, &cbex, ex, cbdata); + err = func(inode, path, &cbex, ex, cbdata); ext4_ext_drop_refs(path); if (err < 0) @@ -2020,7 +2020,7 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, if (ex == NULL) { /* there is no extent yet, so gap is [0;-] */ lblock = 0; - len = EXT_MAX_BLOCKS; + len = EXT_MAX_BLOCK; ext_debug("cache gap(whole file):"); } else if (block < le32_to_cpu(ex->ee_block)) { lblock = block; @@ -2350,7 +2350,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, * never happen because at least one of the end points * needs to be on the edge of the extent. */ - if (end == EXT_MAX_BLOCKS - 1) { + if (end == EXT_MAX_BLOCK) { ext_debug(" bad truncate %u:%u\n", start, end); block = 0; @@ -2398,7 +2398,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, * If this is a truncate, this condition * should never happen */ - if (end == EXT_MAX_BLOCKS - 1) { + if (end == EXT_MAX_BLOCK) { ext_debug(" bad truncate %u:%u\n", start, end); err = -EIO; @@ -2478,7 +2478,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, * we need to remove it from the leaf */ if (num == 0) { - if (end != EXT_MAX_BLOCKS - 1) { + if (end != EXT_MAX_BLOCK) { /* * For hole punching, we need to scoot all the * extents up when an extent is removed so that @@ -3699,7 +3699,7 @@ void ext4_ext_truncate(struct inode *inode) last_block = (inode->i_size + sb->s_blocksize - 1) >> EXT4_BLOCK_SIZE_BITS(sb); - err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1); + err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCK); /* In a multi-transaction truncate, we only make the final * transaction synchronous. @@ -3914,13 +3914,14 @@ int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset, /* * Callback function called for each extent to gather FIEMAP information. */ -static int ext4_ext_fiemap_cb(struct inode *inode, ext4_lblk_t next, +static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path, struct ext4_ext_cache *newex, struct ext4_extent *ex, void *data) { __u64 logical; __u64 physical; __u64 length; + loff_t size; __u32 flags = 0; int ret = 0; struct fiemap_extent_info *fieinfo = data; @@ -4102,7 +4103,8 @@ static int ext4_ext_fiemap_cb(struct inode *inode, ext4_lblk_t next, if (ex && ext4_ext_is_uninitialized(ex)) flags |= FIEMAP_EXTENT_UNWRITTEN; - if (next == EXT_MAX_BLOCKS) + size = i_size_read(inode); + if (logical + length >= size) flags |= FIEMAP_EXTENT_LAST; ret = fiemap_fill_next_extent(fieinfo, logical, physical, @@ -4345,8 +4347,8 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, start_blk = start >> inode->i_sb->s_blocksize_bits; last_blk = (start + len - 1) >> inode->i_sb->s_blocksize_bits; - if (last_blk >= EXT_MAX_BLOCKS) - last_blk = EXT_MAX_BLOCKS-1; + if (last_blk >= EXT_MAX_BLOCK) + last_blk = EXT_MAX_BLOCK-1; len_blks = ((ext4_lblk_t) last_blk) - start_blk + 1; /* diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c index e3126c051006..a5763e3505ba 100644 --- a/trunk/fs/ext4/inode.c +++ b/trunk/fs/ext4/inode.c @@ -2634,7 +2634,7 @@ static int ext4_writepage(struct page *page, struct buffer_head *page_bufs = NULL; struct inode *inode = page->mapping->host; - trace_ext4_writepage(page); + trace_ext4_writepage(inode, page); size = i_size_read(inode); if (page->index == size >> PAGE_CACHE_SHIFT) len = size & ~PAGE_CACHE_MASK; diff --git a/trunk/fs/ext4/mballoc.c b/trunk/fs/ext4/mballoc.c index 6ed859d56850..859f2ae8864e 100644 --- a/trunk/fs/ext4/mballoc.c +++ b/trunk/fs/ext4/mballoc.c @@ -3578,8 +3578,8 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, free += next - bit; trace_ext4_mballoc_discard(sb, NULL, group, bit, next - bit); - trace_ext4_mb_release_inode_pa(pa, grp_blk_start + bit, - next - bit); + trace_ext4_mb_release_inode_pa(sb, pa->pa_inode, pa, + grp_blk_start + bit, next - bit); mb_free_blocks(pa->pa_inode, e4b, bit, next - bit); bit = next + 1; } @@ -3608,7 +3608,7 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b, ext4_group_t group; ext4_grpblk_t bit; - trace_ext4_mb_release_group_pa(pa); + trace_ext4_mb_release_group_pa(sb, pa); BUG_ON(pa->pa_deleted == 0); ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); BUG_ON(group != e4b->bd_group && pa->pa_len != 0); @@ -4448,7 +4448,7 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b, * @inode: inode * @block: start physical block to free * @count: number of blocks to count - * @flags: flags used by ext4_free_blocks + * @metadata: Are these metadata blocks */ void ext4_free_blocks(handle_t *handle, struct inode *inode, struct buffer_head *bh, ext4_fsblk_t block, diff --git a/trunk/fs/ext4/move_extent.c b/trunk/fs/ext4/move_extent.c index f57455a1b1b2..2b8304bf3c50 100644 --- a/trunk/fs/ext4/move_extent.c +++ b/trunk/fs/ext4/move_extent.c @@ -1002,12 +1002,12 @@ mext_check_arguments(struct inode *orig_inode, return -EINVAL; } - if ((orig_start >= EXT_MAX_BLOCKS) || - (donor_start >= EXT_MAX_BLOCKS) || - (*len > EXT_MAX_BLOCKS) || - (orig_start + *len >= EXT_MAX_BLOCKS)) { + if ((orig_start > EXT_MAX_BLOCK) || + (donor_start > EXT_MAX_BLOCK) || + (*len > EXT_MAX_BLOCK) || + (orig_start + *len > EXT_MAX_BLOCK)) { ext4_debug("ext4 move extent: Can't handle over [%u] blocks " - "[ino:orig %lu, donor %lu]\n", EXT_MAX_BLOCKS, + "[ino:orig %lu, donor %lu]\n", EXT_MAX_BLOCK, orig_inode->i_ino, donor_inode->i_ino); return -EINVAL; } diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index 9ea71aa864b3..cc5c157aa11d 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -2243,12 +2243,6 @@ static void ext4_orphan_cleanup(struct super_block *sb, * in the vfs. ext4 inode has 48 bits of i_block in fsblock units, * so that won't be a limiting factor. * - * However there is other limiting factor. We do store extents in the form - * of starting block and length, hence the resulting length of the extent - * covering maximum file size must fit into on-disk format containers as - * well. Given that length is always by 1 unit bigger than max unit (because - * we count 0 as well) we have to lower the s_maxbytes by one fs block. - * * Note, this does *not* consider any metadata overhead for vfs i_blocks. */ static loff_t ext4_max_size(int blkbits, int has_huge_files) @@ -2270,13 +2264,10 @@ static loff_t ext4_max_size(int blkbits, int has_huge_files) upper_limit <<= blkbits; } - /* - * 32-bit extent-start container, ee_block. We lower the maxbytes - * by one fs block, so ee_len can cover the extent of maximum file - * size - */ - res = (1LL << 32) - 1; + /* 32-bit extent-start container, ee_block */ + res = 1LL << 32; res <<= blkbits; + res -= 1; /* Sanity check against vm- & vfs- imposed limits */ if (res > upper_limit) diff --git a/trunk/fs/jbd2/checkpoint.c b/trunk/fs/jbd2/checkpoint.c index 2c62c5aae82f..6a79fd0a1a32 100644 --- a/trunk/fs/jbd2/checkpoint.c +++ b/trunk/fs/jbd2/checkpoint.c @@ -97,14 +97,10 @@ static int __try_to_free_cp_buf(struct journal_head *jh) if (jh->b_jlist == BJ_None && !buffer_locked(bh) && !buffer_dirty(bh) && !buffer_write_io_error(bh)) { - /* - * Get our reference so that bh cannot be freed before - * we unlock it - */ - get_bh(bh); JBUFFER_TRACE(jh, "remove from checkpoint list"); ret = __jbd2_journal_remove_checkpoint(jh) + 1; jbd_unlock_bh_state(bh); + jbd2_journal_remove_journal_head(bh); BUFFER_TRACE(bh, "release"); __brelse(bh); } else { @@ -227,8 +223,8 @@ static int __wait_cp_io(journal_t *journal, transaction_t *transaction) spin_lock(&journal->j_list_lock); goto restart; } - get_bh(bh); if (buffer_locked(bh)) { + atomic_inc(&bh->b_count); spin_unlock(&journal->j_list_lock); jbd_unlock_bh_state(bh); wait_on_buffer(bh); @@ -247,6 +243,7 @@ static int __wait_cp_io(journal_t *journal, transaction_t *transaction) */ released = __jbd2_journal_remove_checkpoint(jh); jbd_unlock_bh_state(bh); + jbd2_journal_remove_journal_head(bh); __brelse(bh); } @@ -287,7 +284,7 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh, int ret = 0; if (buffer_locked(bh)) { - get_bh(bh); + atomic_inc(&bh->b_count); spin_unlock(&journal->j_list_lock); jbd_unlock_bh_state(bh); wait_on_buffer(bh); @@ -319,12 +316,12 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh, ret = 1; if (unlikely(buffer_write_io_error(bh))) ret = -EIO; - get_bh(bh); J_ASSERT_JH(jh, !buffer_jbddirty(bh)); BUFFER_TRACE(bh, "remove from checkpoint"); __jbd2_journal_remove_checkpoint(jh); spin_unlock(&journal->j_list_lock); jbd_unlock_bh_state(bh); + jbd2_journal_remove_journal_head(bh); __brelse(bh); } else { /* @@ -557,8 +554,7 @@ int jbd2_cleanup_journal_tail(journal_t *journal) /* * journal_clean_one_cp_list * - * Find all the written-back checkpoint buffers in the given list and - * release them. + * Find all the written-back checkpoint buffers in the given list and release them. * * Called with the journal locked. * Called with j_list_lock held. @@ -667,8 +663,8 @@ int __jbd2_journal_clean_checkpoint_list(journal_t *journal) * checkpoint lists. * * The function returns 1 if it frees the transaction, 0 otherwise. - * The function can free jh and bh. * + * This function is called with the journal locked. * This function is called with j_list_lock held. * This function is called with jbd_lock_bh_state(jh2bh(jh)) */ @@ -688,14 +684,13 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh) } journal = transaction->t_journal; - JBUFFER_TRACE(jh, "removing from transaction"); __buffer_unlink(jh); jh->b_cp_transaction = NULL; - jbd2_journal_put_journal_head(jh); if (transaction->t_checkpoint_list != NULL || transaction->t_checkpoint_io_list != NULL) goto out; + JBUFFER_TRACE(jh, "transaction has no more buffers"); /* * There is one special case to worry about: if we have just pulled the @@ -706,8 +701,10 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh) * The locking here around t_state is a bit sleazy. * See the comment at the end of jbd2_journal_commit_transaction(). */ - if (transaction->t_state != T_FINISHED) + if (transaction->t_state != T_FINISHED) { + JBUFFER_TRACE(jh, "belongs to running/committing transaction"); goto out; + } /* OK, that was the last buffer for the transaction: we can now safely remove this transaction from the log */ @@ -726,6 +723,7 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh) wake_up(&journal->j_wait_logspace); ret = 1; out: + JBUFFER_TRACE(jh, "exit"); return ret; } @@ -744,8 +742,6 @@ void __jbd2_journal_insert_checkpoint(struct journal_head *jh, J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh))); J_ASSERT_JH(jh, jh->b_cp_transaction == NULL); - /* Get reference for checkpointing transaction */ - jbd2_journal_grab_journal_head(jh2bh(jh)); jh->b_cp_transaction = transaction; if (!transaction->t_checkpoint_list) { diff --git a/trunk/fs/jbd2/commit.c b/trunk/fs/jbd2/commit.c index eef6979821a4..7f21cf3aaf92 100644 --- a/trunk/fs/jbd2/commit.c +++ b/trunk/fs/jbd2/commit.c @@ -848,16 +848,10 @@ void jbd2_journal_commit_transaction(journal_t *journal) while (commit_transaction->t_forget) { transaction_t *cp_transaction; struct buffer_head *bh; - int try_to_free = 0; jh = commit_transaction->t_forget; spin_unlock(&journal->j_list_lock); bh = jh2bh(jh); - /* - * Get a reference so that bh cannot be freed before we are - * done with it. - */ - get_bh(bh); jbd_lock_bh_state(bh); J_ASSERT_JH(jh, jh->b_transaction == commit_transaction); @@ -920,27 +914,28 @@ void jbd2_journal_commit_transaction(journal_t *journal) __jbd2_journal_insert_checkpoint(jh, commit_transaction); if (is_journal_aborted(journal)) clear_buffer_jbddirty(bh); + JBUFFER_TRACE(jh, "refile for checkpoint writeback"); + __jbd2_journal_refile_buffer(jh); + jbd_unlock_bh_state(bh); } else { J_ASSERT_BH(bh, !buffer_dirty(bh)); - /* - * The buffer on BJ_Forget list and not jbddirty means + /* The buffer on BJ_Forget list and not jbddirty means * it has been freed by this transaction and hence it * could not have been reallocated until this * transaction has committed. *BUT* it could be * reallocated once we have written all the data to * disk and before we process the buffer on BJ_Forget - * list. - */ - if (!jh->b_next_transaction) - try_to_free = 1; + * list. */ + JBUFFER_TRACE(jh, "refile or unfile freed buffer"); + __jbd2_journal_refile_buffer(jh); + if (!jh->b_transaction) { + jbd_unlock_bh_state(bh); + /* needs a brelse */ + jbd2_journal_remove_journal_head(bh); + release_buffer_page(bh); + } else + jbd_unlock_bh_state(bh); } - JBUFFER_TRACE(jh, "refile or unfile buffer"); - __jbd2_journal_refile_buffer(jh); - jbd_unlock_bh_state(bh); - if (try_to_free) - release_buffer_page(bh); /* Drops bh reference */ - else - __brelse(bh); cond_resched_lock(&journal->j_list_lock); } spin_unlock(&journal->j_list_lock); diff --git a/trunk/fs/jbd2/journal.c b/trunk/fs/jbd2/journal.c index 0dfa5b598e68..9a7826990304 100644 --- a/trunk/fs/jbd2/journal.c +++ b/trunk/fs/jbd2/journal.c @@ -2078,9 +2078,10 @@ static void journal_free_journal_head(struct journal_head *jh) * When a buffer has its BH_JBD bit set it is immune from being released by * core kernel code, mainly via ->b_count. * - * A journal_head is detached from its buffer_head when the journal_head's - * b_jcount reaches zero. Running transaction (b_transaction) and checkpoint - * transaction (b_cp_transaction) hold their references to b_jcount. + * A journal_head may be detached from its buffer_head when the journal_head's + * b_transaction, b_cp_transaction and b_next_transaction pointers are NULL. + * Various places in JBD call jbd2_journal_remove_journal_head() to indicate that the + * journal_head can be dropped if needed. * * Various places in the kernel want to attach a journal_head to a buffer_head * _before_ attaching the journal_head to a transaction. To protect the @@ -2093,16 +2094,17 @@ static void journal_free_journal_head(struct journal_head *jh) * (Attach a journal_head if needed. Increments b_jcount) * struct journal_head *jh = jbd2_journal_add_journal_head(bh); * ... - * (Get another reference for transaction) - * jbd2_journal_grab_journal_head(bh); * jh->b_transaction = xxx; - * (Put original reference) * jbd2_journal_put_journal_head(jh); + * + * Now, the journal_head's b_jcount is zero, but it is safe from being released + * because it has a non-zero b_transaction. */ /* * Give a buffer_head a journal_head. * + * Doesn't need the journal lock. * May sleep. */ struct journal_head *jbd2_journal_add_journal_head(struct buffer_head *bh) @@ -2166,29 +2168,61 @@ static void __journal_remove_journal_head(struct buffer_head *bh) struct journal_head *jh = bh2jh(bh); J_ASSERT_JH(jh, jh->b_jcount >= 0); - J_ASSERT_JH(jh, jh->b_transaction == NULL); - J_ASSERT_JH(jh, jh->b_next_transaction == NULL); - J_ASSERT_JH(jh, jh->b_cp_transaction == NULL); - J_ASSERT_JH(jh, jh->b_jlist == BJ_None); - J_ASSERT_BH(bh, buffer_jbd(bh)); - J_ASSERT_BH(bh, jh2bh(jh) == bh); - BUFFER_TRACE(bh, "remove journal_head"); - if (jh->b_frozen_data) { - printk(KERN_WARNING "%s: freeing b_frozen_data\n", __func__); - jbd2_free(jh->b_frozen_data, bh->b_size); - } - if (jh->b_committed_data) { - printk(KERN_WARNING "%s: freeing b_committed_data\n", __func__); - jbd2_free(jh->b_committed_data, bh->b_size); + + get_bh(bh); + if (jh->b_jcount == 0) { + if (jh->b_transaction == NULL && + jh->b_next_transaction == NULL && + jh->b_cp_transaction == NULL) { + J_ASSERT_JH(jh, jh->b_jlist == BJ_None); + J_ASSERT_BH(bh, buffer_jbd(bh)); + J_ASSERT_BH(bh, jh2bh(jh) == bh); + BUFFER_TRACE(bh, "remove journal_head"); + if (jh->b_frozen_data) { + printk(KERN_WARNING "%s: freeing " + "b_frozen_data\n", + __func__); + jbd2_free(jh->b_frozen_data, bh->b_size); + } + if (jh->b_committed_data) { + printk(KERN_WARNING "%s: freeing " + "b_committed_data\n", + __func__); + jbd2_free(jh->b_committed_data, bh->b_size); + } + bh->b_private = NULL; + jh->b_bh = NULL; /* debug, really */ + clear_buffer_jbd(bh); + __brelse(bh); + journal_free_journal_head(jh); + } else { + BUFFER_TRACE(bh, "journal_head was locked"); + } } - bh->b_private = NULL; - jh->b_bh = NULL; /* debug, really */ - clear_buffer_jbd(bh); - journal_free_journal_head(jh); } /* - * Drop a reference on the passed journal_head. If it fell to zero then + * jbd2_journal_remove_journal_head(): if the buffer isn't attached to a transaction + * and has a zero b_jcount then remove and release its journal_head. If we did + * see that the buffer is not used by any transaction we also "logically" + * decrement ->b_count. + * + * We in fact take an additional increment on ->b_count as a convenience, + * because the caller usually wants to do additional things with the bh + * after calling here. + * The caller of jbd2_journal_remove_journal_head() *must* run __brelse(bh) at some + * time. Once the caller has run __brelse(), the buffer is eligible for + * reaping by try_to_free_buffers(). + */ +void jbd2_journal_remove_journal_head(struct buffer_head *bh) +{ + jbd_lock_bh_journal_head(bh); + __journal_remove_journal_head(bh); + jbd_unlock_bh_journal_head(bh); +} + +/* + * Drop a reference on the passed journal_head. If it fell to zero then try to * release the journal_head from the buffer_head. */ void jbd2_journal_put_journal_head(struct journal_head *jh) @@ -2198,12 +2232,11 @@ void jbd2_journal_put_journal_head(struct journal_head *jh) jbd_lock_bh_journal_head(bh); J_ASSERT_JH(jh, jh->b_jcount > 0); --jh->b_jcount; - if (!jh->b_jcount) { + if (!jh->b_jcount && !jh->b_transaction) { __journal_remove_journal_head(bh); - jbd_unlock_bh_journal_head(bh); __brelse(bh); - } else - jbd_unlock_bh_journal_head(bh); + } + jbd_unlock_bh_journal_head(bh); } /* diff --git a/trunk/fs/jbd2/transaction.c b/trunk/fs/jbd2/transaction.c index 2d7109414cdd..3eec82d32fd4 100644 --- a/trunk/fs/jbd2/transaction.c +++ b/trunk/fs/jbd2/transaction.c @@ -30,7 +30,6 @@ #include static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh); -static void __jbd2_journal_unfile_buffer(struct journal_head *jh); /* * jbd2_get_transaction: obtain a new transaction_t object. @@ -765,6 +764,7 @@ do_get_write_access(handle_t *handle, struct journal_head *jh, if (!jh->b_transaction) { JBUFFER_TRACE(jh, "no transaction"); J_ASSERT_JH(jh, !jh->b_next_transaction); + jh->b_transaction = transaction; JBUFFER_TRACE(jh, "file as BJ_Reserved"); spin_lock(&journal->j_list_lock); __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved); @@ -814,6 +814,7 @@ do_get_write_access(handle_t *handle, struct journal_head *jh, * int jbd2_journal_get_write_access() - notify intent to modify a buffer for metadata (not data) update. * @handle: transaction to add buffer modifications to * @bh: bh to be used for metadata writes + * @credits: variable that will receive credits for the buffer * * Returns an error code or 0 on success. * @@ -895,6 +896,8 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh) * committed and so it's safe to clear the dirty bit. */ clear_buffer_dirty(jh2bh(jh)); + jh->b_transaction = transaction; + /* first access by this transaction */ jh->b_modified = 0; @@ -929,6 +932,7 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh) * non-rewindable consequences * @handle: transaction * @bh: buffer to undo + * @credits: store the number of taken credits here (if not NULL) * * Sometimes there is a need to distinguish between metadata which has * been committed to disk and that which has not. The ext3fs code uses @@ -1228,6 +1232,8 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh) __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); } else { __jbd2_journal_unfile_buffer(jh); + jbd2_journal_remove_journal_head(bh); + __brelse(bh); if (!buffer_jbd(bh)) { spin_unlock(&journal->j_list_lock); jbd_unlock_bh_state(bh); @@ -1550,32 +1556,19 @@ void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh) mark_buffer_dirty(bh); /* Expose it to the VM */ } -/* - * Remove buffer from all transactions. - * - * Called with bh_state lock and j_list_lock - * - * jh and bh may be already freed when this function returns. - */ -static void __jbd2_journal_unfile_buffer(struct journal_head *jh) +void __jbd2_journal_unfile_buffer(struct journal_head *jh) { __jbd2_journal_temp_unlink_buffer(jh); jh->b_transaction = NULL; - jbd2_journal_put_journal_head(jh); } void jbd2_journal_unfile_buffer(journal_t *journal, struct journal_head *jh) { - struct buffer_head *bh = jh2bh(jh); - - /* Get reference so that buffer cannot be freed before we unlock it */ - get_bh(bh); - jbd_lock_bh_state(bh); + jbd_lock_bh_state(jh2bh(jh)); spin_lock(&journal->j_list_lock); __jbd2_journal_unfile_buffer(jh); spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - __brelse(bh); + jbd_unlock_bh_state(jh2bh(jh)); } /* @@ -1602,6 +1595,8 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) if (jh->b_jlist == BJ_None) { JBUFFER_TRACE(jh, "remove from checkpoint list"); __jbd2_journal_remove_checkpoint(jh); + jbd2_journal_remove_journal_head(bh); + __brelse(bh); } } spin_unlock(&journal->j_list_lock); @@ -1664,6 +1659,7 @@ int jbd2_journal_try_to_free_buffers(journal_t *journal, /* * We take our own ref against the journal_head here to avoid * having to add tons of locking around each instance of + * jbd2_journal_remove_journal_head() and * jbd2_journal_put_journal_head(). */ jh = jbd2_journal_grab_journal_head(bh); @@ -1701,9 +1697,10 @@ static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction) int may_free = 1; struct buffer_head *bh = jh2bh(jh); + __jbd2_journal_unfile_buffer(jh); + if (jh->b_cp_transaction) { JBUFFER_TRACE(jh, "on running+cp transaction"); - __jbd2_journal_temp_unlink_buffer(jh); /* * We don't want to write the buffer anymore, clear the * bit so that we don't confuse checks in @@ -1714,7 +1711,8 @@ static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction) may_free = 0; } else { JBUFFER_TRACE(jh, "on running transaction"); - __jbd2_journal_unfile_buffer(jh); + jbd2_journal_remove_journal_head(bh); + __brelse(bh); } return may_free; } @@ -1992,8 +1990,6 @@ void __jbd2_journal_file_buffer(struct journal_head *jh, if (jh->b_transaction) __jbd2_journal_temp_unlink_buffer(jh); - else - jbd2_journal_grab_journal_head(bh); jh->b_transaction = transaction; switch (jlist) { @@ -2045,10 +2041,9 @@ void jbd2_journal_file_buffer(struct journal_head *jh, * already started to be used by a subsequent transaction, refile the * buffer on that transaction's metadata list. * - * Called under j_list_lock - * Called under jbd_lock_bh_state(jh2bh(jh)) + * Called under journal->j_list_lock * - * jh and bh may be already free when this function returns + * Called under jbd_lock_bh_state(jh2bh(jh)) */ void __jbd2_journal_refile_buffer(struct journal_head *jh) { @@ -2072,11 +2067,6 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh) was_dirty = test_clear_buffer_jbddirty(bh); __jbd2_journal_temp_unlink_buffer(jh); - /* - * We set b_transaction here because b_next_transaction will inherit - * our jh reference and thus __jbd2_journal_file_buffer() must not - * take a new one. - */ jh->b_transaction = jh->b_next_transaction; jh->b_next_transaction = NULL; if (buffer_freed(bh)) @@ -2093,21 +2083,30 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh) } /* - * __jbd2_journal_refile_buffer() with necessary locking added. We take our - * bh reference so that we can safely unlock bh. - * - * The jh and bh may be freed by this call. + * For the unlocked version of this call, also make sure that any + * hanging journal_head is cleaned up if necessary. + * + * __jbd2_journal_refile_buffer is usually called as part of a single locked + * operation on a buffer_head, in which the caller is probably going to + * be hooking the journal_head onto other lists. In that case it is up + * to the caller to remove the journal_head if necessary. For the + * unlocked jbd2_journal_refile_buffer call, the caller isn't going to be + * doing anything else to the buffer so we need to do the cleanup + * ourselves to avoid a jh leak. + * + * *** The journal_head may be freed by this call! *** */ void jbd2_journal_refile_buffer(journal_t *journal, struct journal_head *jh) { struct buffer_head *bh = jh2bh(jh); - /* Get reference so that buffer cannot be freed before we unlock it */ - get_bh(bh); jbd_lock_bh_state(bh); spin_lock(&journal->j_list_lock); + __jbd2_journal_refile_buffer(jh); jbd_unlock_bh_state(bh); + jbd2_journal_remove_journal_head(bh); + spin_unlock(&journal->j_list_lock); __brelse(bh); } diff --git a/trunk/fs/jfs/file.c b/trunk/fs/jfs/file.c index 2f3f531f3606..c5ce6c1d1ff4 100644 --- a/trunk/fs/jfs/file.c +++ b/trunk/fs/jfs/file.c @@ -66,9 +66,9 @@ static int jfs_open(struct inode *inode, struct file *file) struct jfs_inode_info *ji = JFS_IP(inode); spin_lock_irq(&ji->ag_lock); if (ji->active_ag == -1) { - struct jfs_sb_info *jfs_sb = JFS_SBI(inode->i_sb); - ji->active_ag = BLKTOAG(addressPXD(&ji->ixpxd), jfs_sb); - atomic_inc( &jfs_sb->bmap->db_active[ji->active_ag]); + ji->active_ag = ji->agno; + atomic_inc( + &JFS_SBI(inode->i_sb)->bmap->db_active[ji->agno]); } spin_unlock_irq(&ji->ag_lock); } diff --git a/trunk/fs/jfs/jfs_imap.c b/trunk/fs/jfs/jfs_imap.c index b78b2f978f04..ed53a4740168 100644 --- a/trunk/fs/jfs/jfs_imap.c +++ b/trunk/fs/jfs/jfs_imap.c @@ -397,7 +397,7 @@ int diRead(struct inode *ip) release_metapage(mp); /* set the ag for the inode */ - JFS_IP(ip)->agstart = agstart; + JFS_IP(ip)->agno = BLKTOAG(agstart, sbi); JFS_IP(ip)->active_ag = -1; return (rc); @@ -901,7 +901,7 @@ int diFree(struct inode *ip) /* get the allocation group for this ino. */ - agno = BLKTOAG(JFS_IP(ip)->agstart, JFS_SBI(ip->i_sb)); + agno = JFS_IP(ip)->agno; /* Lock the AG specific inode map information */ @@ -1315,11 +1315,12 @@ int diFree(struct inode *ip) static inline void diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp) { + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); struct jfs_inode_info *jfs_ip = JFS_IP(ip); ip->i_ino = (iagno << L2INOSPERIAG) + ino; jfs_ip->ixpxd = iagp->inoext[extno]; - jfs_ip->agstart = le64_to_cpu(iagp->agstart); + jfs_ip->agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi); jfs_ip->active_ag = -1; } @@ -1378,7 +1379,7 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip) */ /* get the ag number of this iag */ - agno = BLKTOAG(JFS_IP(pip)->agstart, JFS_SBI(pip->i_sb)); + agno = JFS_IP(pip)->agno; if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) { /* @@ -2920,9 +2921,10 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) continue; } + /* agstart that computes to the same ag is treated as same; */ agstart = le64_to_cpu(iagp->agstart); + /* iagp->agstart = agstart & ~(mp->db_agsize - 1); */ n = agstart >> mp->db_agl2size; - iagp->agstart = cpu_to_le64((s64)n << mp->db_agl2size); /* compute backed inodes */ numinos = (EXTSPERIAG - le32_to_cpu(iagp->nfreeexts)) diff --git a/trunk/fs/jfs/jfs_incore.h b/trunk/fs/jfs/jfs_incore.h index 584a4a1a6e81..1439f119ec83 100644 --- a/trunk/fs/jfs/jfs_incore.h +++ b/trunk/fs/jfs/jfs_incore.h @@ -50,9 +50,8 @@ struct jfs_inode_info { short btindex; /* btpage entry index*/ struct inode *ipimap; /* inode map */ unsigned long cflag; /* commit flags */ - u64 agstart; /* agstart of the containing IAG */ u16 bxflag; /* xflag of pseudo buffer? */ - unchar pad; + unchar agno; /* ag number */ signed char active_ag; /* ag currently allocating from */ lid_t blid; /* lid of pseudo buffer? */ lid_t atlhead; /* anonymous tlock list head */ diff --git a/trunk/fs/jfs/resize.c b/trunk/fs/jfs/resize.c index 8d0c1c7c0820..8ea5efb5a34e 100644 --- a/trunk/fs/jfs/resize.c +++ b/trunk/fs/jfs/resize.c @@ -80,7 +80,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) int log_formatted = 0; struct inode *iplist[1]; struct jfs_superblock *j_sb, *j_sb2; - s64 old_agsize; + uint old_agsize; int agsizechanged = 0; struct buffer_head *bh, *bh2; diff --git a/trunk/fs/lockd/clntproc.c b/trunk/fs/lockd/clntproc.c index e374050a911c..adb45ec9038c 100644 --- a/trunk/fs/lockd/clntproc.c +++ b/trunk/fs/lockd/clntproc.c @@ -708,13 +708,7 @@ static void nlmclnt_unlock_callback(struct rpc_task *task, void *data) if (task->tk_status < 0) { dprintk("lockd: unlock failed (err = %d)\n", -task->tk_status); - switch (task->tk_status) { - case -EACCES: - case -EIO: - goto die; - default: - goto retry_rebind; - } + goto retry_rebind; } if (status == NLM_LCK_DENIED_GRACE_PERIOD) { rpc_delay(task, NLMCLNT_GRACE_WAIT); diff --git a/trunk/fs/nfs/inode.c b/trunk/fs/nfs/inode.c index 6f4850deb272..144f2a3c7185 100644 --- a/trunk/fs/nfs/inode.c +++ b/trunk/fs/nfs/inode.c @@ -256,8 +256,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) nfs_attr_check_mountpoint(sb, fattr); - if (((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0) && - !nfs_attr_use_mounted_on_fileid(fattr)) + if ((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0 && (fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0) goto out_no_inode; if ((fattr->valid & NFS_ATTR_FATTR_TYPE) == 0) goto out_no_inode; @@ -1295,8 +1294,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) if (new_isize != cur_isize) { /* Do we perhaps have any outstanding writes, or has * the file grown beyond our last write? */ - if ((nfsi->npages == 0 && !test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) || - new_isize > cur_isize) { + if (nfsi->npages == 0 || new_isize > cur_isize) { i_size_write(inode, new_isize); invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; } diff --git a/trunk/fs/nfs/internal.h b/trunk/fs/nfs/internal.h index 2a55347a2daa..b9056cbe68d6 100644 --- a/trunk/fs/nfs/internal.h +++ b/trunk/fs/nfs/internal.h @@ -45,17 +45,6 @@ static inline void nfs_attr_check_mountpoint(struct super_block *parent, struct fattr->valid |= NFS_ATTR_FATTR_MOUNTPOINT; } -static inline int nfs_attr_use_mounted_on_fileid(struct nfs_fattr *fattr) -{ - if (((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) == 0) || - (((fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0) && - ((fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) == 0))) - return 0; - - fattr->fileid = fattr->mounted_on_fileid; - return 1; -} - struct nfs_clone_mount { const struct super_block *sb; const struct dentry *dentry; diff --git a/trunk/fs/nfs/nfs4filelayout.c b/trunk/fs/nfs/nfs4filelayout.c index 0bafcc91c27f..426908809c97 100644 --- a/trunk/fs/nfs/nfs4filelayout.c +++ b/trunk/fs/nfs/nfs4filelayout.c @@ -30,7 +30,6 @@ */ #include -#include #include "internal.h" #include "nfs4filelayout.h" @@ -553,18 +552,13 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, __func__, nfl_util, fl->num_fh, fl->first_stripe_index, fl->pattern_offset); - /* Note that a zero value for num_fh is legal for STRIPE_SPARSE. - * Futher checking is done in filelayout_check_layout */ - if (fl->num_fh < 0 || fl->num_fh > - max(NFS4_PNFS_MAX_STRIPE_CNT, NFS4_PNFS_MAX_MULTI_CNT)) + if (!fl->num_fh) goto out_err; - if (fl->num_fh > 0) { - fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *), - gfp_flags); - if (!fl->fh_array) - goto out_err; - } + fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *), + gfp_flags); + if (!fl->fh_array) + goto out_err; for (i = 0; i < fl->num_fh; i++) { /* Do we want to use a mempool here? */ @@ -667,9 +661,8 @@ filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, u64 p_stripe, r_stripe; u32 stripe_unit; - if (!pnfs_generic_pg_test(pgio, prev, req) || - !nfs_generic_pg_test(pgio, prev, req)) - return false; + if (!pnfs_generic_pg_test(pgio, prev, req)) + return 0; if (!pgio->pg_lseg) return 1; diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 5879b23e0c99..d2c4b59c896d 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -2265,14 +2265,12 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, return nfs4_map_errors(status); } -static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr); /* * Get locations and (maybe) other attributes of a referral. * Note that we'll actually follow the referral later when * we detect fsid mismatch in inode revalidation */ -static int nfs4_get_referral(struct inode *dir, const struct qstr *name, - struct nfs_fattr *fattr, struct nfs_fh *fhandle) +static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct nfs_fattr *fattr, struct nfs_fh *fhandle) { int status = -ENOMEM; struct page *page = NULL; @@ -2290,16 +2288,15 @@ static int nfs4_get_referral(struct inode *dir, const struct qstr *name, goto out; /* Make sure server returned a different fsid for the referral */ if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) { - dprintk("%s: server did not return a different fsid for" - " a referral at %s\n", __func__, name->name); + dprintk("%s: server did not return a different fsid for a referral at %s\n", __func__, name->name); status = -EIO; goto out; } - /* Fixup attributes for the nfs_lookup() call to nfs_fhget() */ - nfs_fixup_referral_attributes(&locations->fattr); - /* replace the lookup nfs_fattr with the locations nfs_fattr */ memcpy(fattr, &locations->fattr, sizeof(struct nfs_fattr)); + fattr->valid |= NFS_ATTR_FATTR_V4_REFERRAL; + if (!fattr->mode) + fattr->mode = S_IFDIR; memset(fhandle, 0, sizeof(struct nfs_fh)); out: if (page) @@ -4670,15 +4667,11 @@ static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list, return len; } -/* - * nfs_fhget will use either the mounted_on_fileid or the fileid - */ static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr) { - if (!(((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) || - (fattr->valid & NFS_ATTR_FATTR_FILEID)) && - (fattr->valid & NFS_ATTR_FATTR_FSID) && - (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL))) + if (!((fattr->valid & NFS_ATTR_FATTR_FILEID) && + (fattr->valid & NFS_ATTR_FATTR_FSID) && + (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL))) return; fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE | @@ -4693,6 +4686,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, struct nfs_server *server = NFS_SERVER(dir); u32 bitmask[2] = { [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, + [1] = FATTR4_WORD1_MOUNTED_ON_FILEID, }; struct nfs4_fs_locations_arg args = { .dir_fh = NFS_FH(dir), @@ -4711,18 +4705,11 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, int status; dprintk("%s: start\n", __func__); - - /* Ask for the fileid of the absent filesystem if mounted_on_fileid - * is not supported */ - if (NFS_SERVER(dir)->attr_bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) - bitmask[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID; - else - bitmask[0] |= FATTR4_WORD0_FILEID; - nfs_fattr_init(&fs_locations->fattr); fs_locations->server = server; fs_locations->nlocations = 0; status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); + nfs_fixup_referral_attributes(&fs_locations->fattr); dprintk("%s: returned status = %d\n", __func__, status); return status; } @@ -5111,6 +5098,7 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args) if (mxresp_sz == 0) mxresp_sz = NFS_MAX_FILE_IO_SIZE; /* Fore channel attributes */ + args->fc_attrs.headerpadsz = 0; args->fc_attrs.max_rqst_sz = mxrqst_sz; args->fc_attrs.max_resp_sz = mxresp_sz; args->fc_attrs.max_ops = NFS4_MAX_OPS; @@ -5123,6 +5111,7 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args) args->fc_attrs.max_ops, args->fc_attrs.max_reqs); /* Back channel attributes */ + args->bc_attrs.headerpadsz = 0; args->bc_attrs.max_rqst_sz = PAGE_SIZE; args->bc_attrs.max_resp_sz = PAGE_SIZE; args->bc_attrs.max_resp_sz_cached = 0; @@ -5142,6 +5131,8 @@ static int nfs4_verify_fore_channel_attrs(struct nfs41_create_session_args *args struct nfs4_channel_attrs *sent = &args->fc_attrs; struct nfs4_channel_attrs *rcvd = &session->fc_attrs; + if (rcvd->headerpadsz > sent->headerpadsz) + return -EINVAL; if (rcvd->max_resp_sz > sent->max_resp_sz) return -EINVAL; /* @@ -5706,7 +5697,6 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) { struct nfs4_layoutreturn *lrp = calldata; struct nfs_server *server; - struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout; dprintk("--> %s\n", __func__); @@ -5718,15 +5708,16 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) nfs_restart_rpc(task, lrp->clp); return; } - spin_lock(&lo->plh_inode->i_lock); if (task->tk_status == 0) { + struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout; + if (lrp->res.lrs_present) { + spin_lock(&lo->plh_inode->i_lock); pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); + spin_unlock(&lo->plh_inode->i_lock); } else BUG_ON(!list_empty(&lo->plh_segs)); } - lo->plh_block_lgets--; - spin_unlock(&lo->plh_inode->i_lock); dprintk("<-- %s\n", __func__); } diff --git a/trunk/fs/nfs/nfs4xdr.c b/trunk/fs/nfs/nfs4xdr.c index 6870bc61ceec..d869a5e5464b 100644 --- a/trunk/fs/nfs/nfs4xdr.c +++ b/trunk/fs/nfs/nfs4xdr.c @@ -255,7 +255,7 @@ static int nfs4_stat_to_errno(int); #define decode_fs_locations_maxsz \ (0) #define encode_secinfo_maxsz (op_encode_hdr_maxsz + nfs4_name_maxsz) -#define decode_secinfo_maxsz (op_decode_hdr_maxsz + 1 + ((NFS_MAX_SECFLAVORS * (16 + GSS_OID_MAX_LEN)) / 4)) +#define decode_secinfo_maxsz (op_decode_hdr_maxsz + 4 + (NFS_MAX_SECFLAVORS * (16 + GSS_OID_MAX_LEN))) #if defined(CONFIG_NFS_V4_1) #define NFS4_MAX_MACHINE_NAME_LEN (64) @@ -1725,7 +1725,7 @@ static void encode_create_session(struct xdr_stream *xdr, *p++ = cpu_to_be32(args->flags); /*flags */ /* Fore Channel */ - *p++ = cpu_to_be32(0); /* header padding size */ + *p++ = cpu_to_be32(args->fc_attrs.headerpadsz); /* header padding size */ *p++ = cpu_to_be32(args->fc_attrs.max_rqst_sz); /* max req size */ *p++ = cpu_to_be32(args->fc_attrs.max_resp_sz); /* max resp size */ *p++ = cpu_to_be32(max_resp_sz_cached); /* Max resp sz cached */ @@ -1734,7 +1734,7 @@ static void encode_create_session(struct xdr_stream *xdr, *p++ = cpu_to_be32(0); /* rdmachannel_attrs */ /* Back Channel */ - *p++ = cpu_to_be32(0); /* header padding size */ + *p++ = cpu_to_be32(args->fc_attrs.headerpadsz); /* header padding size */ *p++ = cpu_to_be32(args->bc_attrs.max_rqst_sz); /* max req size */ *p++ = cpu_to_be32(args->bc_attrs.max_resp_sz); /* max resp size */ *p++ = cpu_to_be32(args->bc_attrs.max_resp_sz_cached); /* Max resp sz cached */ @@ -3098,7 +3098,7 @@ static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint return -EIO; } -static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t *res) +static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap) { __be32 *p; @@ -3109,7 +3109,7 @@ static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t * if (unlikely(!p)) goto out_overflow; bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR; - *res = -be32_to_cpup(p); + return -be32_to_cpup(p); } return 0; out_overflow: @@ -4070,7 +4070,6 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, int status; umode_t fmode = 0; uint32_t type; - int32_t err; status = decode_attr_type(xdr, bitmap, &type); if (status < 0) @@ -4096,12 +4095,13 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, goto xdr_error; fattr->valid |= status; - err = 0; - status = decode_attr_error(xdr, bitmap, &err); + status = decode_attr_error(xdr, bitmap); + if (status == -NFS4ERR_WRONGSEC) { + nfs_fixup_secinfo_attributes(fattr, fh); + status = 0; + } if (status < 0) goto xdr_error; - if (err == -NFS4ERR_WRONGSEC) - nfs_fixup_secinfo_attributes(fattr, fh); status = decode_attr_filehandle(xdr, bitmap, fh); if (status < 0) @@ -4997,14 +4997,12 @@ static int decode_chan_attrs(struct xdr_stream *xdr, struct nfs4_channel_attrs *attrs) { __be32 *p; - u32 nr_attrs, val; + u32 nr_attrs; p = xdr_inline_decode(xdr, 28); if (unlikely(!p)) goto out_overflow; - val = be32_to_cpup(p++); /* headerpadsz */ - if (val) - return -EINVAL; /* no support for header padding yet */ + attrs->headerpadsz = be32_to_cpup(p++); attrs->max_rqst_sz = be32_to_cpup(p++); attrs->max_resp_sz = be32_to_cpup(p++); attrs->max_resp_sz_cached = be32_to_cpup(p++); diff --git a/trunk/fs/nfs/objlayout/objio_osd.c b/trunk/fs/nfs/objlayout/objio_osd.c index 8ff2ea3f10ef..9cf208df1f25 100644 --- a/trunk/fs/nfs/objlayout/objio_osd.c +++ b/trunk/fs/nfs/objlayout/objio_osd.c @@ -108,6 +108,7 @@ _dev_list_add(const struct nfs_server *nfss, de = n; } + atomic_inc(&de->id_node.ref); return de; } @@ -1000,9 +1001,6 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio, if (!pnfs_generic_pg_test(pgio, prev, req)) return false; - if (pgio->pg_lseg == NULL) - return true; - return pgio->pg_count + req->wb_bytes <= OBJIO_LSEG(pgio->pg_lseg)->max_io_size; } diff --git a/trunk/fs/nfs/objlayout/objlayout.c b/trunk/fs/nfs/objlayout/objlayout.c index 1d06f8e2adea..dc3956c0de80 100644 --- a/trunk/fs/nfs/objlayout/objlayout.c +++ b/trunk/fs/nfs/objlayout/objlayout.c @@ -291,7 +291,7 @@ objlayout_read_done(struct objlayout_io_state *state, ssize_t status, bool sync) struct nfs_read_data *rdata; state->status = status; - dprintk("%s: Begin status=%zd eof=%d\n", __func__, status, eof); + dprintk("%s: Begin status=%ld eof=%d\n", __func__, status, eof); rdata = state->rpcdata; rdata->task.tk_status = status; if (status >= 0) { diff --git a/trunk/fs/nfs/pagelist.c b/trunk/fs/nfs/pagelist.c index 009855716286..7913961aff22 100644 --- a/trunk/fs/nfs/pagelist.c +++ b/trunk/fs/nfs/pagelist.c @@ -204,7 +204,7 @@ nfs_wait_on_request(struct nfs_page *req) TASK_UNINTERRUPTIBLE); } -bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_page *prev, struct nfs_page *req) +static bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_page *prev, struct nfs_page *req) { /* * FIXME: ideally we should be able to coalesce all requests @@ -218,7 +218,6 @@ bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_page *pr return desc->pg_count + req->wb_bytes <= desc->pg_bsize; } -EXPORT_SYMBOL_GPL(nfs_generic_pg_test); /** * nfs_pageio_init - initialise a page io descriptor diff --git a/trunk/fs/nfs/pnfs.c b/trunk/fs/nfs/pnfs.c index 29c0ca7fc347..8c1309d852a6 100644 --- a/trunk/fs/nfs/pnfs.c +++ b/trunk/fs/nfs/pnfs.c @@ -634,16 +634,14 @@ _pnfs_return_layout(struct inode *ino) spin_lock(&ino->i_lock); lo = nfsi->layout; - if (!lo) { + if (!lo || !mark_matching_lsegs_invalid(lo, &tmp_list, NULL)) { spin_unlock(&ino->i_lock); - dprintk("%s: no layout to return\n", __func__); - return status; + dprintk("%s: no layout segments to return\n", __func__); + goto out; } stateid = nfsi->layout->plh_stateid; /* Reference matched in nfs4_layoutreturn_release */ get_layout_hdr(lo); - mark_matching_lsegs_invalid(lo, &tmp_list, NULL); - lo->plh_block_lgets++; spin_unlock(&ino->i_lock); pnfs_free_lseg_list(&tmp_list); @@ -652,9 +650,6 @@ _pnfs_return_layout(struct inode *ino) lrp = kzalloc(sizeof(*lrp), GFP_KERNEL); if (unlikely(lrp == NULL)) { status = -ENOMEM; - set_bit(NFS_LAYOUT_RW_FAILED, &lo->plh_flags); - set_bit(NFS_LAYOUT_RO_FAILED, &lo->plh_flags); - put_layout_hdr(lo); goto out; } @@ -892,7 +887,7 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo, ret = get_lseg(lseg); break; } - if (lseg->pls_range.offset > range->offset) + if (cmp_layout(range, &lseg->pls_range) > 0) break; } @@ -1064,36 +1059,23 @@ pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, gfp_flags = GFP_NOFS; } - if (pgio->pg_lseg == NULL) { - if (pgio->pg_count != prev->wb_bytes) - return true; + if (pgio->pg_count == prev->wb_bytes) { /* This is first coelesce call for a series of nfs_pages */ pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, prev->wb_context, - req_offset(prev), + req_offset(req), pgio->pg_count, access_type, gfp_flags); - if (pgio->pg_lseg == NULL) - return true; + return true; } - /* - * Test if a nfs_page is fully contained in the pnfs_layout_range. - * Note that this test makes several assumptions: - * - that the previous nfs_page in the struct nfs_pageio_descriptor - * is known to lie within the range. - * - that the nfs_page being tested is known to be contiguous with the - * previous nfs_page. - * - Layout ranges are page aligned, so we only have to test the - * start offset of the request. - * - * Please also note that 'end_offset' is actually the offset of the - * first byte that lies outside the pnfs_layout_range. FIXME? - * - */ - return req_offset(req) < end_offset(pgio->pg_lseg->pls_range.offset, - pgio->pg_lseg->pls_range.length); + if (pgio->pg_lseg && + req_offset(req) > end_offset(pgio->pg_lseg->pls_range.offset, + pgio->pg_lseg->pls_range.length)) + return false; + + return true; } EXPORT_SYMBOL_GPL(pnfs_generic_pg_test); diff --git a/trunk/fs/nfs/pnfs.h b/trunk/fs/nfs/pnfs.h index 96bf4e6f45be..48d0a8e4d062 100644 --- a/trunk/fs/nfs/pnfs.h +++ b/trunk/fs/nfs/pnfs.h @@ -186,7 +186,6 @@ int pnfs_ld_read_done(struct nfs_read_data *); /* pnfs_dev.c */ struct nfs4_deviceid_node { struct hlist_node node; - struct hlist_node tmpnode; const struct pnfs_layoutdriver_type *ld; const struct nfs_client *nfs_client; struct nfs4_deviceid deviceid; diff --git a/trunk/fs/nfs/pnfs_dev.c b/trunk/fs/nfs/pnfs_dev.c index f0f8e1e22f6c..c65e133ce9c0 100644 --- a/trunk/fs/nfs/pnfs_dev.c +++ b/trunk/fs/nfs/pnfs_dev.c @@ -174,7 +174,6 @@ nfs4_init_deviceid_node(struct nfs4_deviceid_node *d, const struct nfs4_deviceid *id) { INIT_HLIST_NODE(&d->node); - INIT_HLIST_NODE(&d->tmpnode); d->ld = ld; d->nfs_client = nfs_client; d->deviceid = *id; @@ -209,7 +208,6 @@ nfs4_insert_deviceid_node(struct nfs4_deviceid_node *new) hlist_add_head_rcu(&new->node, &nfs4_deviceid_cache[hash]); spin_unlock(&nfs4_deviceid_lock); - atomic_inc(&new->ref); return new; } @@ -240,29 +238,24 @@ static void _deviceid_purge_client(const struct nfs_client *clp, long hash) { struct nfs4_deviceid_node *d; - struct hlist_node *n; + struct hlist_node *n, *next; HLIST_HEAD(tmp); - spin_lock(&nfs4_deviceid_lock); rcu_read_lock(); hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node) if (d->nfs_client == clp && atomic_read(&d->ref)) { hlist_del_init_rcu(&d->node); - hlist_add_head(&d->tmpnode, &tmp); + hlist_add_head(&d->node, &tmp); } rcu_read_unlock(); - spin_unlock(&nfs4_deviceid_lock); if (hlist_empty(&tmp)) return; synchronize_rcu(); - while (!hlist_empty(&tmp)) { - d = hlist_entry(tmp.first, struct nfs4_deviceid_node, tmpnode); - hlist_del(&d->tmpnode); + hlist_for_each_entry_safe(d, n, next, &tmp, node) if (atomic_dec_and_test(&d->ref)) d->ld->free_deviceid_node(d); - } } void @@ -270,8 +263,8 @@ nfs4_deviceid_purge_client(const struct nfs_client *clp) { long h; - if (!(clp->cl_exchange_flags & EXCHGID4_FLAG_USE_PNFS_MDS)) - return; + spin_lock(&nfs4_deviceid_lock); for (h = 0; h < NFS4_DEVICE_ID_HASH_SIZE; h++) _deviceid_purge_client(clp, h); + spin_unlock(&nfs4_deviceid_lock); } diff --git a/trunk/fs/omfs/file.c b/trunk/fs/omfs/file.c index 2c6d95257a4d..d738a7e493dd 100644 --- a/trunk/fs/omfs/file.c +++ b/trunk/fs/omfs/file.c @@ -4,6 +4,7 @@ * Released under GPL v2. */ +#include #include #include #include diff --git a/trunk/include/linux/blk_types.h b/trunk/include/linux/blk_types.h index 6395692b2e7a..2a7cea53ca0d 100644 --- a/trunk/include/linux/blk_types.h +++ b/trunk/include/linux/blk_types.h @@ -167,7 +167,7 @@ enum rq_flag_bits { (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER) #define REQ_COMMON_MASK \ (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_DISCARD | \ - REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE) + REQ_NOIDLE | REQ_FLUSH | REQ_FUA) #define REQ_CLONE_MASK REQ_COMMON_MASK #define REQ_RAHEAD (1 << __REQ_RAHEAD) diff --git a/trunk/include/linux/blktrace_api.h b/trunk/include/linux/blktrace_api.h index 8c7c2de7631a..b22fb0d3db0f 100644 --- a/trunk/include/linux/blktrace_api.h +++ b/trunk/include/linux/blktrace_api.h @@ -169,8 +169,7 @@ extern void blk_trace_shutdown(struct request_queue *); extern int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, struct block_device *bdev, struct blk_user_trace_setup *buts); -extern __attribute__((format(printf, 2, 3))) -void __trace_note_message(struct blk_trace *, const char *fmt, ...); +extern void __trace_note_message(struct blk_trace *, const char *fmt, ...); /** * blk_add_trace_msg - Add a (simple) message to the blktrace stream diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index 553fd37b173b..c66111affca9 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -654,13 +654,13 @@ static inline int device_is_registered(struct device *dev) static inline void device_enable_async_suspend(struct device *dev) { - if (!dev->power.is_prepared) + if (!dev->power.in_suspend) dev->power.async_suspend = true; } static inline void device_disable_async_suspend(struct device *dev) { - if (!dev->power.is_prepared) + if (!dev->power.in_suspend) dev->power.async_suspend = false; } diff --git a/trunk/include/linux/jbd2.h b/trunk/include/linux/jbd2.h index d087c2e7b2aa..4ecb7b16b278 100644 --- a/trunk/include/linux/jbd2.h +++ b/trunk/include/linux/jbd2.h @@ -1024,6 +1024,7 @@ struct journal_s /* Filing buffers */ extern void jbd2_journal_unfile_buffer(journal_t *, struct journal_head *); +extern void __jbd2_journal_unfile_buffer(struct journal_head *); extern void __jbd2_journal_refile_buffer(struct journal_head *); extern void jbd2_journal_refile_buffer(journal_t *, struct journal_head *); extern void __jbd2_journal_file_buffer(struct journal_head *, transaction_t *, int); @@ -1164,6 +1165,7 @@ extern void jbd2_journal_release_jbd_inode(journal_t *journal, struct jbd2_in */ struct journal_head *jbd2_journal_add_journal_head(struct buffer_head *bh); struct journal_head *jbd2_journal_grab_journal_head(struct buffer_head *bh); +void jbd2_journal_remove_journal_head(struct buffer_head *bh); void jbd2_journal_put_journal_head(struct journal_head *jh); /* diff --git a/trunk/include/linux/nfs_page.h b/trunk/include/linux/nfs_page.h index 25311b3bedf8..3a34e80ae92f 100644 --- a/trunk/include/linux/nfs_page.h +++ b/trunk/include/linux/nfs_page.h @@ -92,9 +92,6 @@ extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *, struct nfs_page *); extern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc); extern void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *, pgoff_t); -extern bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, - struct nfs_page *prev, - struct nfs_page *req); extern int nfs_wait_on_request(struct nfs_page *); extern void nfs_unlock_request(struct nfs_page *req); extern int nfs_set_page_tag_locked(struct nfs_page *req); diff --git a/trunk/include/linux/nfs_xdr.h b/trunk/include/linux/nfs_xdr.h index 00848d86ffb2..5e8444a11adf 100644 --- a/trunk/include/linux/nfs_xdr.h +++ b/trunk/include/linux/nfs_xdr.h @@ -158,6 +158,7 @@ struct nfs_seqid; /* nfs41 sessions channel attributes */ struct nfs4_channel_attrs { + u32 headerpadsz; u32 max_rqst_sz; u32 max_resp_sz; u32 max_resp_sz_cached; diff --git a/trunk/include/linux/pm.h b/trunk/include/linux/pm.h index 411e4f4be52b..3160648ccdda 100644 --- a/trunk/include/linux/pm.h +++ b/trunk/include/linux/pm.h @@ -425,8 +425,7 @@ struct dev_pm_info { pm_message_t power_state; unsigned int can_wakeup:1; unsigned int async_suspend:1; - bool is_prepared:1; /* Owned by the PM core */ - bool is_suspended:1; /* Ditto */ + unsigned int in_suspend:1; /* Owned by the PM core */ spinlock_t lock; #ifdef CONFIG_PM_SLEEP struct list_head entry; diff --git a/trunk/include/linux/sunrpc/sched.h b/trunk/include/linux/sunrpc/sched.h index fe2d8e6b923b..f73c482ec9c6 100644 --- a/trunk/include/linux/sunrpc/sched.h +++ b/trunk/include/linux/sunrpc/sched.h @@ -84,8 +84,7 @@ struct rpc_task { #endif unsigned char tk_priority : 2,/* Task priority */ tk_garb_retry : 2, - tk_cred_retry : 2, - tk_rebind_retry : 2; + tk_cred_retry : 2; }; #define tk_xprt tk_client->cl_xprt diff --git a/trunk/include/sound/soc.h b/trunk/include/sound/soc.h index 3a4bd3a3c68d..f1de3e0c75bc 100644 --- a/trunk/include/sound/soc.h +++ b/trunk/include/sound/soc.h @@ -248,7 +248,8 @@ typedef int (*hw_write_t)(void *,const char* ,int); extern struct snd_ac97_bus_ops soc_ac97_ops; enum snd_soc_control_type { - SND_SOC_I2C = 1, + SND_SOC_CUSTOM = 1, + SND_SOC_I2C, SND_SOC_SPI, }; diff --git a/trunk/include/trace/events/ext4.h b/trunk/include/trace/events/ext4.h index 5ce2b2f5f524..e09592d2f916 100644 --- a/trunk/include/trace/events/ext4.h +++ b/trunk/include/trace/events/ext4.h @@ -26,7 +26,7 @@ TRACE_EVENT(ext4_free_inode, __field( umode_t, mode ) __field( uid_t, uid ) __field( gid_t, gid ) - __field( __u64, blocks ) + __field( blkcnt_t, blocks ) ), TP_fast_assign( @@ -40,8 +40,9 @@ TRACE_EVENT(ext4_free_inode, TP_printk("dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %llu", MAJOR(__entry->dev), MINOR(__entry->dev), - (unsigned long) __entry->ino, __entry->mode, - __entry->uid, __entry->gid, __entry->blocks) + (unsigned long) __entry->ino, + __entry->mode, __entry->uid, __entry->gid, + (unsigned long long) __entry->blocks) ); TRACE_EVENT(ext4_request_inode, @@ -177,7 +178,7 @@ TRACE_EVENT(ext4_begin_ordered_truncate, TP_printk("dev %d,%d ino %lu new_size %lld", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - __entry->new_size) + (long long) __entry->new_size) ); DECLARE_EVENT_CLASS(ext4__write_begin, @@ -203,7 +204,7 @@ DECLARE_EVENT_CLASS(ext4__write_begin, __entry->flags = flags; ), - TP_printk("dev %d,%d ino %lu pos %lld len %u flags %u", + TP_printk("dev %d,%d ino %lu pos %llu len %u flags %u", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, __entry->pos, __entry->len, __entry->flags) @@ -247,7 +248,7 @@ DECLARE_EVENT_CLASS(ext4__write_end, __entry->copied = copied; ), - TP_printk("dev %d,%d ino %lu pos %lld len %u copied %u", + TP_printk("dev %d,%d ino %lu pos %llu len %u copied %u", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, __entry->pos, __entry->len, __entry->copied) @@ -285,6 +286,29 @@ DEFINE_EVENT(ext4__write_end, ext4_da_write_end, TP_ARGS(inode, pos, len, copied) ); +TRACE_EVENT(ext4_writepage, + TP_PROTO(struct inode *inode, struct page *page), + + TP_ARGS(inode, page), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( pgoff_t, index ) + + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->index = page->index; + ), + + TP_printk("dev %d,%d ino %lu page_index %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, __entry->index) +); + TRACE_EVENT(ext4_da_writepages, TP_PROTO(struct inode *inode, struct writeback_control *wbc), @@ -317,7 +341,7 @@ TRACE_EVENT(ext4_da_writepages, ), TP_printk("dev %d,%d ino %lu nr_to_write %ld pages_skipped %ld " - "range_start %lld range_end %lld sync_mode %d" + "range_start %llu range_end %llu sync_mode %d" "for_kupdate %d range_cyclic %d writeback_index %lu", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, __entry->nr_to_write, @@ -425,14 +449,7 @@ DECLARE_EVENT_CLASS(ext4__page_op, TP_printk("dev %d,%d ino %lu page_index %lu", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - (unsigned long) __entry->index) -); - -DEFINE_EVENT(ext4__page_op, ext4_writepage, - - TP_PROTO(struct page *page), - - TP_ARGS(page) + __entry->index) ); DEFINE_EVENT(ext4__page_op, ext4_readpage, @@ -472,7 +489,7 @@ TRACE_EVENT(ext4_invalidatepage, TP_printk("dev %d,%d ino %lu page_index %lu offset %lu", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - (unsigned long) __entry->index, __entry->offset) + __entry->index, __entry->offset) ); TRACE_EVENT(ext4_discard_blocks, @@ -545,10 +562,12 @@ DEFINE_EVENT(ext4__mb_new_pa, ext4_mb_new_group_pa, ); TRACE_EVENT(ext4_mb_release_inode_pa, - TP_PROTO(struct ext4_prealloc_space *pa, + TP_PROTO(struct super_block *sb, + struct inode *inode, + struct ext4_prealloc_space *pa, unsigned long long block, unsigned int count), - TP_ARGS(pa, block, count), + TP_ARGS(sb, inode, pa, block, count), TP_STRUCT__entry( __field( dev_t, dev ) @@ -559,8 +578,8 @@ TRACE_EVENT(ext4_mb_release_inode_pa, ), TP_fast_assign( - __entry->dev = pa->pa_inode->i_sb->s_dev; - __entry->ino = pa->pa_inode->i_ino; + __entry->dev = sb->s_dev; + __entry->ino = inode->i_ino; __entry->block = block; __entry->count = count; ), @@ -572,9 +591,10 @@ TRACE_EVENT(ext4_mb_release_inode_pa, ); TRACE_EVENT(ext4_mb_release_group_pa, - TP_PROTO(struct ext4_prealloc_space *pa), + TP_PROTO(struct super_block *sb, + struct ext4_prealloc_space *pa), - TP_ARGS(pa), + TP_ARGS(sb, pa), TP_STRUCT__entry( __field( dev_t, dev ) @@ -584,7 +604,7 @@ TRACE_EVENT(ext4_mb_release_group_pa, ), TP_fast_assign( - __entry->dev = pa->pa_inode->i_sb->s_dev; + __entry->dev = sb->s_dev; __entry->pa_pstart = pa->pa_pstart; __entry->pa_len = pa->pa_len; ), @@ -646,10 +666,10 @@ TRACE_EVENT(ext4_request_blocks, __field( ino_t, ino ) __field( unsigned int, flags ) __field( unsigned int, len ) - __field( __u32, logical ) - __field( __u32, lleft ) - __field( __u32, lright ) + __field( __u64, logical ) __field( __u64, goal ) + __field( __u64, lleft ) + __field( __u64, lright ) __field( __u64, pleft ) __field( __u64, pright ) ), @@ -667,13 +687,17 @@ TRACE_EVENT(ext4_request_blocks, __entry->pright = ar->pright; ), - TP_printk("dev %d,%d ino %lu flags %u len %u lblk %u goal %llu " - "lleft %u lright %u pleft %llu pright %llu ", + TP_printk("dev %d,%d ino %lu flags %u len %u lblk %llu goal %llu " + "lleft %llu lright %llu pleft %llu pright %llu ", MAJOR(__entry->dev), MINOR(__entry->dev), - (unsigned long) __entry->ino, __entry->flags, - __entry->len, __entry->logical, __entry->goal, - __entry->lleft, __entry->lright, __entry->pleft, - __entry->pright) + (unsigned long) __entry->ino, + __entry->flags, __entry->len, + (unsigned long long) __entry->logical, + (unsigned long long) __entry->goal, + (unsigned long long) __entry->lleft, + (unsigned long long) __entry->lright, + (unsigned long long) __entry->pleft, + (unsigned long long) __entry->pright) ); TRACE_EVENT(ext4_allocate_blocks, @@ -687,10 +711,10 @@ TRACE_EVENT(ext4_allocate_blocks, __field( __u64, block ) __field( unsigned int, flags ) __field( unsigned int, len ) - __field( __u32, logical ) - __field( __u32, lleft ) - __field( __u32, lright ) + __field( __u64, logical ) __field( __u64, goal ) + __field( __u64, lleft ) + __field( __u64, lright ) __field( __u64, pleft ) __field( __u64, pright ) ), @@ -709,13 +733,17 @@ TRACE_EVENT(ext4_allocate_blocks, __entry->pright = ar->pright; ), - TP_printk("dev %d,%d ino %lu flags %u len %u block %llu lblk %u " - "goal %llu lleft %u lright %u pleft %llu pright %llu", + TP_printk("dev %d,%d ino %lu flags %u len %u block %llu lblk %llu " + "goal %llu lleft %llu lright %llu pleft %llu pright %llu", MAJOR(__entry->dev), MINOR(__entry->dev), - (unsigned long) __entry->ino, __entry->flags, - __entry->len, __entry->block, __entry->logical, - __entry->goal, __entry->lleft, __entry->lright, - __entry->pleft, __entry->pright) + (unsigned long) __entry->ino, + __entry->flags, __entry->len, __entry->block, + (unsigned long long) __entry->logical, + (unsigned long long) __entry->goal, + (unsigned long long) __entry->lleft, + (unsigned long long) __entry->lright, + (unsigned long long) __entry->pleft, + (unsigned long long) __entry->pright) ); TRACE_EVENT(ext4_free_blocks, @@ -727,10 +755,10 @@ TRACE_EVENT(ext4_free_blocks, TP_STRUCT__entry( __field( dev_t, dev ) __field( ino_t, ino ) - __field( umode_t, mode ) + __field( umode_t, mode ) __field( __u64, block ) __field( unsigned long, count ) - __field( int, flags ) + __field( int, flags ) ), TP_fast_assign( @@ -770,7 +798,7 @@ TRACE_EVENT(ext4_sync_file_enter, __entry->parent = dentry->d_parent->d_inode->i_ino; ), - TP_printk("dev %d,%d ino %lu parent %lu datasync %d ", + TP_printk("dev %d,%d ino %ld parent %ld datasync %d ", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, (unsigned long) __entry->parent, __entry->datasync) @@ -793,7 +821,7 @@ TRACE_EVENT(ext4_sync_file_exit, __entry->dev = inode->i_sb->s_dev; ), - TP_printk("dev %d,%d ino %lu ret %d", + TP_printk("dev %d,%d ino %ld ret %d", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, __entry->ret) @@ -977,7 +1005,7 @@ DECLARE_EVENT_CLASS(ext4__mballoc, __entry->result_len = len; ), - TP_printk("dev %d,%d inode %lu extent %u/%d/%d ", + TP_printk("dev %d,%d inode %lu extent %u/%d/%u ", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, __entry->result_group, __entry->result_start, @@ -1065,7 +1093,7 @@ TRACE_EVENT(ext4_da_update_reserve_space, "allocated_meta_blocks %d", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - __entry->mode, __entry->i_blocks, + __entry->mode, (unsigned long long) __entry->i_blocks, __entry->used_blocks, __entry->reserved_data_blocks, __entry->reserved_meta_blocks, __entry->allocated_meta_blocks) ); @@ -1099,7 +1127,7 @@ TRACE_EVENT(ext4_da_reserve_space, "reserved_data_blocks %d reserved_meta_blocks %d", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - __entry->mode, __entry->i_blocks, + __entry->mode, (unsigned long long) __entry->i_blocks, __entry->md_needed, __entry->reserved_data_blocks, __entry->reserved_meta_blocks) ); @@ -1136,7 +1164,7 @@ TRACE_EVENT(ext4_da_release_space, "allocated_meta_blocks %d", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - __entry->mode, __entry->i_blocks, + __entry->mode, (unsigned long long) __entry->i_blocks, __entry->freed_blocks, __entry->reserved_data_blocks, __entry->reserved_meta_blocks, __entry->allocated_meta_blocks) ); @@ -1211,15 +1239,14 @@ TRACE_EVENT(ext4_direct_IO_enter, __entry->rw = rw; ), - TP_printk("dev %d,%d ino %lu pos %lld len %lu rw %d", + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - __entry->pos, __entry->len, __entry->rw) + (unsigned long long) __entry->pos, __entry->len, __entry->rw) ); TRACE_EVENT(ext4_direct_IO_exit, - TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, - int rw, int ret), + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, int rw, int ret), TP_ARGS(inode, offset, len, rw, ret), @@ -1241,10 +1268,10 @@ TRACE_EVENT(ext4_direct_IO_exit, __entry->ret = ret; ), - TP_printk("dev %d,%d ino %lu pos %lld len %lu rw %d ret %d", + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d ret %d", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - __entry->pos, __entry->len, + (unsigned long long) __entry->pos, __entry->len, __entry->rw, __entry->ret) ); @@ -1269,15 +1296,15 @@ TRACE_EVENT(ext4_fallocate_enter, __entry->mode = mode; ), - TP_printk("dev %d,%d ino %lu pos %lld len %lld mode %d", + TP_printk("dev %d,%d ino %ld pos %llu len %llu mode %d", MAJOR(__entry->dev), MINOR(__entry->dev), - (unsigned long) __entry->ino, __entry->pos, - __entry->len, __entry->mode) + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, + (unsigned long long) __entry->len, __entry->mode) ); TRACE_EVENT(ext4_fallocate_exit, - TP_PROTO(struct inode *inode, loff_t offset, - unsigned int max_blocks, int ret), + TP_PROTO(struct inode *inode, loff_t offset, unsigned int max_blocks, int ret), TP_ARGS(inode, offset, max_blocks, ret), @@ -1285,7 +1312,7 @@ TRACE_EVENT(ext4_fallocate_exit, __field( ino_t, ino ) __field( dev_t, dev ) __field( loff_t, pos ) - __field( unsigned int, blocks ) + __field( unsigned, blocks ) __field( int, ret ) ), @@ -1297,10 +1324,10 @@ TRACE_EVENT(ext4_fallocate_exit, __entry->ret = ret; ), - TP_printk("dev %d,%d ino %lu pos %lld blocks %u ret %d", + TP_printk("dev %d,%d ino %ld pos %llu blocks %d ret %d", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - __entry->pos, __entry->blocks, + (unsigned long long) __entry->pos, __entry->blocks, __entry->ret) ); @@ -1323,7 +1350,7 @@ TRACE_EVENT(ext4_unlink_enter, __entry->dev = dentry->d_inode->i_sb->s_dev; ), - TP_printk("dev %d,%d ino %lu size %lld parent %lu", + TP_printk("dev %d,%d ino %ld size %lld parent %ld", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, __entry->size, (unsigned long) __entry->parent) @@ -1346,7 +1373,7 @@ TRACE_EVENT(ext4_unlink_exit, __entry->ret = ret; ), - TP_printk("dev %d,%d ino %lu ret %d", + TP_printk("dev %d,%d ino %ld ret %d", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, __entry->ret) @@ -1360,7 +1387,7 @@ DECLARE_EVENT_CLASS(ext4__truncate, TP_STRUCT__entry( __field( ino_t, ino ) __field( dev_t, dev ) - __field( __u64, blocks ) + __field( blkcnt_t, blocks ) ), TP_fast_assign( @@ -1369,9 +1396,9 @@ DECLARE_EVENT_CLASS(ext4__truncate, __entry->blocks = inode->i_blocks; ), - TP_printk("dev %d,%d ino %lu blocks %llu", + TP_printk("dev %d,%d ino %lu blocks %lu", MAJOR(__entry->dev), MINOR(__entry->dev), - (unsigned long) __entry->ino, __entry->blocks) + (unsigned long) __entry->ino, (unsigned long) __entry->blocks) ); DEFINE_EVENT(ext4__truncate, ext4_truncate_enter, @@ -1390,7 +1417,7 @@ DEFINE_EVENT(ext4__truncate, ext4_truncate_exit, DECLARE_EVENT_CLASS(ext4__map_blocks_enter, TP_PROTO(struct inode *inode, ext4_lblk_t lblk, - unsigned int len, unsigned int flags), + unsigned len, unsigned flags), TP_ARGS(inode, lblk, len, flags), @@ -1398,8 +1425,8 @@ DECLARE_EVENT_CLASS(ext4__map_blocks_enter, __field( ino_t, ino ) __field( dev_t, dev ) __field( ext4_lblk_t, lblk ) - __field( unsigned int, len ) - __field( unsigned int, flags ) + __field( unsigned, len ) + __field( unsigned, flags ) ), TP_fast_assign( @@ -1413,7 +1440,7 @@ DECLARE_EVENT_CLASS(ext4__map_blocks_enter, TP_printk("dev %d,%d ino %lu lblk %u len %u flags %u", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - __entry->lblk, __entry->len, __entry->flags) + (unsigned) __entry->lblk, __entry->len, __entry->flags) ); DEFINE_EVENT(ext4__map_blocks_enter, ext4_ext_map_blocks_enter, @@ -1432,7 +1459,7 @@ DEFINE_EVENT(ext4__map_blocks_enter, ext4_ind_map_blocks_enter, DECLARE_EVENT_CLASS(ext4__map_blocks_exit, TP_PROTO(struct inode *inode, ext4_lblk_t lblk, - ext4_fsblk_t pblk, unsigned int len, int ret), + ext4_fsblk_t pblk, unsigned len, int ret), TP_ARGS(inode, lblk, pblk, len, ret), @@ -1441,7 +1468,7 @@ DECLARE_EVENT_CLASS(ext4__map_blocks_exit, __field( dev_t, dev ) __field( ext4_lblk_t, lblk ) __field( ext4_fsblk_t, pblk ) - __field( unsigned int, len ) + __field( unsigned, len ) __field( int, ret ) ), @@ -1457,7 +1484,7 @@ DECLARE_EVENT_CLASS(ext4__map_blocks_exit, TP_printk("dev %d,%d ino %lu lblk %u pblk %llu len %u ret %d", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - __entry->lblk, __entry->pblk, + (unsigned) __entry->lblk, (unsigned long long) __entry->pblk, __entry->len, __entry->ret) ); @@ -1497,7 +1524,7 @@ TRACE_EVENT(ext4_ext_load_extent, TP_printk("dev %d,%d ino %lu lblk %u pblk %llu", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, - __entry->lblk, __entry->pblk) + (unsigned) __entry->lblk, (unsigned long long) __entry->pblk) ); TRACE_EVENT(ext4_load_inode, diff --git a/trunk/init/calibrate.c b/trunk/init/calibrate.c index aae2f40fea4c..2568d22a304e 100644 --- a/trunk/init/calibrate.c +++ b/trunk/init/calibrate.c @@ -245,32 +245,30 @@ static unsigned long __cpuinit calibrate_delay_converge(void) void __cpuinit calibrate_delay(void) { - unsigned long lpj; static bool printed; if (preset_lpj) { - lpj = preset_lpj; + loops_per_jiffy = preset_lpj; if (!printed) pr_info("Calibrating delay loop (skipped) " "preset value.. "); } else if ((!printed) && lpj_fine) { - lpj = lpj_fine; + loops_per_jiffy = lpj_fine; pr_info("Calibrating delay loop (skipped), " "value calculated using timer frequency.. "); - } else if ((lpj = calibrate_delay_direct()) != 0) { + } else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) { if (!printed) pr_info("Calibrating delay using timer " "specific routine.. "); } else { if (!printed) pr_info("Calibrating delay loop... "); - lpj = calibrate_delay_converge(); + loops_per_jiffy = calibrate_delay_converge(); } if (!printed) pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n", - lpj/(500000/HZ), - (lpj/(5000/HZ)) % 100, lpj); + loops_per_jiffy/(500000/HZ), + (loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy); - loops_per_jiffy = lpj; printed = true; } diff --git a/trunk/kernel/power/user.c b/trunk/kernel/power/user.c index 42ddbc6f0de6..7d02d33be699 100644 --- a/trunk/kernel/power/user.c +++ b/trunk/kernel/power/user.c @@ -113,10 +113,8 @@ static int snapshot_open(struct inode *inode, struct file *filp) if (error) pm_notifier_call_chain(PM_POST_RESTORE); } - if (error) { - free_basic_memory_bitmaps(); + if (error) atomic_inc(&snapshot_device_available); - } data->frozen = 0; data->ready = 0; data->platform_support = 0; diff --git a/trunk/kernel/time/alarmtimer.c b/trunk/kernel/time/alarmtimer.c index 59f369f98a04..2d966244ea60 100644 --- a/trunk/kernel/time/alarmtimer.c +++ b/trunk/kernel/time/alarmtimer.c @@ -42,76 +42,16 @@ static struct alarm_base { clockid_t base_clockid; } alarm_bases[ALARM_NUMTYPE]; -/* freezer delta & lock used to handle clock_nanosleep triggered wakeups */ -static ktime_t freezer_delta; -static DEFINE_SPINLOCK(freezer_delta_lock); - #ifdef CONFIG_RTC_CLASS /* rtc timer and device for setting alarm wakeups at suspend */ static struct rtc_timer rtctimer; static struct rtc_device *rtcdev; -static DEFINE_SPINLOCK(rtcdev_lock); - -/** - * has_wakealarm - check rtc device has wakealarm ability - * @dev: current device - * @name_ptr: name to be returned - * - * This helper function checks to see if the rtc device can wake - * from suspend. - */ -static int has_wakealarm(struct device *dev, void *name_ptr) -{ - struct rtc_device *candidate = to_rtc_device(dev); - - if (!candidate->ops->set_alarm) - return 0; - if (!device_may_wakeup(candidate->dev.parent)) - return 0; - - *(const char **)name_ptr = dev_name(dev); - return 1; -} - -/** - * alarmtimer_get_rtcdev - Return selected rtcdevice - * - * This function returns the rtc device to use for wakealarms. - * If one has not already been chosen, it checks to see if a - * functional rtc device is available. - */ -static struct rtc_device *alarmtimer_get_rtcdev(void) -{ - struct device *dev; - char *str; - unsigned long flags; - struct rtc_device *ret; - - spin_lock_irqsave(&rtcdev_lock, flags); - if (!rtcdev) { - /* Find an rtc device and init the rtc_timer */ - dev = class_find_device(rtc_class, NULL, &str, has_wakealarm); - /* If we have a device then str is valid. See has_wakealarm() */ - if (dev) { - rtcdev = rtc_class_open(str); - /* - * Drop the reference we got in class_find_device, - * rtc_open takes its own. - */ - put_device(dev); - rtc_timer_init(&rtctimer, NULL, NULL); - } - } - ret = rtcdev; - spin_unlock_irqrestore(&rtcdev_lock, flags); - - return ret; -} -#else -#define alarmtimer_get_rtcdev() (0) -#define rtcdev (0) #endif +/* freezer delta & lock used to handle clock_nanosleep triggered wakeups */ +static ktime_t freezer_delta; +static DEFINE_SPINLOCK(freezer_delta_lock); + /** * alarmtimer_enqueue - Adds an alarm timer to an alarm_base timerqueue @@ -226,7 +166,6 @@ static int alarmtimer_suspend(struct device *dev) struct rtc_time tm; ktime_t min, now; unsigned long flags; - struct rtc_device *rtc; int i; spin_lock_irqsave(&freezer_delta_lock, flags); @@ -234,9 +173,8 @@ static int alarmtimer_suspend(struct device *dev) freezer_delta = ktime_set(0, 0); spin_unlock_irqrestore(&freezer_delta_lock, flags); - rtc = rtcdev; /* If we have no rtcdev, just return */ - if (!rtc) + if (!rtcdev) return 0; /* Find the soonest timer to expire*/ @@ -261,12 +199,12 @@ static int alarmtimer_suspend(struct device *dev) WARN_ON(min.tv64 < NSEC_PER_SEC); /* Setup an rtc timer to fire that far in the future */ - rtc_timer_cancel(rtc, &rtctimer); - rtc_read_time(rtc, &tm); + rtc_timer_cancel(rtcdev, &rtctimer); + rtc_read_time(rtcdev, &tm); now = rtc_tm_to_ktime(tm); now = ktime_add(now, min); - rtc_timer_start(rtc, &rtctimer, now, ktime_set(0, 0)); + rtc_timer_start(rtcdev, &rtctimer, now, ktime_set(0, 0)); return 0; } @@ -384,9 +322,6 @@ static int alarm_clock_getres(const clockid_t which_clock, struct timespec *tp) { clockid_t baseid = alarm_bases[clock2alarm(which_clock)].base_clockid; - if (!alarmtimer_get_rtcdev()) - return -ENOTSUPP; - return hrtimer_get_res(baseid, tp); } @@ -401,9 +336,6 @@ static int alarm_clock_get(clockid_t which_clock, struct timespec *tp) { struct alarm_base *base = &alarm_bases[clock2alarm(which_clock)]; - if (!alarmtimer_get_rtcdev()) - return -ENOTSUPP; - *tp = ktime_to_timespec(base->gettime()); return 0; } @@ -419,9 +351,6 @@ static int alarm_timer_create(struct k_itimer *new_timer) enum alarmtimer_type type; struct alarm_base *base; - if (!alarmtimer_get_rtcdev()) - return -ENOTSUPP; - if (!capable(CAP_WAKE_ALARM)) return -EPERM; @@ -456,9 +385,6 @@ static void alarm_timer_get(struct k_itimer *timr, */ static int alarm_timer_del(struct k_itimer *timr) { - if (!rtcdev) - return -ENOTSUPP; - alarm_cancel(&timr->it.alarmtimer); return 0; } @@ -476,9 +402,6 @@ static int alarm_timer_set(struct k_itimer *timr, int flags, struct itimerspec *new_setting, struct itimerspec *old_setting) { - if (!rtcdev) - return -ENOTSUPP; - /* Save old values */ old_setting->it_interval = ktime_to_timespec(timr->it.alarmtimer.period); @@ -618,9 +541,6 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags, int ret = 0; struct restart_block *restart; - if (!alarmtimer_get_rtcdev()) - return -ENOTSUPP; - if (!capable(CAP_WAKE_ALARM)) return -EPERM; @@ -718,3 +638,65 @@ static int __init alarmtimer_init(void) } device_initcall(alarmtimer_init); +#ifdef CONFIG_RTC_CLASS +/** + * has_wakealarm - check rtc device has wakealarm ability + * @dev: current device + * @name_ptr: name to be returned + * + * This helper function checks to see if the rtc device can wake + * from suspend. + */ +static int __init has_wakealarm(struct device *dev, void *name_ptr) +{ + struct rtc_device *candidate = to_rtc_device(dev); + + if (!candidate->ops->set_alarm) + return 0; + if (!device_may_wakeup(candidate->dev.parent)) + return 0; + + *(const char **)name_ptr = dev_name(dev); + return 1; +} + +/** + * alarmtimer_init_late - Late initializing of alarmtimer code + * + * This function locates a rtc device to use for wakealarms. + * Run as late_initcall to make sure rtc devices have been + * registered. + */ +static int __init alarmtimer_init_late(void) +{ + struct device *dev; + char *str; + + /* Find an rtc device and init the rtc_timer */ + dev = class_find_device(rtc_class, NULL, &str, has_wakealarm); + /* If we have a device then str is valid. See has_wakealarm() */ + if (dev) { + rtcdev = rtc_class_open(str); + /* + * Drop the reference we got in class_find_device, + * rtc_open takes its own. + */ + put_device(dev); + } + if (!rtcdev) { + printk(KERN_WARNING "No RTC device found, ALARM timers will" + " not wake from suspend"); + } + rtc_timer_init(&rtctimer, NULL, NULL); + + return 0; +} +#else +static int __init alarmtimer_init_late(void) +{ + printk(KERN_WARNING "Kernel not built with RTC support, ALARM timers" + " will not wake from suspend"); + return 0; +} +#endif +late_initcall(alarmtimer_init_late); diff --git a/trunk/mm/memory_hotplug.c b/trunk/mm/memory_hotplug.c index c46887b5a11e..02159c755136 100644 --- a/trunk/mm/memory_hotplug.c +++ b/trunk/mm/memory_hotplug.c @@ -498,9 +498,7 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start) * The node we allocated has no zone fallback lists. For avoiding * to access not-initialized zonelist, build here. */ - mutex_lock(&zonelists_mutex); build_all_zonelists(NULL); - mutex_unlock(&zonelists_mutex); return pgdat; } @@ -523,7 +521,7 @@ int mem_online_node(int nid) lock_memory_hotplug(); pgdat = hotadd_new_pgdat(nid, 0); - if (!pgdat) { + if (pgdat) { ret = -ENOMEM; goto out; } diff --git a/trunk/net/sunrpc/auth_gss/auth_gss.c b/trunk/net/sunrpc/auth_gss/auth_gss.c index 5daf6cc4faea..339ba64cce1e 100644 --- a/trunk/net/sunrpc/auth_gss/auth_gss.c +++ b/trunk/net/sunrpc/auth_gss/auth_gss.c @@ -577,13 +577,13 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) } inode = &gss_msg->inode->vfs_inode; for (;;) { - prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE); + prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_INTERRUPTIBLE); spin_lock(&inode->i_lock); if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { break; } spin_unlock(&inode->i_lock); - if (fatal_signal_pending(current)) { + if (signalled()) { err = -ERESTARTSYS; goto out_intr; } diff --git a/trunk/net/sunrpc/clnt.c b/trunk/net/sunrpc/clnt.c index 8c9141583d6f..b84d7395535e 100644 --- a/trunk/net/sunrpc/clnt.c +++ b/trunk/net/sunrpc/clnt.c @@ -1061,7 +1061,7 @@ call_allocate(struct rpc_task *task) dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid); - if (RPC_IS_ASYNC(task) || !fatal_signal_pending(current)) { + if (RPC_IS_ASYNC(task) || !signalled()) { task->tk_action = call_allocate; rpc_delay(task, HZ>>4); return; @@ -1175,9 +1175,6 @@ call_bind_status(struct rpc_task *task) status = -EOPNOTSUPP; break; } - if (task->tk_rebind_retry == 0) - break; - task->tk_rebind_retry--; rpc_delay(task, 3*HZ); goto retry_timeout; case -ETIMEDOUT: diff --git a/trunk/net/sunrpc/sched.c b/trunk/net/sunrpc/sched.c index a27406b1654f..6b43ee7221d5 100644 --- a/trunk/net/sunrpc/sched.c +++ b/trunk/net/sunrpc/sched.c @@ -792,7 +792,6 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta /* Initialize retry counters */ task->tk_garb_retry = 2; task->tk_cred_retry = 2; - task->tk_rebind_retry = 2; task->tk_priority = task_setup_data->priority - RPC_PRIORITY_LOW; task->tk_owner = current->tgid; diff --git a/trunk/security/keys/request_key.c b/trunk/security/keys/request_key.c index 82465328c39b..8e319a416eec 100644 --- a/trunk/security/keys/request_key.c +++ b/trunk/security/keys/request_key.c @@ -469,7 +469,7 @@ static struct key *construct_key_and_link(struct key_type *type, } else if (ret == -EINPROGRESS) { ret = 0; } else { - goto couldnt_alloc_key; + key = ERR_PTR(ret); } key_put(dest_keyring); @@ -479,7 +479,6 @@ static struct key *construct_key_and_link(struct key_type *type, construction_failed: key_negate_and_link(key, key_negative_timeout, NULL, NULL); key_put(key); -couldnt_alloc_key: key_put(dest_keyring); kleave(" = %d", ret); return ERR_PTR(ret); diff --git a/trunk/sound/pci/asihpi/asihpi.c b/trunk/sound/pci/asihpi/asihpi.c index e3569bdd3b64..2ca6f4f85b41 100644 --- a/trunk/sound/pci/asihpi/asihpi.c +++ b/trunk/sound/pci/asihpi/asihpi.c @@ -27,6 +27,7 @@ #include "hpioctl.h" #include +#include #include #include #include diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index d21191dcfe88..61a774b3d3cb 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -4883,6 +4883,7 @@ static const struct snd_pci_quirk alc880_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), + SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), @@ -12599,7 +12600,6 @@ static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { */ enum { PINFIX_FSC_H270, - PINFIX_HP_Z200, }; static const struct alc_fixup alc262_fixups[] = { @@ -12612,17 +12612,9 @@ static const struct alc_fixup alc262_fixups[] = { { } } }, - [PINFIX_HP_Z200] = { - .type = ALC_FIXUP_PINS, - .v.pins = (const struct alc_pincfg[]) { - { 0x16, 0x99130120 }, /* internal speaker */ - { } - } - }, }; static const struct snd_pci_quirk alc262_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200), SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270), {} }; @@ -12739,8 +12731,6 @@ static const struct snd_pci_quirk alc262_cfg_tbl[] = { ALC262_HP_BPC), SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", - ALC262_AUTO), SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), @@ -13882,6 +13872,7 @@ static const struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), + SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), {} }; diff --git a/trunk/sound/pci/hda/patch_via.c b/trunk/sound/pci/hda/patch_via.c index f43bb0eaed8b..c952582fb218 100644 --- a/trunk/sound/pci/hda/patch_via.c +++ b/trunk/sound/pci/hda/patch_via.c @@ -745,23 +745,12 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, struct via_spec *spec = codec->spec; hda_nid_t nid = kcontrol->private_value; unsigned int pinsel = ucontrol->value.enumerated.item[0]; - unsigned int parm0, parm1; /* Get Independent Mode index of headphone pin widget */ spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel ? 1 : 0; - if (spec->codec_type == VT1718S) { + if (spec->codec_type == VT1718S) snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0); - /* Set correct mute switch for MW3 */ - parm0 = spec->hp_independent_mode ? - AMP_IN_UNMUTE(0) : AMP_IN_MUTE(0); - parm1 = spec->hp_independent_mode ? - AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1); - snd_hda_codec_write(codec, 0x1b, 0, - AC_VERB_SET_AMP_GAIN_MUTE, parm0); - snd_hda_codec_write(codec, 0x1b, 0, - AC_VERB_SET_AMP_GAIN_MUTE, parm1); - } else snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); @@ -4294,6 +4283,9 @@ static const struct hda_verb vt1718S_volume_init_verbs[] = { {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, + + /* Setup default input of Front HP to MW9 */ + {0x28, AC_VERB_SET_CONNECT_SEL, 0x1}, /* PW9 PW10 Output enable */ {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN}, {0x2e, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN}, @@ -4302,10 +4294,10 @@ static const struct hda_verb vt1718S_volume_init_verbs[] = { /* Enable Boost Volume backdoor */ {0x1, 0xf88, 0x8}, /* MW0/1/2/3/4: un-mute index 0 (AOWx), mute index 1 (MW9) */ - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, @@ -4315,6 +4307,8 @@ static const struct hda_verb vt1718S_volume_init_verbs[] = { /* set MUX1 = 2 (AOW4), MUX2 = 1 (AOW3) */ {0x34, AC_VERB_SET_CONNECT_SEL, 0x2}, {0x35, AC_VERB_SET_CONNECT_SEL, 0x1}, + /* Unmute MW4's index 0 */ + {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, { } }; @@ -4462,19 +4456,6 @@ static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec, if (err < 0) return err; } else if (i == AUTO_SEQ_FRONT) { - /* add control to mixer index 0 */ - err = via_add_control(spec, VIA_CTL_WIDGET_VOL, - "Master Front Playback Volume", - HDA_COMPOSE_AMP_VAL(0x21, 3, 5, - HDA_INPUT)); - if (err < 0) - return err; - err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, - "Master Front Playback Switch", - HDA_COMPOSE_AMP_VAL(0x21, 3, 5, - HDA_INPUT)); - if (err < 0) - return err; /* Front */ sprintf(name, "%s Playback Volume", chname[i]); err = via_add_control( diff --git a/trunk/sound/soc/codecs/wm8991.c b/trunk/sound/soc/codecs/wm8991.c index 6af23d06870f..3c2ee1bb73cd 100644 --- a/trunk/sound/soc/codecs/wm8991.c +++ b/trunk/sound/soc/codecs/wm8991.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include diff --git a/trunk/sound/soc/imx/Kconfig b/trunk/sound/soc/imx/Kconfig index bb699bb55a50..d8f130d39dd9 100644 --- a/trunk/sound/soc/imx/Kconfig +++ b/trunk/sound/soc/imx/Kconfig @@ -11,6 +11,9 @@ menuconfig SND_IMX_SOC if SND_IMX_SOC +config SND_MXC_SOC_SSI + tristate + config SND_MXC_SOC_FIQ tristate @@ -21,6 +24,7 @@ config SND_MXC_SOC_WM1133_EV1 tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted" depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL select SND_SOC_WM8350 + select SND_MXC_SOC_SSI select SND_MXC_SOC_FIQ help Enable support for audio on the i.MX31ADS with the WM1133-EV1 @@ -30,6 +34,7 @@ config SND_SOC_MX27VIS_AIC32X4 tristate "SoC audio support for Visstrim M10 boards" depends on MACH_IMX27_VISSTRIM_M10 select SND_SOC_TVL320AIC32X4 + select SND_MXC_SOC_SSI select SND_MXC_SOC_MX2 help Say Y if you want to add support for SoC audio on Visstrim SM10 @@ -39,6 +44,7 @@ config SND_SOC_PHYCORE_AC97 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards" depends on MACH_PCM043 || MACH_PCA100 select SND_SOC_WM9712 + select SND_MXC_SOC_SSI select SND_MXC_SOC_FIQ help Say Y if you want to add support for SoC audio on Phytec phyCORE @@ -51,6 +57,7 @@ config SND_SOC_EUKREA_TLV320 || MACH_EUKREA_MBIMXSD35_BASEBOARD \ || MACH_EUKREA_MBIMXSD51_BASEBOARD select SND_SOC_TLV320AIC23 + select SND_MXC_SOC_SSI select SND_MXC_SOC_FIQ help Enable I2S based access to the TLV320AIC23B codec attached diff --git a/trunk/sound/soc/imx/imx-pcm-dma-mx2.c b/trunk/sound/soc/imx/imx-pcm-dma-mx2.c index 4173b3d87f97..aab7765f401a 100644 --- a/trunk/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/trunk/sound/soc/imx/imx-pcm-dma-mx2.c @@ -337,5 +337,3 @@ static void __exit snd_imx_pcm_exit(void) platform_driver_unregister(&imx_pcm_driver); } module_exit(snd_imx_pcm_exit); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:imx-pcm-audio"); diff --git a/trunk/sound/soc/imx/imx-ssi.c b/trunk/sound/soc/imx/imx-ssi.c index 61fceb09cdb5..5b13feca7537 100644 --- a/trunk/sound/soc/imx/imx-ssi.c +++ b/trunk/sound/soc/imx/imx-ssi.c @@ -774,4 +774,4 @@ module_exit(imx_ssi_exit); MODULE_AUTHOR("Sascha Hauer, "); MODULE_DESCRIPTION("i.MX I2S/ac97 SoC Interface"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:imx-ssi"); + diff --git a/trunk/sound/soc/pxa/pxa2xx-pcm.c b/trunk/sound/soc/pxa/pxa2xx-pcm.c index fab20a54e863..2ce0b2d891d5 100644 --- a/trunk/sound/soc/pxa/pxa2xx-pcm.c +++ b/trunk/sound/soc/pxa/pxa2xx-pcm.c @@ -95,14 +95,14 @@ static int pxa2xx_soc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { + if (dai->driver->playback.channels_min) { ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto out; } - if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { + if (dai->driver->capture.channels_min) { ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) diff --git a/trunk/sound/soc/soc-cache.c b/trunk/sound/soc/soc-cache.c index 039b9532b270..c005ceb70c9d 100644 --- a/trunk/sound/soc/soc-cache.c +++ b/trunk/sound/soc/soc-cache.c @@ -409,6 +409,9 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, codec->bulk_write_raw = snd_soc_hw_bulk_write_raw; switch (control) { + case SND_SOC_CUSTOM: + break; + case SND_SOC_I2C: #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) codec->hw_write = (hw_write_t)i2c_master_send;