diff --git a/[refs] b/[refs] index 5238d6eca668..605f5beb2a17 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 44b7f4b98d8877e2a4427f2a2f2e42ae8227a58f +refs/heads/master: 75fc2d3797c47f5f70ca71c41c342c352845cd06 diff --git a/trunk/CREDITS b/trunk/CREDITS index 44fce988eaac..07e32a87d956 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -688,13 +688,10 @@ S: Oxfordshire, UK. N: Kees Cook E: kees@outflux.net -E: kees@ubuntu.com -E: keescook@chromium.org -W: http://outflux.net/blog/ -P: 4096R/DC6DC026 A5C3 F68F 229D D60F 723E 6E13 8972 F4DF DC6D C026 -D: Various security things, bug fixes, and documentation. +W: http://outflux.net/ +P: 1024D/17063E6D 9FA3 C49C 23C9 D1BC 2E30 1975 1FFF 4BA9 1706 3E6D +D: Minor updates to SCSI types, added /proc/pid/maps protection S: (ask for current address) -S: Portland, Oregon S: USA N: Robin Cornelius diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-rbd b/trunk/Documentation/ABI/testing/sysfs-bus-rbd index dbedafb095e2..fa72ccb2282e 100644 --- a/trunk/Documentation/ABI/testing/sysfs-bus-rbd +++ b/trunk/Documentation/ABI/testing/sysfs-bus-rbd @@ -57,6 +57,13 @@ create_snap $ echo > /sys/bus/rbd/devices//snap_create +rollback_snap + + Rolls back data to the specified snapshot. This goes over the entire + list of rados blocks and sends a rollback command to each. + + $ echo > /sys/bus/rbd/devices//snap_rollback + snap_* A directory per each snapshot diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 81c287fad79d..5e22c3f1f8bd 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -320,7 +320,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. on: enable for both 32- and 64-bit processes off: disable for both 32- and 64-bit processes - amd_iommu= [HW,X86-64] + amd_iommu= [HW,X86-84] Pass parameters to the AMD IOMMU driver in the system. Possible values are: fullflush - enable flushing of IO/TLB entries when diff --git a/trunk/Documentation/networking/ip-sysctl.txt b/trunk/Documentation/networking/ip-sysctl.txt index 589f2da5d545..f049a1ca186f 100644 --- a/trunk/Documentation/networking/ip-sysctl.txt +++ b/trunk/Documentation/networking/ip-sysctl.txt @@ -282,11 +282,11 @@ tcp_max_ssthresh - INTEGER Default: 0 (off) tcp_max_syn_backlog - INTEGER - Maximal number of remembered connection requests, which have not - received an acknowledgment from connecting client. - The minimal value is 128 for low memory machines, and it will - increase in proportion to the memory of machine. - If server suffers from overload, try increasing this number. + Maximal number of remembered connection requests, which are + still did not receive an acknowledgment from connecting client. + Default value is 1024 for systems with more than 128Mb of memory, + and 128 for low memory machines. If server suffers of overload, + try to increase this number. tcp_max_tw_buckets - INTEGER Maximal number of timewait sockets held by system simultaneously. diff --git a/trunk/Documentation/sound/alsa/soc/machine.txt b/trunk/Documentation/sound/alsa/soc/machine.txt index d50c14df3411..3e2ec9cbf397 100644 --- a/trunk/Documentation/sound/alsa/soc/machine.txt +++ b/trunk/Documentation/sound/alsa/soc/machine.txt @@ -50,7 +50,8 @@ Machine DAI Configuration The machine DAI configuration glues all the codec and CPU DAIs together. It can also be used to set up the DAI system clock and for any machine related DAI initialisation e.g. the machine audio map can be connected to the codec audio -map, unconnected codec pins can be set as such. +map, unconnected codec pins can be set as such. Please see corgi.c, spitz.c +for examples. struct snd_soc_dai_link is used to set up each DAI in your machine. e.g. @@ -82,7 +83,8 @@ Machine Power Map The machine driver can optionally extend the codec power map and to become an audio power map of the audio subsystem. This allows for automatic power up/down of speaker/HP amplifiers, etc. Codec pins can be connected to the machines jack -sockets in the machine init function. +sockets in the machine init function. See soc/pxa/spitz.c and dapm.txt for +details. Machine Controls diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index b9db108f01c8..9706a21edcbd 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -511,8 +511,8 @@ M: Joerg Roedel L: iommu@lists.linux-foundation.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu.git S: Supported -F: drivers/iommu/amd_iommu*.[ch] -F: include/linux/amd-iommu.h +F: arch/x86/kernel/amd_iommu*.c +F: arch/x86/include/asm/amd_iommu*.h AMD MICROCODE UPDATE SUPPORT M: Andreas Herrmann @@ -1054,18 +1054,35 @@ ARM/SAMSUNG ARM ARCHITECTURES M: Ben Dooks M: Kukjin Kim L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) W: http://www.fluff.org/ben/linux/ S: Maintained F: arch/arm/plat-samsung/ F: arch/arm/plat-s3c24xx/ F: arch/arm/plat-s5p/ -F: arch/arm/mach-s3c24*/ -F: arch/arm/mach-s3c64xx/ F: drivers/*/*s3c2410* F: drivers/*/*/*s3c2410* -F: drivers/spi/spi-s3c* -F: sound/soc/samsung/* + +ARM/S3C2410 ARM ARCHITECTURE +M: Ben Dooks +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +W: http://www.fluff.org/ben/linux/ +S: Maintained +F: arch/arm/mach-s3c2410/ + +ARM/S3C244x ARM ARCHITECTURE +M: Ben Dooks +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +W: http://www.fluff.org/ben/linux/ +S: Maintained +F: arch/arm/mach-s3c2440/ +F: arch/arm/mach-s3c2443/ + +ARM/S3C64xx ARM ARCHITECTURE +M: Ben Dooks +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +W: http://www.fluff.org/ben/linux/ +S: Maintained +F: arch/arm/mach-s3c64xx/ ARM/S5P EXYNOS ARM ARCHITECTURES M: Kukjin Kim @@ -3101,6 +3118,7 @@ F: include/linux/hid* HIGH-RESOLUTION TIMERS, CLOCKEVENTS, DYNTICKS M: Thomas Gleixner +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core S: Maintained F: Documentation/timers/ F: kernel/hrtimer.c @@ -3610,7 +3628,7 @@ F: net/irda/ IRQ SUBSYSTEM M: Thomas Gleixner S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git irq/core +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core F: kernel/irq/ ISAPNP @@ -4098,7 +4116,7 @@ F: drivers/hwmon/lm90.c LOCKDEP AND LOCKSTAT M: Peter Zijlstra M: Ingo Molnar -T: git git://git.kernel.org/pub/scm/linux/kernel/git/peterz/linux-2.6-lockdep.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core/locking S: Maintained F: Documentation/lockdep*.txt F: Documentation/lockstat.txt @@ -4302,9 +4320,8 @@ F: include/linux/mm.h F: mm/ MEMORY RESOURCE CONTROLLER -M: Johannes Weiner -M: Michal Hocko M: Balbir Singh +M: Daisuke Nishimura M: KAMEZAWA Hiroyuki L: cgroups@vger.kernel.org L: linux-mm@kvack.org @@ -5086,6 +5103,7 @@ M: Peter Zijlstra M: Paul Mackerras M: Ingo Molnar M: Arnaldo Carvalho de Melo +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core S: Supported F: kernel/events/* F: include/linux/perf_event.h @@ -5165,6 +5183,7 @@ F: drivers/scsi/pm8001/ POSIX CLOCKS and TIMERS M: Thomas Gleixner +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core S: Supported F: fs/timerfd.c F: include/linux/timer* @@ -5680,6 +5699,7 @@ F: drivers/dma/dw_dmac.c TIMEKEEPING, NTP M: John Stultz M: Thomas Gleixner +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core S: Supported F: include/linux/clocksource.h F: include/linux/time.h @@ -5704,6 +5724,7 @@ F: drivers/watchdog/sc1200wdt.c SCHEDULER M: Ingo Molnar M: Peter Zijlstra +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched/core S: Maintained F: kernel/sched* F: include/linux/sched.h @@ -6631,7 +6652,7 @@ TRACING M: Steven Rostedt M: Frederic Weisbecker M: Ingo Molnar -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git perf/core +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core S: Maintained F: Documentation/trace/ftrace.txt F: arch/*/*/*/ftrace.h @@ -7381,7 +7402,7 @@ M: Thomas Gleixner M: Ingo Molnar M: "H. Peter Anvin" M: x86@kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core S: Maintained F: Documentation/x86/ F: arch/x86/ diff --git a/trunk/Makefile b/trunk/Makefile index d1ea73f74c2f..12aafc20efbd 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 2 SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc4 NAME = Saber-toothed Squirrel # *DOCUMENTATION* diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 776d76b8cb69..e084b7e981e8 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -220,9 +220,8 @@ config NEED_MACH_MEMORY_H be avoided when possible. config PHYS_OFFSET - hex "Physical address of main memory" if MMU + hex "Physical address of main memory" depends on !ARM_PATCH_PHYS_VIRT && !NEED_MACH_MEMORY_H - default DRAM_BASE if !MMU help Please provide the physical address corresponding to the location of main memory in your system. diff --git a/trunk/arch/arm/configs/omap1_defconfig b/trunk/arch/arm/configs/omap1_defconfig index 945a34f2a34d..a7e777581378 100644 --- a/trunk/arch/arm/configs/omap1_defconfig +++ b/trunk/arch/arm/configs/omap1_defconfig @@ -48,7 +48,12 @@ CONFIG_MACH_SX1=y CONFIG_MACH_NOKIA770=y CONFIG_MACH_AMS_DELTA=y CONFIG_MACH_OMAP_GENERIC=y +CONFIG_OMAP_ARM_216MHZ=y +CONFIG_OMAP_ARM_195MHZ=y +CONFIG_OMAP_ARM_192MHZ=y CONFIG_OMAP_ARM_182MHZ=y +CONFIG_OMAP_ARM_168MHZ=y +# CONFIG_OMAP_ARM_60MHZ is not set # CONFIG_ARM_THUMB is not set CONFIG_PCCARD=y CONFIG_OMAP_CF=y diff --git a/trunk/arch/arm/include/asm/unwind.h b/trunk/arch/arm/include/asm/unwind.h index d1c3f3a71c94..a5edf421005c 100644 --- a/trunk/arch/arm/include/asm/unwind.h +++ b/trunk/arch/arm/include/asm/unwind.h @@ -30,15 +30,14 @@ enum unwind_reason_code { }; struct unwind_idx { - unsigned long addr_offset; + unsigned long addr; unsigned long insn; }; struct unwind_table { struct list_head list; - const struct unwind_idx *start; - const struct unwind_idx *origin; - const struct unwind_idx *stop; + struct unwind_idx *start; + struct unwind_idx *stop; unsigned long begin_addr; unsigned long end_addr; }; @@ -50,6 +49,15 @@ extern struct unwind_table *unwind_table_add(unsigned long start, extern void unwind_table_del(struct unwind_table *tab); extern void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk); +#ifdef CONFIG_ARM_UNWIND +extern int __init unwind_init(void); +#else +static inline int __init unwind_init(void) +{ + return 0; +} +#endif + #endif /* !__ASSEMBLY__ */ #ifdef CONFIG_ARM_UNWIND diff --git a/trunk/arch/arm/kernel/perf_event.c b/trunk/arch/arm/kernel/perf_event.c index 88b0941ce51e..8e9c98edc068 100644 --- a/trunk/arch/arm/kernel/perf_event.c +++ b/trunk/arch/arm/kernel/perf_event.c @@ -640,9 +640,6 @@ static struct platform_device_id armpmu_plat_device_ids[] = { static int __devinit armpmu_device_probe(struct platform_device *pdev) { - if (!cpu_pmu) - return -ENODEV; - cpu_pmu->plat_device = pdev; return 0; } diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index 8fc2c8fcbdc6..3448a3f9cc8c 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -895,6 +895,8 @@ void __init setup_arch(char **cmdline_p) { struct machine_desc *mdesc; + unwind_init(); + setup_processor(); mdesc = setup_machine_fdt(__atags_pointer); if (!mdesc) @@ -902,12 +904,6 @@ void __init setup_arch(char **cmdline_p) machine_desc = mdesc; machine_name = mdesc->name; -#ifdef CONFIG_ZONE_DMA - if (mdesc->dma_zone_size) { - extern unsigned long arm_dma_zone_size; - arm_dma_zone_size = mdesc->dma_zone_size; - } -#endif if (mdesc->soft_reboot) reboot_setup("s"); @@ -938,6 +934,12 @@ void __init setup_arch(char **cmdline_p) tcm_init(); +#ifdef CONFIG_ZONE_DMA + if (mdesc->dma_zone_size) { + extern unsigned long arm_dma_zone_size; + arm_dma_zone_size = mdesc->dma_zone_size; + } +#endif #ifdef CONFIG_MULTI_IRQ_HANDLER handle_arch_irq = mdesc->handle_irq; #endif diff --git a/trunk/arch/arm/kernel/unwind.c b/trunk/arch/arm/kernel/unwind.c index 3f03fe0c3269..e7e8365795c3 100644 --- a/trunk/arch/arm/kernel/unwind.c +++ b/trunk/arch/arm/kernel/unwind.c @@ -67,7 +67,7 @@ EXPORT_SYMBOL(__aeabi_unwind_cpp_pr2); struct unwind_ctrl_block { unsigned long vrs[16]; /* virtual register set */ - const unsigned long *insn; /* pointer to the current instructions word */ + unsigned long *insn; /* pointer to the current instructions word */ int entries; /* number of entries left to interpret */ int byte; /* current byte number in the instructions word */ }; @@ -83,9 +83,8 @@ enum regs { PC = 15 }; -extern const struct unwind_idx __start_unwind_idx[]; -static const struct unwind_idx *__origin_unwind_idx; -extern const struct unwind_idx __stop_unwind_idx[]; +extern struct unwind_idx __start_unwind_idx[]; +extern struct unwind_idx __stop_unwind_idx[]; static DEFINE_SPINLOCK(unwind_lock); static LIST_HEAD(unwind_tables); @@ -99,99 +98,45 @@ static LIST_HEAD(unwind_tables); }) /* - * Binary search in the unwind index. The entries are + * Binary search in the unwind index. The entries entries are * guaranteed to be sorted in ascending order by the linker. - * - * start = first entry - * origin = first entry with positive offset (or stop if there is no such entry) - * stop - 1 = last entry */ -static const struct unwind_idx *search_index(unsigned long addr, - const struct unwind_idx *start, - const struct unwind_idx *origin, - const struct unwind_idx *stop) +static struct unwind_idx *search_index(unsigned long addr, + struct unwind_idx *first, + struct unwind_idx *last) { - unsigned long addr_prel31; - - pr_debug("%s(%08lx, %p, %p, %p)\n", - __func__, addr, start, origin, stop); - - /* - * only search in the section with the matching sign. This way the - * prel31 numbers can be compared as unsigned longs. - */ - if (addr < (unsigned long)start) - /* negative offsets: [start; origin) */ - stop = origin; - else - /* positive offsets: [origin; stop) */ - start = origin; - - /* prel31 for address relavive to start */ - addr_prel31 = (addr - (unsigned long)start) & 0x7fffffff; + pr_debug("%s(%08lx, %p, %p)\n", __func__, addr, first, last); - while (start < stop - 1) { - const struct unwind_idx *mid = start + ((stop - start) >> 1); - - /* - * As addr_prel31 is relative to start an offset is needed to - * make it relative to mid. - */ - if (addr_prel31 - ((unsigned long)mid - (unsigned long)start) < - mid->addr_offset) - stop = mid; - else { - /* keep addr_prel31 relative to start */ - addr_prel31 -= ((unsigned long)mid - - (unsigned long)start); - start = mid; - } - } - - if (likely(start->addr_offset <= addr_prel31)) - return start; - else { + if (addr < first->addr) { pr_warning("unwind: Unknown symbol address %08lx\n", addr); return NULL; - } -} + } else if (addr >= last->addr) + return last; -static const struct unwind_idx *unwind_find_origin( - const struct unwind_idx *start, const struct unwind_idx *stop) -{ - pr_debug("%s(%p, %p)\n", __func__, start, stop); - while (start < stop - 1) { - const struct unwind_idx *mid = start + ((stop - start) >> 1); + while (first < last - 1) { + struct unwind_idx *mid = first + ((last - first + 1) >> 1); - if (mid->addr_offset >= 0x40000000) - /* negative offset */ - start = mid; + if (addr < mid->addr) + last = mid; else - /* positive offset */ - stop = mid; + first = mid; } - pr_debug("%s -> %p\n", __func__, stop); - return stop; + + return first; } -static const struct unwind_idx *unwind_find_idx(unsigned long addr) +static struct unwind_idx *unwind_find_idx(unsigned long addr) { - const struct unwind_idx *idx = NULL; + struct unwind_idx *idx = NULL; unsigned long flags; pr_debug("%s(%08lx)\n", __func__, addr); - if (core_kernel_text(addr)) { - if (unlikely(!__origin_unwind_idx)) - __origin_unwind_idx = - unwind_find_origin(__start_unwind_idx, - __stop_unwind_idx); - + if (core_kernel_text(addr)) /* main unwind table */ idx = search_index(addr, __start_unwind_idx, - __origin_unwind_idx, - __stop_unwind_idx); - } else { + __stop_unwind_idx - 1); + else { /* module unwind tables */ struct unwind_table *table; @@ -200,8 +145,7 @@ static const struct unwind_idx *unwind_find_idx(unsigned long addr) if (addr >= table->begin_addr && addr < table->end_addr) { idx = search_index(addr, table->start, - table->origin, - table->stop); + table->stop - 1); /* Move-to-front to exploit common traces */ list_move(&table->list, &unwind_tables); break; @@ -330,7 +274,7 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl) int unwind_frame(struct stackframe *frame) { unsigned long high, low; - const struct unwind_idx *idx; + struct unwind_idx *idx; struct unwind_ctrl_block ctrl; /* only go to a higher address on the stack */ @@ -455,6 +399,7 @@ struct unwind_table *unwind_table_add(unsigned long start, unsigned long size, unsigned long text_size) { unsigned long flags; + struct unwind_idx *idx; struct unwind_table *tab = kmalloc(sizeof(*tab), GFP_KERNEL); pr_debug("%s(%08lx, %08lx, %08lx, %08lx)\n", __func__, start, size, @@ -463,12 +408,15 @@ struct unwind_table *unwind_table_add(unsigned long start, unsigned long size, if (!tab) return tab; - tab->start = (const struct unwind_idx *)start; - tab->stop = (const struct unwind_idx *)(start + size); - tab->origin = unwind_find_origin(tab->start, tab->stop); + tab->start = (struct unwind_idx *)start; + tab->stop = (struct unwind_idx *)(start + size); tab->begin_addr = text_addr; tab->end_addr = text_addr + text_size; + /* Convert the symbol addresses to absolute values */ + for (idx = tab->start; idx < tab->stop; idx++) + idx->addr = prel31_to_addr(&idx->addr); + spin_lock_irqsave(&unwind_lock, flags); list_add_tail(&tab->list, &unwind_tables); spin_unlock_irqrestore(&unwind_lock, flags); @@ -489,3 +437,16 @@ void unwind_table_del(struct unwind_table *tab) kfree(tab); } + +int __init unwind_init(void) +{ + struct unwind_idx *idx; + + /* Convert the symbol addresses to absolute values */ + for (idx = __start_unwind_idx; idx < __stop_unwind_idx; idx++) + idx->addr = prel31_to_addr(&idx->addr); + + pr_debug("unwind: ARM stack unwinding initialised\n"); + + return 0; +} diff --git a/trunk/arch/arm/mach-at91/at91rm9200_devices.c b/trunk/arch/arm/mach-at91/at91rm9200_devices.c index ad930688358c..66591fa53e05 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200_devices.c +++ b/trunk/arch/arm/mach-at91/at91rm9200_devices.c @@ -83,7 +83,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} * USB Device (Gadget) * -------------------------------------------------------------------- */ -#ifdef CONFIG_USB_AT91 +#ifdef CONFIG_USB_GADGET_AT91 static struct at91_udc_data udc_data; static struct resource udc_resources[] = { diff --git a/trunk/arch/arm/mach-at91/at91sam9260.c b/trunk/arch/arm/mach-at91/at91sam9260.c index 0d20677fbef0..b84a9f642f59 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260.c +++ b/trunk/arch/arm/mach-at91/at91sam9260.c @@ -195,9 +195,9 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), - CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), - CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), + CLKDEV_CON_DEV_ID("t3_clk", "atmel_tcb.1", &tc3_clk), + CLKDEV_CON_DEV_ID("t4_clk", "atmel_tcb.1", &tc4_clk), + CLKDEV_CON_DEV_ID("t5_clk", "atmel_tcb.1", &tc5_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), /* more usart lookup table for DT entries */ CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), diff --git a/trunk/arch/arm/mach-at91/at91sam9260_devices.c b/trunk/arch/arm/mach-at91/at91sam9260_devices.c index 629fa9774972..25e3464fb07f 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9260_devices.c @@ -84,7 +84,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} * USB Device (Gadget) * -------------------------------------------------------------------- */ -#ifdef CONFIG_USB_AT91 +#ifdef CONFIG_USB_GADGET_AT91 static struct at91_udc_data udc_data; static struct resource udc_resources[] = { diff --git a/trunk/arch/arm/mach-at91/at91sam9261_devices.c b/trunk/arch/arm/mach-at91/at91sam9261_devices.c index a178b58b0b9c..ae78f4d03b73 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9261_devices.c @@ -87,7 +87,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} * USB Device (Gadget) * -------------------------------------------------------------------- */ -#ifdef CONFIG_USB_AT91 +#ifdef CONFIG_USB_GADGET_AT91 static struct at91_udc_data udc_data; static struct resource udc_resources[] = { diff --git a/trunk/arch/arm/mach-at91/at91sam9263_devices.c b/trunk/arch/arm/mach-at91/at91sam9263_devices.c index d5fbac9ff4fa..ad017eb1f8df 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9263_devices.c @@ -92,7 +92,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} * USB Device (Gadget) * -------------------------------------------------------------------- */ -#ifdef CONFIG_USB_AT91 +#ifdef CONFIG_USB_GADGET_AT91 static struct at91_udc_data udc_data; static struct resource udc_resources[] = { diff --git a/trunk/arch/arm/mach-at91/include/mach/system_rev.h b/trunk/arch/arm/mach-at91/include/mach/system_rev.h index ec164a4124c9..8f4866045b41 100644 --- a/trunk/arch/arm/mach-at91/include/mach/system_rev.h +++ b/trunk/arch/arm/mach-at91/include/mach/system_rev.h @@ -19,7 +19,7 @@ #define BOARD_HAVE_NAND_16BIT (1 << 31) static inline int board_have_nand_16bit(void) { - return (system_rev & BOARD_HAVE_NAND_16BIT) ? 1 : 0; + return system_rev & BOARD_HAVE_NAND_16BIT; } #endif /* __ARCH_SYSTEM_REV_H__ */ diff --git a/trunk/arch/arm/mach-davinci/board-da850-evm.c b/trunk/arch/arm/mach-davinci/board-da850-evm.c index 6659a90dbcad..1d7d24995226 100644 --- a/trunk/arch/arm/mach-davinci/board-da850-evm.c +++ b/trunk/arch/arm/mach-davinci/board-da850-evm.c @@ -753,7 +753,7 @@ static struct snd_platform_data da850_evm_snd_data = { .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), .tdm_slots = 2, .serial_dir = da850_iis_serializer_direction, - .asp_chan_q = EVENTQ_0, + .asp_chan_q = EVENTQ_1, .version = MCASP_VERSION_2, .txnumevt = 1, .rxnumevt = 1, diff --git a/trunk/arch/arm/mach-davinci/board-dm365-evm.c b/trunk/arch/arm/mach-davinci/board-dm365-evm.c index 46e1f4173b97..1918ae711428 100644 --- a/trunk/arch/arm/mach-davinci/board-dm365-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm365-evm.c @@ -107,7 +107,7 @@ static struct mtd_partition davinci_nand_partitions[] = { /* UBL (a few copies) plus U-Boot */ .name = "bootloader", .offset = 0, - .size = 30 * NAND_BLOCK_SIZE, + .size = 28 * NAND_BLOCK_SIZE, .mask_flags = MTD_WRITEABLE, /* force read-only */ }, { /* U-Boot environment */ diff --git a/trunk/arch/arm/mach-davinci/board-dm646x-evm.c b/trunk/arch/arm/mach-davinci/board-dm646x-evm.c index 635bf7740157..e574d7f837a8 100644 --- a/trunk/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm646x-evm.c @@ -564,7 +564,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) int val; u32 value; - if (!vpif_vidclkctl_reg || !cpld_client) + if (!vpif_vsclkdis_reg || !cpld_client) return -ENXIO; val = i2c_smbus_read_byte(cpld_client); @@ -572,7 +572,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) return val; spin_lock_irqsave(&vpif_reg_lock, flags); - value = __raw_readl(vpif_vidclkctl_reg); + value = __raw_readl(vpif_vsclkdis_reg); if (mux_mode) { val &= VPIF_INPUT_TWO_CHANNEL; value |= VIDCH1CLK; @@ -580,7 +580,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) val |= VPIF_INPUT_ONE_CHANNEL; value &= ~VIDCH1CLK; } - __raw_writel(value, vpif_vidclkctl_reg); + __raw_writel(value, vpif_vsclkdis_reg); spin_unlock_irqrestore(&vpif_reg_lock, flags); err = i2c_smbus_write_byte(cpld_client, val); diff --git a/trunk/arch/arm/mach-davinci/dm646x.c b/trunk/arch/arm/mach-davinci/dm646x.c index af27c130595f..0b68ed534f8e 100644 --- a/trunk/arch/arm/mach-davinci/dm646x.c +++ b/trunk/arch/arm/mach-davinci/dm646x.c @@ -161,6 +161,7 @@ static struct clk dsp_clk = { .name = "dsp", .parent = &pll1_sysclk1, .lpsc = DM646X_LPSC_C64X_CPU, + .flags = PSC_DSP, .usecount = 1, /* REVISIT how to disable? */ }; diff --git a/trunk/arch/arm/mach-davinci/include/mach/psc.h b/trunk/arch/arm/mach-davinci/include/mach/psc.h index 8bc3fc256171..fa59c097223d 100644 --- a/trunk/arch/arm/mach-davinci/include/mach/psc.h +++ b/trunk/arch/arm/mach-davinci/include/mach/psc.h @@ -233,7 +233,7 @@ #define PTCMD 0x120 #define PTSTAT 0x128 #define PDSTAT 0x200 -#define PDCTL 0x300 +#define PDCTL1 0x304 #define MDSTAT 0x800 #define MDCTL 0xA00 @@ -244,10 +244,7 @@ #define PSC_STATE_ENABLE 3 #define MDSTAT_STATE_MASK 0x3f -#define PDSTAT_STATE_MASK 0x1f #define MDCTL_FORCE BIT(31) -#define PDCTL_NEXT BIT(1) -#define PDCTL_EPCGOOD BIT(8) #ifndef __ASSEMBLER__ diff --git a/trunk/arch/arm/mach-davinci/psc.c b/trunk/arch/arm/mach-davinci/psc.c index d7e210f4b55c..1fb6bdff38c1 100644 --- a/trunk/arch/arm/mach-davinci/psc.c +++ b/trunk/arch/arm/mach-davinci/psc.c @@ -52,7 +52,7 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) void davinci_psc_config(unsigned int domain, unsigned int ctlr, unsigned int id, bool enable, u32 flags) { - u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl; + u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl; void __iomem *psc_base; struct davinci_soc_info *soc_info = &davinci_soc_info; u32 next_state = PSC_STATE_ENABLE; @@ -79,11 +79,11 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, mdctl |= MDCTL_FORCE; __raw_writel(mdctl, psc_base + MDCTL + 4 * id); - pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain); - if ((pdstat & PDSTAT_STATE_MASK) == 0) { - pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); - pdctl |= PDCTL_NEXT; - __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); + pdstat = __raw_readl(psc_base + PDSTAT); + if ((pdstat & 0x00000001) == 0) { + pdctl1 = __raw_readl(psc_base + PDCTL1); + pdctl1 |= 0x1; + __raw_writel(pdctl1, psc_base + PDCTL1); ptcmd = 1 << domain; __raw_writel(ptcmd, psc_base + PTCMD); @@ -92,9 +92,9 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, epcpr = __raw_readl(psc_base + EPCPR); } while ((((epcpr >> domain) & 1) == 0)); - pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); - pdctl |= PDCTL_EPCGOOD; - __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); + pdctl1 = __raw_readl(psc_base + PDCTL1); + pdctl1 |= 0x100; + __raw_writel(pdctl1, psc_base + PDCTL1); } else { ptcmd = 1 << domain; __raw_writel(ptcmd, psc_base + PTCMD); diff --git a/trunk/arch/arm/mach-imx/mach-imx6q.c b/trunk/arch/arm/mach-imx/mach-imx6q.c index 8deb012189b5..9cd860a27af5 100644 --- a/trunk/arch/arm/mach-imx/mach-imx6q.c +++ b/trunk/arch/arm/mach-imx/mach-imx6q.c @@ -37,15 +37,14 @@ static void __init imx6q_map_io(void) imx6q_clock_map_io(); } -static int __init imx6q_gpio_add_irq_domain(struct device_node *np, +static void __init imx6q_gpio_add_irq_domain(struct device_node *np, struct device_node *interrupt_parent) { - static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; + static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS - + 32 * 7; /* imx6q gets 7 gpio ports */ - gpio_irq_base -= 32; irq_domain_add_simple(np, gpio_irq_base); - - return 0; + gpio_irq_base += 32; } static const struct of_device_id imx6q_irq_match[] __initconst = { diff --git a/trunk/arch/arm/mach-msm/devices-iommu.c b/trunk/arch/arm/mach-msm/devices-iommu.c index 0fb7a17df398..24030d0da6e3 100644 --- a/trunk/arch/arm/mach-msm/devices-iommu.c +++ b/trunk/arch/arm/mach-msm/devices-iommu.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-mx5/imx51-dt.c b/trunk/arch/arm/mach-mx5/imx51-dt.c index 596edd967dbf..ccc61585659b 100644 --- a/trunk/arch/arm/mach-mx5/imx51-dt.c +++ b/trunk/arch/arm/mach-mx5/imx51-dt.c @@ -44,22 +44,20 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = { { /* sentinel */ } }; -static int __init imx51_tzic_add_irq_domain(struct device_node *np, +static void __init imx51_tzic_add_irq_domain(struct device_node *np, struct device_node *interrupt_parent) { irq_domain_add_simple(np, 0); - return 0; } -static int __init imx51_gpio_add_irq_domain(struct device_node *np, +static void __init imx51_gpio_add_irq_domain(struct device_node *np, struct device_node *interrupt_parent) { - static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; + static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS - + 32 * 4; /* imx51 gets 4 gpio ports */ - gpio_irq_base -= 32; irq_domain_add_simple(np, gpio_irq_base); - - return 0; + gpio_irq_base += 32; } static const struct of_device_id imx51_irq_match[] __initconst = { diff --git a/trunk/arch/arm/mach-mx5/imx53-dt.c b/trunk/arch/arm/mach-mx5/imx53-dt.c index 85bfd5ff21b0..ccaa0b81b768 100644 --- a/trunk/arch/arm/mach-mx5/imx53-dt.c +++ b/trunk/arch/arm/mach-mx5/imx53-dt.c @@ -48,22 +48,20 @@ static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = { { /* sentinel */ } }; -static int __init imx53_tzic_add_irq_domain(struct device_node *np, +static void __init imx53_tzic_add_irq_domain(struct device_node *np, struct device_node *interrupt_parent) { irq_domain_add_simple(np, 0); - return 0; } -static int __init imx53_gpio_add_irq_domain(struct device_node *np, +static void __init imx53_gpio_add_irq_domain(struct device_node *np, struct device_node *interrupt_parent) { - static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; + static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS - + 32 * 7; /* imx53 gets 7 gpio ports */ - gpio_irq_base -= 32; irq_domain_add_simple(np, gpio_irq_base); - - return 0; + gpio_irq_base += 32; } static const struct of_device_id imx53_irq_match[] __initconst = { diff --git a/trunk/arch/arm/mach-mxs/include/mach/mx28.h b/trunk/arch/arm/mach-mxs/include/mach/mx28.h index 30c7990f3c01..75d86118b76a 100644 --- a/trunk/arch/arm/mach-mxs/include/mach/mx28.h +++ b/trunk/arch/arm/mach-mxs/include/mach/mx28.h @@ -104,8 +104,8 @@ #define MX28_INT_CAN1 9 #define MX28_INT_LRADC_TOUCH 10 #define MX28_INT_HSADC 13 -#define MX28_INT_LRADC_THRESH0 14 -#define MX28_INT_LRADC_THRESH1 15 +#define MX28_INT_IRADC_THRESH0 14 +#define MX28_INT_IRADC_THRESH1 15 #define MX28_INT_LRADC_CH0 16 #define MX28_INT_LRADC_CH1 17 #define MX28_INT_LRADC_CH2 18 diff --git a/trunk/arch/arm/mach-mxs/include/mach/mxs.h b/trunk/arch/arm/mach-mxs/include/mach/mxs.h index bde5f6634747..0d2d2b470998 100644 --- a/trunk/arch/arm/mach-mxs/include/mach/mxs.h +++ b/trunk/arch/arm/mach-mxs/include/mach/mxs.h @@ -30,7 +30,6 @@ */ #define cpu_is_mx23() ( \ machine_is_mx23evk() || \ - machine_is_stmp378x() || \ 0) #define cpu_is_mx28() ( \ machine_is_mx28evk() || \ diff --git a/trunk/arch/arm/mach-mxs/mach-m28evk.c b/trunk/arch/arm/mach-mxs/mach-m28evk.c index 6b00577b7025..3b1681e4f49a 100644 --- a/trunk/arch/arm/mach-mxs/mach-m28evk.c +++ b/trunk/arch/arm/mach-mxs/mach-m28evk.c @@ -361,6 +361,6 @@ static struct sys_timer m28evk_timer = { MACHINE_START(M28EVK, "DENX M28 EVK") .map_io = mx28_map_io, .init_irq = mx28_init_irq, - .timer = &m28evk_timer, .init_machine = m28evk_init, + .timer = &m28evk_timer, MACHINE_END diff --git a/trunk/arch/arm/mach-mxs/mach-stmp378x_devb.c b/trunk/arch/arm/mach-mxs/mach-stmp378x_devb.c index 6834dea38c04..177e53123a02 100644 --- a/trunk/arch/arm/mach-mxs/mach-stmp378x_devb.c +++ b/trunk/arch/arm/mach-mxs/mach-stmp378x_devb.c @@ -115,6 +115,6 @@ static struct sys_timer stmp378x_dvb_timer = { MACHINE_START(STMP378X, "STMP378X") .map_io = mx23_map_io, .init_irq = mx23_init_irq, - .timer = &stmp378x_dvb_timer, .init_machine = stmp378x_dvb_init, + .timer = &stmp378x_dvb_timer, MACHINE_END diff --git a/trunk/arch/arm/mach-mxs/module-tx28.c b/trunk/arch/arm/mach-mxs/module-tx28.c index 9a7b08b2a925..0fcff47009cf 100644 --- a/trunk/arch/arm/mach-mxs/module-tx28.c +++ b/trunk/arch/arm/mach-mxs/module-tx28.c @@ -66,11 +66,11 @@ static const iomux_cfg_t tx28_fec1_pads[] __initconst = { MX28_PAD_ENET0_CRS__ENET1_RX_EN, }; -static const struct fec_platform_data tx28_fec0_data __initconst = { +static struct fec_platform_data tx28_fec0_data = { .phy = PHY_INTERFACE_MODE_RMII, }; -static const struct fec_platform_data tx28_fec1_data __initconst = { +static struct fec_platform_data tx28_fec1_data = { .phy = PHY_INTERFACE_MODE_RMII, }; diff --git a/trunk/arch/arm/mach-omap1/clock_data.c b/trunk/arch/arm/mach-omap1/clock_data.c index 9ff90a744a21..1297bb58869c 100644 --- a/trunk/arch/arm/mach-omap1/clock_data.c +++ b/trunk/arch/arm/mach-omap1/clock_data.c @@ -16,8 +16,6 @@ #include #include -#include -#include #include #include /* for machine_is_* */ @@ -929,22 +927,16 @@ int __init omap1_clk_init(void) void __init omap1_clk_late_init(void) { - unsigned long rate = ck_dpll1.rate; - - if (rate >= OMAP1_DPLL1_SANE_VALUE) + if (ck_dpll1.rate >= OMAP1_DPLL1_SANE_VALUE) return; - /* System booting at unusable rate, force reprogramming of DPLL1 */ - ck_dpll1_p->rate = 0; - /* Find the highest supported frequency and enable it */ if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { pr_err("System frequencies not set, using default. Check your config.\n"); omap_writew(0x2290, DPLL_CTL); - omap_writew(cpu_is_omap7xx() ? 0x2005 : 0x0005, ARM_CKCTL); + omap_writew(cpu_is_omap7xx() ? 0x3005 : 0x1005, ARM_CKCTL); ck_dpll1.rate = OMAP1_DPLL1_SANE_VALUE; } propagate_rate(&ck_dpll1); omap1_show_rates(); - loops_per_jiffy = cpufreq_scale(loops_per_jiffy, rate, ck_dpll1.rate); } diff --git a/trunk/arch/arm/mach-prima2/pm.c b/trunk/arch/arm/mach-prima2/pm.c index 26ebb57719df..cb53160f6c5d 100644 --- a/trunk/arch/arm/mach-prima2/pm.c +++ b/trunk/arch/arm/mach-prima2/pm.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-prima2/prima2.c b/trunk/arch/arm/mach-prima2/prima2.c index a12b689a8702..ef555c041962 100644 --- a/trunk/arch/arm/mach-prima2/prima2.c +++ b/trunk/arch/arm/mach-prima2/prima2.c @@ -8,7 +8,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-s3c64xx/dev-spi.c b/trunk/arch/arm/mach-s3c64xx/dev-spi.c index 3341fd118723..5e6b42089eb4 100644 --- a/trunk/arch/arm/mach-s3c64xx/dev-spi.c +++ b/trunk/arch/arm/mach-s3c64xx/dev-spi.c @@ -10,7 +10,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-s3c64xx/s3c6400.c b/trunk/arch/arm/mach-s3c64xx/s3c6400.c index 51c00f2453c6..7a3bc32df425 100644 --- a/trunk/arch/arm/mach-s3c64xx/s3c6400.c +++ b/trunk/arch/arm/mach-s3c64xx/s3c6400.c @@ -70,7 +70,7 @@ void __init s3c6400_init_irq(void) s3c64xx_init_irq(~0 & ~(0xf << 5), ~0); } -static struct sysdev_class s3c6400_sysclass = { +struct sysdev_class s3c6400_sysclass = { .name = "s3c6400-core", }; diff --git a/trunk/arch/arm/mach-s3c64xx/setup-fb-24bpp.c b/trunk/arch/arm/mach-s3c64xx/setup-fb-24bpp.c index 2cf80026c58d..83d2afb79e9f 100644 --- a/trunk/arch/arm/mach-s3c64xx/setup-fb-24bpp.c +++ b/trunk/arch/arm/mach-s3c64xx/setup-fb-24bpp.c @@ -20,7 +20,7 @@ #include #include -void s3c64xx_fb_gpio_setup_24bpp(void) +extern void s3c64xx_fb_gpio_setup_24bpp(void) { s3c_gpio_cfgrange_nopull(S3C64XX_GPI(0), 16, S3C_GPIO_SFN(2)); s3c_gpio_cfgrange_nopull(S3C64XX_GPJ(0), 12, S3C_GPIO_SFN(2)); diff --git a/trunk/arch/arm/mach-sa1100/Makefile.boot b/trunk/arch/arm/mach-sa1100/Makefile.boot index f7951aa04562..5a616f6e5612 100644 --- a/trunk/arch/arm/mach-sa1100/Makefile.boot +++ b/trunk/arch/arm/mach-sa1100/Makefile.boot @@ -1,5 +1,5 @@ -ifeq ($(CONFIG_SA1111),y) - zreladdr-y += 0xc0208000 +ifeq ($(CONFIG_ARCH_SA1100),y) + zreladdr-$(CONFIG_SA1111) += 0xc0208000 else zreladdr-y += 0xc0008000 endif diff --git a/trunk/arch/m68k/include/asm/unistd.h b/trunk/arch/m68k/include/asm/unistd.h index 303192fc9260..43f984e93970 100644 --- a/trunk/arch/m68k/include/asm/unistd.h +++ b/trunk/arch/m68k/include/asm/unistd.h @@ -350,12 +350,10 @@ #define __NR_clock_adjtime 342 #define __NR_syncfs 343 #define __NR_setns 344 -#define __NR_process_vm_readv 345 -#define __NR_process_vm_writev 346 #ifdef __KERNEL__ -#define NR_syscalls 347 +#define NR_syscalls 345 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/arch/m68k/kernel/syscalltable.S b/trunk/arch/m68k/kernel/syscalltable.S index ce827b376110..c468f2edaa85 100644 --- a/trunk/arch/m68k/kernel/syscalltable.S +++ b/trunk/arch/m68k/kernel/syscalltable.S @@ -365,6 +365,4 @@ ENTRY(sys_call_table) .long sys_clock_adjtime .long sys_syncfs .long sys_setns - .long sys_process_vm_readv /* 345 */ - .long sys_process_vm_writev diff --git a/trunk/arch/tile/include/asm/irq.h b/trunk/arch/tile/include/asm/irq.h index f80f8ceabc67..94e9a511de84 100644 --- a/trunk/arch/tile/include/asm/irq.h +++ b/trunk/arch/tile/include/asm/irq.h @@ -74,6 +74,16 @@ enum { */ void tile_irq_activate(unsigned int irq, int tile_irq_type); +/* + * For onboard, non-PCI (e.g. TILE_IRQ_PERCPU) devices, drivers know + * how to use enable/disable_percpu_irq() to manage interrupts on each + * core. We can't use the generic enable/disable_irq() because they + * use a single reference count per irq, rather than per cpu per irq. + */ +void enable_percpu_irq(unsigned int irq); +void disable_percpu_irq(unsigned int irq); + + void setup_irq_regs(void); #endif /* _ASM_TILE_IRQ_H */ diff --git a/trunk/arch/tile/kernel/irq.c b/trunk/arch/tile/kernel/irq.c index 02e628065012..aa0134db2dd6 100644 --- a/trunk/arch/tile/kernel/irq.c +++ b/trunk/arch/tile/kernel/irq.c @@ -152,13 +152,14 @@ void tile_dev_intr(struct pt_regs *regs, int intnum) * Remove an irq from the disabled mask. If we're in an interrupt * context, defer enabling the HW interrupt until we leave. */ -static void tile_irq_chip_enable(struct irq_data *d) +void enable_percpu_irq(unsigned int irq) { - get_cpu_var(irq_disable_mask) &= ~(1UL << d->irq); + get_cpu_var(irq_disable_mask) &= ~(1UL << irq); if (__get_cpu_var(irq_depth) == 0) - unmask_irqs(1UL << d->irq); + unmask_irqs(1UL << irq); put_cpu_var(irq_disable_mask); } +EXPORT_SYMBOL(enable_percpu_irq); /* * Add an irq to the disabled mask. We disable the HW interrupt @@ -166,12 +167,13 @@ static void tile_irq_chip_enable(struct irq_data *d) * in an interrupt context, the return path is careful to avoid * unmasking a newly disabled interrupt. */ -static void tile_irq_chip_disable(struct irq_data *d) +void disable_percpu_irq(unsigned int irq) { - get_cpu_var(irq_disable_mask) |= (1UL << d->irq); - mask_irqs(1UL << d->irq); + get_cpu_var(irq_disable_mask) |= (1UL << irq); + mask_irqs(1UL << irq); put_cpu_var(irq_disable_mask); } +EXPORT_SYMBOL(disable_percpu_irq); /* Mask an interrupt. */ static void tile_irq_chip_mask(struct irq_data *d) @@ -207,8 +209,6 @@ static void tile_irq_chip_eoi(struct irq_data *d) static struct irq_chip tile_irq_chip = { .name = "tile_irq_chip", - .irq_enable = tile_irq_chip_enable, - .irq_disable = tile_irq_chip_disable, .irq_ack = tile_irq_chip_ack, .irq_eoi = tile_irq_chip_eoi, .irq_mask = tile_irq_chip_mask, diff --git a/trunk/arch/tile/kernel/pci-dma.c b/trunk/arch/tile/kernel/pci-dma.c index b3ed19f8779c..658f2ce426a4 100644 --- a/trunk/arch/tile/kernel/pci-dma.c +++ b/trunk/arch/tile/kernel/pci-dma.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/tile/kernel/pci.c b/trunk/arch/tile/kernel/pci.c index 9d610d3fb11e..2a8014cb1ff5 100644 --- a/trunk/arch/tile/kernel/pci.c +++ b/trunk/arch/tile/kernel/pci.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/tile/kernel/sysfs.c b/trunk/arch/tile/kernel/sysfs.c index 602908268093..b671a86f4515 100644 --- a/trunk/arch/tile/kernel/sysfs.c +++ b/trunk/arch/tile/kernel/sysfs.c @@ -18,7 +18,6 @@ #include #include #include -#include #include /* Return a string queried from the hypervisor, truncated to page size. */ diff --git a/trunk/arch/tile/lib/exports.c b/trunk/arch/tile/lib/exports.c index 2a81d32de0da..a87d2a859ba9 100644 --- a/trunk/arch/tile/lib/exports.c +++ b/trunk/arch/tile/lib/exports.c @@ -39,9 +39,6 @@ EXPORT_SYMBOL(finv_user_asm); EXPORT_SYMBOL(current_text_addr); EXPORT_SYMBOL(dump_stack); -/* arch/tile/kernel/head.S */ -EXPORT_SYMBOL(empty_zero_page); - /* arch/tile/lib/, various memcpy files */ EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(__copy_to_user_inatomic); diff --git a/trunk/arch/tile/mm/homecache.c b/trunk/arch/tile/mm/homecache.c index 1cc6ae477c98..cbe6f4f9eca3 100644 --- a/trunk/arch/tile/mm/homecache.c +++ b/trunk/arch/tile/mm/homecache.c @@ -449,12 +449,9 @@ void homecache_free_pages(unsigned long addr, unsigned int order) VM_BUG_ON(!virt_addr_valid((void *)addr)); page = virt_to_page((void *)addr); if (put_page_testzero(page)) { + int pages = (1 << order); homecache_change_page_home(page, order, initial_page_home()); - if (order == 0) { - free_hot_cold_page(page, 0); - } else { - init_page_count(page); - __free_pages(page, order); - } + while (pages--) + __free_page(page++); } } diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index efb42949cc09..cb9a1044a771 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -390,7 +390,7 @@ config X86_INTEL_CE This option compiles in support for the CE4100 SOC for settop boxes and media devices. -config X86_WANT_INTEL_MID +config X86_INTEL_MID bool "Intel MID platform support" depends on X86_32 depends on X86_EXTENDED_PLATFORM @@ -399,10 +399,7 @@ config X86_WANT_INTEL_MID systems which do not have the PCI legacy interfaces (Moorestown, Medfield). If you are building for a PC class system say N here. -if X86_WANT_INTEL_MID - -config X86_INTEL_MID - bool +if X86_INTEL_MID config X86_MRST bool "Moorestown MID platform" @@ -414,7 +411,6 @@ config X86_MRST select SPI select INTEL_SCU_IPC select X86_PLATFORM_DEVICES - select X86_INTEL_MID ---help--- Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin Internet Device(MID) platform. Moorestown consists of two chips: diff --git a/trunk/arch/x86/kernel/hpet.c b/trunk/arch/x86/kernel/hpet.c index 1bb0bf4d92cd..b946a9eac7d9 100644 --- a/trunk/arch/x86/kernel/hpet.c +++ b/trunk/arch/x86/kernel/hpet.c @@ -1049,14 +1049,6 @@ int hpet_rtc_timer_init(void) } EXPORT_SYMBOL_GPL(hpet_rtc_timer_init); -static void hpet_disable_rtc_channel(void) -{ - unsigned long cfg; - cfg = hpet_readl(HPET_T1_CFG); - cfg &= ~HPET_TN_ENABLE; - hpet_writel(cfg, HPET_T1_CFG); -} - /* * The functions below are called from rtc driver. * Return 0 if HPET is not being used. @@ -1068,9 +1060,6 @@ int hpet_mask_rtc_irq_bit(unsigned long bit_mask) return 0; hpet_rtc_flags &= ~bit_mask; - if (unlikely(!hpet_rtc_flags)) - hpet_disable_rtc_channel(); - return 1; } EXPORT_SYMBOL_GPL(hpet_mask_rtc_irq_bit); @@ -1136,11 +1125,15 @@ EXPORT_SYMBOL_GPL(hpet_rtc_dropped_irq); static void hpet_rtc_timer_reinit(void) { - unsigned int delta; + unsigned int cfg, delta; int lost_ints = -1; - if (unlikely(!hpet_rtc_flags)) - hpet_disable_rtc_channel(); + if (unlikely(!hpet_rtc_flags)) { + cfg = hpet_readl(HPET_T1_CFG); + cfg &= ~HPET_TN_ENABLE; + hpet_writel(cfg, HPET_T1_CFG); + return; + } if (!(hpet_rtc_flags & RTC_PIE) || hpet_pie_limit) delta = hpet_default_delta; diff --git a/trunk/arch/x86/mm/gup.c b/trunk/arch/x86/mm/gup.c index dd74e46828c0..ea305856151c 100644 --- a/trunk/arch/x86/mm/gup.c +++ b/trunk/arch/x86/mm/gup.c @@ -201,8 +201,6 @@ static noinline int gup_huge_pud(pud_t pud, unsigned long addr, do { VM_BUG_ON(compound_head(page) != head); pages[*nr] = page; - if (PageTail(page)) - get_huge_page_tail(page); (*nr)++; page++; refs++; diff --git a/trunk/arch/x86/platform/efi/efi_32.c b/trunk/arch/x86/platform/efi/efi_32.c index 40e446941dd7..e36bf714cb77 100644 --- a/trunk/arch/x86/platform/efi/efi_32.c +++ b/trunk/arch/x86/platform/efi/efi_32.c @@ -39,14 +39,43 @@ */ static unsigned long efi_rt_eflags; +static pgd_t efi_bak_pg_dir_pointer[2]; void efi_call_phys_prelog(void) { + unsigned long cr4; + unsigned long temp; struct desc_ptr gdt_descr; local_irq_save(efi_rt_eflags); - load_cr3(initial_page_table); + /* + * If I don't have PAE, I should just duplicate two entries in page + * directory. If I have PAE, I just need to duplicate one entry in + * page directory. + */ + cr4 = read_cr4_safe(); + + if (cr4 & X86_CR4_PAE) { + efi_bak_pg_dir_pointer[0].pgd = + swapper_pg_dir[pgd_index(0)].pgd; + swapper_pg_dir[0].pgd = + swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd; + } else { + efi_bak_pg_dir_pointer[0].pgd = + swapper_pg_dir[pgd_index(0)].pgd; + efi_bak_pg_dir_pointer[1].pgd = + swapper_pg_dir[pgd_index(0x400000)].pgd; + swapper_pg_dir[pgd_index(0)].pgd = + swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd; + temp = PAGE_OFFSET + 0x400000; + swapper_pg_dir[pgd_index(0x400000)].pgd = + swapper_pg_dir[pgd_index(temp)].pgd; + } + + /* + * After the lock is released, the original page table is restored. + */ __flush_tlb_all(); gdt_descr.address = __pa(get_cpu_gdt_table(0)); @@ -56,13 +85,28 @@ void efi_call_phys_prelog(void) void efi_call_phys_epilog(void) { + unsigned long cr4; struct desc_ptr gdt_descr; gdt_descr.address = (unsigned long)get_cpu_gdt_table(0); gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); - load_cr3(swapper_pg_dir); + cr4 = read_cr4_safe(); + + if (cr4 & X86_CR4_PAE) { + swapper_pg_dir[pgd_index(0)].pgd = + efi_bak_pg_dir_pointer[0].pgd; + } else { + swapper_pg_dir[pgd_index(0)].pgd = + efi_bak_pg_dir_pointer[0].pgd; + swapper_pg_dir[pgd_index(0x400000)].pgd = + efi_bak_pg_dir_pointer[1].pgd; + } + + /* + * After the lock is released, the original page table is restored. + */ __flush_tlb_all(); local_irq_restore(efi_rt_eflags); diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index 919daa7cd5b1..d8b3d89db043 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -1743,10 +1743,8 @@ void device_shutdown(void) */ list_del_init(&dev->kobj.entry); spin_unlock(&devices_kset->list_lock); - - /* Don't allow any more runtime suspends */ - pm_runtime_get_noresume(dev); - pm_runtime_barrier(dev); + /* Disable all device's runtime power management */ + pm_runtime_disable(dev); if (dev->bus && dev->bus->shutdown) { dev_dbg(dev, "shutdown\n"); diff --git a/trunk/drivers/block/rbd.c b/trunk/drivers/block/rbd.c index 148ab944378d..65cc424359b0 100644 --- a/trunk/drivers/block/rbd.c +++ b/trunk/drivers/block/rbd.c @@ -183,6 +183,10 @@ static LIST_HEAD(rbd_client_list); /* clients */ static int __rbd_init_snaps_header(struct rbd_device *rbd_dev); static void rbd_dev_release(struct device *dev); +static ssize_t rbd_snap_rollback(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size); static ssize_t rbd_snap_add(struct device *dev, struct device_attribute *attr, const char *buf, @@ -457,10 +461,6 @@ static int rbd_header_from_disk(struct rbd_image_header *header, u32 snap_count = le32_to_cpu(ondisk->snap_count); int ret = -ENOMEM; - if (memcmp(ondisk, RBD_HEADER_TEXT, sizeof(RBD_HEADER_TEXT))) { - return -ENXIO; - } - init_rwsem(&header->snap_rwsem); header->snap_names_len = le64_to_cpu(ondisk->snap_names_len); header->snapc = kmalloc(sizeof(struct ceph_snap_context) + @@ -1355,6 +1355,32 @@ static int rbd_req_sync_notify(struct rbd_device *dev, return ret; } +/* + * Request sync osd rollback + */ +static int rbd_req_sync_rollback_obj(struct rbd_device *dev, + u64 snapid, + const char *obj) +{ + struct ceph_osd_req_op *ops; + int ret = rbd_create_rw_ops(&ops, 1, CEPH_OSD_OP_ROLLBACK, 0); + if (ret < 0) + return ret; + + ops[0].snap.snapid = snapid; + + ret = rbd_req_sync_op(dev, NULL, + CEPH_NOSNAP, + 0, + CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, + ops, + 1, obj, 0, 0, NULL, NULL, NULL); + + rbd_destroy_ops(ops); + + return ret; +} + /* * Request sync osd read */ @@ -1584,13 +1610,8 @@ static int rbd_read_header(struct rbd_device *rbd_dev, goto out_dh; rc = rbd_header_from_disk(header, dh, snap_count, GFP_KERNEL); - if (rc < 0) { - if (rc == -ENXIO) { - pr_warning("unrecognized header format" - " for image %s", rbd_dev->obj); - } + if (rc < 0) goto out_dh; - } if (snap_count != header->total_snaps) { snap_count = header->total_snaps; @@ -1861,6 +1882,7 @@ static DEVICE_ATTR(name, S_IRUGO, rbd_name_show, NULL); static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh); static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL); static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add); +static DEVICE_ATTR(rollback_snap, S_IWUSR, NULL, rbd_snap_rollback); static struct attribute *rbd_attrs[] = { &dev_attr_size.attr, @@ -1871,6 +1893,7 @@ static struct attribute *rbd_attrs[] = { &dev_attr_current_snap.attr, &dev_attr_refresh.attr, &dev_attr_create_snap.attr, + &dev_attr_rollback_snap.attr, NULL }; @@ -2401,6 +2424,64 @@ static ssize_t rbd_snap_add(struct device *dev, return ret; } +static ssize_t rbd_snap_rollback(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct rbd_device *rbd_dev = dev_to_rbd(dev); + int ret; + u64 snapid; + u64 cur_ofs; + char *seg_name = NULL; + char *snap_name = kmalloc(count + 1, GFP_KERNEL); + ret = -ENOMEM; + if (!snap_name) + return ret; + + /* parse snaps add command */ + snprintf(snap_name, count, "%s", buf); + seg_name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO); + if (!seg_name) + goto done; + + mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); + + ret = snap_by_name(&rbd_dev->header, snap_name, &snapid, NULL); + if (ret < 0) + goto done_unlock; + + dout("snapid=%lld\n", snapid); + + cur_ofs = 0; + while (cur_ofs < rbd_dev->header.image_size) { + cur_ofs += rbd_get_segment(&rbd_dev->header, + rbd_dev->obj, + cur_ofs, (u64)-1, + seg_name, NULL); + dout("seg_name=%s\n", seg_name); + + ret = rbd_req_sync_rollback_obj(rbd_dev, snapid, seg_name); + if (ret < 0) + pr_warning("could not roll back obj %s err=%d\n", + seg_name, ret); + } + + ret = __rbd_update_snaps(rbd_dev); + if (ret < 0) + goto done_unlock; + + ret = count; + +done_unlock: + mutex_unlock(&ctl_mutex); +done: + kfree(seg_name); + kfree(snap_name); + + return ret; +} + static struct bus_attribute rbd_bus_attrs[] = { __ATTR(add, S_IWUSR, NULL, rbd_add), __ATTR(remove, S_IWUSR, NULL, rbd_remove), diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 60ff1b63b568..8359dc777041 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -2026,13 +2026,8 @@ i915_wait_request(struct intel_ring_buffer *ring, * to handle this, the waiter on a request often wants an associated * buffer to have made it to the inactive list, and we would need * a separate wait queue to handle that. - * - * To avoid a recursion with the ilk VT-d workaround (that calls - * gpu_idle when unbinding objects with interruptible==false) don't - * retire requests in that case (because it might call unbind if the - * active list holds the last reference to the object). */ - if (ret == 0 && dev_priv->mm.interruptible) + if (ret == 0) i915_gem_retire_requests_ring(ring); return ret; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c index 4b27efa4405b..06e413e6a920 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c @@ -233,12 +233,13 @@ u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder) switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_TRAVIS: case ENCODER_OBJECT_ID_NUTMEG: - return radeon_encoder->encoder_id; + return true; default: - return ENCODER_OBJECT_ID_NONE; + return false; } } - return ENCODER_OBJECT_ID_NONE; + + return false; } void radeon_panel_mode_fixup(struct drm_encoder *encoder, diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 5ff561d4e0b4..3f6343502d1f 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -140,7 +140,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data, goto out_clips; } - clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); + clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); if (clips == NULL) { DRM_ERROR("Failed to allocate clip rect list.\n"); ret = -ENOMEM; @@ -232,7 +232,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data, goto out_clips; } - clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); + clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); if (clips == NULL) { DRM_ERROR("Failed to allocate clip rect list.\n"); ret = -ENOMEM; diff --git a/trunk/drivers/hwmon/jz4740-hwmon.c b/trunk/drivers/hwmon/jz4740-hwmon.c index 5253d23361d9..7a48b1eb4233 100644 --- a/trunk/drivers/hwmon/jz4740-hwmon.c +++ b/trunk/drivers/hwmon/jz4740-hwmon.c @@ -59,7 +59,7 @@ static ssize_t jz4740_hwmon_read_adcin(struct device *dev, { struct jz4740_hwmon *hwmon = dev_get_drvdata(dev); struct completion *completion = &hwmon->read_completion; - long t; + unsigned long t; unsigned long val; int ret; @@ -203,7 +203,7 @@ static int __devexit jz4740_hwmon_remove(struct platform_device *pdev) return 0; } -static struct platform_driver jz4740_hwmon_driver = { +struct platform_driver jz4740_hwmon_driver = { .probe = jz4740_hwmon_probe, .remove = __devexit_p(jz4740_hwmon_remove), .driver = { diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index b6907118283a..7878712721bf 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -1106,12 +1106,10 @@ void bitmap_write_all(struct bitmap *bitmap) */ int i; - spin_lock_irq(&bitmap->lock); for (i = 0; i < bitmap->file_pages; i++) set_page_attr(bitmap, bitmap->filemap[i], BITMAP_PAGE_NEEDWRITE); bitmap->allclean = 0; - spin_unlock_irq(&bitmap->lock); } static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc) @@ -1607,9 +1605,7 @@ void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e) for (chunk = s; chunk <= e; chunk++) { sector_t sec = (sector_t)chunk << CHUNK_BLOCK_SHIFT(bitmap); bitmap_set_memory_bits(bitmap, sec, 1); - spin_lock_irq(&bitmap->lock); bitmap_file_set_bit(bitmap, sec); - spin_unlock_irq(&bitmap->lock); if (sec < bitmap->mddev->recovery_cp) /* We are asserting that the array is dirty, * so move the recovery_cp address back so diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index ee981737edfc..84acfe7d10e4 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -570,7 +570,7 @@ static void mddev_put(struct mddev *mddev) mddev->ctime == 0 && !mddev->hold_active) { /* Array is not configured at all, and not held active, * so destroy it */ - list_del_init(&mddev->all_mddevs); + list_del(&mddev->all_mddevs); bs = mddev->bio_set; mddev->bio_set = NULL; if (mddev->gendisk) { @@ -2546,8 +2546,7 @@ state_show(struct md_rdev *rdev, char *page) sep = ","; } if (test_bit(Blocked, &rdev->flags) || - (rdev->badblocks.unacked_exist - && !test_bit(Faulty, &rdev->flags))) { + rdev->badblocks.unacked_exist) { len += sprintf(page+len, "%sblocked", sep); sep = ","; } @@ -3789,8 +3788,6 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) if (err) return err; else { - if (mddev->hold_active == UNTIL_IOCTL) - mddev->hold_active = 0; sysfs_notify_dirent_safe(mddev->sysfs_state); return len; } @@ -4490,20 +4487,11 @@ md_attr_show(struct kobject *kobj, struct attribute *attr, char *page) if (!entry->show) return -EIO; - spin_lock(&all_mddevs_lock); - if (list_empty(&mddev->all_mddevs)) { - spin_unlock(&all_mddevs_lock); - return -EBUSY; - } - mddev_get(mddev); - spin_unlock(&all_mddevs_lock); - rv = mddev_lock(mddev); if (!rv) { rv = entry->show(mddev, page); mddev_unlock(mddev); } - mddev_put(mddev); return rv; } @@ -4519,19 +4507,13 @@ md_attr_store(struct kobject *kobj, struct attribute *attr, return -EIO; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - spin_lock(&all_mddevs_lock); - if (list_empty(&mddev->all_mddevs)) { - spin_unlock(&all_mddevs_lock); - return -EBUSY; - } - mddev_get(mddev); - spin_unlock(&all_mddevs_lock); rv = mddev_lock(mddev); + if (mddev->hold_active == UNTIL_IOCTL) + mddev->hold_active = 0; if (!rv) { rv = entry->store(mddev, page, length); mddev_unlock(mddev); } - mddev_put(mddev); return rv; } @@ -7858,7 +7840,6 @@ int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors, s + rdev->data_offset, sectors, acknowledged); if (rv) { /* Make sure they get written out promptly */ - sysfs_notify_dirent_safe(rdev->sysfs_state); set_bit(MD_CHANGE_CLEAN, &rdev->mddev->flags); md_wakeup_thread(rdev->mddev->thread); } diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index 31670f8d6b65..297e26092178 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -3036,8 +3036,6 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) if (dev->written) s->written++; rdev = rcu_dereference(conf->disks[i].rdev); - if (rdev && test_bit(Faulty, &rdev->flags)) - rdev = NULL; if (rdev) { is_bad = is_badblock(rdev, sh->sector, STRIPE_SECTORS, &first_bad, &bad_sectors); @@ -3065,12 +3063,12 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) } } else if (test_bit(In_sync, &rdev->flags)) set_bit(R5_Insync, &dev->flags); - else { + else if (!test_bit(Faulty, &rdev->flags)) { /* in sync if before recovery_offset */ if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) set_bit(R5_Insync, &dev->flags); } - if (rdev && test_bit(R5_WriteError, &dev->flags)) { + if (test_bit(R5_WriteError, &dev->flags)) { clear_bit(R5_Insync, &dev->flags); if (!test_bit(Faulty, &rdev->flags)) { s->handle_bad_blocks = 1; @@ -3078,7 +3076,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) } else clear_bit(R5_WriteError, &dev->flags); } - if (rdev && test_bit(R5_MadeGood, &dev->flags)) { + if (test_bit(R5_MadeGood, &dev->flags)) { if (!test_bit(Faulty, &rdev->flags)) { s->handle_bad_blocks = 1; atomic_inc(&rdev->nr_pending); diff --git a/trunk/drivers/mmc/card/block.c b/trunk/drivers/mmc/card/block.c index 1e0e27cbe987..a1cb21f95302 100644 --- a/trunk/drivers/mmc/card/block.c +++ b/trunk/drivers/mmc/card/block.c @@ -1606,14 +1606,6 @@ static const struct mmc_fixup blk_fixups[] = MMC_QUIRK_BLK_NO_CMD23), MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc, MMC_QUIRK_BLK_NO_CMD23), - - /* - * Some Micron MMC cards needs longer data read timeout than - * indicated in CSD. - */ - MMC_FIXUP(CID_NAME_ANY, 0x13, 0x200, add_quirk_mmc, - MMC_QUIRK_LONG_READ_TIME), - END_FIXUP }; diff --git a/trunk/drivers/mmc/core/core.c b/trunk/drivers/mmc/core/core.c index 950b97d7412a..5278ffb20e74 100644 --- a/trunk/drivers/mmc/core/core.c +++ b/trunk/drivers/mmc/core/core.c @@ -529,18 +529,6 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) data->timeout_clks = 0; } } - - /* - * Some cards require longer data read timeout than indicated in CSD. - * Address this by setting the read timeout to a "reasonably high" - * value. For the cards tested, 300ms has proven enough. If necessary, - * this value can be increased if other problematic cards require this. - */ - if (mmc_card_long_read_time(card) && data->flags & MMC_DATA_READ) { - data->timeout_ns = 300000000; - data->timeout_clks = 0; - } - /* * Some cards need very high timeouts if driven in SPI mode. * The worst observed timeout was 900ms after writing a @@ -1225,46 +1213,6 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type) mmc_host_clk_release(host); } -static void mmc_poweroff_notify(struct mmc_host *host) -{ - struct mmc_card *card; - unsigned int timeout; - unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION; - int err = 0; - - card = host->card; - - /* - * Send power notify command only if card - * is mmc and notify state is powered ON - */ - if (card && mmc_card_mmc(card) && - (card->poweroff_notify_state == MMC_POWERED_ON)) { - - if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) { - notify_type = EXT_CSD_POWER_OFF_SHORT; - timeout = card->ext_csd.generic_cmd6_time; - card->poweroff_notify_state = MMC_POWEROFF_SHORT; - } else { - notify_type = EXT_CSD_POWER_OFF_LONG; - timeout = card->ext_csd.power_off_longtime; - card->poweroff_notify_state = MMC_POWEROFF_LONG; - } - - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_POWER_OFF_NOTIFICATION, - notify_type, timeout); - - if (err && err != -EBADMSG) - pr_err("Device failed to respond within %d poweroff " - "time. Forcefully powering down the device\n", - timeout); - - /* Set the card state to no notification after the poweroff */ - card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION; - } -} - /* * Apply power to the MMC stack. This is a two-stage process. * First, we enable power to the card without the clock running. @@ -1321,12 +1269,42 @@ static void mmc_power_up(struct mmc_host *host) void mmc_power_off(struct mmc_host *host) { + struct mmc_card *card; + unsigned int notify_type; + unsigned int timeout; + int err; + mmc_host_clk_hold(host); + card = host->card; host->ios.clock = 0; host->ios.vdd = 0; - mmc_poweroff_notify(host); + if (card && mmc_card_mmc(card) && + (card->poweroff_notify_state == MMC_POWERED_ON)) { + + if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) { + notify_type = EXT_CSD_POWER_OFF_SHORT; + timeout = card->ext_csd.generic_cmd6_time; + card->poweroff_notify_state = MMC_POWEROFF_SHORT; + } else { + notify_type = EXT_CSD_POWER_OFF_LONG; + timeout = card->ext_csd.power_off_longtime; + card->poweroff_notify_state = MMC_POWEROFF_LONG; + } + + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_POWER_OFF_NOTIFICATION, + notify_type, timeout); + + if (err && err != -EBADMSG) + pr_err("Device failed to respond within %d poweroff " + "time. Forcefully powering down the device\n", + timeout); + + /* Set the card state to no notification after the poweroff */ + card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION; + } /* * Reset ocr mask to be the highest possible voltage supported for @@ -2218,7 +2196,7 @@ int mmc_card_sleep(struct mmc_host *host) mmc_bus_get(host); - if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep) + if (host->bus_ops && !host->bus_dead && host->bus_ops->awake) err = host->bus_ops->sleep(host); mmc_bus_put(host); @@ -2324,17 +2302,8 @@ int mmc_suspend_host(struct mmc_host *host) * pre-claim the host. */ if (mmc_try_claim_host(host)) { - if (host->bus_ops->suspend) { - /* - * For eMMC 4.5 device send notify command - * before sleep, because in sleep state eMMC 4.5 - * devices respond to only RESET and AWAKE cmd - */ - mmc_poweroff_notify(host); + if (host->bus_ops->suspend) err = host->bus_ops->suspend(host); - } - mmc_do_release_host(host); - if (err == -ENOSYS || !host->bus_ops->resume) { /* * We simply "remove" the card in this case. @@ -2349,6 +2318,7 @@ int mmc_suspend_host(struct mmc_host *host) host->pm_flags = 0; err = 0; } + mmc_do_release_host(host); } else { err = -EBUSY; } diff --git a/trunk/drivers/mmc/core/mmc.c b/trunk/drivers/mmc/core/mmc.c index d240427c1246..dbf421a6279c 100644 --- a/trunk/drivers/mmc/core/mmc.c +++ b/trunk/drivers/mmc/core/mmc.c @@ -876,22 +876,18 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * set the notification byte in the ext_csd register of device */ if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) && - (card->ext_csd.rev >= 6)) { + (card->poweroff_notify_state == MMC_NO_POWER_NOTIFICATION)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_POWER_OFF_NOTIFICATION, EXT_CSD_POWER_ON, card->ext_csd.generic_cmd6_time); if (err && err != -EBADMSG) goto free_card; - - /* - * The err can be -EBADMSG or 0, - * so check for success and update the flag - */ - if (!err) - card->poweroff_notify_state = MMC_POWERED_ON; } + if (!err) + card->poweroff_notify_state = MMC_POWERED_ON; + /* * Activate high speed (if supported) */ diff --git a/trunk/drivers/mmc/host/mxcmmc.c b/trunk/drivers/mmc/host/mxcmmc.c index 8e0fbe994047..325ea61e12d3 100644 --- a/trunk/drivers/mmc/host/mxcmmc.c +++ b/trunk/drivers/mmc/host/mxcmmc.c @@ -732,7 +732,6 @@ static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) "failed to config DMA channel. Falling back to PIO\n"); dma_release_channel(host->dma); host->do_dma = 0; - host->dma = NULL; } } diff --git a/trunk/drivers/mmc/host/omap_hsmmc.c b/trunk/drivers/mmc/host/omap_hsmmc.c index d5fe43d53c51..101cd31c8220 100644 --- a/trunk/drivers/mmc/host/omap_hsmmc.c +++ b/trunk/drivers/mmc/host/omap_hsmmc.c @@ -1010,7 +1010,6 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno) host->data->sg_len, omap_hsmmc_get_dma_dir(host, host->data)); omap_free_dma(dma_ch); - host->data->host_cookie = 0; } host->data = NULL; } @@ -1576,10 +1575,8 @@ static void omap_hsmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, struct mmc_data *data = mrq->data; if (host->use_dma) { - if (data->host_cookie) - dma_unmap_sg(mmc_dev(host->mmc), data->sg, - data->sg_len, - omap_hsmmc_get_dma_dir(host, data)); + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + omap_hsmmc_get_dma_dir(host, data)); data->host_cookie = 0; } } diff --git a/trunk/drivers/mmc/host/sdhci-cns3xxx.c b/trunk/drivers/mmc/host/sdhci-cns3xxx.c index 87b6f079b6e0..4b920b7621cf 100644 --- a/trunk/drivers/mmc/host/sdhci-cns3xxx.c +++ b/trunk/drivers/mmc/host/sdhci-cns3xxx.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include "sdhci-pltfm.h" diff --git a/trunk/drivers/mmc/host/sdhci-s3c.c b/trunk/drivers/mmc/host/sdhci-s3c.c index cb60c4197e0a..3d00e722efc9 100644 --- a/trunk/drivers/mmc/host/sdhci-s3c.c +++ b/trunk/drivers/mmc/host/sdhci-s3c.c @@ -644,6 +644,8 @@ static int sdhci_s3c_resume(struct platform_device *dev) static struct platform_driver sdhci_s3c_driver = { .probe = sdhci_s3c_probe, .remove = __devexit_p(sdhci_s3c_remove), + .suspend = sdhci_s3c_suspend, + .resume = sdhci_s3c_resume, .driver = { .owner = THIS_MODULE, .name = "s3c-sdhci", diff --git a/trunk/drivers/mmc/host/sh_mmcif.c b/trunk/drivers/mmc/host/sh_mmcif.c index d5505f3fe2a1..369366c8e205 100644 --- a/trunk/drivers/mmc/host/sh_mmcif.c +++ b/trunk/drivers/mmc/host/sh_mmcif.c @@ -908,7 +908,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (host->power) { pm_runtime_put(&host->pd->dev); host->power = false; - if (p->down_pwr && ios->power_mode == MMC_POWER_OFF) + if (p->down_pwr) p->down_pwr(host->pd); } host->state = STATE_IDLE; diff --git a/trunk/drivers/mmc/host/tmio_mmc_pio.c b/trunk/drivers/mmc/host/tmio_mmc_pio.c index 4208b3958069..d85a60cda167 100644 --- a/trunk/drivers/mmc/host/tmio_mmc_pio.c +++ b/trunk/drivers/mmc/host/tmio_mmc_pio.c @@ -798,7 +798,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) /* start bus clock */ tmio_mmc_clk_start(host); } else if (ios->power_mode != MMC_POWER_UP) { - if (host->set_pwr && ios->power_mode == MMC_POWER_OFF) + if (host->set_pwr) host->set_pwr(host->pdev, 0); if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) && pdata->power) { diff --git a/trunk/drivers/net/ethernet/pasemi/Makefile b/trunk/drivers/net/ethernet/pasemi/Makefile index 90497ffb1ac3..05db5434bafc 100644 --- a/trunk/drivers/net/ethernet/pasemi/Makefile +++ b/trunk/drivers/net/ethernet/pasemi/Makefile @@ -2,5 +2,4 @@ # Makefile for the A Semi network device drivers. # -obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o -pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o +obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o pasemi_mac_ethtool.o diff --git a/trunk/drivers/net/ethernet/realtek/r8169.c b/trunk/drivers/net/ethernet/realtek/r8169.c index 67bf07819992..6f06aa10f0d7 100644 --- a/trunk/drivers/net/ethernet/realtek/r8169.c +++ b/trunk/drivers/net/ethernet/realtek/r8169.c @@ -1183,13 +1183,11 @@ static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) return value; } -static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) +static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) { - void __iomem *ioaddr = tp->mmio_addr; - RTL_W16(IntrMask, 0x0000); - RTL_W16(IntrStatus, tp->intr_event); - RTL_R8(ChipCmd); + + RTL_W16(IntrStatus, 0xffff); } static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) @@ -3935,6 +3933,8 @@ static void rtl_hw_reset(struct rtl8169_private *tp) break; udelay(100); } + + rtl8169_init_ring_indexes(tp); } static int __devinit @@ -4339,7 +4339,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) void __iomem *ioaddr = tp->mmio_addr; /* Disable interrupts */ - rtl8169_irq_mask_and_ack(tp); + rtl8169_irq_mask_and_ack(ioaddr); rtl_rx_close(tp); @@ -4885,7 +4885,8 @@ static void rtl_hw_start_8168(struct net_device *dev) RTL_W16(IntrMitigate, 0x5151); /* Work around for RxFIFO overflow. */ - if (tp->mac_version == RTL_GIGA_MAC_VER_11) { + if (tp->mac_version == RTL_GIGA_MAC_VER_11 || + tp->mac_version == RTL_GIGA_MAC_VER_22) { tp->intr_event |= RxFIFOOver | PCSTimeout; tp->intr_event &= ~RxOverflow; } @@ -5075,11 +5076,6 @@ static void rtl_hw_start_8101(struct net_device *dev) void __iomem *ioaddr = tp->mmio_addr; struct pci_dev *pdev = tp->pci_dev; - if (tp->mac_version >= RTL_GIGA_MAC_VER_30) { - tp->intr_event &= ~RxFIFOOver; - tp->napi_event &= ~RxFIFOOver; - } - if (tp->mac_version == RTL_GIGA_MAC_VER_13 || tp->mac_version == RTL_GIGA_MAC_VER_16) { int cap = pci_pcie_cap(pdev); @@ -5346,7 +5342,7 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev) /* Wait for any pending NAPI task to complete */ napi_disable(&tp->napi); - rtl8169_irq_mask_and_ack(tp); + rtl8169_irq_mask_and_ack(ioaddr); tp->intr_mask = 0xffff; RTL_W16(IntrMask, tp->intr_event); @@ -5393,16 +5389,14 @@ static void rtl8169_reset_task(struct work_struct *work) if (!netif_running(dev)) goto out_unlock; - rtl8169_hw_reset(tp); - rtl8169_wait_for_quiescence(dev); for (i = 0; i < NUM_RX_DESC; i++) rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz); rtl8169_tx_clear(tp); - rtl8169_init_ring_indexes(tp); + rtl8169_hw_reset(tp); rtl_hw_start(dev); netif_wake_queue(dev); rtl8169_check_link_status(dev, tp, tp->mmio_addr); @@ -5413,6 +5407,11 @@ static void rtl8169_reset_task(struct work_struct *work) static void rtl8169_tx_timeout(struct net_device *dev) { + struct rtl8169_private *tp = netdev_priv(dev); + + rtl8169_hw_reset(tp); + + /* Let's wait a bit while any (async) irq lands on */ rtl8169_schedule_work(dev, rtl8169_reset_task); } @@ -5805,10 +5804,6 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) */ status = RTL_R16(IntrStatus); while (status && status != 0xffff) { - status &= tp->intr_event; - if (!status) - break; - handled = 1; /* Handle all of the error cases first. These will reset @@ -5823,9 +5818,27 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) switch (tp->mac_version) { /* Work around for rx fifo overflow */ case RTL_GIGA_MAC_VER_11: + case RTL_GIGA_MAC_VER_22: + case RTL_GIGA_MAC_VER_26: netif_stop_queue(dev); rtl8169_tx_timeout(dev); goto done; + /* Testers needed. */ + case RTL_GIGA_MAC_VER_17: + case RTL_GIGA_MAC_VER_19: + case RTL_GIGA_MAC_VER_20: + case RTL_GIGA_MAC_VER_21: + case RTL_GIGA_MAC_VER_23: + case RTL_GIGA_MAC_VER_24: + case RTL_GIGA_MAC_VER_27: + case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: + /* Experimental science. Pktgen proof. */ + case RTL_GIGA_MAC_VER_12: + case RTL_GIGA_MAC_VER_25: + if (status == RxFIFOOver) + goto done; + break; default: break; } diff --git a/trunk/drivers/net/ethernet/tile/tilepro.c b/trunk/drivers/net/ethernet/tile/tilepro.c index 1187a1169eb2..10826d8a2a2d 100644 --- a/trunk/drivers/net/ethernet/tile/tilepro.c +++ b/trunk/drivers/net/ethernet/tile/tilepro.c @@ -926,7 +926,7 @@ static int tile_net_poll(struct napi_struct *napi, int budget) goto done; /* Re-enable the ingress interrupt. */ - enable_percpu_irq(priv->intr_id, 0); + enable_percpu_irq(priv->intr_id); /* HACK: Avoid the "rotting packet" problem (see above). */ if (qup->__packet_receive_read != @@ -1296,7 +1296,7 @@ static void tile_net_open_enable(void *dev_ptr) info->napi_enabled = true; /* Enable the ingress interrupt. */ - enable_percpu_irq(priv->intr_id, 0); + enable_percpu_irq(priv->intr_id); } @@ -1697,7 +1697,7 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags, for (i = 0; i < sh->nr_frags; i++) { skb_frag_t *f = &sh->frags[i]; - unsigned long pfn = page_to_pfn(skb_frag_page(f)); + unsigned long pfn = page_to_pfn(f->page); /* FIXME: Compute "hash_for_home" properly. */ /* ISSUE: The hypervisor checks CHIP_HAS_REV1_DMA_PACKETS(). */ @@ -1706,7 +1706,7 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags, /* FIXME: Hmmm. */ if (!hash_default) { void *va = pfn_to_kaddr(pfn) + f->page_offset; - BUG_ON(PageHighMem(skb_frag_page(f))); + BUG_ON(PageHighMem(f->page)); finv_buffer_remote(va, f->size, 0); } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c index dd008b0e6417..e12b48c2cff6 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -191,7 +191,6 @@ static struct iwl_base_params iwl1000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 128, - .wd_disable = true, }; static struct iwl_ht_params iwl1000_ht_params = { .ht_greenfield_support = true, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c index f55fb2d1af52..c511c98a89a8 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -364,7 +364,6 @@ static struct iwl_base_params iwl5000_base_params = { .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, .no_idle_support = true, - .wd_disable = true, }; static struct iwl_ht_params iwl5000_ht_params = { .ht_greenfield_support = true, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index a7a6def40d05..58a381c01c89 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -528,24 +528,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return 0; } -void iwlagn_config_ht40(struct ieee80211_conf *conf, - struct iwl_rxon_context *ctx) -{ - if (conf_is_ht40_minus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ctx->ht.is_40mhz = true; - } else if (conf_is_ht40_plus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ctx->ht.is_40mhz = true; - } else { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_NONE; - ctx->ht.is_40mhz = false; - } -} - int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) { struct iwl_priv *priv = hw->priv; @@ -604,11 +586,19 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) ctx->ht.enabled = conf_is_ht(conf); if (ctx->ht.enabled) { - /* if HT40 is used, it should not change - * after associated except channel switch */ - if (iwl_is_associated_ctx(ctx) && - !ctx->ht.is_40mhz) - iwlagn_config_ht40(conf, ctx); + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } } else ctx->ht.is_40mhz = false; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 4b2aa1da0953..ed6283623932 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -1268,6 +1268,9 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, switch (keyconf->cipher) { case WLAN_CIPHER_SUITE_TKIP: + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + if (sta) addr = sta->addr; else /* station mode case only */ @@ -1280,6 +1283,8 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, seq.tkip.iv32, p1k, CMD_SYNC); break; case WLAN_CIPHER_SUITE_CCMP: + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + /* fall through */ case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: ret = iwlagn_send_sta_key(priv, keyconf, sta_id, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c index bacc06c95e7a..ccba69b7f8a7 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2316,17 +2316,6 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } - switch (key->cipher) { - case WLAN_CIPHER_SUITE_TKIP: - key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - /* fall through */ - case WLAN_CIPHER_SUITE_CCMP: - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - break; - default: - break; - } - /* * We could program these keys into the hardware as well, but we * don't expect much multicast traffic in IBSS and having keys @@ -2610,9 +2599,21 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, /* Configure HT40 channels */ ctx->ht.enabled = conf_is_ht(conf); - if (ctx->ht.enabled) - iwlagn_config_ht40(conf, ctx); - else + if (ctx->ht.enabled) { + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } + } else ctx->ht.is_40mhz = false; if ((le16_to_cpu(ctx->staging.channel) != ch)) @@ -3498,10 +3499,9 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); -module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO); +module_param_named(wd_disable, iwlagn_mod_params.wd_disable, bool, S_IRUGO); MODULE_PARM_DESC(wd_disable, - "Disable stuck queue watchdog timer 0=system default, " - "1=disable, 2=enable (default: 0)"); + "Disable stuck queue watchdog timer (default: 0 [enabled])"); /* * set bt_coex_active to true, uCode will do kill/defer diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h index 3856abaea507..5b936ec1a541 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -86,8 +86,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes); -void iwlagn_config_ht40(struct ieee80211_conf *conf, - struct iwl_rxon_context *ctx); /* uCode */ int iwlagn_rx_calib_result(struct iwl_priv *priv, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c index fcf54160e4ed..001fdf140abb 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1810,23 +1810,11 @@ void iwl_setup_watchdog(struct iwl_priv *priv) { unsigned int timeout = priv->cfg->base_params->wd_timeout; - if (!iwlagn_mod_params.wd_disable) { - /* use system default */ - if (timeout && !priv->cfg->base_params->wd_disable) - mod_timer(&priv->watchdog, - jiffies + - msecs_to_jiffies(IWL_WD_TICK(timeout))); - else - del_timer(&priv->watchdog); - } else { - /* module parameter overwrite default configuration */ - if (timeout && iwlagn_mod_params.wd_disable == 2) - mod_timer(&priv->watchdog, - jiffies + - msecs_to_jiffies(IWL_WD_TICK(timeout))); - else - del_timer(&priv->watchdog); - } + if (timeout && !iwlagn_mod_params.wd_disable) + mod_timer(&priv->watchdog, + jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); + else + del_timer(&priv->watchdog); } /** diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h index f2fc288f3dd3..137da3380704 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h @@ -113,7 +113,6 @@ struct iwl_lib_ops { * @shadow_reg_enable: HW shadhow register bit * @no_idle_support: do not support idle mode * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up - * wd_disable: disable watchdog timer */ struct iwl_base_params { int eeprom_size; @@ -135,7 +134,6 @@ struct iwl_base_params { const bool shadow_reg_enable; const bool no_idle_support; const bool hd_v2; - const bool wd_disable; }; /* * @advanced_bt_coexist: support advanced bt coexist diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-shared.h b/trunk/drivers/net/wireless/iwlwifi/iwl-shared.h index 14eaf37ce3b1..1f7a93c67c45 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -120,7 +120,7 @@ extern struct iwl_mod_params iwlagn_mod_params; * @restart_fw: restart firmware, default = 1 * @plcp_check: enable plcp health check, default = true * @ack_check: disable ack health check, default = false - * @wd_disable: enable stuck queue check, default = 0 + * @wd_disable: enable stuck queue check, default = false * @bt_coex_active: enable bt coex, default = true * @led_mode: system default, default = 0 * @no_sleep_autoadjust: disable autoadjust, default = true @@ -141,7 +141,7 @@ struct iwl_mod_params { int restart_fw; bool plcp_check; bool ack_check; - int wd_disable; + bool wd_disable; bool bt_coex_active; int led_mode; bool no_sleep_autoadjust; diff --git a/trunk/drivers/net/xen-netback/netback.c b/trunk/drivers/net/xen-netback/netback.c index 15e332d08c8d..1ae270eed51a 100644 --- a/trunk/drivers/net/xen-netback/netback.c +++ b/trunk/drivers/net/xen-netback/netback.c @@ -1668,7 +1668,7 @@ static int __init netback_init(void) "netback/%u", group); if (IS_ERR(netbk->task)) { - printk(KERN_ALERT "kthread_create() fails at netback\n"); + printk(KERN_ALERT "kthread_run() fails at netback\n"); del_timer(&netbk->net_timer); rc = PTR_ERR(netbk->task); goto failed_init; diff --git a/trunk/drivers/of/irq.c b/trunk/drivers/of/irq.c index 0f0cfa3bca30..19c0115092dd 100644 --- a/trunk/drivers/of/irq.c +++ b/trunk/drivers/of/irq.c @@ -26,6 +26,11 @@ #include #include +/* For archs that don't support NO_IRQ (such as x86), provide a dummy value */ +#ifndef NO_IRQ +#define NO_IRQ 0 +#endif + /** * irq_of_parse_and_map - Parse and map an interrupt into linux virq space * @device: Device node of the device whose interrupt is to be mapped @@ -39,7 +44,7 @@ unsigned int irq_of_parse_and_map(struct device_node *dev, int index) struct of_irq oirq; if (of_irq_map_one(dev, index, &oirq)) - return 0; + return NO_IRQ; return irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); @@ -340,7 +345,7 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) /* Only dereference the resource if both the * resource and the irq are valid. */ - if (r && irq) { + if (r && irq != NO_IRQ) { r->start = r->end = irq; r->flags = IORESOURCE_IRQ; r->name = dev->full_name; @@ -358,7 +363,7 @@ int of_irq_count(struct device_node *dev) { int nr = 0; - while (of_irq_to_resource(dev, nr, NULL)) + while (of_irq_to_resource(dev, nr, NULL) != NO_IRQ) nr++; return nr; @@ -378,7 +383,7 @@ int of_irq_to_resource_table(struct device_node *dev, struct resource *res, int i; for (i = 0; i < nr_irqs; i++, res++) - if (!of_irq_to_resource(dev, i, res)) + if (of_irq_to_resource(dev, i, res) == NO_IRQ) break; return i; diff --git a/trunk/drivers/platform/x86/toshiba_acpi.c b/trunk/drivers/platform/x86/toshiba_acpi.c index dcdc1f4a4624..13ef8c37471d 100644 --- a/trunk/drivers/platform/x86/toshiba_acpi.c +++ b/trunk/drivers/platform/x86/toshiba_acpi.c @@ -121,7 +121,6 @@ struct toshiba_acpi_dev { int illumination_supported:1; int video_supported:1; int fan_supported:1; - int system_event_supported:1; struct mutex mutex; }; @@ -725,7 +724,7 @@ static int keys_proc_show(struct seq_file *m, void *v) u32 hci_result; u32 value; - if (!dev->key_event_valid && dev->system_event_supported) { + if (!dev->key_event_valid) { hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); if (hci_result == HCI_SUCCESS) { dev->key_event_valid = 1; @@ -965,8 +964,6 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev) /* enable event fifo */ hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); - if (hci_result == HCI_SUCCESS) - dev->system_event_supported = 1; props.type = BACKLIGHT_PLATFORM; props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; @@ -1035,15 +1032,12 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) { struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); u32 hci_result, value; - int retries = 3; - if (!dev->system_event_supported || event != 0x80) + if (event != 0x80) return; - do { hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); - switch (hci_result) { - case HCI_SUCCESS: + if (hci_result == HCI_SUCCESS) { if (value == 0x100) continue; /* act on key press; ignore key release */ @@ -1055,19 +1049,14 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) pr_info("Unknown key %x\n", value); } - break; - case HCI_NOT_SUPPORTED: + } else if (hci_result == HCI_NOT_SUPPORTED) { /* This is a workaround for an unresolved issue on * some machines where system events sporadically * become disabled. */ hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); pr_notice("Re-enabled hotkeys\n"); - /* fall through */ - default: - retries--; - break; } - } while (retries && hci_result != HCI_EMPTY); + } while (hci_result != HCI_EMPTY); } diff --git a/trunk/drivers/ptp/ptp_clock.c b/trunk/drivers/ptp/ptp_clock.c index 10451a15e828..cf3f9997546d 100644 --- a/trunk/drivers/ptp/ptp_clock.c +++ b/trunk/drivers/ptp/ptp_clock.c @@ -101,9 +101,7 @@ static s32 scaled_ppm_to_ppb(long ppm) static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp) { - tp->tv_sec = 0; - tp->tv_nsec = 1; - return 0; + return 1; /* always round timer functions to one nanosecond */ } static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp) diff --git a/trunk/drivers/rapidio/devices/tsi721.c b/trunk/drivers/rapidio/devices/tsi721.c index 691b1ab1a3d0..5225930a10cd 100644 --- a/trunk/drivers/rapidio/devices/tsi721.c +++ b/trunk/drivers/rapidio/devices/tsi721.c @@ -851,12 +851,14 @@ static int tsi721_doorbell_init(struct tsi721_device *priv) INIT_WORK(&priv->idb_work, tsi721_db_dpc); /* Allocate buffer for inbound doorbells queue */ - priv->idb_base = dma_zalloc_coherent(&priv->pdev->dev, + priv->idb_base = dma_alloc_coherent(&priv->pdev->dev, IDB_QSIZE * TSI721_IDB_ENTRY_SIZE, &priv->idb_dma, GFP_KERNEL); if (!priv->idb_base) return -ENOMEM; + memset(priv->idb_base, 0, IDB_QSIZE * TSI721_IDB_ENTRY_SIZE); + dev_dbg(&priv->pdev->dev, "Allocated IDB buffer @ %p (phys = %llx)\n", priv->idb_base, (unsigned long long)priv->idb_dma); @@ -902,7 +904,7 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) */ /* Allocate space for DMA descriptors */ - bd_ptr = dma_zalloc_coherent(&priv->pdev->dev, + bd_ptr = dma_alloc_coherent(&priv->pdev->dev, bd_num * sizeof(struct tsi721_dma_desc), &bd_phys, GFP_KERNEL); if (!bd_ptr) @@ -911,6 +913,8 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) priv->bdma[chnum].bd_phys = bd_phys; priv->bdma[chnum].bd_base = bd_ptr; + memset(bd_ptr, 0, bd_num * sizeof(struct tsi721_dma_desc)); + dev_dbg(&priv->pdev->dev, "DMA descriptors @ %p (phys = %llx)\n", bd_ptr, (unsigned long long)bd_phys); @@ -918,7 +922,7 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) sts_size = (bd_num >= TSI721_DMA_MINSTSSZ) ? bd_num : TSI721_DMA_MINSTSSZ; sts_size = roundup_pow_of_two(sts_size); - sts_ptr = dma_zalloc_coherent(&priv->pdev->dev, + sts_ptr = dma_alloc_coherent(&priv->pdev->dev, sts_size * sizeof(struct tsi721_dma_sts), &sts_phys, GFP_KERNEL); if (!sts_ptr) { @@ -934,6 +938,8 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) priv->bdma[chnum].sts_base = sts_ptr; priv->bdma[chnum].sts_size = sts_size; + memset(sts_ptr, 0, sts_size); + dev_dbg(&priv->pdev->dev, "desc status FIFO @ %p (phys = %llx) size=0x%x\n", sts_ptr, (unsigned long long)sts_phys, sts_size); @@ -1394,7 +1400,7 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id, /* Outbound message descriptor status FIFO allocation */ priv->omsg_ring[mbox].sts_size = roundup_pow_of_two(entries + 1); - priv->omsg_ring[mbox].sts_base = dma_zalloc_coherent(&priv->pdev->dev, + priv->omsg_ring[mbox].sts_base = dma_alloc_coherent(&priv->pdev->dev, priv->omsg_ring[mbox].sts_size * sizeof(struct tsi721_dma_sts), &priv->omsg_ring[mbox].sts_phys, GFP_KERNEL); @@ -1406,6 +1412,9 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id, goto out_desc; } + memset(priv->omsg_ring[mbox].sts_base, 0, + entries * sizeof(struct tsi721_dma_sts)); + /* * Configure Outbound Messaging Engine */ @@ -2107,8 +2116,8 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv) INIT_LIST_HEAD(&mport->dbells); rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); - rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 3); - rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 3); + rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 0); + rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0); strcpy(mport->name, "Tsi721 mport"); /* Hook up interrupt handler */ @@ -2154,7 +2163,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct tsi721_device *priv; - int i, cap; + int i; int err; u32 regval; @@ -2262,20 +2271,10 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, dev_info(&pdev->dev, "Unable to set consistent DMA mask\n"); } - cap = pci_pcie_cap(pdev); - BUG_ON(cap == 0); - - /* Clear "no snoop" and "relaxed ordering" bits, use default MRRS. */ - pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, ®val); - regval &= ~(PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN | - PCI_EXP_DEVCTL_NOSNOOP_EN); - regval |= 0x2 << MAX_READ_REQUEST_SZ_SHIFT; - pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL, regval); - - /* Adjust PCIe completion timeout. */ - pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL2, ®val); - regval &= ~(0x0f); - pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL2, regval | 0x2); + /* Clear "no snoop" and "relaxed ordering" bits. */ + pci_read_config_dword(pdev, 0x40 + PCI_EXP_DEVCTL, ®val); + regval &= ~(PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN); + pci_write_config_dword(pdev, 0x40 + PCI_EXP_DEVCTL, regval); /* * FIXUP: correct offsets of MSI-X tables in the MSI-X Capability Block diff --git a/trunk/drivers/rapidio/devices/tsi721.h b/trunk/drivers/rapidio/devices/tsi721.h index 822e54c394d5..58be4deb1402 100644 --- a/trunk/drivers/rapidio/devices/tsi721.h +++ b/trunk/drivers/rapidio/devices/tsi721.h @@ -72,8 +72,6 @@ #define TSI721_MSIXPBA_OFFSET 0x2a000 #define TSI721_PCIECFG_EPCTL 0x400 -#define MAX_READ_REQUEST_SZ_SHIFT 12 - /* * Event Management Registers */ diff --git a/trunk/drivers/rtc/rtc-s3c.c b/trunk/drivers/rtc/rtc-s3c.c index 5b979d9cc332..7639ab906f02 100644 --- a/trunk/drivers/rtc/rtc-s3c.c +++ b/trunk/drivers/rtc/rtc-s3c.c @@ -202,6 +202,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) void __iomem *base = s3c_rtc_base; int year = tm->tm_year - 100; + clk_enable(rtc_clk); pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n", 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); @@ -213,7 +214,6 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) return -EINVAL; } - clk_enable(rtc_clk); writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC); writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN); writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR); diff --git a/trunk/drivers/spi/Kconfig b/trunk/drivers/spi/Kconfig index 8ba4510a9519..a1fd73df5416 100644 --- a/trunk/drivers/spi/Kconfig +++ b/trunk/drivers/spi/Kconfig @@ -199,7 +199,7 @@ config SPI_FSL_LIB depends on FSL_SOC config SPI_FSL_SPI - bool "Freescale SPI controller" + tristate "Freescale SPI controller" depends on FSL_SOC select SPI_FSL_LIB help @@ -208,7 +208,7 @@ config SPI_FSL_SPI MPC8569 uses the controller in QE mode, MPC8610 in cpu mode. config SPI_FSL_ESPI - bool "Freescale eSPI controller" + tristate "Freescale eSPI controller" depends on FSL_SOC select SPI_FSL_LIB help diff --git a/trunk/drivers/spi/spi-ath79.c b/trunk/drivers/spi/spi-ath79.c index acc88b4d2869..024b48aed5ca 100644 --- a/trunk/drivers/spi/spi-ath79.c +++ b/trunk/drivers/spi/spi-ath79.c @@ -13,7 +13,6 @@ */ #include -#include #include #include #include diff --git a/trunk/drivers/spi/spi-gpio.c b/trunk/drivers/spi/spi-gpio.c index 0094c645ff0d..e093d3ec41ba 100644 --- a/trunk/drivers/spi/spi-gpio.c +++ b/trunk/drivers/spi/spi-gpio.c @@ -256,7 +256,7 @@ static void spi_gpio_cleanup(struct spi_device *spi) spi_bitbang_cleanup(spi); } -static int __devinit spi_gpio_alloc(unsigned pin, const char *label, bool is_in) +static int __init spi_gpio_alloc(unsigned pin, const char *label, bool is_in) { int value; @@ -270,7 +270,7 @@ static int __devinit spi_gpio_alloc(unsigned pin, const char *label, bool is_in) return value; } -static int __devinit +static int __init spi_gpio_request(struct spi_gpio_platform_data *pdata, const char *label, u16 *res_flags) { diff --git a/trunk/drivers/spi/spi-nuc900.c b/trunk/drivers/spi/spi-nuc900.c index 182e9c873822..21c70b2b8311 100644 --- a/trunk/drivers/spi/spi-nuc900.c +++ b/trunk/drivers/spi/spi-nuc900.c @@ -8,7 +8,6 @@ * */ -#include #include #include #include diff --git a/trunk/drivers/target/iscsi/iscsi_target.c b/trunk/drivers/target/iscsi/iscsi_target.c index 8599545cdf9e..0fd96c10271d 100644 --- a/trunk/drivers/target/iscsi/iscsi_target.c +++ b/trunk/drivers/target/iscsi/iscsi_target.c @@ -614,12 +614,13 @@ int iscsit_add_reject( hdr = (struct iscsi_reject *) cmd->pdu; hdr->reason = reason; - cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); + cmd->buf_ptr = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL); if (!cmd->buf_ptr) { pr_err("Unable to allocate memory for cmd->buf_ptr\n"); iscsit_release_cmd(cmd); return -1; } + memcpy(cmd->buf_ptr, buf, ISCSI_HDR_LEN); spin_lock_bh(&conn->cmd_lock); list_add_tail(&cmd->i_list, &conn->conn_cmd_list); @@ -660,12 +661,13 @@ int iscsit_add_reject_from_cmd( hdr = (struct iscsi_reject *) cmd->pdu; hdr->reason = reason; - cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); + cmd->buf_ptr = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL); if (!cmd->buf_ptr) { pr_err("Unable to allocate memory for cmd->buf_ptr\n"); iscsit_release_cmd(cmd); return -1; } + memcpy(cmd->buf_ptr, buf, ISCSI_HDR_LEN); if (add_to_conn) { spin_lock_bh(&conn->cmd_lock); @@ -1015,6 +1017,11 @@ static int iscsit_handle_scsi_cmd( " non-existent or non-exported iSCSI LUN:" " 0x%016Lx\n", get_unaligned_le64(&hdr->lun)); } + if (ret == PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES) + return iscsit_add_reject_from_cmd( + ISCSI_REASON_BOOKMARK_NO_RESOURCES, + 1, 1, buf, cmd); + send_check_condition = 1; goto attach_cmd; } @@ -1037,8 +1044,6 @@ static int iscsit_handle_scsi_cmd( */ send_check_condition = 1; } else { - cmd->data_length = cmd->se_cmd.data_length; - if (iscsit_decide_list_to_build(cmd, payload_length) < 0) return iscsit_add_reject_from_cmd( ISCSI_REASON_BOOKMARK_NO_RESOURCES, @@ -1118,7 +1123,7 @@ static int iscsit_handle_scsi_cmd( * the backend memory allocation. */ ret = transport_generic_new_cmd(&cmd->se_cmd); - if (ret < 0) { + if ((ret < 0) || (cmd->se_cmd.se_cmd_flags & SCF_SE_CMD_FAILED)) { immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; dump_immediate_data = 1; goto after_immediate_data; @@ -1336,7 +1341,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) spin_lock_irqsave(&se_cmd->t_state_lock, flags); if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) || - (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION)) + (se_cmd->se_cmd_flags & SCF_SE_CMD_FAILED)) dump_unsolicited_data = 1; spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); @@ -2508,10 +2513,10 @@ static int iscsit_send_data_in( if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW; - hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); + hdr->residual_count = cpu_to_be32(cmd->residual_count); } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW; - hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); + hdr->residual_count = cpu_to_be32(cmd->residual_count); } } hton24(hdr->dlength, datain.length); @@ -3013,10 +3018,10 @@ static int iscsit_send_status( hdr->flags |= ISCSI_FLAG_CMD_FINAL; if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { hdr->flags |= ISCSI_FLAG_CMD_OVERFLOW; - hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); + hdr->residual_count = cpu_to_be32(cmd->residual_count); } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { hdr->flags |= ISCSI_FLAG_CMD_UNDERFLOW; - hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); + hdr->residual_count = cpu_to_be32(cmd->residual_count); } hdr->response = cmd->iscsi_response; hdr->cmd_status = cmd->se_cmd.scsi_status; @@ -3128,7 +3133,6 @@ static int iscsit_send_task_mgt_rsp( hdr = (struct iscsi_tm_rsp *) cmd->pdu; memset(hdr, 0, ISCSI_HDR_LEN); hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; - hdr->flags = ISCSI_FLAG_CMD_FINAL; hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr); hdr->itt = cpu_to_be32(cmd->init_task_tag); cmd->stat_sn = conn->stat_sn++; diff --git a/trunk/drivers/target/iscsi/iscsi_target_auth.c b/trunk/drivers/target/iscsi/iscsi_target_auth.c index 1cd6ce373b83..beb39469e7f1 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_auth.c +++ b/trunk/drivers/target/iscsi/iscsi_target_auth.c @@ -30,11 +30,9 @@ static int chap_string_to_hex(unsigned char *dst, unsigned char *src, int len) { - int j = DIV_ROUND_UP(len, 2), rc; + int j = DIV_ROUND_UP(len, 2); - rc = hex2bin(dst, src, j); - if (rc < 0) - pr_debug("CHAP string contains non hex digit symbols\n"); + hex2bin(dst, src, j); dst[j] = '\0'; return j; diff --git a/trunk/drivers/target/iscsi/iscsi_target_core.h b/trunk/drivers/target/iscsi/iscsi_target_core.h index f1a02dad05a0..3723d90d5ae5 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_core.h +++ b/trunk/drivers/target/iscsi/iscsi_target_core.h @@ -398,6 +398,7 @@ struct iscsi_cmd { u32 pdu_send_order; /* Current struct iscsi_pdu in struct iscsi_cmd->pdu_list */ u32 pdu_start; + u32 residual_count; /* Next struct iscsi_seq to send in struct iscsi_cmd->seq_list */ u32 seq_send_order; /* Number of struct iscsi_seq in struct iscsi_cmd->seq_list */ @@ -534,6 +535,7 @@ struct iscsi_conn { atomic_t connection_exit; atomic_t connection_recovery; atomic_t connection_reinstatement; + atomic_t connection_wait; atomic_t connection_wait_rcfr; atomic_t sleep_on_conn_wait_comp; atomic_t transport_failed; @@ -641,6 +643,7 @@ struct iscsi_session { atomic_t session_reinstatement; atomic_t session_stop_active; atomic_t sleep_on_sess_wait_comp; + atomic_t transport_wait_cmds; /* connection list */ struct list_head sess_conn_list; struct list_head cr_active_list; diff --git a/trunk/drivers/target/iscsi/iscsi_target_erl1.c b/trunk/drivers/target/iscsi/iscsi_target_erl1.c index 101b1beb3bca..c4c68da3e500 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_erl1.c +++ b/trunk/drivers/target/iscsi/iscsi_target_erl1.c @@ -938,7 +938,8 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) * handle the SCF_SCSI_RESERVATION_CONFLICT case here as well. */ if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) { - if (se_cmd->scsi_sense_reason == TCM_RESERVATION_CONFLICT) { + if (se_cmd->se_cmd_flags & + SCF_SCSI_RESERVATION_CONFLICT) { cmd->i_state = ISTATE_SEND_STATUS; spin_unlock_bh(&cmd->istate_lock); iscsit_add_cmd_to_response_queue(cmd, cmd->conn, diff --git a/trunk/drivers/target/iscsi/iscsi_target_login.c b/trunk/drivers/target/iscsi/iscsi_target_login.c index d734bdec24f9..daad362a93ce 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_login.c +++ b/trunk/drivers/target/iscsi/iscsi_target_login.c @@ -224,7 +224,7 @@ static int iscsi_login_zero_tsih_s1( iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, ISCSI_LOGIN_STATUS_NO_RESOURCES); pr_err("Could not allocate memory for session\n"); - return -ENOMEM; + return -1; } iscsi_login_set_conn_values(sess, conn, pdu->cid); @@ -250,8 +250,7 @@ static int iscsi_login_zero_tsih_s1( pr_err("idr_pre_get() for sess_idr failed\n"); iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, ISCSI_LOGIN_STATUS_NO_RESOURCES); - kfree(sess); - return -ENOMEM; + return -1; } spin_lock(&sess_idr_lock); idr_get_new(&sess_idr, NULL, &sess->session_index); @@ -271,16 +270,14 @@ static int iscsi_login_zero_tsih_s1( ISCSI_LOGIN_STATUS_NO_RESOURCES); pr_err("Unable to allocate memory for" " struct iscsi_sess_ops.\n"); - kfree(sess); - return -ENOMEM; + return -1; } sess->se_sess = transport_init_session(); - if (IS_ERR(sess->se_sess)) { + if (!sess->se_sess) { iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, ISCSI_LOGIN_STATUS_NO_RESOURCES); - kfree(sess); - return -ENOMEM; + return -1; } return 0; diff --git a/trunk/drivers/target/iscsi/iscsi_target_nego.c b/trunk/drivers/target/iscsi/iscsi_target_nego.c index 98936cb7c294..426cd4bf6a9a 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_nego.c +++ b/trunk/drivers/target/iscsi/iscsi_target_nego.c @@ -981,13 +981,14 @@ struct iscsi_login *iscsi_target_init_negotiation( return NULL; } - login->req = kmemdup(login_pdu, ISCSI_HDR_LEN, GFP_KERNEL); + login->req = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL); if (!login->req) { pr_err("Unable to allocate memory for Login Request.\n"); iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, ISCSI_LOGIN_STATUS_NO_RESOURCES); goto out; } + memcpy(login->req, login_pdu, ISCSI_HDR_LEN); login->req_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL); if (!login->req_buf) { diff --git a/trunk/drivers/target/loopback/tcm_loop.c b/trunk/drivers/target/loopback/tcm_loop.c index 81d5832fbbd5..3df1c9b8ae6b 100644 --- a/trunk/drivers/target/loopback/tcm_loop.c +++ b/trunk/drivers/target/loopback/tcm_loop.c @@ -113,9 +113,11 @@ static struct se_cmd *tcm_loop_allocate_core_cmd( scsi_bufflen(sc), sc->sc_data_direction, sam_task_attr, &tl_cmd->tl_sense_buf[0]); + /* + * Signal BIDI usage with T_TASK(cmd)->t_tasks_bidi + */ if (scsi_bidi_cmnd(sc)) - se_cmd->se_cmd_flags |= SCF_BIDI; - + se_cmd->t_tasks_bidi = 1; /* * Locate the struct se_lun pointer and attach it to struct se_cmd */ @@ -146,13 +148,27 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd) * Allocate the necessary tasks to complete the received CDB+data */ ret = transport_generic_allocate_tasks(se_cmd, sc->cmnd); - if (ret != 0) - return ret; + if (ret == -ENOMEM) { + /* Out of Resources */ + return PYX_TRANSPORT_LU_COMM_FAILURE; + } else if (ret == -EINVAL) { + /* + * Handle case for SAM_STAT_RESERVATION_CONFLICT + */ + if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) + return PYX_TRANSPORT_RESERVATION_CONFLICT; + /* + * Otherwise, return SAM_STAT_CHECK_CONDITION and return + * sense data. + */ + return PYX_TRANSPORT_USE_SENSE_REASON; + } + /* * For BIDI commands, pass in the extra READ buffer * to transport_generic_map_mem_to_cmd() below.. */ - if (se_cmd->se_cmd_flags & SCF_BIDI) { + if (se_cmd->t_tasks_bidi) { struct scsi_data_buffer *sdb = scsi_in(sc); sgl_bidi = sdb->table.sgl; @@ -178,8 +194,12 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd) } /* Tell the core about our preallocated memory */ - return transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), + ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), scsi_sg_count(sc), sgl_bidi, sgl_bidi_count); + if (ret < 0) + return PYX_TRANSPORT_LU_COMM_FAILURE; + + return 0; } /* @@ -1340,16 +1360,17 @@ void tcm_loop_drop_scsi_hba( { struct tcm_loop_hba *tl_hba = container_of(wwn, struct tcm_loop_hba, tl_hba_wwn); - - pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target" - " SAS Address: %s at Linux/SCSI Host ID: %d\n", - tl_hba->tl_wwn_address, tl_hba->sh->host_no); + int host_no = tl_hba->sh->host_no; /* * Call device_unregister() on the original tl_hba->dev. * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will * release *tl_hba; */ device_unregister(&tl_hba->dev); + + pr_debug("TCM_Loop_ConfigFS: Deallocated emulated Target" + " SAS Address: %s at Linux/SCSI Host ID: %d\n", + config_item_name(&wwn->wwn_group.cg_item), host_no); } /* Start items for tcm_loop_cit */ diff --git a/trunk/drivers/target/target_core_alua.c b/trunk/drivers/target/target_core_alua.c index 1dcbef499d6a..88f2ad43ec8b 100644 --- a/trunk/drivers/target/target_core_alua.c +++ b/trunk/drivers/target/target_core_alua.c @@ -191,10 +191,9 @@ int target_emulate_set_target_port_groups(struct se_task *task) int alua_access_state, primary = 0, rc; u16 tg_pt_id, rtpi; - if (!l_port) { - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; - } + if (!l_port) + return PYX_TRANSPORT_LU_COMM_FAILURE; + buf = transport_kmap_first_data_page(cmd); /* @@ -204,8 +203,7 @@ int target_emulate_set_target_port_groups(struct se_task *task) l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem; if (!l_tg_pt_gp_mem) { pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n"); - cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; - rc = -EINVAL; + rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; goto out; } spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); @@ -213,8 +211,7 @@ int target_emulate_set_target_port_groups(struct se_task *task) if (!l_tg_pt_gp) { spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n"); - cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; - rc = -EINVAL; + rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; goto out; } rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA); @@ -223,8 +220,7 @@ int target_emulate_set_target_port_groups(struct se_task *task) if (!rc) { pr_debug("Unable to process SET_TARGET_PORT_GROUPS" " while TPGS_EXPLICT_ALUA is disabled\n"); - cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; - rc = -EINVAL; + rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; goto out; } @@ -249,8 +245,7 @@ int target_emulate_set_target_port_groups(struct se_task *task) * REQUEST, and the additional sense code set to INVALID * FIELD IN PARAMETER LIST. */ - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - rc = -EINVAL; + rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } rc = -1; @@ -303,8 +298,7 @@ int target_emulate_set_target_port_groups(struct se_task *task) * throw an exception with ASCQ: INVALID_PARAMETER_LIST */ if (rc != 0) { - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - rc = -EINVAL; + rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } } else { @@ -341,8 +335,7 @@ int target_emulate_set_target_port_groups(struct se_task *task) * INVALID_PARAMETER_LIST */ if (rc != 0) { - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - rc = -EINVAL; + rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } } @@ -1191,6 +1184,7 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp) * struct t10_alua_lu_gp. */ spin_lock(&lu_gps_lock); + atomic_set(&lu_gp->lu_gp_shutdown, 1); list_del(&lu_gp->lu_gp_node); alua_lu_gps_count--; spin_unlock(&lu_gps_lock); @@ -1444,6 +1438,7 @@ struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem( tg_pt_gp_mem->tg_pt = port; port->sep_alua_tg_pt_gp_mem = tg_pt_gp_mem; + atomic_set(&port->sep_tg_pt_gp_active, 1); return tg_pt_gp_mem; } diff --git a/trunk/drivers/target/target_core_cdb.c b/trunk/drivers/target/target_core_cdb.c index 831468b3163d..683ba02b8247 100644 --- a/trunk/drivers/target/target_core_cdb.c +++ b/trunk/drivers/target/target_core_cdb.c @@ -478,7 +478,7 @@ target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) if (cmd->data_length < 60) return 0; - buf[3] = 0x3c; + buf[2] = 0x3c; /* Set HEADSUP, ORDSUP, SIMPSUP */ buf[5] = 0x07; @@ -703,7 +703,6 @@ int target_emulate_inquiry(struct se_task *task) if (cmd->data_length < 4) { pr_err("SCSI Inquiry payload length: %u" " too small for EVPD=1\n", cmd->data_length); - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; return -EINVAL; } @@ -720,7 +719,6 @@ int target_emulate_inquiry(struct se_task *task) } pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); - cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; ret = -EINVAL; out_unmap: @@ -971,8 +969,7 @@ int target_emulate_modesense(struct se_task *task) default: pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", cdb[2] & 0x3f, cdb[3]); - cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE; - return -EINVAL; + return PYX_TRANSPORT_UNKNOWN_MODE_PAGE; } offset += length; @@ -1030,8 +1027,7 @@ int target_emulate_request_sense(struct se_task *task) if (cdb[1] & 0x01) { pr_err("REQUEST_SENSE description emulation not" " supported\n"); - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - return -ENOSYS; + return PYX_TRANSPORT_INVALID_CDB_FIELD; } buf = transport_kmap_first_data_page(cmd); @@ -1104,8 +1100,7 @@ int target_emulate_unmap(struct se_task *task) if (!dev->transport->do_discard) { pr_err("UNMAP emulation not supported for: %s\n", dev->transport->name); - cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; - return -ENOSYS; + return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } /* First UNMAP block descriptor starts at 8 byte offset */ @@ -1162,8 +1157,7 @@ int target_emulate_write_same(struct se_task *task) if (!dev->transport->do_discard) { pr_err("WRITE_SAME emulation not supported" " for: %s\n", dev->transport->name); - cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; - return -ENOSYS; + return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } if (cmd->t_task_cdb[0] == WRITE_SAME) @@ -1199,13 +1193,11 @@ int target_emulate_write_same(struct se_task *task) int target_emulate_synchronize_cache(struct se_task *task) { struct se_device *dev = task->task_se_cmd->se_dev; - struct se_cmd *cmd = task->task_se_cmd; if (!dev->transport->do_sync_cache) { pr_err("SYNCHRONIZE_CACHE emulation not supported" " for: %s\n", dev->transport->name); - cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; - return -ENOSYS; + return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } dev->transport->do_sync_cache(task); diff --git a/trunk/drivers/target/target_core_configfs.c b/trunk/drivers/target/target_core_configfs.c index 93d4f6a1b798..e0c1e8a8dd4e 100644 --- a/trunk/drivers/target/target_core_configfs.c +++ b/trunk/drivers/target/target_core_configfs.c @@ -67,6 +67,9 @@ static struct config_group target_core_hbagroup; static struct config_group alua_group; static struct config_group alua_lu_gps_group; +static DEFINE_SPINLOCK(se_device_lock); +static LIST_HEAD(se_dev_list); + static inline struct se_hba * item_to_hba(struct config_item *item) { @@ -2738,6 +2741,7 @@ static struct config_group *target_core_make_subdev( " struct se_subsystem_dev\n"); goto unlock; } + INIT_LIST_HEAD(&se_dev->se_dev_node); INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list); spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock); INIT_LIST_HEAD(&se_dev->t10_pr.registration_list); @@ -2773,6 +2777,9 @@ static struct config_group *target_core_make_subdev( " from allocate_virtdevice()\n"); goto out; } + spin_lock(&se_device_lock); + list_add_tail(&se_dev->se_dev_node, &se_dev_list); + spin_unlock(&se_device_lock); config_group_init_type_name(&se_dev->se_dev_group, name, &target_core_dev_cit); @@ -2867,6 +2874,10 @@ static void target_core_drop_subdev( mutex_lock(&hba->hba_access_mutex); t = hba->transport; + spin_lock(&se_device_lock); + list_del(&se_dev->se_dev_node); + spin_unlock(&se_device_lock); + dev_stat_grp = &se_dev->dev_stat_grps.stat_group; for (i = 0; dev_stat_grp->default_groups[i]; i++) { df_item = &dev_stat_grp->default_groups[i]->cg_item; diff --git a/trunk/drivers/target/target_core_device.c b/trunk/drivers/target/target_core_device.c index 9b8639425472..ba5edec2c5f8 100644 --- a/trunk/drivers/target/target_core_device.c +++ b/trunk/drivers/target/target_core_device.c @@ -104,6 +104,7 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) se_cmd->se_lun = deve->se_lun; se_cmd->pr_res_key = deve->pr_res_key; se_cmd->orig_fe_lun = unpacked_lun; + se_cmd->se_orig_obj_ptr = se_cmd->se_lun->lun_se_dev; se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; } spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); @@ -136,6 +137,7 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) se_lun = &se_sess->se_tpg->tpg_virt_lun0; se_cmd->se_lun = &se_sess->se_tpg->tpg_virt_lun0; se_cmd->orig_fe_lun = 0; + se_cmd->se_orig_obj_ptr = se_cmd->se_lun->lun_se_dev; se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; } /* @@ -198,6 +200,7 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) se_lun = deve->se_lun; se_cmd->pr_res_key = deve->pr_res_key; se_cmd->orig_fe_lun = unpacked_lun; + se_cmd->se_orig_obj_ptr = se_cmd->se_dev; } spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); @@ -705,7 +708,7 @@ int target_report_luns(struct se_task *se_task) se_task->task_scsi_status = GOOD; transport_complete_task(se_task, 1); - return 0; + return PYX_TRANSPORT_SENT_TO_TRANSPORT; } /* se_release_device_for_hba(): @@ -954,12 +957,8 @@ int se_dev_set_emulate_dpo(struct se_device *dev, int flag) return -EINVAL; } - if (flag) { - pr_err("dpo_emulated not supported\n"); - return -EINVAL; - } - - return 0; + pr_err("dpo_emulated not supported\n"); + return -EINVAL; } int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) @@ -969,7 +968,7 @@ int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) return -EINVAL; } - if (flag && dev->transport->fua_write_emulated == 0) { + if (dev->transport->fua_write_emulated == 0) { pr_err("fua_write_emulated not supported\n"); return -EINVAL; } @@ -986,12 +985,8 @@ int se_dev_set_emulate_fua_read(struct se_device *dev, int flag) return -EINVAL; } - if (flag) { - pr_err("ua read emulated not supported\n"); - return -EINVAL; - } - - return 0; + pr_err("ua read emulated not supported\n"); + return -EINVAL; } int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) @@ -1000,7 +995,7 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) pr_err("Illegal value %d\n", flag); return -EINVAL; } - if (flag && dev->transport->write_cache_emulated == 0) { + if (dev->transport->write_cache_emulated == 0) { pr_err("write_cache_emulated not supported\n"); return -EINVAL; } @@ -1061,7 +1056,7 @@ int se_dev_set_emulate_tpu(struct se_device *dev, int flag) * We expect this value to be non-zero when generic Block Layer * Discard supported is detected iblock_create_virtdevice(). */ - if (flag && !dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { + if (!dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { pr_err("Generic Block Discard not supported\n"); return -ENOSYS; } @@ -1082,7 +1077,7 @@ int se_dev_set_emulate_tpws(struct se_device *dev, int flag) * We expect this value to be non-zero when generic Block Layer * Discard supported is detected iblock_create_virtdevice(). */ - if (flag && !dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { + if (!dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { pr_err("Generic Block Discard not supported\n"); return -ENOSYS; } @@ -1592,6 +1587,7 @@ int core_dev_setup_virtual_lun0(void) ret = -ENOMEM; goto out; } + INIT_LIST_HEAD(&se_dev->se_dev_node); INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list); spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock); INIT_LIST_HEAD(&se_dev->t10_pr.registration_list); diff --git a/trunk/drivers/target/target_core_file.c b/trunk/drivers/target/target_core_file.c index b4864fba4ef0..67cd6fe05bfa 100644 --- a/trunk/drivers/target/target_core_file.c +++ b/trunk/drivers/target/target_core_file.c @@ -289,9 +289,9 @@ static int fd_do_readv(struct se_task *task) return -ENOMEM; } - for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { - iov[i].iov_len = sg->length; - iov[i].iov_base = sg_virt(sg); + for (i = 0; i < task->task_sg_nents; i++) { + iov[i].iov_len = sg[i].length; + iov[i].iov_base = sg_virt(&sg[i]); } old_fs = get_fs(); @@ -342,9 +342,9 @@ static int fd_do_writev(struct se_task *task) return -ENOMEM; } - for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { - iov[i].iov_len = sg->length; - iov[i].iov_base = sg_virt(sg); + for (i = 0; i < task->task_sg_nents; i++) { + iov[i].iov_len = sg[i].length; + iov[i].iov_base = sg_virt(&sg[i]); } old_fs = get_fs(); @@ -438,7 +438,7 @@ static int fd_do_task(struct se_task *task) if (ret > 0 && dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 && dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && - (cmd->se_cmd_flags & SCF_FUA)) { + cmd->t_tasks_fua) { /* * We might need to be a bit smarter here * and return some sense data to let the initiator @@ -449,15 +449,13 @@ static int fd_do_task(struct se_task *task) } - if (ret < 0) { - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + if (ret < 0) return ret; - } if (ret) { task->task_scsi_status = GOOD; transport_complete_task(task, 1); } - return 0; + return PYX_TRANSPORT_SENT_TO_TRANSPORT; } /* fd_free_task(): (Part of se_subsystem_api_t template) diff --git a/trunk/drivers/target/target_core_iblock.c b/trunk/drivers/target/target_core_iblock.c index 4aa992204438..7698efe29262 100644 --- a/trunk/drivers/target/target_core_iblock.c +++ b/trunk/drivers/target/target_core_iblock.c @@ -531,7 +531,7 @@ static int iblock_do_task(struct se_task *task) */ if (dev->se_sub_dev->se_dev_attrib.emulate_write_cache == 0 || (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && - (cmd->se_cmd_flags & SCF_FUA))) + task->task_se_cmd->t_tasks_fua)) rw = WRITE_FUA; else rw = WRITE; @@ -554,15 +554,12 @@ static int iblock_do_task(struct se_task *task) else { pr_err("Unsupported SCSI -> BLOCK LBA conversion:" " %u\n", dev->se_sub_dev->se_dev_attrib.block_size); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -ENOSYS; + return PYX_TRANSPORT_LU_COMM_FAILURE; } bio = iblock_get_bio(task, block_lba, sg_num); - if (!bio) { - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -ENOMEM; - } + if (!bio) + return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; bio_list_init(&list); bio_list_add(&list, bio); @@ -591,13 +588,12 @@ static int iblock_do_task(struct se_task *task) submit_bio(rw, bio); blk_finish_plug(&plug); - return 0; + return PYX_TRANSPORT_SENT_TO_TRANSPORT; fail: while ((bio = bio_list_pop(&list))) bio_put(bio); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -ENOMEM; + return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; } static u32 iblock_get_device_rev(struct se_device *dev) diff --git a/trunk/drivers/target/target_core_pr.c b/trunk/drivers/target/target_core_pr.c index 95dee7074aeb..5a4ebfc3a54f 100644 --- a/trunk/drivers/target/target_core_pr.c +++ b/trunk/drivers/target/target_core_pr.c @@ -191,7 +191,7 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) pr_err("Received legacy SPC-2 RESERVE/RELEASE" " while active SPC-3 registrations exist," " returning RESERVATION_CONFLICT\n"); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; + *ret = PYX_TRANSPORT_RESERVATION_CONFLICT; return true; } @@ -252,8 +252,7 @@ int target_scsi2_reservation_reserve(struct se_task *task) (cmd->t_task_cdb[1] & 0x02)) { pr_err("LongIO and Obselete Bits set, returning" " ILLEGAL_REQUEST\n"); - cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; - ret = -EINVAL; + ret = PYX_TRANSPORT_ILLEGAL_REQUEST; goto out; } /* @@ -278,8 +277,7 @@ int target_scsi2_reservation_reserve(struct se_task *task) " from %s \n", cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun, sess->se_node_acl->initiatorname); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - ret = -EINVAL; + ret = PYX_TRANSPORT_RESERVATION_CONFLICT; goto out_unlock; } @@ -1512,8 +1510,7 @@ static int core_scsi3_decode_spec_i_port( tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL); if (!tidh_new) { pr_err("Unable to allocate tidh_new\n"); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; + return PYX_TRANSPORT_LU_COMM_FAILURE; } INIT_LIST_HEAD(&tidh_new->dest_list); tidh_new->dest_tpg = tpg; @@ -1525,8 +1522,7 @@ static int core_scsi3_decode_spec_i_port( sa_res_key, all_tg_pt, aptpl); if (!local_pr_reg) { kfree(tidh_new); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -ENOMEM; + return PYX_TRANSPORT_LU_COMM_FAILURE; } tidh_new->dest_pr_reg = local_pr_reg; /* @@ -1552,8 +1548,7 @@ static int core_scsi3_decode_spec_i_port( pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header" " does not equal CDB data_length: %u\n", tpdl, cmd->data_length); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } /* @@ -1603,9 +1598,7 @@ static int core_scsi3_decode_spec_i_port( " for tmp_tpg\n"); atomic_dec(&tmp_tpg->tpg_pr_ref_count); smp_mb__after_atomic_dec(); - cmd->scsi_sense_reason = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - ret = -EINVAL; + ret = PYX_TRANSPORT_LU_COMM_FAILURE; goto out; } /* @@ -1635,9 +1628,7 @@ static int core_scsi3_decode_spec_i_port( atomic_dec(&dest_node_acl->acl_pr_ref_count); smp_mb__after_atomic_dec(); core_scsi3_tpg_undepend_item(tmp_tpg); - cmd->scsi_sense_reason = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - ret = -EINVAL; + ret = PYX_TRANSPORT_LU_COMM_FAILURE; goto out; } @@ -1655,8 +1646,7 @@ static int core_scsi3_decode_spec_i_port( if (!dest_tpg) { pr_err("SPC-3 PR SPEC_I_PT: Unable to locate" " dest_tpg\n"); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } #if 0 @@ -1670,8 +1660,7 @@ static int core_scsi3_decode_spec_i_port( " %u for Transport ID: %s\n", tid_len, ptr); core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_tpg_undepend_item(dest_tpg); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } /* @@ -1689,8 +1678,7 @@ static int core_scsi3_decode_spec_i_port( core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_tpg_undepend_item(dest_tpg); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } @@ -1702,9 +1690,7 @@ static int core_scsi3_decode_spec_i_port( smp_mb__after_atomic_dec(); core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_tpg_undepend_item(dest_tpg); - cmd->scsi_sense_reason = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - ret = -EINVAL; + ret = PYX_TRANSPORT_LU_COMM_FAILURE; goto out; } #if 0 @@ -1741,9 +1727,7 @@ static int core_scsi3_decode_spec_i_port( core_scsi3_lunacl_undepend_item(dest_se_deve); core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_tpg_undepend_item(dest_tpg); - cmd->scsi_sense_reason = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - ret = -ENOMEM; + ret = PYX_TRANSPORT_LU_COMM_FAILURE; goto out; } INIT_LIST_HEAD(&tidh_new->dest_list); @@ -1775,8 +1759,7 @@ static int core_scsi3_decode_spec_i_port( core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_tpg_undepend_item(dest_tpg); kfree(tidh_new); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } tidh_new->dest_pr_reg = dest_pr_reg; @@ -2115,8 +2098,7 @@ static int core_scsi3_emulate_pro_register( if (!se_sess || !se_lun) { pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; + return PYX_TRANSPORT_LU_COMM_FAILURE; } se_tpg = se_sess->se_tpg; se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; @@ -2135,14 +2117,13 @@ static int core_scsi3_emulate_pro_register( if (res_key) { pr_warn("SPC-3 PR: Reservation Key non-zero" " for SA REGISTER, returning CONFLICT\n"); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } /* * Do nothing but return GOOD status. */ if (!sa_res_key) - return 0; + return PYX_TRANSPORT_SENT_TO_TRANSPORT; if (!spec_i_pt) { /* @@ -2157,8 +2138,7 @@ static int core_scsi3_emulate_pro_register( if (ret != 0) { pr_err("Unable to allocate" " struct t10_pr_registration\n"); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - return -EINVAL; + return PYX_TRANSPORT_INVALID_PARAMETER_LIST; } } else { /* @@ -2217,16 +2197,14 @@ static int core_scsi3_emulate_pro_register( " 0x%016Lx\n", res_key, pr_reg->pr_res_key); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } } if (spec_i_pt) { pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT" " set while sa_res_key=0\n"); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - return -EINVAL; + return PYX_TRANSPORT_INVALID_PARAMETER_LIST; } /* * An existing ALL_TG_PT=1 registration being released @@ -2237,8 +2215,7 @@ static int core_scsi3_emulate_pro_register( " registration exists, but ALL_TG_PT=1 bit not" " present in received PROUT\n"); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - return -EINVAL; + return PYX_TRANSPORT_INVALID_CDB_FIELD; } /* * Allocate APTPL metadata buffer used for UNREGISTER ops @@ -2250,9 +2227,7 @@ static int core_scsi3_emulate_pro_register( pr_err("Unable to allocate" " pr_aptpl_buf\n"); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; + return PYX_TRANSPORT_LU_COMM_FAILURE; } } /* @@ -2266,8 +2241,7 @@ static int core_scsi3_emulate_pro_register( if (pr_holder < 0) { kfree(pr_aptpl_buf); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } spin_lock(&pr_tmpl->registration_lock); @@ -2431,8 +2405,7 @@ static int core_scsi3_pro_reserve( if (!se_sess || !se_lun) { pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; + return PYX_TRANSPORT_LU_COMM_FAILURE; } se_tpg = se_sess->se_tpg; se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; @@ -2444,8 +2417,7 @@ static int core_scsi3_pro_reserve( if (!pr_reg) { pr_err("SPC-3 PR: Unable to locate" " PR_REGISTERED *pr_reg for RESERVE\n"); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; + return PYX_TRANSPORT_LU_COMM_FAILURE; } /* * From spc4r17 Section 5.7.9: Reserving: @@ -2461,8 +2433,7 @@ static int core_scsi3_pro_reserve( " does not match existing SA REGISTER res_key:" " 0x%016Lx\n", res_key, pr_reg->pr_res_key); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } /* * From spc4r17 Section 5.7.9: Reserving: @@ -2477,8 +2448,7 @@ static int core_scsi3_pro_reserve( if (scope != PR_SCOPE_LU_SCOPE) { pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - return -EINVAL; + return PYX_TRANSPORT_INVALID_PARAMETER_LIST; } /* * See if we have an existing PR reservation holder pointer at @@ -2510,8 +2480,7 @@ static int core_scsi3_pro_reserve( spin_unlock(&dev->dev_reservation_lock); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } /* * From spc4r17 Section 5.7.9: Reserving: @@ -2534,8 +2503,7 @@ static int core_scsi3_pro_reserve( spin_unlock(&dev->dev_reservation_lock); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } /* * From spc4r17 Section 5.7.9: Reserving: @@ -2549,7 +2517,7 @@ static int core_scsi3_pro_reserve( */ spin_unlock(&dev->dev_reservation_lock); core_scsi3_put_pr_reg(pr_reg); - return 0; + return PYX_TRANSPORT_SENT_TO_TRANSPORT; } /* * Otherwise, our *pr_reg becomes the PR reservation holder for said @@ -2606,8 +2574,7 @@ static int core_scsi3_emulate_pro_reserve( default: pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:" " 0x%02x\n", type); - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - return -EINVAL; + return PYX_TRANSPORT_INVALID_CDB_FIELD; } return ret; @@ -2663,8 +2630,7 @@ static int core_scsi3_emulate_pro_release( if (!se_sess || !se_lun) { pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; + return PYX_TRANSPORT_LU_COMM_FAILURE; } /* * Locate the existing *pr_reg via struct se_node_acl pointers @@ -2673,8 +2639,7 @@ static int core_scsi3_emulate_pro_release( if (!pr_reg) { pr_err("SPC-3 PR: Unable to locate" " PR_REGISTERED *pr_reg for RELEASE\n"); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; + return PYX_TRANSPORT_LU_COMM_FAILURE; } /* * From spc4r17 Section 5.7.11.2 Releasing: @@ -2696,7 +2661,7 @@ static int core_scsi3_emulate_pro_release( */ spin_unlock(&dev->dev_reservation_lock); core_scsi3_put_pr_reg(pr_reg); - return 0; + return PYX_TRANSPORT_SENT_TO_TRANSPORT; } if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) @@ -2710,7 +2675,7 @@ static int core_scsi3_emulate_pro_release( */ spin_unlock(&dev->dev_reservation_lock); core_scsi3_put_pr_reg(pr_reg); - return 0; + return PYX_TRANSPORT_SENT_TO_TRANSPORT; } /* * From spc4r17 Section 5.7.11.2 Releasing: @@ -2732,8 +2697,7 @@ static int core_scsi3_emulate_pro_release( " 0x%016Lx\n", res_key, pr_reg->pr_res_key); spin_unlock(&dev->dev_reservation_lock); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } /* * From spc4r17 Section 5.7.11.2 Releasing and above: @@ -2755,8 +2719,7 @@ static int core_scsi3_emulate_pro_release( spin_unlock(&dev->dev_reservation_lock); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } /* * In response to a persistent reservation release request from the @@ -2839,8 +2802,7 @@ static int core_scsi3_emulate_pro_clear( if (!pr_reg_n) { pr_err("SPC-3 PR: Unable to locate" " PR_REGISTERED *pr_reg for CLEAR\n"); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; + return PYX_TRANSPORT_LU_COMM_FAILURE; } /* * From spc4r17 section 5.7.11.6, Clearing: @@ -2859,8 +2821,7 @@ static int core_scsi3_emulate_pro_clear( " existing SA REGISTER res_key:" " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key); core_scsi3_put_pr_reg(pr_reg_n); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } /* * a) Release the persistent reservation, if any; @@ -3018,10 +2979,8 @@ static int core_scsi3_pro_preempt( int all_reg = 0, calling_it_nexus = 0, released_regs = 0; int prh_type = 0, prh_scope = 0, ret; - if (!se_sess) { - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; - } + if (!se_sess) + return PYX_TRANSPORT_LU_COMM_FAILURE; se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, @@ -3030,19 +2989,16 @@ static int core_scsi3_pro_preempt( pr_err("SPC-3 PR: Unable to locate" " PR_REGISTERED *pr_reg for PREEMPT%s\n", (abort) ? "_AND_ABORT" : ""); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } if (pr_reg_n->pr_res_key != res_key) { core_scsi3_put_pr_reg(pr_reg_n); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } if (scope != PR_SCOPE_LU_SCOPE) { pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); core_scsi3_put_pr_reg(pr_reg_n); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - return -EINVAL; + return PYX_TRANSPORT_INVALID_PARAMETER_LIST; } INIT_LIST_HEAD(&preempt_and_abort_list); @@ -3056,8 +3012,7 @@ static int core_scsi3_pro_preempt( if (!all_reg && !sa_res_key) { spin_unlock(&dev->dev_reservation_lock); core_scsi3_put_pr_reg(pr_reg_n); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - return -EINVAL; + return PYX_TRANSPORT_INVALID_PARAMETER_LIST; } /* * From spc4r17, section 5.7.11.4.4 Removing Registrations: @@ -3151,8 +3106,7 @@ static int core_scsi3_pro_preempt( if (!released_regs) { spin_unlock(&dev->dev_reservation_lock); core_scsi3_put_pr_reg(pr_reg_n); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } /* * For an existing all registrants type reservation @@ -3343,8 +3297,7 @@ static int core_scsi3_emulate_pro_preempt( default: pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type); - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - return -EINVAL; + return PYX_TRANSPORT_INVALID_CDB_FIELD; } return ret; @@ -3378,8 +3331,7 @@ static int core_scsi3_emulate_pro_register_and_move( if (!se_sess || !se_lun) { pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; + return PYX_TRANSPORT_LU_COMM_FAILURE; } memset(dest_iport, 0, 64); memset(i_buf, 0, PR_REG_ISID_ID_LEN); @@ -3397,8 +3349,7 @@ static int core_scsi3_emulate_pro_register_and_move( if (!pr_reg) { pr_err("SPC-3 PR: Unable to locate PR_REGISTERED" " *pr_reg for REGISTER_AND_MOVE\n"); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; + return PYX_TRANSPORT_LU_COMM_FAILURE; } /* * The provided reservation key much match the existing reservation key @@ -3409,8 +3360,7 @@ static int core_scsi3_emulate_pro_register_and_move( " res_key: 0x%016Lx does not match existing SA REGISTER" " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } /* * The service active reservation key needs to be non zero @@ -3419,8 +3369,7 @@ static int core_scsi3_emulate_pro_register_and_move( pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero" " sa_res_key\n"); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - return -EINVAL; + return PYX_TRANSPORT_INVALID_PARAMETER_LIST; } /* @@ -3443,8 +3392,7 @@ static int core_scsi3_emulate_pro_register_and_move( " does not equal CDB data_length: %u\n", tid_len, cmd->data_length); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - return -EINVAL; + return PYX_TRANSPORT_INVALID_PARAMETER_LIST; } spin_lock(&dev->se_port_lock); @@ -3469,8 +3417,7 @@ static int core_scsi3_emulate_pro_register_and_move( atomic_dec(&dest_se_tpg->tpg_pr_ref_count); smp_mb__after_atomic_dec(); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; + return PYX_TRANSPORT_LU_COMM_FAILURE; } spin_lock(&dev->se_port_lock); @@ -3483,8 +3430,7 @@ static int core_scsi3_emulate_pro_register_and_move( " fabric ops from Relative Target Port Identifier:" " %hu\n", rtpi); core_scsi3_put_pr_reg(pr_reg); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - return -EINVAL; + return PYX_TRANSPORT_INVALID_PARAMETER_LIST; } buf = transport_kmap_first_data_page(cmd); @@ -3499,16 +3445,14 @@ static int core_scsi3_emulate_pro_register_and_move( " from fabric: %s\n", proto_ident, dest_tf_ops->get_fabric_proto_ident(dest_se_tpg), dest_tf_ops->get_fabric_name()); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) { pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not" " containg a valid tpg_parse_pr_out_transport_id" " function pointer\n"); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - ret = -EINVAL; + ret = PYX_TRANSPORT_LU_COMM_FAILURE; goto out; } initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg, @@ -3516,8 +3460,7 @@ static int core_scsi3_emulate_pro_register_and_move( if (!initiator_str) { pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" " initiator_str from Transport ID\n"); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } @@ -3546,8 +3489,7 @@ static int core_scsi3_emulate_pro_register_and_move( pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s" " matches: %s on received I_T Nexus\n", initiator_str, pr_reg_nacl->initiatorname); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) { @@ -3555,8 +3497,7 @@ static int core_scsi3_emulate_pro_register_and_move( " matches: %s %s on received I_T Nexus\n", initiator_str, iport_ptr, pr_reg_nacl->initiatorname, pr_reg->pr_reg_isid); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } after_iport_check: @@ -3576,8 +3517,7 @@ static int core_scsi3_emulate_pro_register_and_move( pr_err("Unable to locate %s dest_node_acl for" " TransportID%s\n", dest_tf_ops->get_fabric_name(), initiator_str); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } ret = core_scsi3_nodeacl_depend_item(dest_node_acl); @@ -3587,8 +3527,7 @@ static int core_scsi3_emulate_pro_register_and_move( atomic_dec(&dest_node_acl->acl_pr_ref_count); smp_mb__after_atomic_dec(); dest_node_acl = NULL; - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_LU_COMM_FAILURE; goto out; } #if 0 @@ -3604,8 +3543,7 @@ static int core_scsi3_emulate_pro_register_and_move( if (!dest_se_deve) { pr_err("Unable to locate %s dest_se_deve from RTPI:" " %hu\n", dest_tf_ops->get_fabric_name(), rtpi); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } @@ -3615,8 +3553,7 @@ static int core_scsi3_emulate_pro_register_and_move( atomic_dec(&dest_se_deve->pr_ref_count); smp_mb__after_atomic_dec(); dest_se_deve = NULL; - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - ret = -EINVAL; + ret = PYX_TRANSPORT_LU_COMM_FAILURE; goto out; } #if 0 @@ -3635,8 +3572,7 @@ static int core_scsi3_emulate_pro_register_and_move( pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation" " currently held\n"); spin_unlock(&dev->dev_reservation_lock); - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_CDB_FIELD; goto out; } /* @@ -3649,8 +3585,7 @@ static int core_scsi3_emulate_pro_register_and_move( pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" " Nexus is not reservation holder\n"); spin_unlock(&dev->dev_reservation_lock); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - ret = -EINVAL; + ret = PYX_TRANSPORT_RESERVATION_CONFLICT; goto out; } /* @@ -3668,8 +3603,7 @@ static int core_scsi3_emulate_pro_register_and_move( " reservation for type: %s\n", core_scsi3_pr_dump_type(pr_res_holder->pr_res_type)); spin_unlock(&dev->dev_reservation_lock); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - ret = -EINVAL; + ret = PYX_TRANSPORT_RESERVATION_CONFLICT; goto out; } pr_res_nacl = pr_res_holder->pr_reg_nacl; @@ -3706,8 +3640,7 @@ static int core_scsi3_emulate_pro_register_and_move( sa_res_key, 0, aptpl, 2, 1); if (ret != 0) { spin_unlock(&dev->dev_reservation_lock); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, @@ -3838,8 +3771,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task) pr_err("Received PERSISTENT_RESERVE CDB while legacy" " SPC-2 reservation is held, returning" " RESERVATION_CONFLICT\n"); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - ret = EINVAL; + ret = PYX_TRANSPORT_RESERVATION_CONFLICT; goto out; } @@ -3847,16 +3779,13 @@ int target_scsi3_emulate_pr_out(struct se_task *task) * FIXME: A NULL struct se_session pointer means an this is not coming from * a $FABRIC_MOD's nexus, but from internal passthrough ops. */ - if (!cmd->se_sess) { - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -EINVAL; - } + if (!cmd->se_sess) + return PYX_TRANSPORT_LU_COMM_FAILURE; if (cmd->data_length < 24) { pr_warn("SPC-PR: Received PR OUT parameter list" " length too small: %u\n", cmd->data_length); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } /* @@ -3891,8 +3820,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task) * SPEC_I_PT=1 is only valid for Service action: REGISTER */ if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) { - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } @@ -3909,8 +3837,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task) (cmd->data_length != 24)) { pr_warn("SPC-PR: Received PR OUT illegal parameter" " list length: %u\n", cmd->data_length); - cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; goto out; } /* @@ -3951,8 +3878,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task) default: pr_err("Unknown PERSISTENT_RESERVE_OUT service" " action: 0x%02x\n", cdb[1] & 0x1f); - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_CDB_FIELD; break; } @@ -3980,8 +3906,7 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd) if (cmd->data_length < 8) { pr_err("PRIN SA READ_KEYS SCSI Data Length: %u" " too small\n", cmd->data_length); - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - return -EINVAL; + return PYX_TRANSPORT_INVALID_CDB_FIELD; } buf = transport_kmap_first_data_page(cmd); @@ -4040,8 +3965,7 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd) if (cmd->data_length < 8) { pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u" " too small\n", cmd->data_length); - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - return -EINVAL; + return PYX_TRANSPORT_INVALID_CDB_FIELD; } buf = transport_kmap_first_data_page(cmd); @@ -4123,8 +4047,7 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd) if (cmd->data_length < 6) { pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:" " %u too small\n", cmd->data_length); - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - return -EINVAL; + return PYX_TRANSPORT_INVALID_CDB_FIELD; } buf = transport_kmap_first_data_page(cmd); @@ -4185,8 +4108,7 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) if (cmd->data_length < 8) { pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u" " too small\n", cmd->data_length); - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - return -EINVAL; + return PYX_TRANSPORT_INVALID_CDB_FIELD; } buf = transport_kmap_first_data_page(cmd); @@ -4333,8 +4255,7 @@ int target_scsi3_emulate_pr_in(struct se_task *task) pr_err("Received PERSISTENT_RESERVE CDB while legacy" " SPC-2 reservation is held, returning" " RESERVATION_CONFLICT\n"); - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EINVAL; + return PYX_TRANSPORT_RESERVATION_CONFLICT; } switch (cmd->t_task_cdb[1] & 0x1f) { @@ -4353,8 +4274,7 @@ int target_scsi3_emulate_pr_in(struct se_task *task) default: pr_err("Unknown PERSISTENT_RESERVE_IN service" " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - ret = -EINVAL; + ret = PYX_TRANSPORT_INVALID_CDB_FIELD; break; } diff --git a/trunk/drivers/target/target_core_pscsi.c b/trunk/drivers/target/target_core_pscsi.c index 8b15e56b0384..ed32e1efe429 100644 --- a/trunk/drivers/target/target_core_pscsi.c +++ b/trunk/drivers/target/target_core_pscsi.c @@ -963,7 +963,6 @@ static inline struct bio *pscsi_get_bio(int sg_num) static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg, struct bio **hbio) { - struct se_cmd *cmd = task->task_se_cmd; struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; u32 task_sg_num = task->task_sg_nents; struct bio *bio = NULL, *tbio = NULL; @@ -972,7 +971,7 @@ static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg, u32 data_len = task->task_size, i, len, bytes, off; int nr_pages = (task->task_size + task_sg[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT; - int nr_vecs = 0, rc; + int nr_vecs = 0, rc, ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; int rw = (task->task_data_direction == DMA_TO_DEVICE); *hbio = NULL; @@ -1059,13 +1058,11 @@ static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg, bio->bi_next = NULL; bio_endio(bio, 0); /* XXX: should be error */ } - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -ENOMEM; + return ret; } static int pscsi_do_task(struct se_task *task) { - struct se_cmd *cmd = task->task_se_cmd; struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; struct pscsi_plugin_task *pt = PSCSI_TASK(task); struct request *req; @@ -1081,9 +1078,7 @@ static int pscsi_do_task(struct se_task *task) if (!req || IS_ERR(req)) { pr_err("PSCSI: blk_get_request() failed: %ld\n", req ? IS_ERR(req) : -ENOMEM); - cmd->scsi_sense_reason = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -ENODEV; + return PYX_TRANSPORT_LU_COMM_FAILURE; } } else { BUG_ON(!task->task_size); @@ -1092,11 +1087,8 @@ static int pscsi_do_task(struct se_task *task) * Setup the main struct request for the task->task_sg[] payload */ ret = pscsi_map_sg(task, task->task_sg, &hbio); - if (ret < 0) { - cmd->scsi_sense_reason = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return ret; - } + if (ret < 0) + return PYX_TRANSPORT_LU_COMM_FAILURE; req = blk_make_request(pdv->pdv_sd->request_queue, hbio, GFP_KERNEL); @@ -1123,7 +1115,7 @@ static int pscsi_do_task(struct se_task *task) (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG), pscsi_req_done); - return 0; + return PYX_TRANSPORT_SENT_TO_TRANSPORT; fail: while (hbio) { @@ -1132,8 +1124,7 @@ static int pscsi_do_task(struct se_task *task) bio->bi_next = NULL; bio_endio(bio, 0); /* XXX: should be error */ } - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -ENOMEM; + return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; } /* pscsi_get_sense_buffer(): @@ -1207,8 +1198,9 @@ static inline void pscsi_process_SAM_status( " 0x%02x Result: 0x%08x\n", task, pt->pscsi_cdb[0], pt->pscsi_result); task->task_scsi_status = SAM_STAT_CHECK_CONDITION; - task->task_se_cmd->scsi_sense_reason = - TCM_UNSUPPORTED_SCSI_OPCODE; + task->task_error_status = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; + task->task_se_cmd->transport_error_status = + PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; transport_complete_task(task, 0); break; } diff --git a/trunk/drivers/target/target_core_rd.c b/trunk/drivers/target/target_core_rd.c index 02e51faa2f4e..5158d3846f19 100644 --- a/trunk/drivers/target/target_core_rd.c +++ b/trunk/drivers/target/target_core_rd.c @@ -343,74 +343,235 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page) return NULL; } -static int rd_MEMCPY(struct rd_request *req, u32 read_rd) +/* rd_MEMCPY_read(): + * + * + */ +static int rd_MEMCPY_read(struct rd_request *req) { struct se_task *task = &req->rd_task; struct rd_dev *dev = req->rd_task.task_se_cmd->se_dev->dev_ptr; struct rd_dev_sg_table *table; - struct scatterlist *rd_sg; - struct sg_mapping_iter m; + struct scatterlist *sg_d, *sg_s; + void *dst, *src; + u32 i = 0, j = 0, dst_offset = 0, src_offset = 0; + u32 length, page_end = 0, table_sg_end; u32 rd_offset = req->rd_offset; - u32 src_len; table = rd_get_sg_table(dev, req->rd_page); if (!table) return -EINVAL; - rd_sg = &table->sg_table[req->rd_page - table->page_start_offset]; + table_sg_end = (table->page_end_offset - req->rd_page); + sg_d = task->task_sg; + sg_s = &table->sg_table[req->rd_page - table->page_start_offset]; - pr_debug("RD[%u]: %s LBA: %llu, Size: %u Page: %u, Offset: %u\n", - dev->rd_dev_id, read_rd ? "Read" : "Write", - task->task_lba, req->rd_size, req->rd_page, - rd_offset); + pr_debug("RD[%u]: Read LBA: %llu, Size: %u Page: %u, Offset:" + " %u\n", dev->rd_dev_id, task->task_lba, req->rd_size, + req->rd_page, req->rd_offset); - src_len = PAGE_SIZE - rd_offset; - sg_miter_start(&m, task->task_sg, task->task_sg_nents, - read_rd ? SG_MITER_TO_SG : SG_MITER_FROM_SG); - while (req->rd_size) { - u32 len; - void *rd_addr; + src_offset = rd_offset; - sg_miter_next(&m); - len = min((u32)m.length, src_len); - m.consumed = len; + while (req->rd_size) { + if ((sg_d[i].length - dst_offset) < + (sg_s[j].length - src_offset)) { + length = (sg_d[i].length - dst_offset); + + pr_debug("Step 1 - sg_d[%d]: %p length: %d" + " offset: %u sg_s[%d].length: %u\n", i, + &sg_d[i], sg_d[i].length, sg_d[i].offset, j, + sg_s[j].length); + pr_debug("Step 1 - length: %u dst_offset: %u" + " src_offset: %u\n", length, dst_offset, + src_offset); + + if (length > req->rd_size) + length = req->rd_size; + + dst = sg_virt(&sg_d[i++]) + dst_offset; + BUG_ON(!dst); + + src = sg_virt(&sg_s[j]) + src_offset; + BUG_ON(!src); + + dst_offset = 0; + src_offset = length; + page_end = 0; + } else { + length = (sg_s[j].length - src_offset); + + pr_debug("Step 2 - sg_d[%d]: %p length: %d" + " offset: %u sg_s[%d].length: %u\n", i, + &sg_d[i], sg_d[i].length, sg_d[i].offset, + j, sg_s[j].length); + pr_debug("Step 2 - length: %u dst_offset: %u" + " src_offset: %u\n", length, dst_offset, + src_offset); + + if (length > req->rd_size) + length = req->rd_size; + + dst = sg_virt(&sg_d[i]) + dst_offset; + BUG_ON(!dst); + + if (sg_d[i].length == length) { + i++; + dst_offset = 0; + } else + dst_offset = length; + + src = sg_virt(&sg_s[j++]) + src_offset; + BUG_ON(!src); + + src_offset = 0; + page_end = 1; + } - rd_addr = sg_virt(rd_sg) + rd_offset; + memcpy(dst, src, length); - if (read_rd) - memcpy(m.addr, rd_addr, len); - else - memcpy(rd_addr, m.addr, len); + pr_debug("page: %u, remaining size: %u, length: %u," + " i: %u, j: %u\n", req->rd_page, + (req->rd_size - length), length, i, j); - req->rd_size -= len; + req->rd_size -= length; if (!req->rd_size) + return 0; + + if (!page_end) continue; - src_len -= len; - if (src_len) { - rd_offset += len; + if (++req->rd_page <= table->page_end_offset) { + pr_debug("page: %u in same page table\n", + req->rd_page); continue; } - /* rd page completed, next one please */ - req->rd_page++; - rd_offset = 0; - src_len = PAGE_SIZE; - if (req->rd_page <= table->page_end_offset) { - rd_sg++; + pr_debug("getting new page table for page: %u\n", + req->rd_page); + + table = rd_get_sg_table(dev, req->rd_page); + if (!table) + return -EINVAL; + + sg_s = &table->sg_table[j = 0]; + } + + return 0; +} + +/* rd_MEMCPY_write(): + * + * + */ +static int rd_MEMCPY_write(struct rd_request *req) +{ + struct se_task *task = &req->rd_task; + struct rd_dev *dev = req->rd_task.task_se_cmd->se_dev->dev_ptr; + struct rd_dev_sg_table *table; + struct scatterlist *sg_d, *sg_s; + void *dst, *src; + u32 i = 0, j = 0, dst_offset = 0, src_offset = 0; + u32 length, page_end = 0, table_sg_end; + u32 rd_offset = req->rd_offset; + + table = rd_get_sg_table(dev, req->rd_page); + if (!table) + return -EINVAL; + + table_sg_end = (table->page_end_offset - req->rd_page); + sg_d = &table->sg_table[req->rd_page - table->page_start_offset]; + sg_s = task->task_sg; + + pr_debug("RD[%d] Write LBA: %llu, Size: %u, Page: %u," + " Offset: %u\n", dev->rd_dev_id, task->task_lba, req->rd_size, + req->rd_page, req->rd_offset); + + dst_offset = rd_offset; + + while (req->rd_size) { + if ((sg_s[i].length - src_offset) < + (sg_d[j].length - dst_offset)) { + length = (sg_s[i].length - src_offset); + + pr_debug("Step 1 - sg_s[%d]: %p length: %d" + " offset: %d sg_d[%d].length: %u\n", i, + &sg_s[i], sg_s[i].length, sg_s[i].offset, + j, sg_d[j].length); + pr_debug("Step 1 - length: %u src_offset: %u" + " dst_offset: %u\n", length, src_offset, + dst_offset); + + if (length > req->rd_size) + length = req->rd_size; + + src = sg_virt(&sg_s[i++]) + src_offset; + BUG_ON(!src); + + dst = sg_virt(&sg_d[j]) + dst_offset; + BUG_ON(!dst); + + src_offset = 0; + dst_offset = length; + page_end = 0; + } else { + length = (sg_d[j].length - dst_offset); + + pr_debug("Step 2 - sg_s[%d]: %p length: %d" + " offset: %d sg_d[%d].length: %u\n", i, + &sg_s[i], sg_s[i].length, sg_s[i].offset, + j, sg_d[j].length); + pr_debug("Step 2 - length: %u src_offset: %u" + " dst_offset: %u\n", length, src_offset, + dst_offset); + + if (length > req->rd_size) + length = req->rd_size; + + src = sg_virt(&sg_s[i]) + src_offset; + BUG_ON(!src); + + if (sg_s[i].length == length) { + i++; + src_offset = 0; + } else + src_offset = length; + + dst = sg_virt(&sg_d[j++]) + dst_offset; + BUG_ON(!dst); + + dst_offset = 0; + page_end = 1; + } + + memcpy(dst, src, length); + + pr_debug("page: %u, remaining size: %u, length: %u," + " i: %u, j: %u\n", req->rd_page, + (req->rd_size - length), length, i, j); + + req->rd_size -= length; + if (!req->rd_size) + return 0; + + if (!page_end) + continue; + + if (++req->rd_page <= table->page_end_offset) { + pr_debug("page: %u in same page table\n", + req->rd_page); continue; } + pr_debug("getting new page table for page: %u\n", + req->rd_page); + table = rd_get_sg_table(dev, req->rd_page); - if (!table) { - sg_miter_stop(&m); + if (!table) return -EINVAL; - } - /* since we increment, the first sg entry is correct */ - rd_sg = table->sg_table; + sg_d = &table->sg_table[j = 0]; } - sg_miter_stop(&m); + return 0; } @@ -422,21 +583,28 @@ static int rd_MEMCPY_do_task(struct se_task *task) { struct se_device *dev = task->task_se_cmd->se_dev; struct rd_request *req = RD_REQ(task); - u64 tmp; + unsigned long long lba; int ret; - tmp = task->task_lba * dev->se_sub_dev->se_dev_attrib.block_size; - req->rd_offset = do_div(tmp, PAGE_SIZE); - req->rd_page = tmp; + req->rd_page = (task->task_lba * dev->se_sub_dev->se_dev_attrib.block_size) / PAGE_SIZE; + lba = task->task_lba; + req->rd_offset = (do_div(lba, + (PAGE_SIZE / dev->se_sub_dev->se_dev_attrib.block_size))) * + dev->se_sub_dev->se_dev_attrib.block_size; req->rd_size = task->task_size; - ret = rd_MEMCPY(req, task->task_data_direction == DMA_FROM_DEVICE); + if (task->task_data_direction == DMA_FROM_DEVICE) + ret = rd_MEMCPY_read(req); + else + ret = rd_MEMCPY_write(req); + if (ret != 0) return ret; task->task_scsi_status = GOOD; transport_complete_task(task, 1); - return 0; + + return PYX_TRANSPORT_SENT_TO_TRANSPORT; } /* rd_free_task(): (Part of se_subsystem_api_t template) diff --git a/trunk/drivers/target/target_core_tmr.c b/trunk/drivers/target/target_core_tmr.c index 684522805a1f..217e29df6297 100644 --- a/trunk/drivers/target/target_core_tmr.c +++ b/trunk/drivers/target/target_core_tmr.c @@ -345,6 +345,10 @@ static void core_tmr_drain_cmd_list( " %d t_fe_count: %d\n", (preempt_and_abort_list) ? "Preempt" : "", cmd, cmd->t_state, atomic_read(&cmd->t_fe_count)); + /* + * Signal that the command has failed via cmd->se_cmd_flags, + */ + transport_new_cmd_failure(cmd); core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, atomic_read(&cmd->t_fe_count)); diff --git a/trunk/drivers/target/target_core_transport.c b/trunk/drivers/target/target_core_transport.c index 0257658e2e3e..3400ae6e93f8 100644 --- a/trunk/drivers/target/target_core_transport.c +++ b/trunk/drivers/target/target_core_transport.c @@ -61,6 +61,7 @@ static int sub_api_initialized; static struct workqueue_struct *target_completion_wq; +static struct kmem_cache *se_cmd_cache; static struct kmem_cache *se_sess_cache; struct kmem_cache *se_tmr_req_cache; struct kmem_cache *se_ua_cache; @@ -81,18 +82,24 @@ static int transport_generic_get_mem(struct se_cmd *cmd); static void transport_put_cmd(struct se_cmd *cmd); static void transport_remove_cmd_from_queue(struct se_cmd *cmd); static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq); -static void transport_generic_request_failure(struct se_cmd *); +static void transport_generic_request_failure(struct se_cmd *, int, int); static void target_complete_ok_work(struct work_struct *work); int init_se_kmem_caches(void) { + se_cmd_cache = kmem_cache_create("se_cmd_cache", + sizeof(struct se_cmd), __alignof__(struct se_cmd), 0, NULL); + if (!se_cmd_cache) { + pr_err("kmem_cache_create for struct se_cmd failed\n"); + goto out; + } se_tmr_req_cache = kmem_cache_create("se_tmr_cache", sizeof(struct se_tmr_req), __alignof__(struct se_tmr_req), 0, NULL); if (!se_tmr_req_cache) { pr_err("kmem_cache_create() for struct se_tmr_req" " failed\n"); - goto out; + goto out_free_cmd_cache; } se_sess_cache = kmem_cache_create("se_sess_cache", sizeof(struct se_session), __alignof__(struct se_session), @@ -175,6 +182,8 @@ int init_se_kmem_caches(void) kmem_cache_destroy(se_sess_cache); out_free_tmr_req_cache: kmem_cache_destroy(se_tmr_req_cache); +out_free_cmd_cache: + kmem_cache_destroy(se_cmd_cache); out: return -ENOMEM; } @@ -182,6 +191,7 @@ int init_se_kmem_caches(void) void release_se_kmem_caches(void) { destroy_workqueue(target_completion_wq); + kmem_cache_destroy(se_cmd_cache); kmem_cache_destroy(se_tmr_req_cache); kmem_cache_destroy(se_sess_cache); kmem_cache_destroy(se_ua_cache); @@ -670,9 +680,9 @@ void transport_complete_sync_cache(struct se_cmd *cmd, int good) task->task_scsi_status = GOOD; } else { task->task_scsi_status = SAM_STAT_CHECK_CONDITION; - task->task_se_cmd->scsi_sense_reason = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - + task->task_error_status = PYX_TRANSPORT_ILLEGAL_REQUEST; + task->task_se_cmd->transport_error_status = + PYX_TRANSPORT_ILLEGAL_REQUEST; } transport_complete_task(task, good); @@ -683,7 +693,7 @@ static void target_complete_failure_work(struct work_struct *work) { struct se_cmd *cmd = container_of(work, struct se_cmd, work); - transport_generic_request_failure(cmd); + transport_generic_request_failure(cmd, 1, 1); } /* transport_complete_task(): @@ -745,11 +755,10 @@ void transport_complete_task(struct se_task *task, int success) if (cmd->t_tasks_failed) { if (!task->task_error_status) { task->task_error_status = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - cmd->scsi_sense_reason = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; + cmd->transport_error_status = + PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } - INIT_WORK(&cmd->work, target_complete_failure_work); } else { atomic_set(&cmd->t_transport_complete, 1); @@ -1326,17 +1335,23 @@ struct se_device *transport_add_device_to_core_hba( dev->se_hba = hba; dev->se_sub_dev = se_dev; dev->transport = transport; + atomic_set(&dev->active_cmds, 0); INIT_LIST_HEAD(&dev->dev_list); INIT_LIST_HEAD(&dev->dev_sep_list); INIT_LIST_HEAD(&dev->dev_tmr_list); INIT_LIST_HEAD(&dev->execute_task_list); INIT_LIST_HEAD(&dev->delayed_cmd_list); + INIT_LIST_HEAD(&dev->ordered_cmd_list); INIT_LIST_HEAD(&dev->state_task_list); INIT_LIST_HEAD(&dev->qf_cmd_list); spin_lock_init(&dev->execute_task_lock); spin_lock_init(&dev->delayed_cmd_lock); + spin_lock_init(&dev->ordered_cmd_lock); + spin_lock_init(&dev->state_task_lock); + spin_lock_init(&dev->dev_alua_lock); spin_lock_init(&dev->dev_reservation_lock); spin_lock_init(&dev->dev_status_lock); + spin_lock_init(&dev->dev_status_thr_lock); spin_lock_init(&dev->se_port_lock); spin_lock_init(&dev->se_tmr_lock); spin_lock_init(&dev->qf_cmd_lock); @@ -1492,6 +1507,7 @@ void transport_init_se_cmd( { INIT_LIST_HEAD(&cmd->se_lun_node); INIT_LIST_HEAD(&cmd->se_delayed_node); + INIT_LIST_HEAD(&cmd->se_ordered_node); INIT_LIST_HEAD(&cmd->se_qf_node); INIT_LIST_HEAD(&cmd->se_queue_node); INIT_LIST_HEAD(&cmd->se_cmd_list); @@ -1557,8 +1573,6 @@ int transport_generic_allocate_tasks( pr_err("Received SCSI CDB with command_size: %d that" " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE); - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; return -EINVAL; } /* @@ -1574,9 +1588,6 @@ int transport_generic_allocate_tasks( " %u > sizeof(cmd->__t_task_cdb): %lu ops\n", scsi_command_size(cdb), (unsigned long)sizeof(cmd->__t_task_cdb)); - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->scsi_sense_reason = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; return -ENOMEM; } } else @@ -1647,9 +1658,11 @@ int transport_handle_cdb_direct( * and call transport_generic_request_failure() if necessary.. */ ret = transport_generic_new_cmd(cmd); - if (ret < 0) - transport_generic_request_failure(cmd); - + if (ret < 0) { + cmd->transport_error_status = ret; + transport_generic_request_failure(cmd, 0, + (cmd->data_direction != DMA_TO_DEVICE)); + } return 0; } EXPORT_SYMBOL(transport_handle_cdb_direct); @@ -1785,16 +1798,20 @@ static int transport_stop_tasks_for_cmd(struct se_cmd *cmd) /* * Handle SAM-esque emulation for generic transport request failures. */ -static void transport_generic_request_failure(struct se_cmd *cmd) +static void transport_generic_request_failure( + struct se_cmd *cmd, + int complete, + int sc) { int ret = 0; pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x" " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd), cmd->t_task_cdb[0]); - pr_debug("-----[ i_state: %d t_state: %d scsi_sense_reason: %d\n", + pr_debug("-----[ i_state: %d t_state: %d transport_error_status: %d\n", cmd->se_tfo->get_cmd_state(cmd), - cmd->t_state, cmd->scsi_sense_reason); + cmd->t_state, + cmd->transport_error_status); pr_debug("-----[ t_tasks: %d t_task_cdbs_left: %d" " t_task_cdbs_sent: %d t_task_cdbs_ex_left: %d --" " t_transport_active: %d t_transport_stop: %d" @@ -1812,19 +1829,46 @@ static void transport_generic_request_failure(struct se_cmd *cmd) if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) transport_complete_task_attr(cmd); - switch (cmd->scsi_sense_reason) { - case TCM_NON_EXISTENT_LUN: - case TCM_UNSUPPORTED_SCSI_OPCODE: - case TCM_INVALID_CDB_FIELD: - case TCM_INVALID_PARAMETER_LIST: - case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE: - case TCM_UNKNOWN_MODE_PAGE: - case TCM_WRITE_PROTECTED: - case TCM_CHECK_CONDITION_ABORT_CMD: - case TCM_CHECK_CONDITION_UNIT_ATTENTION: - case TCM_CHECK_CONDITION_NOT_READY: + if (complete) { + cmd->transport_error_status = PYX_TRANSPORT_LU_COMM_FAILURE; + } + + switch (cmd->transport_error_status) { + case PYX_TRANSPORT_UNKNOWN_SAM_OPCODE: + cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; + break; + case PYX_TRANSPORT_REQ_TOO_MANY_SECTORS: + cmd->scsi_sense_reason = TCM_SECTOR_COUNT_TOO_MANY; break; - case TCM_RESERVATION_CONFLICT: + case PYX_TRANSPORT_INVALID_CDB_FIELD: + cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; + break; + case PYX_TRANSPORT_INVALID_PARAMETER_LIST: + cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; + break; + case PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES: + if (!sc) + transport_new_cmd_failure(cmd); + /* + * Currently for PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES, + * we force this session to fall back to session + * recovery. + */ + cmd->se_tfo->fall_back_to_erl0(cmd->se_sess); + cmd->se_tfo->stop_session(cmd->se_sess, 0, 0); + + goto check_stop; + case PYX_TRANSPORT_LU_COMM_FAILURE: + case PYX_TRANSPORT_ILLEGAL_REQUEST: + cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + break; + case PYX_TRANSPORT_UNKNOWN_MODE_PAGE: + cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE; + break; + case PYX_TRANSPORT_WRITE_PROTECTED: + cmd->scsi_sense_reason = TCM_WRITE_PROTECTED; + break; + case PYX_TRANSPORT_RESERVATION_CONFLICT: /* * No SENSE Data payload for this case, set SCSI Status * and queue the response to $FABRIC_MOD. @@ -1849,9 +1893,15 @@ static void transport_generic_request_failure(struct se_cmd *cmd) if (ret == -EAGAIN || ret == -ENOMEM) goto queue_full; goto check_stop; + case PYX_TRANSPORT_USE_SENSE_REASON: + /* + * struct se_cmd->scsi_sense_reason already set + */ + break; default: pr_err("Unknown transport error for CDB 0x%02x: %d\n", - cmd->t_task_cdb[0], cmd->scsi_sense_reason); + cmd->t_task_cdb[0], + cmd->transport_error_status); cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; break; } @@ -1862,10 +1912,14 @@ static void transport_generic_request_failure(struct se_cmd *cmd) * transport_send_check_condition_and_sense() after handling * possible unsoliticied write data payloads. */ - ret = transport_send_check_condition_and_sense(cmd, - cmd->scsi_sense_reason, 0); - if (ret == -EAGAIN || ret == -ENOMEM) - goto queue_full; + if (!sc && !cmd->se_tfo->new_cmd_map) + transport_new_cmd_failure(cmd); + else { + ret = transport_send_check_condition_and_sense(cmd, + cmd->scsi_sense_reason, 0); + if (ret == -EAGAIN || ret == -ENOMEM) + goto queue_full; + } check_stop: transport_lun_remove_cmd(cmd); @@ -1948,12 +2002,19 @@ static inline int transport_execute_task_attr(struct se_cmd *cmd) * to allow the passed struct se_cmd list of tasks to the front of the list. */ if (cmd->sam_task_attr == MSG_HEAD_TAG) { + atomic_inc(&cmd->se_dev->dev_hoq_count); + smp_mb__after_atomic_inc(); pr_debug("Added HEAD_OF_QUEUE for CDB:" " 0x%02x, se_ordered_id: %u\n", cmd->t_task_cdb[0], cmd->se_ordered_id); return 1; } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { + spin_lock(&cmd->se_dev->ordered_cmd_lock); + list_add_tail(&cmd->se_ordered_node, + &cmd->se_dev->ordered_cmd_list); + spin_unlock(&cmd->se_dev->ordered_cmd_lock); + atomic_inc(&cmd->se_dev->dev_ordered_sync); smp_mb__after_atomic_inc(); @@ -2015,9 +2076,9 @@ static int transport_execute_tasks(struct se_cmd *cmd) { int add_tasks; - if (se_dev_check_online(cmd->se_dev) != 0) { - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - transport_generic_request_failure(cmd); + if (se_dev_check_online(cmd->se_orig_obj_ptr) != 0) { + cmd->transport_error_status = PYX_TRANSPORT_LU_COMM_FAILURE; + transport_generic_request_failure(cmd, 0, 1); return 0; } @@ -2102,13 +2163,14 @@ static int __transport_execute_tasks(struct se_device *dev) else error = dev->transport->do_task(task); if (error != 0) { + cmd->transport_error_status = error; spin_lock_irqsave(&cmd->t_state_lock, flags); task->task_flags &= ~TF_ACTIVE; spin_unlock_irqrestore(&cmd->t_state_lock, flags); atomic_set(&cmd->t_transport_sent, 0); transport_stop_tasks_for_cmd(cmd); atomic_inc(&dev->depth_left); - transport_generic_request_failure(cmd); + transport_generic_request_failure(cmd, 0, 1); } goto check_depth; @@ -2116,6 +2178,19 @@ static int __transport_execute_tasks(struct se_device *dev) return 0; } +void transport_new_cmd_failure(struct se_cmd *se_cmd) +{ + unsigned long flags; + /* + * Any unsolicited data will get dumped for failed command inside of + * the fabric plugin + */ + spin_lock_irqsave(&se_cmd->t_state_lock, flags); + se_cmd->se_cmd_flags |= SCF_SE_CMD_FAILED; + se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; + spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); +} + static inline u32 transport_get_sectors_6( unsigned char *cdb, struct se_cmd *cmd, @@ -2138,15 +2213,10 @@ static inline u32 transport_get_sectors_6( /* * Everything else assume TYPE_DISK Sector CDB location. - * Use 8-bit sector value. SBC-3 says: - * - * A TRANSFER LENGTH field set to zero specifies that 256 - * logical blocks shall be written. Any other value - * specifies the number of logical blocks that shall be - * written. + * Use 8-bit sector value. */ type_disk: - return cdb[4] ? : 256; + return (u32)cdb[4]; } static inline u32 transport_get_sectors_10( @@ -2390,6 +2460,27 @@ static int transport_get_sense_data(struct se_cmd *cmd) return -1; } +static int +transport_handle_reservation_conflict(struct se_cmd *cmd) +{ + cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; + cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; + cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; + /* + * For UA Interlock Code 11b, a RESERVATION CONFLICT will + * establish a UNIT ATTENTION with PREVIOUS RESERVATION + * CONFLICT STATUS. + * + * See spc4r17, section 7.4.6 Control Mode Page, Table 349 + */ + if (cmd->se_sess && + cmd->se_dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 2) + core_scsi3_ua_allocate(cmd->se_sess->se_node_acl, + cmd->orig_fe_lun, 0x2C, + ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS); + return -EINVAL; +} + static inline long long transport_dev_end_lba(struct se_device *dev) { return dev->transport->get_blocks(dev) + 1; @@ -2504,12 +2595,8 @@ static int transport_generic_cmd_sequencer( */ if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type) != 0) { if (su_dev->t10_pr.pr_ops.t10_seq_non_holder( - cmd, cdb, pr_reg_type) != 0) { - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; - cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return -EBUSY; - } + cmd, cdb, pr_reg_type) != 0) + return transport_handle_reservation_conflict(cmd); /* * This means the CDB is allowed for the SCSI Initiator port * when said port is *NOT* holding the legacy SPC-2 or @@ -2571,8 +2658,7 @@ static int transport_generic_cmd_sequencer( goto out_unsupported_cdb; size = transport_get_size(sectors, cdb, cmd); cmd->t_task_lba = transport_lba_32(cdb); - if (cdb[1] & 0x8) - cmd->se_cmd_flags |= SCF_FUA; + cmd->t_tasks_fua = (cdb[1] & 0x8); cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; break; case WRITE_12: @@ -2581,8 +2667,7 @@ static int transport_generic_cmd_sequencer( goto out_unsupported_cdb; size = transport_get_size(sectors, cdb, cmd); cmd->t_task_lba = transport_lba_32(cdb); - if (cdb[1] & 0x8) - cmd->se_cmd_flags |= SCF_FUA; + cmd->t_tasks_fua = (cdb[1] & 0x8); cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; break; case WRITE_16: @@ -2591,13 +2676,12 @@ static int transport_generic_cmd_sequencer( goto out_unsupported_cdb; size = transport_get_size(sectors, cdb, cmd); cmd->t_task_lba = transport_lba_64(cdb); - if (cdb[1] & 0x8) - cmd->se_cmd_flags |= SCF_FUA; + cmd->t_tasks_fua = (cdb[1] & 0x8); cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; break; case XDWRITEREAD_10: if ((cmd->data_direction != DMA_TO_DEVICE) || - !(cmd->se_cmd_flags & SCF_BIDI)) + !(cmd->t_tasks_bidi)) goto out_invalid_cdb_field; sectors = transport_get_sectors_10(cdb, cmd, §or_ret); if (sector_ret) @@ -2616,8 +2700,7 @@ static int transport_generic_cmd_sequencer( * Setup BIDI XOR callback to be run after I/O completion. */ cmd->transport_complete_callback = &transport_xor_callback; - if (cdb[1] & 0x8) - cmd->se_cmd_flags |= SCF_FUA; + cmd->t_tasks_fua = (cdb[1] & 0x8); break; case VARIABLE_LENGTH_CMD: service_action = get_unaligned_be16(&cdb[8]); @@ -2645,8 +2728,7 @@ static int transport_generic_cmd_sequencer( * completion. */ cmd->transport_complete_callback = &transport_xor_callback; - if (cdb[1] & 0x8) - cmd->se_cmd_flags |= SCF_FUA; + cmd->t_tasks_fua = (cdb[10] & 0x8); break; case WRITE_SAME_32: sectors = transport_get_sectors_32(cdb, cmd, §or_ret); @@ -3089,13 +3171,18 @@ static void transport_complete_task_attr(struct se_cmd *cmd) " SIMPLE: %u\n", dev->dev_cur_ordered_id, cmd->se_ordered_id); } else if (cmd->sam_task_attr == MSG_HEAD_TAG) { + atomic_dec(&dev->dev_hoq_count); + smp_mb__after_atomic_dec(); dev->dev_cur_ordered_id++; pr_debug("Incremented dev_cur_ordered_id: %u for" " HEAD_OF_QUEUE: %u\n", dev->dev_cur_ordered_id, cmd->se_ordered_id); } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { + spin_lock(&dev->ordered_cmd_lock); + list_del(&cmd->se_ordered_node); atomic_dec(&dev->dev_ordered_sync); smp_mb__after_atomic_dec(); + spin_unlock(&dev->ordered_cmd_lock); dev->dev_cur_ordered_id++; pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED:" @@ -3408,18 +3495,6 @@ int transport_generic_map_mem_to_cmd( if ((cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) || (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)) { - /* - * Reject SCSI data overflow with map_mem_to_cmd() as incoming - * scatterlists already have been set to follow what the fabric - * passes for the original expected data transfer length. - */ - if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { - pr_warn("Rejecting SCSI DATA overflow for fabric using" - " SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC\n"); - cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; - return -EINVAL; - } cmd->t_data_sg = sgl; cmd->t_data_nents = sgl_count; @@ -3738,7 +3813,7 @@ int transport_generic_new_cmd(struct se_cmd *cmd) cmd->data_length) { ret = transport_generic_get_mem(cmd); if (ret < 0) - goto out_fail; + return ret; } /* @@ -3767,15 +3842,8 @@ int transport_generic_new_cmd(struct se_cmd *cmd) task_cdbs = transport_allocate_control_task(cmd); } - if (task_cdbs < 0) + if (task_cdbs <= 0) goto out_fail; - else if (!task_cdbs && (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)) { - cmd->t_state = TRANSPORT_COMPLETE; - atomic_set(&cmd->t_transport_active, 1); - INIT_WORK(&cmd->work, target_complete_ok_work); - queue_work(target_completion_wq, &cmd->work); - return 0; - } if (set_counts) { atomic_inc(&cmd->t_fe_count); @@ -3861,7 +3929,7 @@ static int transport_generic_write_pending(struct se_cmd *cmd) else if (ret < 0) return ret; - return 1; + return PYX_TRANSPORT_WRITE_PENDING; queue_full: pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); @@ -4534,6 +4602,9 @@ void transport_send_task_abort(struct se_cmd *cmd) if (cmd->se_tfo->write_pending_status(cmd) != 0) { atomic_inc(&cmd->t_transport_aborted); smp_mb__after_atomic_inc(); + cmd->scsi_status = SAM_STAT_TASK_ABORTED; + transport_new_cmd_failure(cmd); + return; } } cmd->scsi_status = SAM_STAT_TASK_ABORTED; @@ -4599,6 +4670,8 @@ static int transport_processing_thread(void *param) struct se_cmd *cmd; struct se_device *dev = (struct se_device *) param; + set_user_nice(current, -20); + while (!kthread_should_stop()) { ret = wait_event_interruptible(dev->dev_queue_obj.thread_wq, atomic_read(&dev->dev_queue_obj.queue_cnt) || @@ -4625,13 +4698,18 @@ static int transport_processing_thread(void *param) } ret = cmd->se_tfo->new_cmd_map(cmd); if (ret < 0) { - transport_generic_request_failure(cmd); + cmd->transport_error_status = ret; + transport_generic_request_failure(cmd, + 0, (cmd->data_direction != + DMA_TO_DEVICE)); break; } ret = transport_generic_new_cmd(cmd); if (ret < 0) { - transport_generic_request_failure(cmd); - break; + cmd->transport_error_status = ret; + transport_generic_request_failure(cmd, + 0, (cmd->data_direction != + DMA_TO_DEVICE)); } break; case TRANSPORT_PROCESS_WRITE: diff --git a/trunk/drivers/target/tcm_fc/tfc_cmd.c b/trunk/drivers/target/tcm_fc/tfc_cmd.c index 71fc9cea5dc9..4fac37c4c615 100644 --- a/trunk/drivers/target/tcm_fc/tfc_cmd.c +++ b/trunk/drivers/target/tcm_fc/tfc_cmd.c @@ -200,7 +200,7 @@ int ft_write_pending(struct se_cmd *se_cmd) lport = ep->lp; fp = fc_frame_alloc(lport, sizeof(*txrdy)); if (!fp) - return -ENOMEM; /* Signal QUEUE_FULL */ + return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; txrdy = fc_frame_payload_get(fp, sizeof(*txrdy)); memset(txrdy, 0, sizeof(*txrdy)); diff --git a/trunk/drivers/target/tcm_fc/tfc_conf.c b/trunk/drivers/target/tcm_fc/tfc_conf.c index 9402b7387cac..5f770412ca40 100644 --- a/trunk/drivers/target/tcm_fc/tfc_conf.c +++ b/trunk/drivers/target/tcm_fc/tfc_conf.c @@ -436,7 +436,8 @@ static void ft_del_lport(struct se_wwn *wwn) struct ft_lport_acl *lacl = container_of(wwn, struct ft_lport_acl, fc_lport_wwn); - pr_debug("del lport %s\n", lacl->name); + pr_debug("del lport %s\n", + config_item_name(&wwn->wwn_group.cg_item)); mutex_lock(&ft_lport_lock); list_del(&lacl->list); mutex_unlock(&ft_lport_lock); diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index 2ad813674d77..f0d5718d2587 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -5107,11 +5107,11 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root = orig_root->fs_info->extent_root; struct btrfs_free_cluster *last_ptr = NULL; struct btrfs_block_group_cache *block_group = NULL; - struct btrfs_block_group_cache *used_block_group; int empty_cluster = 2 * 1024 * 1024; int allowed_chunk_alloc = 0; int done_chunk_alloc = 0; struct btrfs_space_info *space_info; + int last_ptr_loop = 0; int loop = 0; int index = 0; int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? @@ -5173,7 +5173,6 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, ideal_cache: block_group = btrfs_lookup_block_group(root->fs_info, search_start); - used_block_group = block_group; /* * we don't want to use the block group if it doesn't match our * allocation bits, or if its not cached. @@ -5211,7 +5210,6 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, u64 offset; int cached; - used_block_group = block_group; btrfs_get_block_group(block_group); search_start = block_group->key.objectid; @@ -5288,62 +5286,71 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, spin_unlock(&block_group->free_space_ctl->tree_lock); /* - * Ok we want to try and use the cluster allocator, so - * lets look there + * Ok we want to try and use the cluster allocator, so lets look + * there, unless we are on LOOP_NO_EMPTY_SIZE, since we will + * have tried the cluster allocator plenty of times at this + * point and not have found anything, so we are likely way too + * fragmented for the clustering stuff to find anything, so lets + * just skip it and let the allocator find whatever block it can + * find */ - if (last_ptr) { + if (last_ptr && loop < LOOP_NO_EMPTY_SIZE) { /* * the refill lock keeps out other * people trying to start a new cluster */ spin_lock(&last_ptr->refill_lock); - used_block_group = last_ptr->block_group; - if (used_block_group != block_group && - (!used_block_group || - used_block_group->ro || - !block_group_bits(used_block_group, data))) { - used_block_group = block_group; + if (!last_ptr->block_group || + last_ptr->block_group->ro || + !block_group_bits(last_ptr->block_group, data)) goto refill_cluster; - } - - if (used_block_group != block_group) - btrfs_get_block_group(used_block_group); - offset = btrfs_alloc_from_cluster(used_block_group, - last_ptr, num_bytes, used_block_group->key.objectid); + offset = btrfs_alloc_from_cluster(block_group, last_ptr, + num_bytes, search_start); if (offset) { /* we have a block, we're done */ spin_unlock(&last_ptr->refill_lock); goto checks; } - WARN_ON(last_ptr->block_group != used_block_group); - if (used_block_group != block_group) { - btrfs_put_block_group(used_block_group); - used_block_group = block_group; - } -refill_cluster: - BUG_ON(used_block_group != block_group); - /* If we are on LOOP_NO_EMPTY_SIZE, we can't - * set up a new clusters, so lets just skip it - * and let the allocator find whatever block - * it can find. If we reach this point, we - * will have tried the cluster allocator - * plenty of times and not have found - * anything, so we are likely way too - * fragmented for the clustering stuff to find - * anything. */ - if (loop >= LOOP_NO_EMPTY_SIZE) { + spin_lock(&last_ptr->lock); + /* + * whoops, this cluster doesn't actually point to + * this block group. Get a ref on the block + * group is does point to and try again + */ + if (!last_ptr_loop && last_ptr->block_group && + last_ptr->block_group != block_group && + index <= + get_block_group_index(last_ptr->block_group)) { + + btrfs_put_block_group(block_group); + block_group = last_ptr->block_group; + btrfs_get_block_group(block_group); + spin_unlock(&last_ptr->lock); spin_unlock(&last_ptr->refill_lock); - goto unclustered_alloc; - } + last_ptr_loop = 1; + search_start = block_group->key.objectid; + /* + * we know this block group is properly + * in the list because + * btrfs_remove_block_group, drops the + * cluster before it removes the block + * group from the list + */ + goto have_block_group; + } + spin_unlock(&last_ptr->lock); +refill_cluster: /* * this cluster didn't work out, free it and * start over */ btrfs_return_cluster_to_free_space(NULL, last_ptr); + last_ptr_loop = 0; + /* allocate a cluster in this block group */ ret = btrfs_find_space_cluster(trans, root, block_group, last_ptr, @@ -5383,7 +5390,6 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, goto loop; } -unclustered_alloc: offset = btrfs_find_space_for_alloc(block_group, search_start, num_bytes, empty_size); /* @@ -5410,14 +5416,14 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, search_start = stripe_align(root, offset); /* move on to the next group */ if (search_start + num_bytes >= search_end) { - btrfs_add_free_space(used_block_group, offset, num_bytes); + btrfs_add_free_space(block_group, offset, num_bytes); goto loop; } /* move on to the next group */ if (search_start + num_bytes > - used_block_group->key.objectid + used_block_group->key.offset) { - btrfs_add_free_space(used_block_group, offset, num_bytes); + block_group->key.objectid + block_group->key.offset) { + btrfs_add_free_space(block_group, offset, num_bytes); goto loop; } @@ -5425,14 +5431,14 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, ins->offset = num_bytes; if (offset < search_start) - btrfs_add_free_space(used_block_group, offset, + btrfs_add_free_space(block_group, offset, search_start - offset); BUG_ON(offset > search_start); - ret = btrfs_update_reserved_bytes(used_block_group, num_bytes, + ret = btrfs_update_reserved_bytes(block_group, num_bytes, alloc_type); if (ret == -EAGAIN) { - btrfs_add_free_space(used_block_group, offset, num_bytes); + btrfs_add_free_space(block_group, offset, num_bytes); goto loop; } @@ -5441,19 +5447,15 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, ins->offset = num_bytes; if (offset < search_start) - btrfs_add_free_space(used_block_group, offset, + btrfs_add_free_space(block_group, offset, search_start - offset); BUG_ON(offset > search_start); - if (used_block_group != block_group) - btrfs_put_block_group(used_block_group); btrfs_put_block_group(block_group); break; loop: failed_cluster_refill = false; failed_alloc = false; BUG_ON(index != get_block_group_index(block_group)); - if (used_block_group != block_group) - btrfs_put_block_group(used_block_group); btrfs_put_block_group(block_group); } up_read(&space_info->groups_sem); diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index 49f3c9dc09f4..be1bf627a14b 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -935,10 +935,8 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, node = tree_search(tree, start); if (!node) { prealloc = alloc_extent_state_atomic(prealloc); - if (!prealloc) { - err = -ENOMEM; - goto out; - } + if (!prealloc) + return -ENOMEM; err = insert_state(tree, prealloc, start, end, &bits); prealloc = NULL; BUG_ON(err == -EEXIST); @@ -994,10 +992,8 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, */ if (state->start < start) { prealloc = alloc_extent_state_atomic(prealloc); - if (!prealloc) { - err = -ENOMEM; - goto out; - } + if (!prealloc) + return -ENOMEM; err = split_state(tree, state, prealloc, start); BUG_ON(err == -EEXIST); prealloc = NULL; @@ -1028,10 +1024,8 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, this_end = last_start - 1; prealloc = alloc_extent_state_atomic(prealloc); - if (!prealloc) { - err = -ENOMEM; - goto out; - } + if (!prealloc) + return -ENOMEM; /* * Avoid to free 'prealloc' if it can be merged with @@ -1057,10 +1051,8 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, */ if (state->start <= end && state->end > end) { prealloc = alloc_extent_state_atomic(prealloc); - if (!prealloc) { - err = -ENOMEM; - goto out; - } + if (!prealloc) + return -ENOMEM; err = split_state(tree, state, prealloc, end + 1); BUG_ON(err == -EEXIST); diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index 0a8c8f8304b1..c37433d3cd82 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -1611,7 +1611,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) if ((sb->s_flags & MS_RDONLY) && !root->fs_info->fs_devices->seeding) return -EINVAL; - bdev = blkdev_get_by_path(device_path, FMODE_WRITE | FMODE_EXCL, + bdev = blkdev_get_by_path(device_path, FMODE_EXCL, root->fs_info->bdev_holder); if (IS_ERR(bdev)) return PTR_ERR(bdev); diff --git a/trunk/fs/ceph/addr.c b/trunk/fs/ceph/addr.c index 173b1d22e59b..4144caf2f9d3 100644 --- a/trunk/fs/ceph/addr.c +++ b/trunk/fs/ceph/addr.c @@ -87,7 +87,7 @@ static int ceph_set_page_dirty(struct page *page) snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context); /* dirty the head */ - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (ci->i_head_snapc == NULL) ci->i_head_snapc = ceph_get_snap_context(snapc); ++ci->i_wrbuffer_ref_head; @@ -100,7 +100,7 @@ static int ceph_set_page_dirty(struct page *page) ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref_head-1, ci->i_wrbuffer_ref, ci->i_wrbuffer_ref_head, snapc, snapc->seq, snapc->num_snaps); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); /* now adjust page */ spin_lock_irq(&mapping->tree_lock); @@ -391,7 +391,7 @@ static struct ceph_snap_context *get_oldest_context(struct inode *inode, struct ceph_snap_context *snapc = NULL; struct ceph_cap_snap *capsnap = NULL; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { dout(" cap_snap %p snapc %p has %d dirty pages\n", capsnap, capsnap->context, capsnap->dirty_pages); @@ -407,7 +407,7 @@ static struct ceph_snap_context *get_oldest_context(struct inode *inode, dout(" head snapc %p has %d dirty pages\n", snapc, ci->i_wrbuffer_ref_head); } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return snapc; } diff --git a/trunk/fs/ceph/caps.c b/trunk/fs/ceph/caps.c index 8b53193e4f7c..0f327c6c9679 100644 --- a/trunk/fs/ceph/caps.c +++ b/trunk/fs/ceph/caps.c @@ -309,7 +309,7 @@ void ceph_reservation_status(struct ceph_fs_client *fsc, /* * Find ceph_cap for given mds, if any. * - * Called with i_ceph_lock held. + * Called with i_lock held. */ static struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds) { @@ -332,9 +332,9 @@ struct ceph_cap *ceph_get_cap_for_mds(struct ceph_inode_info *ci, int mds) { struct ceph_cap *cap; - spin_lock(&ci->i_ceph_lock); + spin_lock(&ci->vfs_inode.i_lock); cap = __get_cap_for_mds(ci, mds); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&ci->vfs_inode.i_lock); return cap; } @@ -361,16 +361,15 @@ static int __ceph_get_cap_mds(struct ceph_inode_info *ci) int ceph_get_cap_mds(struct inode *inode) { - struct ceph_inode_info *ci = ceph_inode(inode); int mds; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); mds = __ceph_get_cap_mds(ceph_inode(inode)); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return mds; } /* - * Called under i_ceph_lock. + * Called under i_lock. */ static void __insert_cap_node(struct ceph_inode_info *ci, struct ceph_cap *new) @@ -416,7 +415,7 @@ static void __cap_set_timeouts(struct ceph_mds_client *mdsc, * * If I_FLUSH is set, leave the inode at the front of the list. * - * Caller holds i_ceph_lock + * Caller holds i_lock * -> we take mdsc->cap_delay_lock */ static void __cap_delay_requeue(struct ceph_mds_client *mdsc, @@ -458,7 +457,7 @@ static void __cap_delay_requeue_front(struct ceph_mds_client *mdsc, /* * Cancel delayed work on cap. * - * Caller must hold i_ceph_lock. + * Caller must hold i_lock. */ static void __cap_delay_cancel(struct ceph_mds_client *mdsc, struct ceph_inode_info *ci) @@ -533,14 +532,14 @@ int ceph_add_cap(struct inode *inode, wanted |= ceph_caps_for_mode(fmode); retry: - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); cap = __get_cap_for_mds(ci, mds); if (!cap) { if (new_cap) { cap = new_cap; new_cap = NULL; } else { - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); new_cap = get_cap(mdsc, caps_reservation); if (new_cap == NULL) return -ENOMEM; @@ -626,7 +625,7 @@ int ceph_add_cap(struct inode *inode, if (fmode >= 0) __ceph_get_fmode(ci, fmode); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); wake_up_all(&ci->i_cap_wq); return 0; } @@ -793,7 +792,7 @@ int ceph_caps_revoking(struct ceph_inode_info *ci, int mask) struct rb_node *p; int ret = 0; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { cap = rb_entry(p, struct ceph_cap, ci_node); if (__cap_is_valid(cap) && @@ -802,7 +801,7 @@ int ceph_caps_revoking(struct ceph_inode_info *ci, int mask) break; } } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); dout("ceph_caps_revoking %p %s = %d\n", inode, ceph_cap_string(mask), ret); return ret; @@ -856,7 +855,7 @@ int __ceph_caps_mds_wanted(struct ceph_inode_info *ci) } /* - * called under i_ceph_lock + * called under i_lock */ static int __ceph_is_any_caps(struct ceph_inode_info *ci) { @@ -866,7 +865,7 @@ static int __ceph_is_any_caps(struct ceph_inode_info *ci) /* * Remove a cap. Take steps to deal with a racing iterate_session_caps. * - * caller should hold i_ceph_lock. + * caller should hold i_lock. * caller will not hold session s_mutex if called from destroy_inode. */ void __ceph_remove_cap(struct ceph_cap *cap) @@ -1029,7 +1028,7 @@ static void __queue_cap_release(struct ceph_mds_session *session, /* * Queue cap releases when an inode is dropped from our cache. Since - * inode is about to be destroyed, there is no need for i_ceph_lock. + * inode is about to be destroyed, there is no need for i_lock. */ void ceph_queue_caps_release(struct inode *inode) { @@ -1050,7 +1049,7 @@ void ceph_queue_caps_release(struct inode *inode) /* * Send a cap msg on the given inode. Update our caps state, then - * drop i_ceph_lock and send the message. + * drop i_lock and send the message. * * Make note of max_size reported/requested from mds, revoked caps * that have now been implemented. @@ -1062,13 +1061,13 @@ void ceph_queue_caps_release(struct inode *inode) * Return non-zero if delayed release, or we experienced an error * such that the caller should requeue + retry later. * - * called with i_ceph_lock, then drops it. + * called with i_lock, then drops it. * caller should hold snap_rwsem (read), s_mutex. */ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, int op, int used, int want, int retain, int flushing, unsigned *pflush_tid) - __releases(cap->ci->i_ceph_lock) + __releases(cap->ci->vfs_inode->i_lock) { struct ceph_inode_info *ci = cap->ci; struct inode *inode = &ci->vfs_inode; @@ -1171,7 +1170,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, xattr_version = ci->i_xattrs.version; } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); ret = send_cap_msg(session, ceph_vino(inode).ino, cap_id, op, keep, want, flushing, seq, flush_tid, issue_seq, mseq, @@ -1199,13 +1198,13 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, * Unless @again is true, skip cap_snaps that were already sent to * the MDS (i.e., during this session). * - * Called under i_ceph_lock. Takes s_mutex as needed. + * Called under i_lock. Takes s_mutex as needed. */ void __ceph_flush_snaps(struct ceph_inode_info *ci, struct ceph_mds_session **psession, int again) - __releases(ci->i_ceph_lock) - __acquires(ci->i_ceph_lock) + __releases(ci->vfs_inode->i_lock) + __acquires(ci->vfs_inode->i_lock) { struct inode *inode = &ci->vfs_inode; int mds; @@ -1262,7 +1261,7 @@ void __ceph_flush_snaps(struct ceph_inode_info *ci, session = NULL; } if (!session) { - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); mutex_lock(&mdsc->mutex); session = __ceph_lookup_mds_session(mdsc, mds); mutex_unlock(&mdsc->mutex); @@ -1276,7 +1275,7 @@ void __ceph_flush_snaps(struct ceph_inode_info *ci, * deletion or migration. retry, and we'll * get a better @mds value next time. */ - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); goto retry; } @@ -1286,7 +1285,7 @@ void __ceph_flush_snaps(struct ceph_inode_info *ci, list_del_init(&capsnap->flushing_item); list_add_tail(&capsnap->flushing_item, &session->s_cap_snaps_flushing); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); dout("flush_snaps %p cap_snap %p follows %lld tid %llu\n", inode, capsnap, capsnap->follows, capsnap->flush_tid); @@ -1303,7 +1302,7 @@ void __ceph_flush_snaps(struct ceph_inode_info *ci, next_follows = capsnap->follows + 1; ceph_put_cap_snap(capsnap); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); goto retry; } @@ -1323,9 +1322,11 @@ void __ceph_flush_snaps(struct ceph_inode_info *ci, static void ceph_flush_snaps(struct ceph_inode_info *ci) { - spin_lock(&ci->i_ceph_lock); + struct inode *inode = &ci->vfs_inode; + + spin_lock(&inode->i_lock); __ceph_flush_snaps(ci, NULL, 0); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } /* @@ -1372,7 +1373,7 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) * Add dirty inode to the flushing list. Assigned a seq number so we * can wait for caps to flush without starving. * - * Called under i_ceph_lock. + * Called under i_lock. */ static int __mark_caps_flushing(struct inode *inode, struct ceph_mds_session *session) @@ -1420,9 +1421,9 @@ static int try_nonblocking_invalidate(struct inode *inode) struct ceph_inode_info *ci = ceph_inode(inode); u32 invalidating_gen = ci->i_rdcache_gen; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); invalidate_mapping_pages(&inode->i_data, 0, -1); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (inode->i_data.nrpages == 0 && invalidating_gen == ci->i_rdcache_gen) { @@ -1469,7 +1470,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, if (mdsc->stopping) is_delayed = 1; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (ci->i_ceph_flags & CEPH_I_FLUSH) flags |= CHECK_CAPS_FLUSH; @@ -1479,7 +1480,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, __ceph_flush_snaps(ci, &session, 0); goto retry_locked; retry: - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); retry_locked: file_wanted = __ceph_caps_file_wanted(ci); used = __ceph_caps_used(ci); @@ -1633,7 +1634,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, if (mutex_trylock(&session->s_mutex) == 0) { dout("inverting session/ino locks on %p\n", session); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (took_snap_rwsem) { up_read(&mdsc->snap_rwsem); took_snap_rwsem = 0; @@ -1647,7 +1648,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, if (down_read_trylock(&mdsc->snap_rwsem) == 0) { dout("inverting snap/in locks on %p\n", inode); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); down_read(&mdsc->snap_rwsem); took_snap_rwsem = 1; goto retry; @@ -1663,10 +1664,10 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, mds = cap->mds; /* remember mds, so we don't repeat */ sent++; - /* __send_cap drops i_ceph_lock */ + /* __send_cap drops i_lock */ delayed += __send_cap(mdsc, cap, CEPH_CAP_OP_UPDATE, used, want, retain, flushing, NULL); - goto retry; /* retake i_ceph_lock and restart our cap scan. */ + goto retry; /* retake i_lock and restart our cap scan. */ } /* @@ -1680,7 +1681,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, else if (!is_delayed || force_requeue) __cap_delay_requeue(mdsc, ci); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (queue_invalidate) ceph_queue_invalidate(inode); @@ -1703,7 +1704,7 @@ static int try_flush_caps(struct inode *inode, struct ceph_mds_session *session, int flushing = 0; retry: - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (ci->i_ceph_flags & CEPH_I_NOFLUSH) { dout("try_flush_caps skipping %p I_NOFLUSH set\n", inode); goto out; @@ -1715,7 +1716,7 @@ static int try_flush_caps(struct inode *inode, struct ceph_mds_session *session, int delayed; if (!session) { - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); session = cap->session; mutex_lock(&session->s_mutex); goto retry; @@ -1726,18 +1727,18 @@ static int try_flush_caps(struct inode *inode, struct ceph_mds_session *session, flushing = __mark_caps_flushing(inode, session); - /* __send_cap drops i_ceph_lock */ + /* __send_cap drops i_lock */ delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, used, want, cap->issued | cap->implemented, flushing, flush_tid); if (!delayed) goto out_unlocked; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); __cap_delay_requeue(mdsc, ci); } out: - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); out_unlocked: if (session && unlock_session) mutex_unlock(&session->s_mutex); @@ -1752,7 +1753,7 @@ static int caps_are_flushed(struct inode *inode, unsigned tid) struct ceph_inode_info *ci = ceph_inode(inode); int i, ret = 1; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); for (i = 0; i < CEPH_CAP_BITS; i++) if ((ci->i_flushing_caps & (1 << i)) && ci->i_cap_flush_tid[i] <= tid) { @@ -1760,7 +1761,7 @@ static int caps_are_flushed(struct inode *inode, unsigned tid) ret = 0; break; } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return ret; } @@ -1867,10 +1868,10 @@ int ceph_write_inode(struct inode *inode, struct writeback_control *wbc) struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (__ceph_caps_dirty(ci)) __cap_delay_requeue_front(mdsc, ci); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } return err; } @@ -1893,7 +1894,7 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc, struct inode *inode = &ci->vfs_inode; struct ceph_cap *cap; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); cap = ci->i_auth_cap; if (cap && cap->session == session) { dout("kick_flushing_caps %p cap %p capsnap %p\n", inode, @@ -1903,7 +1904,7 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc, pr_err("%p auth cap %p not mds%d ???\n", inode, cap, session->s_mds); } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } } @@ -1920,7 +1921,7 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, struct ceph_cap *cap; int delayed = 0; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); cap = ci->i_auth_cap; if (cap && cap->session == session) { dout("kick_flushing_caps %p cap %p %s\n", inode, @@ -1931,14 +1932,14 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, cap->issued | cap->implemented, ci->i_flushing_caps, NULL); if (delayed) { - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); __cap_delay_requeue(mdsc, ci); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } } else { pr_err("%p auth cap %p not mds%d ???\n", inode, cap, session->s_mds); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } } } @@ -1951,7 +1952,7 @@ static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc, struct ceph_cap *cap; int delayed = 0; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); cap = ci->i_auth_cap; dout("kick_flushing_inode_caps %p flushing %s flush_seq %lld\n", inode, ceph_cap_string(ci->i_flushing_caps), ci->i_cap_flush_seq); @@ -1963,12 +1964,12 @@ static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc, cap->issued | cap->implemented, ci->i_flushing_caps, NULL); if (delayed) { - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); __cap_delay_requeue(mdsc, ci); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } } else { - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } } @@ -1977,7 +1978,7 @@ static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc, * Take references to capabilities we hold, so that we don't release * them to the MDS prematurely. * - * Protected by i_ceph_lock. + * Protected by i_lock. */ static void __take_cap_refs(struct ceph_inode_info *ci, int got) { @@ -2015,7 +2016,7 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want, dout("get_cap_refs %p need %s want %s\n", inode, ceph_cap_string(need), ceph_cap_string(want)); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); /* make sure file is actually open */ file_wanted = __ceph_caps_file_wanted(ci); @@ -2076,7 +2077,7 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want, ceph_cap_string(have), ceph_cap_string(need)); } out: - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); dout("get_cap_refs %p ret %d got %s\n", inode, ret, ceph_cap_string(*got)); return ret; @@ -2093,7 +2094,7 @@ static void check_max_size(struct inode *inode, loff_t endoff) int check = 0; /* do we need to explicitly request a larger max_size? */ - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if ((endoff >= ci->i_max_size || endoff > (inode->i_size << 1)) && endoff > ci->i_wanted_max_size) { @@ -2102,7 +2103,7 @@ static void check_max_size(struct inode *inode, loff_t endoff) ci->i_wanted_max_size = endoff; check = 1; } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (check) ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); } @@ -2139,9 +2140,9 @@ int ceph_get_caps(struct ceph_inode_info *ci, int need, int want, int *got, */ void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps) { - spin_lock(&ci->i_ceph_lock); + spin_lock(&ci->vfs_inode.i_lock); __take_cap_refs(ci, caps); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&ci->vfs_inode.i_lock); } /* @@ -2159,7 +2160,7 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) int last = 0, put = 0, flushsnaps = 0, wake = 0; struct ceph_cap_snap *capsnap; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (had & CEPH_CAP_PIN) --ci->i_pin_ref; if (had & CEPH_CAP_FILE_RD) @@ -2192,7 +2193,7 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) } } } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); dout("put_cap_refs %p had %s%s%s\n", inode, ceph_cap_string(had), last ? " last" : "", put ? " put" : ""); @@ -2224,7 +2225,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, int found = 0; struct ceph_cap_snap *capsnap = NULL; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); ci->i_wrbuffer_ref -= nr; last = !ci->i_wrbuffer_ref; @@ -2273,7 +2274,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, } } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (last) { ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); @@ -2290,7 +2291,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, * Handle a cap GRANT message from the MDS. (Note that a GRANT may * actually be a revocation if it specifies a smaller cap set.) * - * caller holds s_mutex and i_ceph_lock, we drop both. + * caller holds s_mutex and i_lock, we drop both. * * return value: * 0 - ok @@ -2301,7 +2302,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, struct ceph_mds_session *session, struct ceph_cap *cap, struct ceph_buffer *xattr_buf) - __releases(ci->i_ceph_lock) + __releases(inode->i_lock) { struct ceph_inode_info *ci = ceph_inode(inode); int mds = session->s_mds; @@ -2452,7 +2453,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, } BUG_ON(cap->issued & ~cap->implemented); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (writeback) /* * queue inode for writeback: we can't actually call @@ -2482,7 +2483,7 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid, struct ceph_mds_caps *m, struct ceph_mds_session *session, struct ceph_cap *cap) - __releases(ci->i_ceph_lock) + __releases(inode->i_lock) { struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; @@ -2538,7 +2539,7 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid, wake_up_all(&ci->i_cap_wq); out: - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (drop) iput(inode); } @@ -2561,7 +2562,7 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid, dout("handle_cap_flushsnap_ack inode %p ci %p mds%d follows %lld\n", inode, ci, session->s_mds, follows); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { if (capsnap->follows == follows) { if (capsnap->flush_tid != flush_tid) { @@ -2584,7 +2585,7 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid, capsnap, capsnap->follows); } } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (drop) iput(inode); } @@ -2597,7 +2598,7 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid, static void handle_cap_trunc(struct inode *inode, struct ceph_mds_caps *trunc, struct ceph_mds_session *session) - __releases(ci->i_ceph_lock) + __releases(inode->i_lock) { struct ceph_inode_info *ci = ceph_inode(inode); int mds = session->s_mds; @@ -2616,7 +2617,7 @@ static void handle_cap_trunc(struct inode *inode, inode, mds, seq, truncate_size, truncate_seq); queue_trunc = ceph_fill_file_size(inode, issued, truncate_seq, truncate_size, size); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (queue_trunc) ceph_queue_vmtruncate(inode); @@ -2645,7 +2646,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex, dout("handle_cap_export inode %p ci %p mds%d mseq %d\n", inode, ci, mds, mseq); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); /* make sure we haven't seen a higher mseq */ for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { @@ -2689,7 +2690,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex, } /* else, we already released it */ - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } /* @@ -2744,9 +2745,9 @@ static void handle_cap_import(struct ceph_mds_client *mdsc, up_read(&mdsc->snap_rwsem); /* make sure we re-request max_size, if necessary */ - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); ci->i_requested_max_size = 0; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } /* @@ -2761,7 +2762,6 @@ void ceph_handle_caps(struct ceph_mds_session *session, struct ceph_mds_client *mdsc = session->s_mdsc; struct super_block *sb = mdsc->fsc->sb; struct inode *inode; - struct ceph_inode_info *ci; struct ceph_cap *cap; struct ceph_mds_caps *h; int mds = session->s_mds; @@ -2815,7 +2815,6 @@ void ceph_handle_caps(struct ceph_mds_session *session, /* lookup ino */ inode = ceph_find_inode(sb, vino); - ci = ceph_inode(inode); dout(" op %s ino %llx.%llx inode %p\n", ceph_cap_op_name(op), vino.ino, vino.snap, inode); if (!inode) { @@ -2845,16 +2844,16 @@ void ceph_handle_caps(struct ceph_mds_session *session, } /* the rest require a cap */ - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); cap = __get_cap_for_mds(ceph_inode(inode), mds); if (!cap) { dout(" no cap on %p ino %llx.%llx from mds%d\n", inode, ceph_ino(inode), ceph_snap(inode), mds); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); goto flush_cap_releases; } - /* note that each of these drops i_ceph_lock for us */ + /* note that each of these drops i_lock for us */ switch (op) { case CEPH_CAP_OP_REVOKE: case CEPH_CAP_OP_GRANT: @@ -2870,7 +2869,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, break; default: - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); pr_err("ceph_handle_caps: unknown cap op %d %s\n", op, ceph_cap_op_name(op)); } @@ -2963,13 +2962,13 @@ void ceph_put_fmode(struct ceph_inode_info *ci, int fmode) struct inode *inode = &ci->vfs_inode; int last = 0; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); dout("put_fmode %p fmode %d %d -> %d\n", inode, fmode, ci->i_nr_by_mode[fmode], ci->i_nr_by_mode[fmode]-1); BUG_ON(ci->i_nr_by_mode[fmode] == 0); if (--ci->i_nr_by_mode[fmode] == 0) last++; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (last && ci->i_vino.snap == CEPH_NOSNAP) ceph_check_caps(ci, 0, NULL); @@ -2992,7 +2991,7 @@ int ceph_encode_inode_release(void **p, struct inode *inode, int used, dirty; int ret = 0; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); used = __ceph_caps_used(ci); dirty = __ceph_caps_dirty(ci); @@ -3047,7 +3046,7 @@ int ceph_encode_inode_release(void **p, struct inode *inode, inode, cap, ceph_cap_string(cap->issued)); } } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return ret; } @@ -3062,7 +3061,7 @@ int ceph_encode_dentry_release(void **p, struct dentry *dentry, /* * force an record for the directory caps if we have a dentry lease. - * this is racy (can't take i_ceph_lock and d_lock together), but it + * this is racy (can't take i_lock and d_lock together), but it * doesn't have to be perfect; the mds will revoke anything we don't * release. */ diff --git a/trunk/fs/ceph/dir.c b/trunk/fs/ceph/dir.c index 3eeb97661262..bca3948e9dbf 100644 --- a/trunk/fs/ceph/dir.c +++ b/trunk/fs/ceph/dir.c @@ -281,18 +281,18 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir) } /* can we use the dcache? */ - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if ((filp->f_pos == 2 || fi->dentry) && !ceph_test_mount_opt(fsc, NOASYNCREADDIR) && ceph_snap(inode) != CEPH_SNAPDIR && ceph_dir_test_complete(inode) && __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) { - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); err = __dcache_readdir(filp, dirent, filldir); if (err != -EAGAIN) return err; } else { - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } if (fi->dentry) { err = note_last_dentry(fi, fi->dentry->d_name.name, @@ -428,12 +428,12 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir) * were released during the whole readdir, and we should have * the complete dir contents in our cache. */ - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (ci->i_release_count == fi->dir_release_count) { ceph_dir_set_complete(inode); ci->i_max_offset = filp->f_pos; } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); dout("readdir %p filp %p done.\n", inode, filp); return 0; @@ -607,7 +607,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, struct ceph_inode_info *ci = ceph_inode(dir); struct ceph_dentry_info *di = ceph_dentry(dentry); - spin_lock(&ci->i_ceph_lock); + spin_lock(&dir->i_lock); dout(" dir %p flags are %d\n", dir, ci->i_ceph_flags); if (strncmp(dentry->d_name.name, fsc->mount_options->snapdir_name, @@ -615,13 +615,13 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, !is_root_ceph_dentry(dir, dentry) && ceph_dir_test_complete(dir) && (__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1))) { - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&dir->i_lock); dout(" dir %p complete, -ENOENT\n", dir); d_add(dentry, NULL); di->lease_shared_gen = ci->i_shared_gen; return NULL; } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&dir->i_lock); } op = ceph_snap(dir) == CEPH_SNAPDIR ? @@ -841,12 +841,12 @@ static int drop_caps_for_unlink(struct inode *inode) struct ceph_inode_info *ci = ceph_inode(inode); int drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (inode->i_nlink == 1) { drop |= ~(__ceph_caps_wanted(ci) | CEPH_CAP_PIN); ci->i_ceph_flags |= CEPH_I_NODELAY; } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return drop; } @@ -1015,10 +1015,10 @@ static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry) struct ceph_dentry_info *di = ceph_dentry(dentry); int valid = 0; - spin_lock(&ci->i_ceph_lock); + spin_lock(&dir->i_lock); if (ci->i_shared_gen == di->lease_shared_gen) valid = __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&dir->i_lock); dout("dir_lease_is_valid dir %p v%u dentry %p v%u = %d\n", dir, (unsigned)ci->i_shared_gen, dentry, (unsigned)di->lease_shared_gen, valid); diff --git a/trunk/fs/ceph/file.c b/trunk/fs/ceph/file.c index ed72428d9c75..ce549d31eeb7 100644 --- a/trunk/fs/ceph/file.c +++ b/trunk/fs/ceph/file.c @@ -147,9 +147,9 @@ int ceph_open(struct inode *inode, struct file *file) /* trivially open snapdir */ if (ceph_snap(inode) == CEPH_SNAPDIR) { - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); __ceph_get_fmode(ci, fmode); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return ceph_init_file(inode, file, fmode); } @@ -158,7 +158,7 @@ int ceph_open(struct inode *inode, struct file *file) * write) or any MDS (for read). Update wanted set * asynchronously. */ - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (__ceph_is_any_real_caps(ci) && (((fmode & CEPH_FILE_MODE_WR) == 0) || ci->i_auth_cap)) { int mds_wanted = __ceph_caps_mds_wanted(ci); @@ -168,7 +168,7 @@ int ceph_open(struct inode *inode, struct file *file) inode, fmode, ceph_cap_string(wanted), ceph_cap_string(issued)); __ceph_get_fmode(ci, fmode); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); /* adjust wanted? */ if ((issued & wanted) != wanted && @@ -180,10 +180,10 @@ int ceph_open(struct inode *inode, struct file *file) } else if (ceph_snap(inode) != CEPH_NOSNAP && (ci->i_snap_caps & wanted) == wanted) { __ceph_get_fmode(ci, fmode); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return ceph_init_file(inode, file, fmode); } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); dout("open fmode %d wants %s\n", fmode, ceph_cap_string(wanted)); req = prepare_open_request(inode->i_sb, flags, 0); @@ -743,9 +743,9 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, */ int dirty; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); ceph_put_cap_refs(ci, got); ret = generic_file_aio_write(iocb, iov, nr_segs, pos); @@ -764,9 +764,9 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, if (ret >= 0) { int dirty; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (dirty) __mark_inode_dirty(inode, dirty); } @@ -797,8 +797,7 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int origin) mutex_lock(&inode->i_mutex); __ceph_do_pending_vmtruncate(inode); - - if (origin == SEEK_END || origin == SEEK_DATA || origin == SEEK_HOLE) { + if (origin != SEEK_CUR || origin != SEEK_SET) { ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE); if (ret < 0) { offset = ret; diff --git a/trunk/fs/ceph/inode.c b/trunk/fs/ceph/inode.c index 87fb132fb330..116f36502f17 100644 --- a/trunk/fs/ceph/inode.c +++ b/trunk/fs/ceph/inode.c @@ -297,8 +297,6 @@ struct inode *ceph_alloc_inode(struct super_block *sb) dout("alloc_inode %p\n", &ci->vfs_inode); - spin_lock_init(&ci->i_ceph_lock); - ci->i_version = 0; ci->i_time_warp_seq = 0; ci->i_ceph_flags = 0; @@ -585,7 +583,7 @@ static int fill_inode(struct inode *inode, iinfo->xattr_len); } - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); /* * provided version will be odd if inode value is projected, @@ -682,7 +680,7 @@ static int fill_inode(struct inode *inode, char *sym; BUG_ON(symlen != inode->i_size); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); err = -ENOMEM; sym = kmalloc(symlen+1, GFP_NOFS); @@ -691,7 +689,7 @@ static int fill_inode(struct inode *inode, memcpy(sym, iinfo->symlink, symlen); sym[symlen] = 0; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (!ci->i_symlink) ci->i_symlink = sym; else @@ -717,7 +715,7 @@ static int fill_inode(struct inode *inode, } no_change: - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); /* queue truncate if we saw i_size decrease */ if (queue_trunc) @@ -752,13 +750,13 @@ static int fill_inode(struct inode *inode, info->cap.flags, caps_reservation); } else { - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); dout(" %p got snap_caps %s\n", inode, ceph_cap_string(le32_to_cpu(info->cap.caps))); ci->i_snap_caps |= le32_to_cpu(info->cap.caps); if (cap_fmode >= 0) __ceph_get_fmode(ci, cap_fmode); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } } else if (cap_fmode >= 0) { pr_warning("mds issued no caps on %llx.%llx\n", @@ -851,20 +849,19 @@ static void ceph_set_dentry_offset(struct dentry *dn) { struct dentry *dir = dn->d_parent; struct inode *inode = dir->d_inode; - struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_dentry_info *di; BUG_ON(!inode); di = ceph_dentry(dn); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (!ceph_dir_test_complete(inode)) { - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return; } di->offset = ceph_inode(inode)->i_max_offset++; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); spin_lock(&dir->d_lock); spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED); @@ -1311,7 +1308,7 @@ int ceph_inode_set_size(struct inode *inode, loff_t size) struct ceph_inode_info *ci = ceph_inode(inode); int ret = 0; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); dout("set_size %p %llu -> %llu\n", inode, inode->i_size, size); inode->i_size = size; inode->i_blocks = (size + (1 << 9) - 1) >> 9; @@ -1321,7 +1318,7 @@ int ceph_inode_set_size(struct inode *inode, loff_t size) (ci->i_reported_size << 1) < ci->i_max_size) ret = 1; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return ret; } @@ -1379,20 +1376,20 @@ static void ceph_invalidate_work(struct work_struct *work) u32 orig_gen; int check = 0; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); dout("invalidate_pages %p gen %d revoking %d\n", inode, ci->i_rdcache_gen, ci->i_rdcache_revoking); if (ci->i_rdcache_revoking != ci->i_rdcache_gen) { /* nevermind! */ - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); goto out; } orig_gen = ci->i_rdcache_gen; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); truncate_inode_pages(&inode->i_data, 0); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (orig_gen == ci->i_rdcache_gen && orig_gen == ci->i_rdcache_revoking) { dout("invalidate_pages %p gen %d successful\n", inode, @@ -1404,7 +1401,7 @@ static void ceph_invalidate_work(struct work_struct *work) inode, orig_gen, ci->i_rdcache_gen, ci->i_rdcache_revoking); } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (check) ceph_check_caps(ci, 0, NULL); @@ -1463,10 +1460,10 @@ void __ceph_do_pending_vmtruncate(struct inode *inode) int wrbuffer_refs, wake = 0; retry: - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (ci->i_truncate_pending == 0) { dout("__do_pending_vmtruncate %p none pending\n", inode); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return; } @@ -1477,7 +1474,7 @@ void __ceph_do_pending_vmtruncate(struct inode *inode) if (ci->i_wrbuffer_ref_head < ci->i_wrbuffer_ref) { dout("__do_pending_vmtruncate %p flushing snaps first\n", inode); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); filemap_write_and_wait_range(&inode->i_data, 0, inode->i_sb->s_maxbytes); goto retry; @@ -1487,15 +1484,15 @@ void __ceph_do_pending_vmtruncate(struct inode *inode) wrbuffer_refs = ci->i_wrbuffer_ref; dout("__do_pending_vmtruncate %p (%d) to %lld\n", inode, ci->i_truncate_pending, to); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); truncate_inode_pages(inode->i_mapping, to); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); ci->i_truncate_pending--; if (ci->i_truncate_pending == 0) wake = 1; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (wrbuffer_refs == 0) ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); @@ -1550,7 +1547,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) if (IS_ERR(req)) return PTR_ERR(req); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); issued = __ceph_caps_issued(ci, NULL); dout("setattr %p issued %s\n", inode, ceph_cap_string(issued)); @@ -1698,7 +1695,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) } release &= issued; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (inode_dirty_flags) __mark_inode_dirty(inode, inode_dirty_flags); @@ -1720,7 +1717,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) __ceph_do_pending_vmtruncate(inode); return err; out: - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); ceph_mdsc_put_request(req); return err; } diff --git a/trunk/fs/ceph/ioctl.c b/trunk/fs/ceph/ioctl.c index 790914a598dd..5a14c29cbba6 100644 --- a/trunk/fs/ceph/ioctl.c +++ b/trunk/fs/ceph/ioctl.c @@ -241,11 +241,11 @@ static long ceph_ioctl_lazyio(struct file *file) struct ceph_inode_info *ci = ceph_inode(inode); if ((fi->fmode & CEPH_FILE_MODE_LAZY) == 0) { - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); ci->i_nr_by_mode[fi->fmode]--; fi->fmode |= CEPH_FILE_MODE_LAZY; ci->i_nr_by_mode[fi->fmode]++; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); dout("ioctl_layzio: file %p marked lazy\n", file); ceph_check_caps(ci, 0, NULL); diff --git a/trunk/fs/ceph/mds_client.c b/trunk/fs/ceph/mds_client.c index 6203d805eb45..264ab701154f 100644 --- a/trunk/fs/ceph/mds_client.c +++ b/trunk/fs/ceph/mds_client.c @@ -732,21 +732,21 @@ static int __choose_mds(struct ceph_mds_client *mdsc, } } - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); cap = NULL; if (mode == USE_AUTH_MDS) cap = ci->i_auth_cap; if (!cap && !RB_EMPTY_ROOT(&ci->i_caps)) cap = rb_entry(rb_first(&ci->i_caps), struct ceph_cap, ci_node); if (!cap) { - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); goto random; } mds = cap->session->s_mds; dout("choose_mds %p %llx.%llx mds%d (%scap %p)\n", inode, ceph_vinop(inode), mds, cap == ci->i_auth_cap ? "auth " : "", cap); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return mds; random: @@ -951,7 +951,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap, dout("removing cap %p, ci is %p, inode is %p\n", cap, ci, &ci->vfs_inode); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); __ceph_remove_cap(cap); if (!__ceph_is_any_real_caps(ci)) { struct ceph_mds_client *mdsc = @@ -984,7 +984,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap, } spin_unlock(&mdsc->cap_dirty_lock); } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); while (drop--) iput(inode); return 0; @@ -1015,10 +1015,10 @@ static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap, wake_up_all(&ci->i_cap_wq); if (arg) { - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); ci->i_wanted_max_size = 0; ci->i_requested_max_size = 0; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } return 0; } @@ -1151,7 +1151,7 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg) if (session->s_trim_caps <= 0) return -1; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); mine = cap->issued | cap->implemented; used = __ceph_caps_used(ci); oissued = __ceph_caps_issued_other(ci, cap); @@ -1170,7 +1170,7 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg) __ceph_remove_cap(cap); } else { /* try to drop referring dentries */ - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); d_prune_aliases(inode); dout("trim_caps_cb %p cap %p pruned, count now %d\n", inode, cap, atomic_read(&inode->i_count)); @@ -1178,7 +1178,7 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg) } out: - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return 0; } @@ -1296,7 +1296,7 @@ static int check_cap_flush(struct ceph_mds_client *mdsc, u64 want_flush_seq) i_flushing_item); struct inode *inode = &ci->vfs_inode; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (ci->i_cap_flush_seq <= want_flush_seq) { dout("check_cap_flush still flushing %p " "seq %lld <= %lld to mds%d\n", inode, @@ -1304,7 +1304,7 @@ static int check_cap_flush(struct ceph_mds_client *mdsc, u64 want_flush_seq) session->s_mds); ret = 0; } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } mutex_unlock(&session->s_mutex); ceph_put_mds_session(session); @@ -1495,7 +1495,6 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, pos, temp); } else if (stop_on_nosnap && inode && ceph_snap(inode) == CEPH_NOSNAP) { - spin_unlock(&temp->d_lock); break; } else { pos -= temp->d_name.len; @@ -2012,10 +2011,10 @@ void ceph_invalidate_dir_request(struct ceph_mds_request *req) struct ceph_inode_info *ci = ceph_inode(inode); dout("invalidate_dir_request %p (D_COMPLETE, lease(s))\n", inode); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); ceph_dir_clear_complete(inode); ci->i_release_count++; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (req->r_dentry) ceph_invalidate_dentry_lease(req->r_dentry); @@ -2423,7 +2422,7 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, if (err) goto out_free; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); cap->seq = 0; /* reset cap seq */ cap->issue_seq = 0; /* and issue_seq */ @@ -2446,7 +2445,7 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, rec.v1.pathbase = cpu_to_le64(pathbase); reclen = sizeof(rec.v1); } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (recon_state->flock) { int num_fcntl_locks, num_flock_locks; diff --git a/trunk/fs/ceph/mds_client.h b/trunk/fs/ceph/mds_client.h index a50ca0e39475..4bb239921dbd 100644 --- a/trunk/fs/ceph/mds_client.h +++ b/trunk/fs/ceph/mds_client.h @@ -20,7 +20,7 @@ * * mdsc->snap_rwsem * - * ci->i_ceph_lock + * inode->i_lock * mdsc->snap_flush_lock * mdsc->cap_delay_lock * diff --git a/trunk/fs/ceph/snap.c b/trunk/fs/ceph/snap.c index a559c80f127a..e26437191333 100644 --- a/trunk/fs/ceph/snap.c +++ b/trunk/fs/ceph/snap.c @@ -446,7 +446,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) return; } - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); used = __ceph_caps_used(ci); dirty = __ceph_caps_dirty(ci); @@ -528,7 +528,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) kfree(capsnap); } - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } /* @@ -537,7 +537,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) * * If capsnap can now be flushed, add to snap_flush list, and return 1. * - * Caller must hold i_ceph_lock. + * Caller must hold i_lock. */ int __ceph_finish_cap_snap(struct ceph_inode_info *ci, struct ceph_cap_snap *capsnap) @@ -739,9 +739,9 @@ static void flush_snaps(struct ceph_mds_client *mdsc) inode = &ci->vfs_inode; ihold(inode); spin_unlock(&mdsc->snap_flush_lock); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); __ceph_flush_snaps(ci, &session, 0); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); iput(inode); spin_lock(&mdsc->snap_flush_lock); } @@ -847,7 +847,7 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, continue; ci = ceph_inode(inode); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (!ci->i_snap_realm) goto skip_inode; /* @@ -876,7 +876,7 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, oldrealm = ci->i_snap_realm; ci->i_snap_realm = realm; spin_unlock(&realm->inodes_with_caps_lock); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); ceph_get_snap_realm(mdsc, realm); ceph_put_snap_realm(mdsc, oldrealm); @@ -885,7 +885,7 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, continue; skip_inode: - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); iput(inode); } diff --git a/trunk/fs/ceph/super.c b/trunk/fs/ceph/super.c index b48f15f101a0..8dc73a594a90 100644 --- a/trunk/fs/ceph/super.c +++ b/trunk/fs/ceph/super.c @@ -383,7 +383,7 @@ static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt) if (fsopt->rsize != CEPH_RSIZE_DEFAULT) seq_printf(m, ",rsize=%d", fsopt->rsize); if (fsopt->rasize != CEPH_RASIZE_DEFAULT) - seq_printf(m, ",rasize=%d", fsopt->rasize); + seq_printf(m, ",rasize=%d", fsopt->rsize); if (fsopt->congestion_kb != default_congestion_kb()) seq_printf(m, ",write_congestion_kb=%d", fsopt->congestion_kb); if (fsopt->caps_wanted_delay_min != CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT) diff --git a/trunk/fs/ceph/super.h b/trunk/fs/ceph/super.h index edcbf3774a56..01bf189e08a9 100644 --- a/trunk/fs/ceph/super.h +++ b/trunk/fs/ceph/super.h @@ -220,7 +220,7 @@ struct ceph_dentry_info { * The locking for D_COMPLETE is a bit odd: * - we can clear it at almost any time (see ceph_d_prune) * - it is only meaningful if: - * - we hold dir inode i_ceph_lock + * - we hold dir inode i_lock * - we hold dir FILE_SHARED caps * - the dentry D_COMPLETE is set */ @@ -250,8 +250,6 @@ struct ceph_inode_xattrs_info { struct ceph_inode_info { struct ceph_vino i_vino; /* ceph ino + snap */ - spinlock_t i_ceph_lock; - u64 i_version; u32 i_time_warp_seq; @@ -273,7 +271,7 @@ struct ceph_inode_info { struct ceph_inode_xattrs_info i_xattrs; - /* capabilities. protected _both_ by i_ceph_lock and cap->session's + /* capabilities. protected _both_ by i_lock and cap->session's * s_mutex. */ struct rb_root i_caps; /* cap list */ struct ceph_cap *i_auth_cap; /* authoritative cap, if any */ @@ -439,18 +437,18 @@ static inline void ceph_i_clear(struct inode *inode, unsigned mask) { struct ceph_inode_info *ci = ceph_inode(inode); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); ci->i_ceph_flags &= ~mask; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } static inline void ceph_i_set(struct inode *inode, unsigned mask) { struct ceph_inode_info *ci = ceph_inode(inode); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); ci->i_ceph_flags |= mask; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } static inline bool ceph_i_test(struct inode *inode, unsigned mask) @@ -458,9 +456,9 @@ static inline bool ceph_i_test(struct inode *inode, unsigned mask) struct ceph_inode_info *ci = ceph_inode(inode); bool r; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); r = (ci->i_ceph_flags & mask) == mask; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return r; } @@ -510,9 +508,9 @@ extern int __ceph_caps_issued_other(struct ceph_inode_info *ci, static inline int ceph_caps_issued(struct ceph_inode_info *ci) { int issued; - spin_lock(&ci->i_ceph_lock); + spin_lock(&ci->vfs_inode.i_lock); issued = __ceph_caps_issued(ci, NULL); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&ci->vfs_inode.i_lock); return issued; } @@ -520,9 +518,9 @@ static inline int ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch) { int r; - spin_lock(&ci->i_ceph_lock); + spin_lock(&ci->vfs_inode.i_lock); r = __ceph_caps_issued_mask(ci, mask, touch); - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&ci->vfs_inode.i_lock); return r; } @@ -745,9 +743,10 @@ extern int ceph_add_cap(struct inode *inode, extern void __ceph_remove_cap(struct ceph_cap *cap); static inline void ceph_remove_cap(struct ceph_cap *cap) { - spin_lock(&cap->ci->i_ceph_lock); + struct inode *inode = &cap->ci->vfs_inode; + spin_lock(&inode->i_lock); __ceph_remove_cap(cap); - spin_unlock(&cap->ci->i_ceph_lock); + spin_unlock(&inode->i_lock); } extern void ceph_put_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap); diff --git a/trunk/fs/ceph/xattr.c b/trunk/fs/ceph/xattr.c index a5e36e4488a7..96c6739a0280 100644 --- a/trunk/fs/ceph/xattr.c +++ b/trunk/fs/ceph/xattr.c @@ -343,8 +343,8 @@ void __ceph_destroy_xattrs(struct ceph_inode_info *ci) } static int __build_xattrs(struct inode *inode) - __releases(ci->i_ceph_lock) - __acquires(ci->i_ceph_lock) + __releases(inode->i_lock) + __acquires(inode->i_lock) { u32 namelen; u32 numattr = 0; @@ -372,7 +372,7 @@ static int __build_xattrs(struct inode *inode) end = p + ci->i_xattrs.blob->vec.iov_len; ceph_decode_32_safe(&p, end, numattr, bad); xattr_version = ci->i_xattrs.version; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); xattrs = kcalloc(numattr, sizeof(struct ceph_xattr *), GFP_NOFS); @@ -387,7 +387,7 @@ static int __build_xattrs(struct inode *inode) goto bad_lock; } - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (ci->i_xattrs.version != xattr_version) { /* lost a race, retry */ for (i = 0; i < numattr; i++) @@ -418,7 +418,7 @@ static int __build_xattrs(struct inode *inode) return err; bad_lock: - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); bad: if (xattrs) { for (i = 0; i < numattr; i++) @@ -512,7 +512,7 @@ ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value, if (vxattrs) vxattr = ceph_match_vxattr(vxattrs, name); - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); dout("getxattr %p ver=%lld index_ver=%lld\n", inode, ci->i_xattrs.version, ci->i_xattrs.index_version); @@ -520,14 +520,14 @@ ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value, (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { goto get_xattr; } else { - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); /* get xattrs from mds (if we don't already have them) */ err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); if (err) return err; } - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (vxattr && vxattr->readonly) { err = vxattr->getxattr_cb(ci, value, size); @@ -558,7 +558,7 @@ ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value, memcpy(value, xattr->val, xattr->val_len); out: - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return err; } @@ -573,7 +573,7 @@ ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size) u32 len; int i; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); dout("listxattr %p ver=%lld index_ver=%lld\n", inode, ci->i_xattrs.version, ci->i_xattrs.index_version); @@ -581,13 +581,13 @@ ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size) (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { goto list_xattr; } else { - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); if (err) return err; } - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); err = __build_xattrs(inode); if (err < 0) @@ -619,7 +619,7 @@ ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size) } out: - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); return err; } @@ -739,7 +739,7 @@ int ceph_setxattr(struct dentry *dentry, const char *name, if (!xattr) goto out; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); retry: issued = __ceph_caps_issued(ci, NULL); if (!(issued & CEPH_CAP_XATTR_EXCL)) @@ -752,12 +752,12 @@ int ceph_setxattr(struct dentry *dentry, const char *name, required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) { struct ceph_buffer *blob = NULL; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); dout(" preaallocating new blob size=%d\n", required_blob_size); blob = ceph_buffer_new(required_blob_size, GFP_NOFS); if (!blob) goto out; - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); if (ci->i_xattrs.prealloc_blob) ceph_buffer_put(ci->i_xattrs.prealloc_blob); ci->i_xattrs.prealloc_blob = blob; @@ -770,13 +770,13 @@ int ceph_setxattr(struct dentry *dentry, const char *name, dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); ci->i_xattrs.dirty = true; inode->i_ctime = CURRENT_TIME; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (dirty) __mark_inode_dirty(inode, dirty); return err; do_sync: - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); err = ceph_sync_setxattr(dentry, name, value, size, flags); out: kfree(newname); @@ -833,7 +833,7 @@ int ceph_removexattr(struct dentry *dentry, const char *name) return -EOPNOTSUPP; } - spin_lock(&ci->i_ceph_lock); + spin_lock(&inode->i_lock); __build_xattrs(inode); issued = __ceph_caps_issued(ci, NULL); dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued)); @@ -846,12 +846,12 @@ int ceph_removexattr(struct dentry *dentry, const char *name) ci->i_xattrs.dirty = true; inode->i_ctime = CURRENT_TIME; - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); if (dirty) __mark_inode_dirty(inode, dirty); return err; do_sync: - spin_unlock(&ci->i_ceph_lock); + spin_unlock(&inode->i_lock); err = ceph_send_removexattr(dentry, name); return err; } diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 8cd4b52d4217..d6a972df0338 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -441,8 +441,6 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig, smb_msg.msg_controllen = 0; for (total_read = 0; to_read; total_read += length, to_read -= length) { - try_to_freeze(); - if (server_unresponsive(server)) { total_read = -EAGAIN; break; diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index 4dd9283885e7..cf0b1539b321 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -702,13 +702,6 @@ cifs_find_lock_conflict(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock, lock->type, lock->netfid, conf_lock); } -/* - * Check if there is another lock that prevents us to set the lock (mandatory - * style). If such a lock exists, update the flock structure with its - * properties. Otherwise, set the flock type to F_UNLCK if we can cache brlocks - * or leave it the same if we can't. Returns 0 if we don't need to request to - * the server or 1 otherwise. - */ static int cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length, __u8 type, __u16 netfid, struct file_lock *flock) @@ -746,12 +739,6 @@ cifs_lock_add(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock) mutex_unlock(&cinode->lock_mutex); } -/* - * Set the byte-range lock (mandatory style). Returns: - * 1) 0, if we set the lock and don't need to request to the server; - * 2) 1, if no locks prevent us but we need to request to the server; - * 3) -EACCESS, if there is a lock that prevents us and wait is false. - */ static int cifs_lock_add_if(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock, bool wait) @@ -791,13 +778,6 @@ cifs_lock_add_if(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock, return rc; } -/* - * Check if there is another lock that prevents us to set the lock (posix - * style). If such a lock exists, update the flock structure with its - * properties. Otherwise, set the flock type to F_UNLCK if we can cache brlocks - * or leave it the same if we can't. Returns 0 if we don't need to request to - * the server or 1 otherwise. - */ static int cifs_posix_lock_test(struct file *file, struct file_lock *flock) { @@ -820,12 +800,6 @@ cifs_posix_lock_test(struct file *file, struct file_lock *flock) return rc; } -/* - * Set the byte-range lock (posix style). Returns: - * 1) 0, if we set the lock and don't need to request to the server; - * 2) 1, if we need to request to the server; - * 3) <0, if the error occurs while setting the lock. - */ static int cifs_posix_lock_set(struct file *file, struct file_lock *flock) { diff --git a/trunk/fs/cifs/readdir.c b/trunk/fs/cifs/readdir.c index a090bbe6ee29..5de03ec20144 100644 --- a/trunk/fs/cifs/readdir.c +++ b/trunk/fs/cifs/readdir.c @@ -554,10 +554,7 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon, rc); return rc; } - /* FindFirst/Next set last_entry to NULL on malformed reply */ - if (cifsFile->srch_inf.last_entry) - cifs_save_resume_key(cifsFile->srch_inf.last_entry, - cifsFile); + cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile); } while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && @@ -565,10 +562,7 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon, cFYI(1, "calling findnext2"); rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, &cifsFile->srch_inf); - /* FindFirst/Next set last_entry to NULL on malformed reply */ - if (cifsFile->srch_inf.last_entry) - cifs_save_resume_key(cifsFile->srch_inf.last_entry, - cifsFile); + cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile); if (rc) return -ENOENT; } diff --git a/trunk/fs/cifs/smbencrypt.c b/trunk/fs/cifs/smbencrypt.c index 80d850881938..7cacba12b8f1 100644 --- a/trunk/fs/cifs/smbencrypt.c +++ b/trunk/fs/cifs/smbencrypt.c @@ -209,7 +209,7 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16, { int rc; int len; - __le16 wpwd[129]; + __u16 wpwd[129]; /* Password cannot be longer than 128 characters */ if (passwd) /* Password must be converted to NT unicode */ @@ -219,8 +219,8 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16, *wpwd = 0; /* Ensure string is null terminated */ } - rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__le16)); - memset(wpwd, 0, 129 * sizeof(__le16)); + rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__u16)); + memset(wpwd, 0, 129 * sizeof(__u16)); return rc; } diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index 89509b5a090e..10ba92def3f6 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -2439,14 +2439,16 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name) /** * prepend_path - Prepend path string to a buffer * @path: the dentry/vfsmount to report - * @root: root vfsmnt/dentry + * @root: root vfsmnt/dentry (may be modified by this function) * @buffer: pointer to the end of the buffer * @buflen: pointer to buffer length * * Caller holds the rename_lock. + * + * If path is not reachable from the supplied root, then the value of + * root is changed (without modifying refcounts). */ -static int prepend_path(const struct path *path, - const struct path *root, +static int prepend_path(const struct path *path, struct path *root, char **buffer, int *buflen) { struct dentry *dentry = path->dentry; @@ -2481,10 +2483,10 @@ static int prepend_path(const struct path *path, dentry = parent; } +out: if (!error && !slash) error = prepend(buffer, buflen, "/", 1); -out: br_read_unlock(vfsmount_lock); return error; @@ -2498,17 +2500,15 @@ static int prepend_path(const struct path *path, WARN(1, "Root dentry has weird name <%.*s>\n", (int) dentry->d_name.len, dentry->d_name.name); } - if (!slash) - error = prepend(buffer, buflen, "/", 1); - if (!error) - error = vfsmnt->mnt_ns ? 1 : 2; + root->mnt = vfsmnt; + root->dentry = dentry; goto out; } /** * __d_path - return the path of a dentry * @path: the dentry/vfsmount to report - * @root: root vfsmnt/dentry + * @root: root vfsmnt/dentry (may be modified by this function) * @buf: buffer to return value in * @buflen: buffer length * @@ -2519,10 +2519,10 @@ static int prepend_path(const struct path *path, * * "buflen" should be positive. * - * If the path is not reachable from the supplied root, return %NULL. + * If path is not reachable from the supplied root, then the value of + * root is changed (without modifying refcounts). */ -char *__d_path(const struct path *path, - const struct path *root, +char *__d_path(const struct path *path, struct path *root, char *buf, int buflen) { char *res = buf + buflen; @@ -2533,28 +2533,7 @@ char *__d_path(const struct path *path, error = prepend_path(path, root, &res, &buflen); write_sequnlock(&rename_lock); - if (error < 0) - return ERR_PTR(error); - if (error > 0) - return NULL; - return res; -} - -char *d_absolute_path(const struct path *path, - char *buf, int buflen) -{ - struct path root = {}; - char *res = buf + buflen; - int error; - - prepend(&res, &buflen, "\0", 1); - write_seqlock(&rename_lock); - error = prepend_path(path, &root, &res, &buflen); - write_sequnlock(&rename_lock); - - if (error > 1) - error = -EINVAL; - if (error < 0) + if (error) return ERR_PTR(error); return res; } @@ -2562,9 +2541,8 @@ char *d_absolute_path(const struct path *path, /* * same as __d_path but appends "(deleted)" for unlinked files. */ -static int path_with_deleted(const struct path *path, - const struct path *root, - char **buf, int *buflen) +static int path_with_deleted(const struct path *path, struct path *root, + char **buf, int *buflen) { prepend(buf, buflen, "\0", 1); if (d_unlinked(path->dentry)) { @@ -2601,6 +2579,7 @@ char *d_path(const struct path *path, char *buf, int buflen) { char *res = buf + buflen; struct path root; + struct path tmp; int error; /* @@ -2615,8 +2594,9 @@ char *d_path(const struct path *path, char *buf, int buflen) get_fs_root(current->fs, &root); write_seqlock(&rename_lock); - error = path_with_deleted(path, &root, &res, &buflen); - if (error < 0) + tmp = root; + error = path_with_deleted(path, &tmp, &res, &buflen); + if (error) res = ERR_PTR(error); write_sequnlock(&rename_lock); path_put(&root); @@ -2637,6 +2617,7 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen) { char *res = buf + buflen; struct path root; + struct path tmp; int error; if (path->dentry->d_op && path->dentry->d_op->d_dname) @@ -2644,8 +2625,9 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen) get_fs_root(current->fs, &root); write_seqlock(&rename_lock); - error = path_with_deleted(path, &root, &res, &buflen); - if (error > 0) + tmp = root; + error = path_with_deleted(path, &tmp, &res, &buflen); + if (!error && !path_equal(&tmp, &root)) error = prepend_unreachable(&res, &buflen); write_sequnlock(&rename_lock); path_put(&root); @@ -2776,18 +2758,19 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) write_seqlock(&rename_lock); if (!d_unlinked(pwd.dentry)) { unsigned long len; + struct path tmp = root; char *cwd = page + PAGE_SIZE; int buflen = PAGE_SIZE; prepend(&cwd, &buflen, "\0", 1); - error = prepend_path(&pwd, &root, &cwd, &buflen); + error = prepend_path(&pwd, &tmp, &cwd, &buflen); write_sequnlock(&rename_lock); - if (error < 0) + if (error) goto out; /* Unreachable from current root */ - if (error > 0) { + if (!path_equal(&tmp, &root)) { error = prepend_unreachable(&cwd, &buflen); if (error) goto out; diff --git a/trunk/fs/fs-writeback.c b/trunk/fs/fs-writeback.c index ac86f8b3e3cb..73c3992b2bb4 100644 --- a/trunk/fs/fs-writeback.c +++ b/trunk/fs/fs-writeback.c @@ -156,7 +156,6 @@ __bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, * bdi_start_writeback - start writeback * @bdi: the backing device to write from * @nr_pages: the number of pages to write - * @reason: reason why some writeback work was initiated * * Description: * This does WB_SYNC_NONE opportunistic writeback. The IO is only @@ -1224,7 +1223,6 @@ static void wait_sb_inodes(struct super_block *sb) * writeback_inodes_sb_nr - writeback dirty inodes from given super_block * @sb: the superblock * @nr: the number of pages to write - * @reason: reason why some writeback work initiated * * Start writeback on some inodes on this super_block. No guarantees are made * on how many (if any) will be written, and this function does not wait @@ -1253,7 +1251,6 @@ EXPORT_SYMBOL(writeback_inodes_sb_nr); /** * writeback_inodes_sb - writeback dirty inodes from given super_block * @sb: the superblock - * @reason: reason why some writeback work was initiated * * Start writeback on some inodes on this super_block. No guarantees are made * on how many (if any) will be written, and this function does not wait @@ -1268,7 +1265,6 @@ EXPORT_SYMBOL(writeback_inodes_sb); /** * writeback_inodes_sb_if_idle - start writeback if none underway * @sb: the superblock - * @reason: reason why some writeback work was initiated * * Invoke writeback_inodes_sb if no writeback is currently underway. * Returns 1 if writeback was started, 0 if not. @@ -1289,7 +1285,6 @@ EXPORT_SYMBOL(writeback_inodes_sb_if_idle); * writeback_inodes_sb_if_idle - start writeback if none underway * @sb: the superblock * @nr: the number of pages to write - * @reason: reason why some writeback work was initiated * * Invoke writeback_inodes_sb if no writeback is currently underway. * Returns 1 if writeback was started, 0 if not. diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index cfc6d4448aa5..6d3a1963879b 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -1048,12 +1048,15 @@ static int show_mountinfo(struct seq_file *m, void *v) if (err) goto out; seq_putc(m, ' '); - - /* mountpoints outside of chroot jail will give SEQ_SKIP on this */ - err = seq_path_root(m, &mnt_path, &root, " \t\n\\"); - if (err) - goto out; - + seq_path_root(m, &mnt_path, &root, " \t\n\\"); + if (root.mnt != p->root.mnt || root.dentry != p->root.dentry) { + /* + * Mountpoint is outside root, discard that one. Ugly, + * but less so than trying to do that in iterator in a + * race-free way (due to renames). + */ + return SEQ_SKIP; + } seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw"); show_mnt_opts(m, mnt); @@ -2773,8 +2776,3 @@ void kern_unmount(struct vfsmount *mnt) } } EXPORT_SYMBOL(kern_unmount); - -bool our_mnt(struct vfsmount *mnt) -{ - return check_mnt(mnt); -} diff --git a/trunk/fs/proc/meminfo.c b/trunk/fs/proc/meminfo.c index 80e4645f7990..586174168e2a 100644 --- a/trunk/fs/proc/meminfo.c +++ b/trunk/fs/proc/meminfo.c @@ -131,13 +131,12 @@ static int meminfo_proc_show(struct seq_file *m, void *v) K(i.freeswap), K(global_page_state(NR_FILE_DIRTY)), K(global_page_state(NR_WRITEBACK)), -#ifdef CONFIG_TRANSPARENT_HUGEPAGE K(global_page_state(NR_ANON_PAGES) +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * - HPAGE_PMD_NR), -#else - K(global_page_state(NR_ANON_PAGES)), + HPAGE_PMD_NR #endif + ), K(global_page_state(NR_FILE_MAPPED)), K(global_page_state(NR_SHMEM)), K(global_page_state(NR_SLAB_RECLAIMABLE) + diff --git a/trunk/fs/proc/stat.c b/trunk/fs/proc/stat.c index 2a30d67dd6b8..42b274da92c3 100644 --- a/trunk/fs/proc/stat.c +++ b/trunk/fs/proc/stat.c @@ -32,7 +32,7 @@ static cputime64_t get_idle_time(int cpu) idle = kstat_cpu(cpu).cpustat.idle; idle = cputime64_add(idle, arch_idle_time(cpu)); } else - idle = nsecs_to_jiffies64(1000 * idle_time); + idle = usecs_to_cputime(idle_time); return idle; } @@ -46,7 +46,7 @@ static cputime64_t get_iowait_time(int cpu) /* !NO_HZ so we can rely on cpustat.iowait */ iowait = kstat_cpu(cpu).cpustat.iowait; else - iowait = nsecs_to_jiffies64(1000 * iowait_time); + iowait = usecs_to_cputime(iowait_time); return iowait; } diff --git a/trunk/fs/seq_file.c b/trunk/fs/seq_file.c index dba43c3ea3af..05d6b0e78c95 100644 --- a/trunk/fs/seq_file.c +++ b/trunk/fs/seq_file.c @@ -449,6 +449,8 @@ EXPORT_SYMBOL(seq_path); /* * Same as seq_path, but relative to supplied root. + * + * root may be changed, see __d_path(). */ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, char *esc) @@ -461,8 +463,6 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, char *p; p = __d_path(path, root, buf, size); - if (!p) - return SEQ_SKIP; res = PTR_ERR(p); if (!IS_ERR(p)) { char *end = mangle_path(buf, p, esc); @@ -474,7 +474,7 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, } seq_commit(m, res); - return res < 0 && res != -ENAMETOOLONG ? res : 0; + return res < 0 ? res : 0; } /* diff --git a/trunk/fs/xfs/xfs_bmap.c b/trunk/fs/xfs/xfs_bmap.c index d0ab78837057..c68baeb0974a 100644 --- a/trunk/fs/xfs/xfs_bmap.c +++ b/trunk/fs/xfs/xfs_bmap.c @@ -2383,8 +2383,6 @@ xfs_bmap_btalloc( int tryagain; int error; - ASSERT(ap->length); - mp = ap->ip->i_mount; align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0; if (unlikely(align)) { @@ -4631,8 +4629,6 @@ xfs_bmapi_allocate( int error; int rt; - ASSERT(bma->length > 0); - rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(bma->ip); /* @@ -4853,7 +4849,6 @@ xfs_bmapi_write( ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); ASSERT(!(flags & XFS_BMAPI_IGSTATE)); ASSERT(tp != NULL); - ASSERT(len > 0); whichfork = (flags & XFS_BMAPI_ATTRFORK) ? XFS_ATTR_FORK : XFS_DATA_FORK; @@ -4923,22 +4918,9 @@ xfs_bmapi_write( bma.eof = eof; bma.conv = !!(flags & XFS_BMAPI_CONVERT); bma.wasdel = wasdelay; + bma.length = len; bma.offset = bno; - /* - * There's a 32/64 bit type mismatch between the - * allocation length request (which can be 64 bits in - * length) and the bma length request, which is - * xfs_extlen_t and therefore 32 bits. Hence we have to - * check for 32-bit overflows and handle them here. - */ - if (len > (xfs_filblks_t)MAXEXTLEN) - bma.length = MAXEXTLEN; - else - bma.length = len; - - ASSERT(len > 0); - ASSERT(bma.length > 0); error = xfs_bmapi_allocate(&bma, flags); if (error) goto error0; diff --git a/trunk/fs/xfs/xfs_export.c b/trunk/fs/xfs/xfs_export.c index 558910f5e3c0..da108977b21f 100644 --- a/trunk/fs/xfs/xfs_export.c +++ b/trunk/fs/xfs/xfs_export.c @@ -98,22 +98,22 @@ xfs_fs_encode_fh( switch (fileid_type) { case FILEID_INO32_GEN_PARENT: spin_lock(&dentry->d_lock); - fid->i32.parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino; + fid->i32.parent_ino = dentry->d_parent->d_inode->i_ino; fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation; spin_unlock(&dentry->d_lock); /*FALLTHRU*/ case FILEID_INO32_GEN: - fid->i32.ino = XFS_I(inode)->i_ino; + fid->i32.ino = inode->i_ino; fid->i32.gen = inode->i_generation; break; case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG: spin_lock(&dentry->d_lock); - fid64->parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino; + fid64->parent_ino = dentry->d_parent->d_inode->i_ino; fid64->parent_gen = dentry->d_parent->d_inode->i_generation; spin_unlock(&dentry->d_lock); /*FALLTHRU*/ case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG: - fid64->ino = XFS_I(inode)->i_ino; + fid64->ino = inode->i_ino; fid64->gen = inode->i_generation; break; } diff --git a/trunk/fs/xfs/xfs_log.c b/trunk/fs/xfs/xfs_log.c index 34817adf4b9e..a14cd89fe465 100644 --- a/trunk/fs/xfs/xfs_log.c +++ b/trunk/fs/xfs/xfs_log.c @@ -150,117 +150,6 @@ xlog_grant_add_space( } while (head_val != old); } -STATIC bool -xlog_reserveq_wake( - struct log *log, - int *free_bytes) -{ - struct xlog_ticket *tic; - int need_bytes; - - list_for_each_entry(tic, &log->l_reserveq, t_queue) { - if (tic->t_flags & XLOG_TIC_PERM_RESERV) - need_bytes = tic->t_unit_res * tic->t_cnt; - else - need_bytes = tic->t_unit_res; - - if (*free_bytes < need_bytes) - return false; - *free_bytes -= need_bytes; - - trace_xfs_log_grant_wake_up(log, tic); - wake_up(&tic->t_wait); - } - - return true; -} - -STATIC bool -xlog_writeq_wake( - struct log *log, - int *free_bytes) -{ - struct xlog_ticket *tic; - int need_bytes; - - list_for_each_entry(tic, &log->l_writeq, t_queue) { - ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV); - - need_bytes = tic->t_unit_res; - - if (*free_bytes < need_bytes) - return false; - *free_bytes -= need_bytes; - - trace_xfs_log_regrant_write_wake_up(log, tic); - wake_up(&tic->t_wait); - } - - return true; -} - -STATIC int -xlog_reserveq_wait( - struct log *log, - struct xlog_ticket *tic, - int need_bytes) -{ - list_add_tail(&tic->t_queue, &log->l_reserveq); - - do { - if (XLOG_FORCED_SHUTDOWN(log)) - goto shutdown; - xlog_grant_push_ail(log, need_bytes); - - XFS_STATS_INC(xs_sleep_logspace); - trace_xfs_log_grant_sleep(log, tic); - - xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock); - trace_xfs_log_grant_wake(log, tic); - - spin_lock(&log->l_grant_reserve_lock); - if (XLOG_FORCED_SHUTDOWN(log)) - goto shutdown; - } while (xlog_space_left(log, &log->l_grant_reserve_head) < need_bytes); - - list_del_init(&tic->t_queue); - return 0; -shutdown: - list_del_init(&tic->t_queue); - return XFS_ERROR(EIO); -} - -STATIC int -xlog_writeq_wait( - struct log *log, - struct xlog_ticket *tic, - int need_bytes) -{ - list_add_tail(&tic->t_queue, &log->l_writeq); - - do { - if (XLOG_FORCED_SHUTDOWN(log)) - goto shutdown; - xlog_grant_push_ail(log, need_bytes); - - XFS_STATS_INC(xs_sleep_logspace); - trace_xfs_log_regrant_write_sleep(log, tic); - - xlog_wait(&tic->t_wait, &log->l_grant_write_lock); - trace_xfs_log_regrant_write_wake(log, tic); - - spin_lock(&log->l_grant_write_lock); - if (XLOG_FORCED_SHUTDOWN(log)) - goto shutdown; - } while (xlog_space_left(log, &log->l_grant_write_head) < need_bytes); - - list_del_init(&tic->t_queue); - return 0; -shutdown: - list_del_init(&tic->t_queue); - return XFS_ERROR(EIO); -} - static void xlog_tic_reset_res(xlog_ticket_t *tic) { @@ -461,19 +350,8 @@ xfs_log_reserve( retval = xlog_grant_log_space(log, internal_ticket); } - if (unlikely(retval)) { - /* - * If we are failing, make sure the ticket doesn't have any - * current reservations. We don't want to add this back - * when the ticket/ transaction gets cancelled. - */ - internal_ticket->t_curr_res = 0; - /* ungrant will give back unit_res * t_cnt. */ - internal_ticket->t_cnt = 0; - } - return retval; -} +} /* xfs_log_reserve */ /* @@ -2603,8 +2481,8 @@ xlog_state_get_iclog_space(xlog_t *log, /* * Atomically get the log space required for a log ticket. * - * Once a ticket gets put onto the reserveq, it will only return after the - * needed reservation is satisfied. + * Once a ticket gets put onto the reserveq, it will only return after + * the needed reservation is satisfied. * * This function is structured so that it has a lock free fast path. This is * necessary because every new transaction reservation will come through this @@ -2612,53 +2490,113 @@ xlog_state_get_iclog_space(xlog_t *log, * every pass. * * As tickets are only ever moved on and off the reserveq under the - * l_grant_reserve_lock, we only need to take that lock if we are going to add - * the ticket to the queue and sleep. We can avoid taking the lock if the ticket - * was never added to the reserveq because the t_queue list head will be empty - * and we hold the only reference to it so it can safely be checked unlocked. + * l_grant_reserve_lock, we only need to take that lock if we are going + * to add the ticket to the queue and sleep. We can avoid taking the lock if the + * ticket was never added to the reserveq because the t_queue list head will be + * empty and we hold the only reference to it so it can safely be checked + * unlocked. */ STATIC int -xlog_grant_log_space( - struct log *log, - struct xlog_ticket *tic) +xlog_grant_log_space(xlog_t *log, + xlog_ticket_t *tic) { - int free_bytes, need_bytes; - int error = 0; + int free_bytes; + int need_bytes; - ASSERT(!(log->l_flags & XLOG_ACTIVE_RECOVERY)); +#ifdef DEBUG + if (log->l_flags & XLOG_ACTIVE_RECOVERY) + panic("grant Recovery problem"); +#endif trace_xfs_log_grant_enter(log, tic); - /* - * If there are other waiters on the queue then give them a chance at - * logspace before us. Wake up the first waiters, if we do not wake - * up all the waiters then go to sleep waiting for more free space, - * otherwise try to get some space for this transaction. - */ need_bytes = tic->t_unit_res; if (tic->t_flags & XFS_LOG_PERM_RESERV) need_bytes *= tic->t_ocnt; - free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); + + /* something is already sleeping; insert new transaction at end */ if (!list_empty_careful(&log->l_reserveq)) { spin_lock(&log->l_grant_reserve_lock); - if (!xlog_reserveq_wake(log, &free_bytes) || - free_bytes < need_bytes) - error = xlog_reserveq_wait(log, tic, need_bytes); - spin_unlock(&log->l_grant_reserve_lock); - } else if (free_bytes < need_bytes) { + /* recheck the queue now we are locked */ + if (list_empty(&log->l_reserveq)) { + spin_unlock(&log->l_grant_reserve_lock); + goto redo; + } + list_add_tail(&tic->t_queue, &log->l_reserveq); + + trace_xfs_log_grant_sleep1(log, tic); + + /* + * Gotta check this before going to sleep, while we're + * holding the grant lock. + */ + if (XLOG_FORCED_SHUTDOWN(log)) + goto error_return; + + XFS_STATS_INC(xs_sleep_logspace); + xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock); + + /* + * If we got an error, and the filesystem is shutting down, + * we'll catch it down below. So just continue... + */ + trace_xfs_log_grant_wake1(log, tic); + } + +redo: + if (XLOG_FORCED_SHUTDOWN(log)) + goto error_return_unlocked; + + free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); + if (free_bytes < need_bytes) { spin_lock(&log->l_grant_reserve_lock); - error = xlog_reserveq_wait(log, tic, need_bytes); + if (list_empty(&tic->t_queue)) + list_add_tail(&tic->t_queue, &log->l_reserveq); + + trace_xfs_log_grant_sleep2(log, tic); + + if (XLOG_FORCED_SHUTDOWN(log)) + goto error_return; + + xlog_grant_push_ail(log, need_bytes); + + XFS_STATS_INC(xs_sleep_logspace); + xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock); + + trace_xfs_log_grant_wake2(log, tic); + goto redo; + } + + if (!list_empty(&tic->t_queue)) { + spin_lock(&log->l_grant_reserve_lock); + list_del_init(&tic->t_queue); spin_unlock(&log->l_grant_reserve_lock); } - if (error) - return error; + /* we've got enough space */ xlog_grant_add_space(log, &log->l_grant_reserve_head, need_bytes); xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); trace_xfs_log_grant_exit(log, tic); xlog_verify_grant_tail(log); return 0; -} + +error_return_unlocked: + spin_lock(&log->l_grant_reserve_lock); +error_return: + list_del_init(&tic->t_queue); + spin_unlock(&log->l_grant_reserve_lock); + trace_xfs_log_grant_error(log, tic); + + /* + * If we are failing, make sure the ticket doesn't have any + * current reservations. We don't want to add this back when + * the ticket/transaction gets cancelled. + */ + tic->t_curr_res = 0; + tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */ + return XFS_ERROR(EIO); +} /* xlog_grant_log_space */ + /* * Replenish the byte reservation required by moving the grant write head. @@ -2667,12 +2605,10 @@ xlog_grant_log_space( * free fast path. */ STATIC int -xlog_regrant_write_log_space( - struct log *log, - struct xlog_ticket *tic) +xlog_regrant_write_log_space(xlog_t *log, + xlog_ticket_t *tic) { - int free_bytes, need_bytes; - int error = 0; + int free_bytes, need_bytes; tic->t_curr_res = tic->t_unit_res; xlog_tic_reset_res(tic); @@ -2680,38 +2616,104 @@ xlog_regrant_write_log_space( if (tic->t_cnt > 0) return 0; - ASSERT(!(log->l_flags & XLOG_ACTIVE_RECOVERY)); +#ifdef DEBUG + if (log->l_flags & XLOG_ACTIVE_RECOVERY) + panic("regrant Recovery problem"); +#endif trace_xfs_log_regrant_write_enter(log, tic); + if (XLOG_FORCED_SHUTDOWN(log)) + goto error_return_unlocked; - /* - * If there are other waiters on the queue then give them a chance at - * logspace before us. Wake up the first waiters, if we do not wake - * up all the waiters then go to sleep waiting for more free space, - * otherwise try to get some space for this transaction. + /* If there are other waiters on the queue then give them a + * chance at logspace before us. Wake up the first waiters, + * if we do not wake up all the waiters then go to sleep waiting + * for more free space, otherwise try to get some space for + * this transaction. */ need_bytes = tic->t_unit_res; - free_bytes = xlog_space_left(log, &log->l_grant_write_head); if (!list_empty_careful(&log->l_writeq)) { + struct xlog_ticket *ntic; + spin_lock(&log->l_grant_write_lock); - if (!xlog_writeq_wake(log, &free_bytes) || - free_bytes < need_bytes) - error = xlog_writeq_wait(log, tic, need_bytes); - spin_unlock(&log->l_grant_write_lock); - } else if (free_bytes < need_bytes) { + free_bytes = xlog_space_left(log, &log->l_grant_write_head); + list_for_each_entry(ntic, &log->l_writeq, t_queue) { + ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV); + + if (free_bytes < ntic->t_unit_res) + break; + free_bytes -= ntic->t_unit_res; + wake_up(&ntic->t_wait); + } + + if (ntic != list_first_entry(&log->l_writeq, + struct xlog_ticket, t_queue)) { + if (list_empty(&tic->t_queue)) + list_add_tail(&tic->t_queue, &log->l_writeq); + trace_xfs_log_regrant_write_sleep1(log, tic); + + xlog_grant_push_ail(log, need_bytes); + + XFS_STATS_INC(xs_sleep_logspace); + xlog_wait(&tic->t_wait, &log->l_grant_write_lock); + trace_xfs_log_regrant_write_wake1(log, tic); + } else + spin_unlock(&log->l_grant_write_lock); + } + +redo: + if (XLOG_FORCED_SHUTDOWN(log)) + goto error_return_unlocked; + + free_bytes = xlog_space_left(log, &log->l_grant_write_head); + if (free_bytes < need_bytes) { spin_lock(&log->l_grant_write_lock); - error = xlog_writeq_wait(log, tic, need_bytes); - spin_unlock(&log->l_grant_write_lock); + if (list_empty(&tic->t_queue)) + list_add_tail(&tic->t_queue, &log->l_writeq); + + if (XLOG_FORCED_SHUTDOWN(log)) + goto error_return; + + xlog_grant_push_ail(log, need_bytes); + + XFS_STATS_INC(xs_sleep_logspace); + trace_xfs_log_regrant_write_sleep2(log, tic); + xlog_wait(&tic->t_wait, &log->l_grant_write_lock); + + trace_xfs_log_regrant_write_wake2(log, tic); + goto redo; } - if (error) - return error; + if (!list_empty(&tic->t_queue)) { + spin_lock(&log->l_grant_write_lock); + list_del_init(&tic->t_queue); + spin_unlock(&log->l_grant_write_lock); + } + /* we've got enough space */ xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); trace_xfs_log_regrant_write_exit(log, tic); xlog_verify_grant_tail(log); return 0; -} + + + error_return_unlocked: + spin_lock(&log->l_grant_write_lock); + error_return: + list_del_init(&tic->t_queue); + spin_unlock(&log->l_grant_write_lock); + trace_xfs_log_regrant_write_error(log, tic); + + /* + * If we are failing, make sure the ticket doesn't have any + * current reservations. We don't want to add this back when + * the ticket/transaction gets cancelled. + */ + tic->t_curr_res = 0; + tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */ + return XFS_ERROR(EIO); +} /* xlog_regrant_write_log_space */ + /* The first cnt-1 times through here we don't need to * move the grant write head because the permanent diff --git a/trunk/fs/xfs/xfs_trace.h b/trunk/fs/xfs/xfs_trace.h index 494035798873..f1d2802b2f07 100644 --- a/trunk/fs/xfs/xfs_trace.h +++ b/trunk/fs/xfs/xfs_trace.h @@ -834,14 +834,18 @@ DEFINE_LOGGRANT_EVENT(xfs_log_umount_write); DEFINE_LOGGRANT_EVENT(xfs_log_grant_enter); DEFINE_LOGGRANT_EVENT(xfs_log_grant_exit); DEFINE_LOGGRANT_EVENT(xfs_log_grant_error); -DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep); -DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake); +DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep1); +DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake1); +DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep2); +DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake2); DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake_up); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_enter); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_exit); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_error); -DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep); -DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep1); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake1); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep2); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake2); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake_up); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_enter); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_exit); diff --git a/trunk/include/asm-generic/unistd.h b/trunk/include/asm-generic/unistd.h index 2292d1af9d70..f4c38d8c6674 100644 --- a/trunk/include/asm-generic/unistd.h +++ b/trunk/include/asm-generic/unistd.h @@ -685,15 +685,9 @@ __SYSCALL(__NR_syncfs, sys_syncfs) __SYSCALL(__NR_setns, sys_setns) #define __NR_sendmmsg 269 __SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg) -#define __NR_process_vm_readv 270 -__SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \ - compat_sys_process_vm_readv) -#define __NR_process_vm_writev 271 -__SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \ - compat_sys_process_vm_writev) #undef __NR_syscalls -#define __NR_syscalls 272 +#define __NR_syscalls 270 /* * All syscalls below here should go away really, diff --git a/trunk/include/linux/compat.h b/trunk/include/linux/compat.h index 66ed067fb729..154bf5683015 100644 --- a/trunk/include/linux/compat.h +++ b/trunk/include/linux/compat.h @@ -552,14 +552,5 @@ extern ssize_t compat_rw_copy_check_uvector(int type, extern void __user *compat_alloc_user_space(unsigned long len); -asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid, - const struct compat_iovec __user *lvec, - unsigned long liovcnt, const struct compat_iovec __user *rvec, - unsigned long riovcnt, unsigned long flags); -asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid, - const struct compat_iovec __user *lvec, - unsigned long liovcnt, const struct compat_iovec __user *rvec, - unsigned long riovcnt, unsigned long flags); - #endif /* CONFIG_COMPAT */ #endif /* _LINUX_COMPAT_H */ diff --git a/trunk/include/linux/dcache.h b/trunk/include/linux/dcache.h index ed9f74f6c519..4df926199369 100644 --- a/trunk/include/linux/dcache.h +++ b/trunk/include/linux/dcache.h @@ -339,8 +339,7 @@ extern int d_validate(struct dentry *, struct dentry *); */ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); -extern char *__d_path(const struct path *, const struct path *, char *, int); -extern char *d_absolute_path(const struct path *, char *, int); +extern char *__d_path(const struct path *path, struct path *root, char *, int); extern char *d_path(const struct path *, char *, int); extern char *d_path_with_unreachable(const struct path *, char *, int); extern char *dentry_path_raw(struct dentry *, char *, int); diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index e0bc4ffb8e7f..e3130220ce3e 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -393,8 +393,8 @@ struct inodes_stat_t { #include #include #include -#include #include +#include #include @@ -1942,7 +1942,6 @@ extern int fd_statfs(int, struct kstatfs *); extern int statfs_by_dentry(struct dentry *, struct kstatfs *); extern int freeze_super(struct super_block *super); extern int thaw_super(struct super_block *super); -extern bool our_mnt(struct vfsmount *mnt); extern int current_umask(void); diff --git a/trunk/include/linux/ftrace_event.h b/trunk/include/linux/ftrace_event.h index c3da42dd22ba..96efa6794ea5 100644 --- a/trunk/include/linux/ftrace_event.h +++ b/trunk/include/linux/ftrace_event.h @@ -172,7 +172,6 @@ enum { TRACE_EVENT_FL_FILTERED_BIT, TRACE_EVENT_FL_RECORDED_CMD_BIT, TRACE_EVENT_FL_CAP_ANY_BIT, - TRACE_EVENT_FL_NO_SET_FILTER_BIT, }; enum { @@ -180,7 +179,6 @@ enum { TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT), TRACE_EVENT_FL_RECORDED_CMD = (1 << TRACE_EVENT_FL_RECORDED_CMD_BIT), TRACE_EVENT_FL_CAP_ANY = (1 << TRACE_EVENT_FL_CAP_ANY_BIT), - TRACE_EVENT_FL_NO_SET_FILTER = (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT), }; struct ftrace_event_call { diff --git a/trunk/include/linux/log2.h b/trunk/include/linux/log2.h index fd7ff3d91e6a..25b808631cd9 100644 --- a/trunk/include/linux/log2.h +++ b/trunk/include/linux/log2.h @@ -185,6 +185,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n) #define rounddown_pow_of_two(n) \ ( \ __builtin_constant_p(n) ? ( \ + (n == 1) ? 0 : \ (1UL << ilog2(n))) : \ __rounddown_pow_of_two(n) \ ) diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 4baadd18f4ad..3dc3a8c2c485 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/include/linux/mmc/card.h b/trunk/include/linux/mmc/card.h index c8ef9bc54d50..415f2db414e1 100644 --- a/trunk/include/linux/mmc/card.h +++ b/trunk/include/linux/mmc/card.h @@ -218,7 +218,6 @@ struct mmc_card { #define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */ #define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */ #define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */ -#define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */ /* byte mode */ unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */ #define MMC_NO_POWER_NOTIFICATION 0 @@ -434,11 +433,6 @@ static inline int mmc_card_broken_byte_mode_512(const struct mmc_card *c) return c->quirks & MMC_QUIRK_BROKEN_BYTE_MODE_512; } -static inline int mmc_card_long_read_time(const struct mmc_card *c) -{ - return c->quirks & MMC_QUIRK_LONG_READ_TIME; -} - #define mmc_card_name(c) ((c)->cid.prod_name) #define mmc_card_id(c) (dev_name(&(c)->dev)) diff --git a/trunk/include/linux/shrinker.h b/trunk/include/linux/shrinker.h index 07ceb97d53fa..a83833a1f7a2 100644 --- a/trunk/include/linux/shrinker.h +++ b/trunk/include/linux/shrinker.h @@ -35,7 +35,7 @@ struct shrinker { /* These are for internal use */ struct list_head list; - atomic_long_t nr_in_batch; /* objs pending delete */ + long nr; /* objs pending delete */ }; #define DEFAULT_SEEKS 2 /* A good number if you don't know better. */ extern void register_shrinker(struct shrinker *); diff --git a/trunk/include/target/target_core_base.h b/trunk/include/target/target_core_base.h index 6873c7dd9145..7f5fed3c89e1 100644 --- a/trunk/include/target/target_core_base.h +++ b/trunk/include/target/target_core_base.h @@ -103,10 +103,9 @@ enum se_cmd_flags_table { SCF_SCSI_NON_DATA_CDB = 0x00000040, SCF_SCSI_CDB_EXCEPTION = 0x00000080, SCF_SCSI_RESERVATION_CONFLICT = 0x00000100, - SCF_FUA = 0x00000200, + SCF_SE_CMD_FAILED = 0x00000400, SCF_SE_LUN_CMD = 0x00000800, SCF_SE_ALLOW_EOO = 0x00001000, - SCF_BIDI = 0x00002000, SCF_SENT_CHECK_CONDITION = 0x00004000, SCF_OVERFLOW_BIT = 0x00008000, SCF_UNDERFLOW_BIT = 0x00010000, @@ -155,7 +154,6 @@ enum tcm_sense_reason_table { TCM_CHECK_CONDITION_ABORT_CMD = 0x0d, TCM_CHECK_CONDITION_UNIT_ATTENTION = 0x0e, TCM_CHECK_CONDITION_NOT_READY = 0x0f, - TCM_RESERVATION_CONFLICT = 0x10, }; struct se_obj { @@ -213,6 +211,7 @@ struct t10_alua_lu_gp { u16 lu_gp_id; int lu_gp_valid_id; u32 lu_gp_members; + atomic_t lu_gp_shutdown; atomic_t lu_gp_ref_cnt; spinlock_t lu_gp_lock; struct config_group lu_gp_group; @@ -423,9 +422,11 @@ struct se_cmd { int sam_task_attr; /* Transport protocol dependent state, see transport_state_table */ enum transport_state_table t_state; + /* Transport specific error status */ + int transport_error_status; /* Used to signal cmd->se_tfo->check_release_cmd() usage per cmd */ - unsigned check_release:1; - unsigned cmd_wait_set:1; + int check_release:1; + int cmd_wait_set:1; /* See se_cmd_flags_table */ u32 se_cmd_flags; u32 se_ordered_id; @@ -440,10 +441,13 @@ struct se_cmd { /* Used for sense data */ void *sense_buffer; struct list_head se_delayed_node; + struct list_head se_ordered_node; struct list_head se_lun_node; struct list_head se_qf_node; struct se_device *se_dev; struct se_dev_entry *se_deve; + struct se_device *se_obj_ptr; + struct se_device *se_orig_obj_ptr; struct se_lun *se_lun; /* Only used for internal passthrough and legacy TCM fabric modules */ struct se_session *se_sess; @@ -459,6 +463,8 @@ struct se_cmd { unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE]; unsigned long long t_task_lba; int t_tasks_failed; + int t_tasks_fua; + bool t_tasks_bidi; u32 t_tasks_sg_chained_no; atomic_t t_fe_count; atomic_t t_se_count; @@ -483,6 +489,14 @@ struct se_cmd { struct work_struct work; + /* + * Used for pre-registered fabric SGL passthrough WRITE and READ + * with the special SCF_PASSTHROUGH_CONTIG_TO_SG case for TCM_Loop + * and other HW target mode fabric modules. + */ + struct scatterlist *t_task_pt_sgl; + u32 t_task_pt_sgl_num; + struct scatterlist *t_data_sg; unsigned int t_data_nents; struct scatterlist *t_bidi_data_sg; @@ -548,7 +562,7 @@ struct se_node_acl { } ____cacheline_aligned; struct se_session { - unsigned sess_tearing_down:1; + int sess_tearing_down:1; u64 sess_bin_isid; struct se_node_acl *se_node_acl; struct se_portal_group *se_tpg; @@ -669,6 +683,7 @@ struct se_subsystem_dev { struct t10_reservation t10_pr; spinlock_t se_dev_lock; void *se_dev_su_ptr; + struct list_head se_dev_node; struct config_group se_dev_group; /* For T10 Reservations */ struct config_group se_dev_pr_group; @@ -677,6 +692,9 @@ struct se_subsystem_dev { } ____cacheline_aligned; struct se_device { + /* Set to 1 if thread is NOT sleeping on thread_sem */ + u8 thread_active; + u8 dev_status_timer_flags; /* RELATIVE TARGET PORT IDENTIFER Counter */ u16 dev_rpti_counter; /* Used for SAM Task Attribute ordering */ @@ -701,10 +719,14 @@ struct se_device { u64 write_bytes; spinlock_t stats_lock; /* Active commands on this virtual SE device */ + atomic_t active_cmds; atomic_t simple_cmds; atomic_t depth_left; atomic_t dev_ordered_id; + atomic_t dev_tur_active; atomic_t execute_tasks; + atomic_t dev_status_thr_count; + atomic_t dev_hoq_count; atomic_t dev_ordered_sync; atomic_t dev_qf_count; struct se_obj dev_obj; @@ -712,9 +734,14 @@ struct se_device { struct se_obj dev_export_obj; struct se_queue_obj dev_queue_obj; spinlock_t delayed_cmd_lock; + spinlock_t ordered_cmd_lock; spinlock_t execute_task_lock; + spinlock_t state_task_lock; + spinlock_t dev_alua_lock; spinlock_t dev_reservation_lock; + spinlock_t dev_state_lock; spinlock_t dev_status_lock; + spinlock_t dev_status_thr_lock; spinlock_t se_port_lock; spinlock_t se_tmr_lock; spinlock_t qf_cmd_lock; @@ -726,10 +753,14 @@ struct se_device { struct t10_pr_registration *dev_pr_res_holder; struct list_head dev_sep_list; struct list_head dev_tmr_list; + struct timer_list dev_status_timer; /* Pointer to descriptor for processing thread */ struct task_struct *process_thread; + pid_t process_thread_pid; + struct task_struct *dev_mgmt_thread; struct work_struct qf_work_queue; struct list_head delayed_cmd_list; + struct list_head ordered_cmd_list; struct list_head execute_task_list; struct list_head state_task_list; struct list_head qf_cmd_list; @@ -740,6 +771,8 @@ struct se_device { struct se_subsystem_api *transport; /* Linked list for struct se_hba struct se_device list */ struct list_head dev_list; + /* Linked list for struct se_global->g_se_dev_list */ + struct list_head g_se_dev_list; } ____cacheline_aligned; struct se_hba { @@ -801,6 +834,7 @@ struct se_port { u32 sep_index; struct scsi_port_stats sep_stats; /* Used for ALUA Target Port Groups membership */ + atomic_t sep_tg_pt_gp_active; atomic_t sep_tg_pt_secondary_offline; /* Used for PR ALL_TG_PT=1 */ atomic_t sep_tg_pt_ref_cnt; diff --git a/trunk/include/target/target_core_transport.h b/trunk/include/target/target_core_transport.h index dac4f2d859fd..c16e9431dd01 100644 --- a/trunk/include/target/target_core_transport.h +++ b/trunk/include/target/target_core_transport.h @@ -10,6 +10,29 @@ #define PYX_TRANSPORT_STATUS_INTERVAL 5 /* In seconds */ +#define PYX_TRANSPORT_SENT_TO_TRANSPORT 0 +#define PYX_TRANSPORT_WRITE_PENDING 1 + +#define PYX_TRANSPORT_UNKNOWN_SAM_OPCODE -1 +#define PYX_TRANSPORT_HBA_QUEUE_FULL -2 +#define PYX_TRANSPORT_REQ_TOO_MANY_SECTORS -3 +#define PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES -4 +#define PYX_TRANSPORT_INVALID_CDB_FIELD -5 +#define PYX_TRANSPORT_INVALID_PARAMETER_LIST -6 +#define PYX_TRANSPORT_LU_COMM_FAILURE -7 +#define PYX_TRANSPORT_UNKNOWN_MODE_PAGE -8 +#define PYX_TRANSPORT_WRITE_PROTECTED -9 +#define PYX_TRANSPORT_RESERVATION_CONFLICT -10 +#define PYX_TRANSPORT_ILLEGAL_REQUEST -11 +#define PYX_TRANSPORT_USE_SENSE_REASON -12 + +#ifndef SAM_STAT_RESERVATION_CONFLICT +#define SAM_STAT_RESERVATION_CONFLICT 0x18 +#endif + +#define TRANSPORT_PLUGIN_FREE 0 +#define TRANSPORT_PLUGIN_REGISTERED 1 + #define TRANSPORT_PLUGIN_PHBA_PDEV 1 #define TRANSPORT_PLUGIN_VHBA_PDEV 2 #define TRANSPORT_PLUGIN_VHBA_VDEV 3 @@ -135,6 +158,7 @@ extern int transport_generic_allocate_tasks(struct se_cmd *, unsigned char *); extern int transport_handle_cdb_direct(struct se_cmd *); extern int transport_generic_handle_cdb_map(struct se_cmd *); extern int transport_generic_handle_data(struct se_cmd *); +extern void transport_new_cmd_failure(struct se_cmd *); extern int transport_generic_handle_tmr(struct se_cmd *); extern bool target_stop_task(struct se_task *task, unsigned long *flags); extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32, diff --git a/trunk/kernel/events/core.c b/trunk/kernel/events/core.c index 58690af323e4..600c1629b64d 100644 --- a/trunk/kernel/events/core.c +++ b/trunk/kernel/events/core.c @@ -2174,11 +2174,11 @@ static void perf_event_context_sched_in(struct perf_event_context *ctx, */ cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE); + perf_event_sched_in(cpuctx, ctx, task); + if (ctx->nr_events) cpuctx->task_ctx = ctx; - perf_event_sched_in(cpuctx, cpuctx->task_ctx, task); - perf_pmu_enable(ctx->pmu); perf_ctx_unlock(cpuctx, ctx); @@ -3558,13 +3558,9 @@ static void ring_buffer_wakeup(struct perf_event *event) rcu_read_lock(); rb = rcu_dereference(event->rb); - if (!rb) - goto unlock; - - list_for_each_entry_rcu(event, &rb->event_list, rb_entry) + list_for_each_entry_rcu(event, &rb->event_list, rb_entry) { wake_up_all(&event->waitq); - -unlock: + } rcu_read_unlock(); } diff --git a/trunk/kernel/jump_label.c b/trunk/kernel/jump_label.c index 66ff7109f697..bbdfe2a462a0 100644 --- a/trunk/kernel/jump_label.c +++ b/trunk/kernel/jump_label.c @@ -66,9 +66,8 @@ void jump_label_inc(struct jump_label_key *key) return; jump_label_lock(); - if (atomic_read(&key->enabled) == 0) + if (atomic_add_return(1, &key->enabled) == 1) jump_label_update(key, JUMP_LABEL_ENABLE); - atomic_inc(&key->enabled); jump_label_unlock(); } diff --git a/trunk/kernel/lockdep.c b/trunk/kernel/lockdep.c index b2e08c932d91..e69434b070da 100644 --- a/trunk/kernel/lockdep.c +++ b/trunk/kernel/lockdep.c @@ -44,7 +44,6 @@ #include #include #include -#include #include @@ -2949,12 +2948,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, void lockdep_init_map(struct lockdep_map *lock, const char *name, struct lock_class_key *key, int subclass) { - int i; - - kmemcheck_mark_initialized(lock, sizeof(*lock)); - - for (i = 0; i < NR_LOCKDEP_CACHING_CLASSES; i++) - lock->class_cache[i] = NULL; + memset(lock, 0, sizeof(*lock)); #ifdef CONFIG_LOCK_STAT lock->cpu = raw_smp_processor_id(); diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c index 7982a0a841ea..1455a0d4eedd 100644 --- a/trunk/kernel/printk.c +++ b/trunk/kernel/printk.c @@ -1293,11 +1293,10 @@ void console_unlock(void) raw_spin_lock(&logbuf_lock); if (con_start != log_end) retry = 1; - raw_spin_unlock_irqrestore(&logbuf_lock, flags); - if (retry && console_trylock()) goto again; + raw_spin_unlock_irqrestore(&logbuf_lock, flags); if (wake_klogd) wake_up_klogd(); } diff --git a/trunk/kernel/time/alarmtimer.c b/trunk/kernel/time/alarmtimer.c index 8a46f5d64504..c436e790b21b 100644 --- a/trunk/kernel/time/alarmtimer.c +++ b/trunk/kernel/time/alarmtimer.c @@ -195,7 +195,7 @@ static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) struct alarm *alarm; ktime_t expired = next->expires; - if (expired.tv64 > now.tv64) + if (expired.tv64 >= now.tv64) break; alarm = container_of(next, struct alarm, node); diff --git a/trunk/kernel/timer.c b/trunk/kernel/timer.c index 9c3c62b0c4bc..dbaa62422b13 100644 --- a/trunk/kernel/timer.c +++ b/trunk/kernel/timer.c @@ -1368,7 +1368,7 @@ SYSCALL_DEFINE0(getppid) int pid; rcu_read_lock(); - pid = task_tgid_vnr(rcu_dereference(current->real_parent)); + pid = task_tgid_vnr(current->real_parent); rcu_read_unlock(); return pid; diff --git a/trunk/kernel/trace/ftrace.c b/trunk/kernel/trace/ftrace.c index b1e8943fed1d..900b409543db 100644 --- a/trunk/kernel/trace/ftrace.c +++ b/trunk/kernel/trace/ftrace.c @@ -152,6 +152,7 @@ void clear_ftrace_function(void) ftrace_pid_function = ftrace_stub; } +#undef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST #ifndef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST /* * For those archs that do not test ftrace_trace_stop in their @@ -1211,9 +1212,7 @@ ftrace_hash_move(struct ftrace_ops *ops, int enable, if (!src->count) { free_ftrace_hash_rcu(*dst); rcu_assign_pointer(*dst, EMPTY_HASH); - /* still need to update the function records */ - ret = 0; - goto out; + return 0; } /* diff --git a/trunk/kernel/trace/trace_events.c b/trunk/kernel/trace/trace_events.c index c212a7f934ec..581876f9f387 100644 --- a/trunk/kernel/trace/trace_events.c +++ b/trunk/kernel/trace/trace_events.c @@ -1078,6 +1078,7 @@ event_subsystem_dir(const char *name, struct dentry *d_events) /* First see if we did not already create this dir */ list_for_each_entry(system, &event_subsystems, list) { if (strcmp(system->name, name) == 0) { + __get_system(system); system->nr_events++; return system->entry; } diff --git a/trunk/kernel/trace/trace_events_filter.c b/trunk/kernel/trace/trace_events_filter.c index 95dc31efd6dd..d6e7926dcd26 100644 --- a/trunk/kernel/trace/trace_events_filter.c +++ b/trunk/kernel/trace/trace_events_filter.c @@ -1649,9 +1649,7 @@ static int replace_system_preds(struct event_subsystem *system, */ err = replace_preds(call, NULL, ps, filter_string, true); if (err) - call->flags |= TRACE_EVENT_FL_NO_SET_FILTER; - else - call->flags &= ~TRACE_EVENT_FL_NO_SET_FILTER; + goto fail; } list_for_each_entry(call, &ftrace_events, list) { @@ -1660,9 +1658,6 @@ static int replace_system_preds(struct event_subsystem *system, if (strcmp(call->class->system, system->name) != 0) continue; - if (call->flags & TRACE_EVENT_FL_NO_SET_FILTER) - continue; - filter_item = kzalloc(sizeof(*filter_item), GFP_KERNEL); if (!filter_item) goto fail_mem; diff --git a/trunk/lib/dma-debug.c b/trunk/lib/dma-debug.c index fea790a2b176..74c6c7fce749 100644 --- a/trunk/lib/dma-debug.c +++ b/trunk/lib/dma-debug.c @@ -245,7 +245,7 @@ static void put_hash_bucket(struct hash_bucket *bucket, static bool exact_match(struct dma_debug_entry *a, struct dma_debug_entry *b) { - return ((a->dev_addr == b->dev_addr) && + return ((a->dev_addr == a->dev_addr) && (a->dev == b->dev)) ? true : false; } diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index c106d3b3cc64..c0018f2d50e0 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -2407,6 +2407,7 @@ static ssize_t generic_perform_write(struct file *file, iov_iter_count(i)); again: + /* * Bring in the user page that we will copy from _first_. * Otherwise there's a nasty deadlock on copying from the @@ -2462,10 +2463,7 @@ static ssize_t generic_perform_write(struct file *file, written += copied; balance_dirty_pages_ratelimited(mapping); - if (fatal_signal_pending(current)) { - status = -EINTR; - break; - } + } while (iov_iter_count(i)); return written ? written : status; diff --git a/trunk/mm/huge_memory.c b/trunk/mm/huge_memory.c index 36b3d988b4ef..4298abaae153 100644 --- a/trunk/mm/huge_memory.c +++ b/trunk/mm/huge_memory.c @@ -2259,8 +2259,12 @@ static void khugepaged_do_scan(struct page **hpage) static void khugepaged_alloc_sleep(void) { - wait_event_freezable_timeout(khugepaged_wait, false, - msecs_to_jiffies(khugepaged_alloc_sleep_millisecs)); + DEFINE_WAIT(wait); + add_wait_queue(&khugepaged_wait, &wait); + schedule_timeout_interruptible( + msecs_to_jiffies( + khugepaged_alloc_sleep_millisecs)); + remove_wait_queue(&khugepaged_wait, &wait); } #ifndef CONFIG_NUMA @@ -2309,10 +2313,14 @@ static void khugepaged_loop(void) if (unlikely(kthread_should_stop())) break; if (khugepaged_has_work()) { + DEFINE_WAIT(wait); if (!khugepaged_scan_sleep_millisecs) continue; - wait_event_freezable_timeout(khugepaged_wait, false, - msecs_to_jiffies(khugepaged_scan_sleep_millisecs)); + add_wait_queue(&khugepaged_wait, &wait); + schedule_timeout_interruptible( + msecs_to_jiffies( + khugepaged_scan_sleep_millisecs)); + remove_wait_queue(&khugepaged_wait, &wait); } else if (khugepaged_enabled()) wait_event_freezable(khugepaged_wait, khugepaged_wait_event()); diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index 73f17c0293c0..bb28a5f9db8d 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -576,7 +576,6 @@ static void prep_compound_gigantic_page(struct page *page, unsigned long order) __SetPageHead(page); for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) { __SetPageTail(p); - set_page_count(p, 0); p->first_page = page; } } diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index 177aca424a06..578e29174fa6 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -871,9 +871,9 @@ static int unmap_and_move_huge_page(new_page_t get_new_page, if (anon_vma) put_anon_vma(anon_vma); +out: unlock_page(hpage); -out: if (rc != -EAGAIN) { list_del(&hpage->lru); put_page(hpage); diff --git a/trunk/mm/page-writeback.c b/trunk/mm/page-writeback.c index 50f08241f981..71252486bc6f 100644 --- a/trunk/mm/page-writeback.c +++ b/trunk/mm/page-writeback.c @@ -411,13 +411,8 @@ void global_dirty_limits(unsigned long *pbackground, unsigned long *pdirty) * * Returns @bdi's dirty limit in pages. The term "dirty" in the context of * dirty balancing includes all PG_dirty, PG_writeback and NFS unstable pages. - * - * Note that balance_dirty_pages() will only seriously take it as a hard limit - * when sleeping max_pause per page is not enough to keep the dirty pages under - * control. For example, when the device is completely stalled due to some error - * conditions, or when there are 1000 dd tasks writing to a slow 10MB/s USB key. - * In the other normal situations, it acts more gently by throttling the tasks - * more (rather than completely block them) when the bdi dirty pages go high. + * And the "limit" in the name is not seriously taken as hard limit in + * balance_dirty_pages(). * * It allocates high/low dirty limits to fast/slow devices, in order to prevent * - starving fast devices @@ -599,13 +594,6 @@ static unsigned long bdi_position_ratio(struct backing_dev_info *bdi, */ if (unlikely(bdi_thresh > thresh)) bdi_thresh = thresh; - /* - * It's very possible that bdi_thresh is close to 0 not because the - * device is slow, but that it has remained inactive for long time. - * Honour such devices a reasonable good (hopefully IO efficient) - * threshold, so that the occasional writes won't be blocked and active - * writes can rampup the threshold quickly. - */ bdi_thresh = max(bdi_thresh, (limit - dirty) / 8); /* * scale global setpoint to bdi's: @@ -989,7 +977,8 @@ static unsigned long bdi_max_pause(struct backing_dev_info *bdi, * * 8 serves as the safety ratio. */ - t = min(t, bdi_dirty * HZ / (8 * bw + 1)); + if (bdi_dirty) + t = min(t, bdi_dirty * HZ / (8 * bw + 1)); /* * The pause time will be settled within range (max_pause/4, max_pause). @@ -1147,19 +1136,6 @@ static void balance_dirty_pages(struct address_space *mapping, if (task_ratelimit) break; - /* - * In the case of an unresponding NFS server and the NFS dirty - * pages exceeds dirty_thresh, give the other good bdi's a pipe - * to go through, so that tasks on them still remain responsive. - * - * In theory 1 page is enough to keep the comsumer-producer - * pipe going: the flusher cleans 1 page => the task dirties 1 - * more page. However bdi_dirty has accounting errors. So use - * the larger and more IO friendly bdi_stat_error. - */ - if (bdi_dirty <= bdi_stat_error(bdi)) - break; - if (fatal_signal_pending(current)) break; } diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 2b8ba3aebf6e..9dd443d89d8b 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -356,8 +356,8 @@ void prep_compound_page(struct page *page, unsigned long order) __SetPageHead(page); for (i = 1; i < nr_pages; i++) { struct page *p = page + i; + __SetPageTail(p); - set_page_count(p, 0); p->first_page = page; } } @@ -3377,15 +3377,9 @@ static void setup_zone_migrate_reserve(struct zone *zone) unsigned long block_migratetype; int reserve; - /* - * Get the start pfn, end pfn and the number of blocks to reserve - * We have to be careful to be aligned to pageblock_nr_pages to - * make sure that we always check pfn_valid for the first page in - * the block. - */ + /* Get the start pfn, end pfn and the number of blocks to reserve */ start_pfn = zone->zone_start_pfn; end_pfn = start_pfn + zone->spanned_pages; - start_pfn = roundup(start_pfn, pageblock_nr_pages); reserve = roundup(min_wmark_pages(zone), pageblock_nr_pages) >> pageblock_order; diff --git a/trunk/mm/vmalloc.c b/trunk/mm/vmalloc.c index 1d8b32f07139..3231bf332878 100644 --- a/trunk/mm/vmalloc.c +++ b/trunk/mm/vmalloc.c @@ -1633,8 +1633,6 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, goto fail; addr = __vmalloc_area_node(area, gfp_mask, prot, node, caller); - if (!addr) - return NULL; /* * In this function, newly allocated vm_struct is not added diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index f54a05b7a61d..a1893c050795 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -183,7 +183,7 @@ static unsigned long zone_nr_lru_pages(struct zone *zone, */ void register_shrinker(struct shrinker *shrinker) { - atomic_long_set(&shrinker->nr_in_batch, 0); + shrinker->nr = 0; down_write(&shrinker_rwsem); list_add_tail(&shrinker->list, &shrinker_list); up_write(&shrinker_rwsem); @@ -247,26 +247,25 @@ unsigned long shrink_slab(struct shrink_control *shrink, list_for_each_entry(shrinker, &shrinker_list, list) { unsigned long long delta; - long total_scan; - long max_pass; + unsigned long total_scan; + unsigned long max_pass; int shrink_ret = 0; long nr; long new_nr; long batch_size = shrinker->batch ? shrinker->batch : SHRINK_BATCH; - max_pass = do_shrinker_shrink(shrinker, shrink, 0); - if (max_pass <= 0) - continue; - /* * copy the current shrinker scan count into a local variable * and zero it so that other concurrent shrinker invocations * don't also do this scanning work. */ - nr = atomic_long_xchg(&shrinker->nr_in_batch, 0); + do { + nr = shrinker->nr; + } while (cmpxchg(&shrinker->nr, nr, 0) != nr); total_scan = nr; + max_pass = do_shrinker_shrink(shrinker, shrink, 0); delta = (4 * nr_pages_scanned) / shrinker->seeks; delta *= max_pass; do_div(delta, lru_pages + 1); @@ -326,11 +325,12 @@ unsigned long shrink_slab(struct shrink_control *shrink, * manner that handles concurrent updates. If we exhausted the * scan, there is no need to do an update. */ - if (total_scan > 0) - new_nr = atomic_long_add_return(total_scan, - &shrinker->nr_in_batch); - else - new_nr = atomic_long_read(&shrinker->nr_in_batch); + do { + nr = shrinker->nr; + new_nr = total_scan + nr; + if (total_scan <= 0) + break; + } while (cmpxchg(&shrinker->nr, nr, new_nr) != nr); trace_mm_shrink_slab_end(shrinker, shrink_ret, nr, new_nr); } diff --git a/trunk/net/ceph/crush/mapper.c b/trunk/net/ceph/crush/mapper.c index 3a94eae7abe9..42599e31dcad 100644 --- a/trunk/net/ceph/crush/mapper.c +++ b/trunk/net/ceph/crush/mapper.c @@ -477,6 +477,7 @@ int crush_do_rule(struct crush_map *map, int i, j; int numrep; int firstn; + int rc = -1; BUG_ON(ruleno >= map->max_rules); @@ -490,18 +491,23 @@ int crush_do_rule(struct crush_map *map, * that this may or may not correspond to the specific types * referenced by the crush rule. */ - if (force >= 0 && - force < map->max_devices && - map->device_parents[force] != 0 && - !is_out(map, weight, force, x)) { - while (1) { - force_context[++force_pos] = force; - if (force >= 0) - force = map->device_parents[force]; - else - force = map->bucket_parents[-1-force]; - if (force == 0) - break; + if (force >= 0) { + if (force >= map->max_devices || + map->device_parents[force] == 0) { + /*dprintk("CRUSH: forcefed device dne\n");*/ + rc = -1; /* force fed device dne */ + goto out; + } + if (!is_out(map, weight, force, x)) { + while (1) { + force_context[++force_pos] = force; + if (force >= 0) + force = map->device_parents[force]; + else + force = map->bucket_parents[-1-force]; + if (force == 0) + break; + } } } @@ -594,7 +600,10 @@ int crush_do_rule(struct crush_map *map, BUG_ON(1); } } - return result_len; + rc = result_len; + +out: + return rc; } diff --git a/trunk/net/core/request_sock.c b/trunk/net/core/request_sock.c index 9b570a6a33c5..182236b2510a 100644 --- a/trunk/net/core/request_sock.c +++ b/trunk/net/core/request_sock.c @@ -26,11 +26,10 @@ * but then some measure against one socket starving all other sockets * would be needed. * - * The minimum value of it is 128. Experiments with real servers show that + * It was 128 by default. Experiments with real servers show, that * it is absolutely not enough even at 100conn/sec. 256 cures most - * of problems. - * This value is adjusted to 128 for low memory machines, - * and it will increase in proportion to the memory of machine. + * of problems. This value is adjusted to 128 for very small machines + * (<=32Mb of memory) and to 1024 on normal or better ones (>=256Mb). * Note : Dont forget somaxconn that may limit backlog too. */ int sysctl_max_syn_backlog = 256; diff --git a/trunk/net/core/secure_seq.c b/trunk/net/core/secure_seq.c index 925991ae6f52..025233de25f9 100644 --- a/trunk/net/core/secure_seq.c +++ b/trunk/net/core/secure_seq.c @@ -19,7 +19,6 @@ static int __init net_secret_init(void) } late_initcall(net_secret_init); -#ifdef CONFIG_INET static u32 seq_scale(u32 seq) { /* @@ -34,7 +33,6 @@ static u32 seq_scale(u32 seq) */ return seq + (ktime_to_ns(ktime_get_real()) >> 6); } -#endif #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) __u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr, diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 46af62363b8c..ca5e237df029 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -112,7 +112,7 @@ #include #define RT_FL_TOS(oldflp4) \ - ((oldflp4)->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK)) + ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) #define IP_MAX_MTU 0xFFF0 @@ -1310,7 +1310,7 @@ static void rt_del(unsigned hash, struct rtable *rt) spin_unlock_bh(rt_hash_lock_addr(hash)); } -static void check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) +static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) { struct rtable *rt = (struct rtable *) dst; __be32 orig_gw = rt->rt_gateway; @@ -1321,19 +1321,21 @@ static void check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) rt->rt_gateway = peer->redirect_learned.a4; n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); - if (IS_ERR(n)) { - rt->rt_gateway = orig_gw; - return; - } + if (IS_ERR(n)) + return PTR_ERR(n); old_n = xchg(&rt->dst._neighbour, n); if (old_n) neigh_release(old_n); - if (!(n->nud_state & NUD_VALID)) { - neigh_event_send(n, NULL); + if (!n || !(n->nud_state & NUD_VALID)) { + if (n) + neigh_event_send(n, NULL); + rt->rt_gateway = orig_gw; + return -EAGAIN; } else { rt->rt_flags |= RTCF_REDIRECTED; call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); } + return 0; } /* called in rcu_read_lock() section */ @@ -1691,7 +1693,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) } -static void ipv4_validate_peer(struct rtable *rt) +static struct rtable *ipv4_validate_peer(struct rtable *rt) { if (rt->rt_peer_genid != rt_peer_genid()) { struct inet_peer *peer; @@ -1706,12 +1708,15 @@ static void ipv4_validate_peer(struct rtable *rt) if (peer->redirect_genid != redirect_genid) peer->redirect_learned.a4 = 0; if (peer->redirect_learned.a4 && - peer->redirect_learned.a4 != rt->rt_gateway) - check_peer_redir(&rt->dst, peer); + peer->redirect_learned.a4 != rt->rt_gateway) { + if (check_peer_redir(&rt->dst, peer)) + return NULL; + } } rt->rt_peer_genid = rt_peer_genid(); } + return rt; } static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) @@ -1720,7 +1725,7 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) if (rt_is_expired(rt)) return NULL; - ipv4_validate_peer(rt); + dst = (struct dst_entry *) ipv4_validate_peer(rt); return dst; } @@ -2375,7 +2380,9 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, rth->rt_mark == skb->mark && net_eq(dev_net(rth->dst.dev), net) && !rt_is_expired(rth)) { - ipv4_validate_peer(rth); + rth = ipv4_validate_peer(rth); + if (!rth) + continue; if (noref) { dst_use_noref(&rth->dst, jiffies); skb_dst_set_noref(skb, &rth->dst); @@ -2434,11 +2441,11 @@ EXPORT_SYMBOL(ip_route_input_common); static struct rtable *__mkroute_output(const struct fib_result *res, const struct flowi4 *fl4, __be32 orig_daddr, __be32 orig_saddr, - int orig_oif, __u8 orig_rtos, - struct net_device *dev_out, + int orig_oif, struct net_device *dev_out, unsigned int flags) { struct fib_info *fi = res->fi; + u32 tos = RT_FL_TOS(fl4); struct in_device *in_dev; u16 type = res->type; struct rtable *rth; @@ -2489,7 +2496,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, rth->rt_genid = rt_genid(dev_net(dev_out)); rth->rt_flags = flags; rth->rt_type = type; - rth->rt_key_tos = orig_rtos; + rth->rt_key_tos = tos; rth->rt_dst = fl4->daddr; rth->rt_src = fl4->saddr; rth->rt_route_iif = 0; @@ -2539,7 +2546,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4) { struct net_device *dev_out = NULL; - __u8 tos = RT_FL_TOS(fl4); + u32 tos = RT_FL_TOS(fl4); unsigned int flags = 0; struct fib_result res; struct rtable *rth; @@ -2715,7 +2722,7 @@ static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4) make_route: rth = __mkroute_output(&res, fl4, orig_daddr, orig_saddr, orig_oif, - tos, dev_out, flags); + dev_out, flags); if (!IS_ERR(rth)) { unsigned int hash; @@ -2751,7 +2758,9 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *flp4) (IPTOS_RT_MASK | RTO_ONLINK)) && net_eq(dev_net(rth->dst.dev), net) && !rt_is_expired(rth)) { - ipv4_validate_peer(rth); + rth = ipv4_validate_peer(rth); + if (!rth) + continue; dst_use(&rth->dst, jiffies); RT_CACHE_STAT_INC(out_hit); rcu_read_unlock_bh(); diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index cae443563ec9..d999bf3b84e1 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -757,12 +757,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (!local->int_scan_req) return -ENOMEM; - for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - if (!local->hw.wiphy->bands[band]) - continue; - local->int_scan_req->rates[band] = (u32) -1; - } - /* if low-level driver supports AP, we also support VLAN */ if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index d5230ecc784d..eca0fad09709 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -1039,6 +1039,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) struct ieee80211_sub_if_data, u.ap); + memset(&sta->sta.drv_priv, 0, hw->sta_data_size); WARN_ON(drv_sta_add(local, sdata, &sta->sta)); } } diff --git a/trunk/net/wireless/reg.c b/trunk/net/wireless/reg.c index 3302c56f60d1..77e926738014 100644 --- a/trunk/net/wireless/reg.c +++ b/trunk/net/wireless/reg.c @@ -57,17 +57,8 @@ #define REG_DBG_PRINT(args...) #endif -static struct regulatory_request core_request_world = { - .initiator = NL80211_REGDOM_SET_BY_CORE, - .alpha2[0] = '0', - .alpha2[1] = '0', - .intersect = false, - .processed = true, - .country_ie_env = ENVIRON_ANY, -}; - /* Receipt of information from last regulatory request */ -static struct regulatory_request *last_request = &core_request_world; +static struct regulatory_request *last_request; /* To trigger userspace events */ static struct platform_device *reg_pdev; @@ -159,7 +150,7 @@ static char user_alpha2[2]; module_param(ieee80211_regdom, charp, 0444); MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); -static void reset_regdomains(bool full_reset) +static void reset_regdomains(void) { /* avoid freeing static information or freeing something twice */ if (cfg80211_regdomain == cfg80211_world_regdom) @@ -174,13 +165,6 @@ static void reset_regdomains(bool full_reset) cfg80211_world_regdom = &world_regdom; cfg80211_regdomain = NULL; - - if (!full_reset) - return; - - if (last_request != &core_request_world) - kfree(last_request); - last_request = &core_request_world; } /* @@ -191,7 +175,7 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd) { BUG_ON(!last_request); - reset_regdomains(false); + reset_regdomains(); cfg80211_world_regdom = rd; cfg80211_regdomain = rd; @@ -1423,8 +1407,7 @@ static int __regulatory_hint(struct wiphy *wiphy, } new_request: - if (last_request != &core_request_world) - kfree(last_request); + kfree(last_request); last_request = pending_request; last_request->intersect = intersect; @@ -1594,6 +1577,9 @@ static int regulatory_hint_core(const char *alpha2) { struct regulatory_request *request; + kfree(last_request); + last_request = NULL; + request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL); if (!request) @@ -1791,7 +1777,7 @@ static void restore_regulatory_settings(bool reset_user) mutex_lock(&cfg80211_mutex); mutex_lock(®_mutex); - reset_regdomains(true); + reset_regdomains(); restore_alpha2(alpha2, reset_user); /* @@ -2051,10 +2037,8 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) } request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); - if (!request_wiphy && - (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER || - last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)) { - schedule_delayed_work(®_timeout, 0); + if (!request_wiphy) { + reg_set_request_processed(); return -ENODEV; } @@ -2062,7 +2046,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) int r; if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) { - reset_regdomains(false); + reset_regdomains(); cfg80211_regdomain = rd; return 0; } @@ -2083,7 +2067,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) if (r) return r; - reset_regdomains(false); + reset_regdomains(); cfg80211_regdomain = rd; return 0; } @@ -2108,7 +2092,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) rd = NULL; - reset_regdomains(false); + reset_regdomains(); cfg80211_regdomain = intersected_rd; return 0; @@ -2128,7 +2112,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) kfree(rd); rd = NULL; - reset_regdomains(false); + reset_regdomains(); cfg80211_regdomain = intersected_rd; return 0; @@ -2281,8 +2265,11 @@ void /* __init_or_exit */ regulatory_exit(void) mutex_lock(&cfg80211_mutex); mutex_lock(®_mutex); - reset_regdomains(true); + reset_regdomains(); + + kfree(last_request); + last_request = NULL; dev_set_uevent_suppress(®_pdev->dev, true); platform_device_unregister(reg_pdev); diff --git a/trunk/security/apparmor/path.c b/trunk/security/apparmor/path.c index b566eba4a65c..36cc0cc39e78 100644 --- a/trunk/security/apparmor/path.c +++ b/trunk/security/apparmor/path.c @@ -57,44 +57,23 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen) static int d_namespace_path(struct path *path, char *buf, int buflen, char **name, int flags) { + struct path root, tmp; char *res; - int error = 0; - int connected = 1; - - if (path->mnt->mnt_flags & MNT_INTERNAL) { - /* it's not mounted anywhere */ - res = dentry_path(path->dentry, buf, buflen); - *name = res; - if (IS_ERR(res)) { - *name = buf; - return PTR_ERR(res); - } - if (path->dentry->d_sb->s_magic == PROC_SUPER_MAGIC && - strncmp(*name, "/sys/", 5) == 0) { - /* TODO: convert over to using a per namespace - * control instead of hard coded /proc - */ - return prepend(name, *name - buf, "/proc", 5); - } - return 0; - } + int connected, error = 0; - /* resolve paths relative to chroot?*/ + /* Get the root we want to resolve too, released below */ if (flags & PATH_CHROOT_REL) { - struct path root; + /* resolve paths relative to chroot */ get_fs_root(current->fs, &root); - res = __d_path(path, &root, buf, buflen); - if (res && !IS_ERR(res)) { - /* everything's fine */ - *name = res; - path_put(&root); - goto ok; - } - path_put(&root); - connected = 0; + } else { + /* resolve paths relative to namespace */ + root.mnt = current->nsproxy->mnt_ns->root; + root.dentry = root.mnt->mnt_root; + path_get(&root); } - res = d_absolute_path(path, buf, buflen); + tmp = root; + res = __d_path(path, &tmp, buf, buflen); *name = res; /* handle error conditions - and still allow a partial path to @@ -105,10 +84,7 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, *name = buf; goto out; } - if (!our_mnt(path->mnt)) - connected = 0; -ok: /* Handle two cases: * 1. A deleted dentry && profile is not allowing mediation of deleted * 2. On some filesystems, newly allocated dentries appear to the @@ -121,7 +97,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, goto out; } - /* If the path is not connected to the expected root, + /* Determine if the path is connected to the expected root */ + connected = tmp.dentry == root.dentry && tmp.mnt == root.mnt; + + /* If the path is not connected, * check if it is a sysctl and handle specially else remove any * leading / that __d_path may have returned. * Unless @@ -133,9 +112,17 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, * namespace root. */ if (!connected) { - if (!(flags & PATH_CONNECT_PATH) && + /* is the disconnect path a sysctl? */ + if (tmp.dentry->d_sb->s_magic == PROC_SUPER_MAGIC && + strncmp(*name, "/sys/", 5) == 0) { + /* TODO: convert over to using a per namespace + * control instead of hard coded /proc + */ + error = prepend(name, *name - buf, "/proc", 5); + } else if (!(flags & PATH_CONNECT_PATH) && !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) && - our_mnt(path->mnt))) { + (tmp.mnt == current->nsproxy->mnt_ns->root && + tmp.dentry == tmp.mnt->mnt_root))) { /* disconnected path, don't return pathname starting * with '/' */ @@ -146,6 +133,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, } out: + path_put(&root); + return error; } diff --git a/trunk/security/tomoyo/realpath.c b/trunk/security/tomoyo/realpath.c index d9f3ced8756e..738bbdf8d4c7 100644 --- a/trunk/security/tomoyo/realpath.c +++ b/trunk/security/tomoyo/realpath.c @@ -101,8 +101,9 @@ static char *tomoyo_get_absolute_path(struct path *path, char * const buffer, { char *pos = ERR_PTR(-ENOMEM); if (buflen >= 256) { + struct path ns_root = { }; /* go to whatever namespace root we are under */ - pos = d_absolute_path(path, buffer, buflen - 1); + pos = __d_path(path, &ns_root, buffer, buflen - 1); if (!IS_ERR(pos) && *pos == '/' && pos[1]) { struct inode *inode = path->dentry->d_inode; if (inode && S_ISDIR(inode->i_mode)) { @@ -293,16 +294,8 @@ char *tomoyo_realpath_from_path(struct path *path) pos = tomoyo_get_local_path(path->dentry, buf, buf_len - 1); /* Get absolute name for the rest. */ - else { + else pos = tomoyo_get_absolute_path(path, buf, buf_len - 1); - /* - * Fall back to local name if absolute name is not - * available. - */ - if (pos == ERR_PTR(-EINVAL)) - pos = tomoyo_get_local_path(path->dentry, buf, - buf_len - 1); - } encode: if (IS_ERR(pos)) continue; diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 1d07e8fa2433..cbde019d3d52 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -297,8 +297,6 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, imux = &spec->input_mux[mux_idx]; if (!imux->num_items && mux_idx > 0) imux = &spec->input_mux[0]; - if (!imux->num_items) - return 0; if (idx >= imux->num_items) idx = imux->num_items - 1; @@ -2631,8 +2629,6 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, case AUTO_PIN_SPEAKER_OUT: if (cfg->line_outs == 1) return "Speaker"; - if (cfg->line_outs == 2) - return ch ? "Bass Speaker" : "Speaker"; break; case AUTO_PIN_HP_OUT: /* for multi-io case, only the primary out */ @@ -2906,7 +2902,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) if (!nid) continue; if (found_in_nid_list(nid, spec->multiout.dac_nids, - ARRAY_SIZE(spec->private_dac_nids))) + spec->multiout.num_dacs)) continue; if (found_in_nid_list(nid, spec->multiout.hp_out_nid, ARRAY_SIZE(spec->multiout.hp_out_nid))) @@ -2927,7 +2923,6 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) return 0; } -/* return 0 if no possible DAC is found, 1 if one or more found */ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, const hda_nid_t *pins, hda_nid_t *dacs) { @@ -2945,7 +2940,7 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, if (!dacs[i]) dacs[i] = alc_auto_look_for_dac(codec, pins[i]); } - return 1; + return 0; } static int alc_auto_fill_multi_ios(struct hda_codec *codec, @@ -2955,7 +2950,7 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec, static int alc_auto_fill_dac_nids(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - struct auto_pin_cfg *cfg = &spec->autocfg; + const struct auto_pin_cfg *cfg = &spec->autocfg; bool redone = false; int i; @@ -2966,7 +2961,6 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) spec->multiout.extra_out_nid[0] = 0; memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); spec->multiout.dac_nids = spec->private_dac_nids; - spec->multi_ios = 0; /* fill hard-wired DACs first */ if (!redone) { @@ -3000,12 +2994,10 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) for (i = 0; i < cfg->line_outs; i++) { if (spec->private_dac_nids[i]) spec->multiout.num_dacs++; - else { + else memmove(spec->private_dac_nids + i, spec->private_dac_nids + i + 1, sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); - spec->private_dac_nids[cfg->line_outs - 1] = 0; - } } if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { @@ -3027,28 +3019,9 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) if (cfg->line_out_type != AUTO_PIN_HP_OUT) alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, spec->multiout.hp_out_nid); - if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { - int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, - cfg->speaker_pins, - spec->multiout.extra_out_nid); - /* if no speaker volume is assigned, try again as the primary - * output - */ - if (!err && cfg->speaker_outs > 0 && - cfg->line_out_type == AUTO_PIN_HP_OUT) { - cfg->hp_outs = cfg->line_outs; - memcpy(cfg->hp_pins, cfg->line_out_pins, - sizeof(cfg->hp_pins)); - cfg->line_outs = cfg->speaker_outs; - memcpy(cfg->line_out_pins, cfg->speaker_pins, - sizeof(cfg->speaker_pins)); - cfg->speaker_outs = 0; - memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); - cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; - redone = false; - goto again; - } - } + if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) + alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins, + spec->multiout.extra_out_nid); return 0; } @@ -3198,8 +3171,7 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, } static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, - hda_nid_t dac, const char *pfx, - int cidx) + hda_nid_t dac, const char *pfx) { struct alc_spec *spec = codec->spec; hda_nid_t sw, vol; @@ -3215,15 +3187,15 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, if (is_ctl_used(spec->sw_ctls, val)) return 0; /* already created */ mark_ctl_usage(spec->sw_ctls, val); - return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val); + return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); } sw = alc_look_for_out_mute_nid(codec, pin, dac); vol = alc_look_for_out_vol_nid(codec, pin, dac); - err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol); + err = alc_auto_add_stereo_vol(codec, pfx, 0, vol); if (err < 0) return err; - err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw); + err = alc_auto_add_stereo_sw(codec, pfx, 0, sw); if (err < 0) return err; return 0; @@ -3264,21 +3236,16 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins, hda_nid_t dac = *dacs; if (!dac) dac = spec->multiout.dac_nids[0]; - return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); + return alc_auto_create_extra_out(codec, *pins, dac, pfx); } if (dacs[num_pins - 1]) { /* OK, we have a multi-output system with individual volumes */ for (i = 0; i < num_pins; i++) { - if (num_pins >= 3) { - snprintf(name, sizeof(name), "%s %s", - pfx, channel_name[i]); - err = alc_auto_create_extra_out(codec, pins[i], dacs[i], - name, 0); - } else { - err = alc_auto_create_extra_out(codec, pins[i], dacs[i], - pfx, i); - } + snprintf(name, sizeof(name), "%s %s", + pfx, channel_name[i]); + err = alc_auto_create_extra_out(codec, pins[i], dacs[i], + name); if (err < 0) return err; } diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index eeb25d529e30..d8d2f9dccd9b 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -215,7 +215,6 @@ struct sigmatel_spec { unsigned int gpio_mute; unsigned int gpio_led; unsigned int gpio_led_polarity; - unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */ unsigned int vref_led; /* stream */ @@ -4319,10 +4318,12 @@ static void stac_store_hints(struct hda_codec *codec) spec->eapd_switch = val; get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { - spec->gpio_mask |= spec->gpio_led; - spec->gpio_dir |= spec->gpio_led; - if (spec->gpio_led_polarity) - spec->gpio_data |= spec->gpio_led; + if (spec->gpio_led <= 8) { + spec->gpio_mask |= spec->gpio_led; + spec->gpio_dir |= spec->gpio_led; + if (spec->gpio_led_polarity) + spec->gpio_data |= spec->gpio_led; + } } } @@ -4442,7 +4443,7 @@ static int stac92xx_init(struct hda_codec *codec) /* power on when no jack detection is available */ /* or when the VREF is used for controlling LED */ if (!spec->hp_detect || - spec->vref_mute_led_nid == nid) { + (spec->gpio_led > 8 && spec->gpio_led == nid)) { stac_toggle_power_map(codec, nid, 1); continue; } @@ -4914,14 +4915,8 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &spec->gpio_led_polarity, &spec->gpio_led) == 2) { - unsigned int max_gpio; - max_gpio = snd_hda_param_read(codec, codec->afg, - AC_PAR_GPIO_CAP); - max_gpio &= AC_GPIO_IO_COUNT; - if (spec->gpio_led < max_gpio) + if (spec->gpio_led < 4) spec->gpio_led = 1 << spec->gpio_led; - else - spec->vref_mute_led_nid = spec->gpio_led; return 1; } if (sscanf(dev->name, "HP_Mute_LED_%d", @@ -5050,12 +5045,15 @@ static int stac92xx_pre_resume(struct hda_codec *codec) struct sigmatel_spec *spec = codec->spec; /* sync mute LED */ - if (spec->vref_mute_led_nid) - stac_vrefout_set(codec, spec->vref_mute_led_nid, - spec->vref_led); - else if (spec->gpio_led) - stac_gpio_set(codec, spec->gpio_mask, - spec->gpio_dir, spec->gpio_data); + if (spec->gpio_led) { + if (spec->gpio_led <= 8) { + stac_gpio_set(codec, spec->gpio_mask, + spec->gpio_dir, spec->gpio_data); + } else { + stac_vrefout_set(codec, + spec->gpio_led, spec->vref_led); + } + } return 0; } @@ -5066,7 +5064,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg, struct sigmatel_spec *spec = codec->spec; if (power_state == AC_PWRST_D3) { - if (spec->vref_mute_led_nid) { + if (spec->gpio_led > 8) { /* with vref-out pin used for mute led control * codec AFG is prevented from D3 state */ @@ -5119,7 +5117,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec) } } /*polarity defines *not* muted state level*/ - if (!spec->vref_mute_led_nid) { + if (spec->gpio_led <= 8) { if (muted) spec->gpio_data &= ~spec->gpio_led; /* orange */ else @@ -5137,8 +5135,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec) muted_lvl = spec->gpio_led_polarity ? AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; spec->vref_led = muted ? muted_lvl : notmtd_lvl; - stac_vrefout_set(codec, spec->vref_mute_led_nid, - spec->vref_led); + stac_vrefout_set(codec, spec->gpio_led, spec->vref_led); } return 0; } @@ -5652,7 +5649,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) #ifdef CONFIG_SND_HDA_POWER_SAVE if (spec->gpio_led) { - if (!spec->vref_mute_led_nid) { + if (spec->gpio_led <= 8) { spec->gpio_mask |= spec->gpio_led; spec->gpio_dir |= spec->gpio_led; spec->gpio_data |= spec->gpio_led; @@ -5965,7 +5962,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) #ifdef CONFIG_SND_HDA_POWER_SAVE if (spec->gpio_led) { - if (!spec->vref_mute_led_nid) { + if (spec->gpio_led <= 8) { spec->gpio_mask |= spec->gpio_led; spec->gpio_dir |= spec->gpio_led; spec->gpio_data |= spec->gpio_led; diff --git a/trunk/sound/pci/sis7019.c b/trunk/sound/pci/sis7019.c index 28dfafb56dd1..a391e622a192 100644 --- a/trunk/sound/pci/sis7019.c +++ b/trunk/sound/pci/sis7019.c @@ -41,7 +41,6 @@ MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}"); static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ static int enable = 1; -static int codecs = 1; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator."); @@ -49,8 +48,6 @@ module_param(id, charp, 0444); MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator."); module_param(enable, bool, 0444); MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); -module_param(codecs, int, 0444); -MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)"); static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, @@ -143,9 +140,6 @@ struct sis7019 { dma_addr_t silence_dma_addr; }; -/* These values are also used by the module param 'codecs' to indicate - * which codecs should be present. - */ #define SIS_PRIMARY_CODEC_PRESENT 0x0001 #define SIS_SECONDARY_CODEC_PRESENT 0x0002 #define SIS_TERTIARY_CODEC_PRESENT 0x0004 @@ -1084,7 +1078,6 @@ static int sis_chip_init(struct sis7019 *sis) { unsigned long io = sis->ioport; void __iomem *ioaddr = sis->ioaddr; - unsigned long timeout; u16 status; int count; int i; @@ -1111,45 +1104,21 @@ static int sis_chip_init(struct sis7019 *sis) while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) udelay(1); - /* Command complete, we can let go of the semaphore now. - */ - outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); - if (!count) - return -EIO; - /* Now that we've finished the reset, find out what's attached. - * There are some codec/board combinations that take an extremely - * long time to come up. 350+ ms has been observed in the field, - * so we'll give them up to 500ms. */ - sis->codecs_present = 0; - timeout = msecs_to_jiffies(500) + jiffies; - while (time_before_eq(jiffies, timeout)) { - status = inl(io + SIS_AC97_STATUS); - if (status & SIS_AC97_STATUS_CODEC_READY) - sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; - if (status & SIS_AC97_STATUS_CODEC2_READY) - sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; - if (status & SIS_AC97_STATUS_CODEC3_READY) - sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; - - if (sis->codecs_present == codecs) - break; - - msleep(1); - } - - /* All done, check for errors. + status = inl(io + SIS_AC97_STATUS); + if (status & SIS_AC97_STATUS_CODEC_READY) + sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; + if (status & SIS_AC97_STATUS_CODEC2_READY) + sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; + if (status & SIS_AC97_STATUS_CODEC3_READY) + sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; + + /* All done, let go of the semaphore, and check for errors */ - if (!sis->codecs_present) { - printk(KERN_ERR "sis7019: could not find any codecs\n"); + outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); + if (!sis->codecs_present || !count) return -EIO; - } - - if (sis->codecs_present != codecs) { - printk(KERN_WARNING "sis7019: missing codecs, found %0x, expected %0x\n", - sis->codecs_present, codecs); - } /* Let the hardware know that the audio driver is alive, * and enable PCM slots on the AC-link for L/R playback (3 & 4) and @@ -1421,17 +1390,6 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci, if (!enable) goto error_out; - /* The user can specify which codecs should be present so that we - * can wait for them to show up if they are slow to recover from - * the AC97 cold reset. We default to a single codec, the primary. - * - * We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2. - */ - codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT | - SIS_TERTIARY_CODEC_PRESENT; - if (!codecs) - codecs = SIS_PRIMARY_CODEC_PRESENT; - rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); if (rc < 0) goto error_out; diff --git a/trunk/sound/soc/codecs/uda1380.c b/trunk/sound/soc/codecs/uda1380.c index 0441893e270e..c5ca8cfea60f 100644 --- a/trunk/sound/soc/codecs/uda1380.c +++ b/trunk/sound/soc/codecs/uda1380.c @@ -863,13 +863,13 @@ static struct i2c_driver uda1380_i2c_driver = { static int __init uda1380_modinit(void) { - int ret = 0; + int ret; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&uda1380_i2c_driver); if (ret != 0) pr_err("Failed to register UDA1380 I2C driver: %d\n", ret); #endif - return ret; + return 0; } module_init(uda1380_modinit); diff --git a/trunk/sound/soc/codecs/wm8994.c b/trunk/sound/soc/codecs/wm8994.c index d0c545b73d78..6c2988549003 100644 --- a/trunk/sound/soc/codecs/wm8994.c +++ b/trunk/sound/soc/codecs/wm8994.c @@ -1325,15 +1325,15 @@ SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), }; static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { -SND_SOC_DAPM_VIRT_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, - adc_mux_ev, SND_SOC_DAPM_PRE_PMU), -SND_SOC_DAPM_VIRT_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, - adc_mux_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, + adc_mux_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, + adc_mux_ev, SND_SOC_DAPM_PRE_PMU), }; static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { -SND_SOC_DAPM_VIRT_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), -SND_SOC_DAPM_VIRT_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), +SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), +SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), }; static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { diff --git a/trunk/sound/soc/imx/Kconfig b/trunk/sound/soc/imx/Kconfig index 738391757f2c..b133bfcc5848 100644 --- a/trunk/sound/soc/imx/Kconfig +++ b/trunk/sound/soc/imx/Kconfig @@ -28,7 +28,7 @@ config SND_MXC_SOC_WM1133_EV1 config SND_SOC_MX27VIS_AIC32X4 tristate "SoC audio support for Visstrim M10 boards" - depends on MACH_IMX27_VISSTRIM_M10 && I2C + depends on MACH_IMX27_VISSTRIM_M10 select SND_SOC_TLV320AIC32X4 select SND_MXC_SOC_MX2 help diff --git a/trunk/sound/soc/kirkwood/Kconfig b/trunk/sound/soc/kirkwood/Kconfig index c62d715235e2..8f49e165f4d1 100644 --- a/trunk/sound/soc/kirkwood/Kconfig +++ b/trunk/sound/soc/kirkwood/Kconfig @@ -12,7 +12,6 @@ config SND_KIRKWOOD_SOC_I2S config SND_KIRKWOOD_SOC_OPENRD tristate "SoC Audio support for Kirkwood Openrd Client" depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE) - depends on I2C select SND_KIRKWOOD_SOC_I2S select SND_SOC_CS42L51 help @@ -21,7 +20,7 @@ config SND_KIRKWOOD_SOC_OPENRD config SND_KIRKWOOD_SOC_T5325 tristate "SoC Audio support for HP t5325" - depends on SND_KIRKWOOD_SOC && MACH_T5325 && I2C + depends on SND_KIRKWOOD_SOC && MACH_T5325 select SND_KIRKWOOD_SOC_I2S select SND_SOC_ALC5623 help diff --git a/trunk/sound/soc/pxa/Kconfig b/trunk/sound/soc/pxa/Kconfig index a0f7d3cfa470..ffd2242e305f 100644 --- a/trunk/sound/soc/pxa/Kconfig +++ b/trunk/sound/soc/pxa/Kconfig @@ -151,7 +151,6 @@ config SND_SOC_ZYLONITE config SND_SOC_RAUMFELD tristate "SoC Audio support Raumfeld audio adapter" depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER || MACH_RAUMFELD_CONNECTOR) - depends on I2C && SPI_MASTER select SND_PXA_SOC_SSP select SND_SOC_CS4270 select SND_SOC_AK4104 @@ -160,7 +159,7 @@ config SND_SOC_RAUMFELD config SND_PXA2XX_SOC_HX4700 tristate "SoC Audio support for HP iPAQ hx4700" - depends on SND_PXA2XX_SOC && MACH_H4700 && I2C + depends on SND_PXA2XX_SOC && MACH_H4700 select SND_PXA2XX_SOC_I2S select SND_SOC_AK4641 help diff --git a/trunk/sound/soc/soc-utils.c b/trunk/sound/soc/soc-utils.c index 4220bb0f2730..0c12b98484bd 100644 --- a/trunk/sound/soc/soc-utils.c +++ b/trunk/sound/soc/soc-utils.c @@ -58,36 +58,7 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params) } EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); -static const struct snd_pcm_hardware dummy_dma_hardware = { - .formats = 0xffffffff, - .channels_min = 1, - .channels_max = UINT_MAX, - - /* Random values to keep userspace happy when checking constraints */ - .info = SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER, - .buffer_bytes_max = 128*1024, - .period_bytes_min = PAGE_SIZE, - .period_bytes_max = PAGE_SIZE*2, - .periods_min = 2, - .periods_max = 128, -}; - -static int dummy_dma_open(struct snd_pcm_substream *substream) -{ - snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware); - - return 0; -} - -static struct snd_pcm_ops dummy_dma_ops = { - .open = dummy_dma_open, - .ioctl = snd_pcm_lib_ioctl, -}; - -static struct snd_soc_platform_driver dummy_platform = { - .ops = &dummy_dma_ops, -}; +static struct snd_soc_platform_driver dummy_platform; static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) { diff --git a/trunk/tools/perf/builtin-stat.c b/trunk/tools/perf/builtin-stat.c index 955930e0a5c3..7d98676808d8 100644 --- a/trunk/tools/perf/builtin-stat.c +++ b/trunk/tools/perf/builtin-stat.c @@ -463,8 +463,7 @@ static int run_perf_stat(int argc __used, const char **argv) list_for_each_entry(counter, &evsel_list->entries, node) { if (create_perf_stat_counter(counter, first) < 0) { - if (errno == EINVAL || errno == ENOSYS || - errno == ENOENT || errno == EOPNOTSUPP) { + if (errno == EINVAL || errno == ENOSYS || errno == ENOENT) { if (verbose) ui__warning("%s event is not supported by the kernel.\n", event_name(counter)); diff --git a/trunk/tools/perf/util/header.c b/trunk/tools/perf/util/header.c index 33c17a2b2a81..bcd05d05b4f0 100644 --- a/trunk/tools/perf/util/header.c +++ b/trunk/tools/perf/util/header.c @@ -388,7 +388,7 @@ static int write_event_desc(int fd, struct perf_header *h __used, /* * write event string as passed on cmdline */ - ret = do_write_string(fd, event_name(attr)); + ret = do_write_string(fd, attr->name); if (ret < 0) return ret; /* diff --git a/trunk/tools/perf/util/trace-event-parse.c b/trunk/tools/perf/util/trace-event-parse.c index 6c164dc9ee95..0a7ed5b5e281 100644 --- a/trunk/tools/perf/util/trace-event-parse.c +++ b/trunk/tools/perf/util/trace-event-parse.c @@ -1537,8 +1537,6 @@ process_flags(struct event *event, struct print_arg *arg, char **tok) field = malloc_or_die(sizeof(*field)); type = process_arg(event, field, &token); - while (type == EVENT_OP) - type = process_op(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ",")) goto out_free;