diff options
42 files changed, 404 insertions, 231 deletions
diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c index 0a37c8bfc959..99ffc5f1c0dd 100644 --- a/arch/sh/boards/board-magicpanelr2.c +++ b/arch/sh/boards/board-magicpanelr2.c | |||
@@ -205,8 +205,6 @@ static void __init setup_port_multiplexing(void) | |||
205 | 205 | ||
206 | static void __init mpr2_setup(char **cmdline_p) | 206 | static void __init mpr2_setup(char **cmdline_p) |
207 | { | 207 | { |
208 | __set_io_port_base(0xa0000000); | ||
209 | |||
210 | /* set Pin Select Register A: | 208 | /* set Pin Select Register A: |
211 | * /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2, | 209 | * /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2, |
212 | * /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND | 210 | * /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND |
diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c index ebe99227d4e6..a4b7402d6176 100644 --- a/arch/sh/boards/mach-dreamcast/setup.c +++ b/arch/sh/boards/mach-dreamcast/setup.c | |||
@@ -42,8 +42,6 @@ static void __init dreamcast_setup(char **cmdline_p) | |||
42 | /* Acknowledge any previous events */ | 42 | /* Acknowledge any previous events */ |
43 | /* XXX */ | 43 | /* XXX */ |
44 | 44 | ||
45 | __set_io_port_base(0xa0000000); | ||
46 | |||
47 | /* Assign all virtual IRQs to the System ASIC int. handler */ | 45 | /* Assign all virtual IRQs to the System ASIC int. handler */ |
48 | for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) | 46 | for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) |
49 | set_irq_chip_and_handler(i, &systemasic_int, | 47 | set_irq_chip_and_handler(i, &systemasic_int, |
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 5f9881e16e2f..3b1ceb46fa54 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/usb/r8a66597.h> | 19 | #include <linux/usb/r8a66597.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/i2c/tsc2007.h> | ||
21 | #include <linux/input.h> | 22 | #include <linux/input.h> |
22 | #include <video/sh_mobile_lcdc.h> | 23 | #include <video/sh_mobile_lcdc.h> |
23 | #include <media/sh_mobile_ceu.h> | 24 | #include <media/sh_mobile_ceu.h> |
@@ -38,6 +39,20 @@ | |||
38 | * 0x1800_0000 MFI 16bit | 39 | * 0x1800_0000 MFI 16bit |
39 | */ | 40 | */ |
40 | 41 | ||
42 | /* SWITCH | ||
43 | *------------------------------ | ||
44 | * DS2[1] = FlashROM write protect ON : write protect | ||
45 | * OFF : No write protect | ||
46 | * DS2[2] = RMII / TS, SCIF ON : RMII | ||
47 | * OFF : TS, SCIF3 | ||
48 | * DS2[3] = Camera / Video ON : Camera | ||
49 | * OFF : NTSC/PAL (IN) | ||
50 | * DS2[5] = NTSC_OUT Clock ON : On board OSC | ||
51 | * OFF : SH7724 DV_CLK | ||
52 | * DS2[6-7] = MMC / SD ON-OFF : SD | ||
53 | * OFF-ON : MMC | ||
54 | */ | ||
55 | |||
41 | /* Heartbeat */ | 56 | /* Heartbeat */ |
42 | static unsigned char led_pos[] = { 0, 1, 2, 3 }; | 57 | static unsigned char led_pos[] = { 0, 1, 2, 3 }; |
43 | static struct heartbeat_data heartbeat_data = { | 58 | static struct heartbeat_data heartbeat_data = { |
@@ -70,7 +85,7 @@ static struct mtd_partition nor_flash_partitions[] = { | |||
70 | .name = "boot loader", | 85 | .name = "boot loader", |
71 | .offset = 0, | 86 | .offset = 0, |
72 | .size = (5 * 1024 * 1024), | 87 | .size = (5 * 1024 * 1024), |
73 | .mask_flags = MTD_CAP_ROM, | 88 | .mask_flags = MTD_WRITEABLE, /* force read-only */ |
74 | }, { | 89 | }, { |
75 | .name = "free-area", | 90 | .name = "free-area", |
76 | .offset = MTDPART_OFS_APPEND, | 91 | .offset = MTDPART_OFS_APPEND, |
@@ -376,6 +391,43 @@ static struct platform_device keysc_device = { | |||
376 | }, | 391 | }, |
377 | }; | 392 | }; |
378 | 393 | ||
394 | /* TouchScreen */ | ||
395 | #define IRQ0 32 | ||
396 | static int ts_get_pendown_state(void) | ||
397 | { | ||
398 | int val = 0; | ||
399 | gpio_free(GPIO_FN_INTC_IRQ0); | ||
400 | gpio_request(GPIO_PTZ0, NULL); | ||
401 | gpio_direction_input(GPIO_PTZ0); | ||
402 | |||
403 | val = gpio_get_value(GPIO_PTZ0); | ||
404 | |||
405 | gpio_free(GPIO_PTZ0); | ||
406 | gpio_request(GPIO_FN_INTC_IRQ0, NULL); | ||
407 | |||
408 | return val ? 0 : 1; | ||
409 | } | ||
410 | |||
411 | static int ts_init(void) | ||
412 | { | ||
413 | gpio_request(GPIO_FN_INTC_IRQ0, NULL); | ||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | struct tsc2007_platform_data tsc2007_info = { | ||
418 | .model = 2007, | ||
419 | .x_plate_ohms = 180, | ||
420 | .get_pendown_state = ts_get_pendown_state, | ||
421 | .init_platform_hw = ts_init, | ||
422 | }; | ||
423 | |||
424 | static struct i2c_board_info ts_i2c_clients = { | ||
425 | I2C_BOARD_INFO("tsc2007", 0x48), | ||
426 | .type = "tsc2007", | ||
427 | .platform_data = &tsc2007_info, | ||
428 | .irq = IRQ0, | ||
429 | }; | ||
430 | |||
379 | static struct platform_device *ecovec_devices[] __initdata = { | 431 | static struct platform_device *ecovec_devices[] __initdata = { |
380 | &heartbeat_device, | 432 | &heartbeat_device, |
381 | &nor_flash_device, | 433 | &nor_flash_device, |
@@ -460,6 +512,11 @@ static void __init sh_eth_init(void) | |||
460 | #define IODRIVEA 0xA405018A | 512 | #define IODRIVEA 0xA405018A |
461 | static int __init arch_setup(void) | 513 | static int __init arch_setup(void) |
462 | { | 514 | { |
515 | /* enable STATUS0, STATUS2 and PDSTATUS */ | ||
516 | gpio_request(GPIO_FN_STATUS0, NULL); | ||
517 | gpio_request(GPIO_FN_STATUS2, NULL); | ||
518 | gpio_request(GPIO_FN_PDSTATUS, NULL); | ||
519 | |||
463 | /* enable SCIFA0 */ | 520 | /* enable SCIFA0 */ |
464 | gpio_request(GPIO_FN_SCIF0_TXD, NULL); | 521 | gpio_request(GPIO_FN_SCIF0_TXD, NULL); |
465 | gpio_request(GPIO_FN_SCIF0_RXD, NULL); | 522 | gpio_request(GPIO_FN_SCIF0_RXD, NULL); |
@@ -590,6 +647,10 @@ static int __init arch_setup(void) | |||
590 | */ | 647 | */ |
591 | gpio_request(GPIO_PTF4, NULL); | 648 | gpio_request(GPIO_PTF4, NULL); |
592 | gpio_direction_output(GPIO_PTF4, 1); | 649 | gpio_direction_output(GPIO_PTF4, 1); |
650 | |||
651 | /* enable TouchScreen */ | ||
652 | i2c_register_board_info(0, &ts_i2c_clients, 1); | ||
653 | set_irq_type(IRQ0, IRQ_TYPE_LEVEL_LOW); | ||
593 | } | 654 | } |
594 | 655 | ||
595 | /* enable CEU0 */ | 656 | /* enable CEU0 */ |
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index 0151933e5253..bb407ef0b91e 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S | |||
@@ -152,8 +152,6 @@ call_do_page_fault: | |||
152 | mov.l 1f, r0 | 152 | mov.l 1f, r0 |
153 | mov.l @r0, r6 | 153 | mov.l @r0, r6 |
154 | 154 | ||
155 | sti | ||
156 | |||
157 | mov.l 3f, r0 | 155 | mov.l 3f, r0 |
158 | mov.l 4f, r1 | 156 | mov.l 4f, r1 |
159 | mov r15, r4 | 157 | mov r15, r4 |
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c index 4ff507239286..b8fa6524760a 100644 --- a/arch/sh/kernel/io_generic.c +++ b/arch/sh/kernel/io_generic.c | |||
@@ -147,6 +147,9 @@ void generic_outsl(unsigned long port, const void *src, unsigned long count) | |||
147 | 147 | ||
148 | void __iomem *generic_ioport_map(unsigned long addr, unsigned int size) | 148 | void __iomem *generic_ioport_map(unsigned long addr, unsigned int size) |
149 | { | 149 | { |
150 | if (PXSEG(addr) >= P1SEG) | ||
151 | return (void __iomem *)addr; | ||
152 | |||
150 | return (void __iomem *)(addr + generic_io_base); | 153 | return (void __iomem *)(addr + generic_io_base); |
151 | } | 154 | } |
152 | 155 | ||
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c index 548f6607fd0f..cbce639b108a 100644 --- a/arch/sh/kernel/machvec.c +++ b/arch/sh/kernel/machvec.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
15 | #include <asm/machvec.h> | 15 | #include <asm/machvec.h> |
16 | #include <asm/sections.h> | 16 | #include <asm/sections.h> |
17 | #include <asm/addrspace.h> | ||
17 | #include <asm/setup.h> | 18 | #include <asm/setup.h> |
18 | #include <asm/io.h> | 19 | #include <asm/io.h> |
19 | #include <asm/irq.h> | 20 | #include <asm/irq.h> |
@@ -133,4 +134,6 @@ void __init sh_mv_setup(void) | |||
133 | 134 | ||
134 | if (!sh_mv.mv_nr_irqs) | 135 | if (!sh_mv.mv_nr_irqs) |
135 | sh_mv.mv_nr_irqs = NR_IRQS; | 136 | sh_mv.mv_nr_irqs = NR_IRQS; |
137 | |||
138 | __set_io_port_base(P2SEG); | ||
136 | } | 139 | } |
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c index 8dbe26b17c44..86c270428357 100644 --- a/arch/sh/kernel/sh_ksyms_32.c +++ b/arch/sh/kernel/sh_ksyms_32.c | |||
@@ -84,6 +84,7 @@ DECLARE_EXPORT(__movstrSI60); | |||
84 | DECLARE_EXPORT(__movstr_i4_even); | 84 | DECLARE_EXPORT(__movstr_i4_even); |
85 | DECLARE_EXPORT(__movstr_i4_odd); | 85 | DECLARE_EXPORT(__movstr_i4_odd); |
86 | DECLARE_EXPORT(__movstrSI12_i4); | 86 | DECLARE_EXPORT(__movstrSI12_i4); |
87 | DECLARE_EXPORT(__movmem); | ||
87 | DECLARE_EXPORT(__movmem_i4_even); | 88 | DECLARE_EXPORT(__movmem_i4_even); |
88 | DECLARE_EXPORT(__movmem_i4_odd); | 89 | DECLARE_EXPORT(__movmem_i4_odd); |
89 | DECLARE_EXPORT(__movmemSI12_i4); | 90 | DECLARE_EXPORT(__movmemSI12_i4); |
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index 69bb1652eccd..e0b5e4b5accd 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c | |||
@@ -54,8 +54,8 @@ static unsigned long se_multi; | |||
54 | /* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not | 54 | /* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not |
55 | valid! */ | 55 | valid! */ |
56 | static int se_usermode = 3; | 56 | static int se_usermode = 3; |
57 | /* 0: no warning 1: print a warning message */ | 57 | /* 0: no warning 1: print a warning message, disabled by default */ |
58 | static int se_kernmode_warn = 1; | 58 | static int se_kernmode_warn; |
59 | 59 | ||
60 | #ifdef CONFIG_PROC_FS | 60 | #ifdef CONFIG_PROC_FS |
61 | static const char *se_usermode_action[] = { | 61 | static const char *se_usermode_action[] = { |
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index b2453bbef4cd..a98c7d8984fa 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c | |||
@@ -43,7 +43,7 @@ static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) = | |||
43 | * Called from kernel/module.c:sys_init_module and routine for a.out format, | 43 | * Called from kernel/module.c:sys_init_module and routine for a.out format, |
44 | * signal handler code and kprobes code | 44 | * signal handler code and kprobes code |
45 | */ | 45 | */ |
46 | static void sh4_flush_icache_range(void *args) | 46 | static void __uses_jump_to_uncached sh4_flush_icache_range(void *args) |
47 | { | 47 | { |
48 | struct flusher_data *data = args; | 48 | struct flusher_data *data = args; |
49 | unsigned long start, end; | 49 | unsigned long start, end; |
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c index 2cadee2037ac..2601935eb589 100644 --- a/arch/sh/mm/cache-sh7705.c +++ b/arch/sh/mm/cache-sh7705.c | |||
@@ -78,7 +78,7 @@ static void sh7705_flush_icache_range(void *args) | |||
78 | /* | 78 | /* |
79 | * Writeback&Invalidate the D-cache of the page | 79 | * Writeback&Invalidate the D-cache of the page |
80 | */ | 80 | */ |
81 | static void __flush_dcache_page(unsigned long phys) | 81 | static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys) |
82 | { | 82 | { |
83 | unsigned long ways, waysize, addrstart; | 83 | unsigned long ways, waysize, addrstart; |
84 | unsigned long flags; | 84 | unsigned long flags; |
@@ -144,7 +144,7 @@ static void sh7705_flush_dcache_page(void *arg) | |||
144 | __flush_dcache_page(PHYSADDR(page_address(page))); | 144 | __flush_dcache_page(PHYSADDR(page_address(page))); |
145 | } | 145 | } |
146 | 146 | ||
147 | static void sh7705_flush_cache_all(void *args) | 147 | static void __uses_jump_to_uncached sh7705_flush_cache_all(void *args) |
148 | { | 148 | { |
149 | unsigned long flags; | 149 | unsigned long flags; |
150 | 150 | ||
diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c index c3250614e3ae..a86eaa9d75a5 100644 --- a/arch/sh/mm/ioremap_32.c +++ b/arch/sh/mm/ioremap_32.c | |||
@@ -83,7 +83,7 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, | |||
83 | * | 83 | * |
84 | * PMB entries are all pre-faulted. | 84 | * PMB entries are all pre-faulted. |
85 | */ | 85 | */ |
86 | if (unlikely(size >= 0x1000000)) { | 86 | if (unlikely(phys_addr >= P1SEG)) { |
87 | unsigned long mapped = pmb_remap(addr, phys_addr, size, flags); | 87 | unsigned long mapped = pmb_remap(addr, phys_addr, size, flags); |
88 | 88 | ||
89 | if (likely(mapped)) { | 89 | if (likely(mapped)) { |
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index b1a714a92b14..aade31102112 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c | |||
@@ -33,6 +33,8 @@ | |||
33 | 33 | ||
34 | #define NR_PMB_ENTRIES 16 | 34 | #define NR_PMB_ENTRIES 16 |
35 | 35 | ||
36 | static void __pmb_unmap(struct pmb_entry *); | ||
37 | |||
36 | static struct kmem_cache *pmb_cache; | 38 | static struct kmem_cache *pmb_cache; |
37 | static unsigned long pmb_map; | 39 | static unsigned long pmb_map; |
38 | 40 | ||
@@ -218,9 +220,10 @@ static struct { | |||
218 | long pmb_remap(unsigned long vaddr, unsigned long phys, | 220 | long pmb_remap(unsigned long vaddr, unsigned long phys, |
219 | unsigned long size, unsigned long flags) | 221 | unsigned long size, unsigned long flags) |
220 | { | 222 | { |
221 | struct pmb_entry *pmbp; | 223 | struct pmb_entry *pmbp, *pmbe; |
222 | unsigned long wanted; | 224 | unsigned long wanted; |
223 | int pmb_flags, i; | 225 | int pmb_flags, i; |
226 | long err; | ||
224 | 227 | ||
225 | /* Convert typical pgprot value to the PMB equivalent */ | 228 | /* Convert typical pgprot value to the PMB equivalent */ |
226 | if (flags & _PAGE_CACHABLE) { | 229 | if (flags & _PAGE_CACHABLE) { |
@@ -236,20 +239,22 @@ long pmb_remap(unsigned long vaddr, unsigned long phys, | |||
236 | 239 | ||
237 | again: | 240 | again: |
238 | for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) { | 241 | for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) { |
239 | struct pmb_entry *pmbe; | ||
240 | int ret; | 242 | int ret; |
241 | 243 | ||
242 | if (size < pmb_sizes[i].size) | 244 | if (size < pmb_sizes[i].size) |
243 | continue; | 245 | continue; |
244 | 246 | ||
245 | pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag); | 247 | pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag); |
246 | if (IS_ERR(pmbe)) | 248 | if (IS_ERR(pmbe)) { |
247 | return PTR_ERR(pmbe); | 249 | err = PTR_ERR(pmbe); |
250 | goto out; | ||
251 | } | ||
248 | 252 | ||
249 | ret = set_pmb_entry(pmbe); | 253 | ret = set_pmb_entry(pmbe); |
250 | if (ret != 0) { | 254 | if (ret != 0) { |
251 | pmb_free(pmbe); | 255 | pmb_free(pmbe); |
252 | return -EBUSY; | 256 | err = -EBUSY; |
257 | goto out; | ||
253 | } | 258 | } |
254 | 259 | ||
255 | phys += pmb_sizes[i].size; | 260 | phys += pmb_sizes[i].size; |
@@ -264,12 +269,25 @@ again: | |||
264 | pmbp->link = pmbe; | 269 | pmbp->link = pmbe; |
265 | 270 | ||
266 | pmbp = pmbe; | 271 | pmbp = pmbe; |
272 | |||
273 | /* | ||
274 | * Instead of trying smaller sizes on every iteration | ||
275 | * (even if we succeed in allocating space), try using | ||
276 | * pmb_sizes[i].size again. | ||
277 | */ | ||
278 | i--; | ||
267 | } | 279 | } |
268 | 280 | ||
269 | if (size >= 0x1000000) | 281 | if (size >= 0x1000000) |
270 | goto again; | 282 | goto again; |
271 | 283 | ||
272 | return wanted - size; | 284 | return wanted - size; |
285 | |||
286 | out: | ||
287 | if (pmbp) | ||
288 | __pmb_unmap(pmbp); | ||
289 | |||
290 | return err; | ||
273 | } | 291 | } |
274 | 292 | ||
275 | void pmb_unmap(unsigned long addr) | 293 | void pmb_unmap(unsigned long addr) |
@@ -283,12 +301,19 @@ void pmb_unmap(unsigned long addr) | |||
283 | if (unlikely(!pmbe)) | 301 | if (unlikely(!pmbe)) |
284 | return; | 302 | return; |
285 | 303 | ||
304 | __pmb_unmap(pmbe); | ||
305 | } | ||
306 | |||
307 | static void __pmb_unmap(struct pmb_entry *pmbe) | ||
308 | { | ||
286 | WARN_ON(!test_bit(pmbe->entry, &pmb_map)); | 309 | WARN_ON(!test_bit(pmbe->entry, &pmb_map)); |
287 | 310 | ||
288 | do { | 311 | do { |
289 | struct pmb_entry *pmblink = pmbe; | 312 | struct pmb_entry *pmblink = pmbe; |
290 | 313 | ||
291 | clear_pmb_entry(pmbe); | 314 | if (pmbe->entry != PMB_NO_ENTRY) |
315 | clear_pmb_entry(pmbe); | ||
316 | |||
292 | pmbe = pmblink->link; | 317 | pmbe = pmblink->link; |
293 | 318 | ||
294 | pmb_free(pmblink); | 319 | pmb_free(pmblink); |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 4edca6eb73ae..b1a257746a19 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -2884,6 +2884,7 @@ static bool ahci_broken_online(struct pci_dev *pdev) | |||
2884 | return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff); | 2884 | return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff); |
2885 | } | 2885 | } |
2886 | 2886 | ||
2887 | #ifdef CONFIG_ATA_ACPI | ||
2887 | static void ahci_gtf_filter_workaround(struct ata_host *host) | 2888 | static void ahci_gtf_filter_workaround(struct ata_host *host) |
2888 | { | 2889 | { |
2889 | static const struct dmi_system_id sysids[] = { | 2890 | static const struct dmi_system_id sysids[] = { |
@@ -2927,6 +2928,10 @@ static void ahci_gtf_filter_workaround(struct ata_host *host) | |||
2927 | dev->gtf_filter |= filter; | 2928 | dev->gtf_filter |= filter; |
2928 | } | 2929 | } |
2929 | } | 2930 | } |
2931 | #else | ||
2932 | static inline void ahci_gtf_filter_workaround(struct ata_host *host) | ||
2933 | {} | ||
2934 | #endif | ||
2930 | 2935 | ||
2931 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2936 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2932 | { | 2937 | { |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 45d507ebd3ff..92aeb918e0c0 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1468,6 +1468,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1468 | spin_lock_init(&dev_priv->user_irq_lock); | 1468 | spin_lock_init(&dev_priv->user_irq_lock); |
1469 | spin_lock_init(&dev_priv->error_lock); | 1469 | spin_lock_init(&dev_priv->error_lock); |
1470 | dev_priv->user_irq_refcount = 0; | 1470 | dev_priv->user_irq_refcount = 0; |
1471 | dev_priv->trace_irq_seqno = 0; | ||
1471 | 1472 | ||
1472 | ret = drm_vblank_init(dev, I915_NUM_PIPE); | 1473 | ret = drm_vblank_init(dev, I915_NUM_PIPE); |
1473 | 1474 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b24b2d145b75..6035d3dae851 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -202,6 +202,7 @@ typedef struct drm_i915_private { | |||
202 | spinlock_t user_irq_lock; | 202 | spinlock_t user_irq_lock; |
203 | /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */ | 203 | /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */ |
204 | int user_irq_refcount; | 204 | int user_irq_refcount; |
205 | u32 trace_irq_seqno; | ||
205 | /** Cached value of IMR to avoid reads in updating the bitfield */ | 206 | /** Cached value of IMR to avoid reads in updating the bitfield */ |
206 | u32 irq_mask_reg; | 207 | u32 irq_mask_reg; |
207 | u32 pipestat[2]; | 208 | u32 pipestat[2]; |
@@ -665,6 +666,7 @@ extern int i915_irq_emit(struct drm_device *dev, void *data, | |||
665 | extern int i915_irq_wait(struct drm_device *dev, void *data, | 666 | extern int i915_irq_wait(struct drm_device *dev, void *data, |
666 | struct drm_file *file_priv); | 667 | struct drm_file *file_priv); |
667 | void i915_user_irq_get(struct drm_device *dev); | 668 | void i915_user_irq_get(struct drm_device *dev); |
669 | void i915_trace_irq_get(struct drm_device *dev, u32 seqno); | ||
668 | void i915_user_irq_put(struct drm_device *dev); | 670 | void i915_user_irq_put(struct drm_device *dev); |
669 | extern void i915_enable_interrupt (struct drm_device *dev); | 671 | extern void i915_enable_interrupt (struct drm_device *dev); |
670 | 672 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 40727d4c2919..abfc27b0c2ea 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1770,7 +1770,7 @@ i915_gem_retire_requests(struct drm_device *dev) | |||
1770 | drm_i915_private_t *dev_priv = dev->dev_private; | 1770 | drm_i915_private_t *dev_priv = dev->dev_private; |
1771 | uint32_t seqno; | 1771 | uint32_t seqno; |
1772 | 1772 | ||
1773 | if (!dev_priv->hw_status_page) | 1773 | if (!dev_priv->hw_status_page || list_empty(&dev_priv->mm.request_list)) |
1774 | return; | 1774 | return; |
1775 | 1775 | ||
1776 | seqno = i915_get_gem_seqno(dev); | 1776 | seqno = i915_get_gem_seqno(dev); |
@@ -1794,6 +1794,12 @@ i915_gem_retire_requests(struct drm_device *dev) | |||
1794 | } else | 1794 | } else |
1795 | break; | 1795 | break; |
1796 | } | 1796 | } |
1797 | |||
1798 | if (unlikely (dev_priv->trace_irq_seqno && | ||
1799 | i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) { | ||
1800 | i915_user_irq_put(dev); | ||
1801 | dev_priv->trace_irq_seqno = 0; | ||
1802 | } | ||
1797 | } | 1803 | } |
1798 | 1804 | ||
1799 | void | 1805 | void |
@@ -3352,7 +3358,7 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev, | |||
3352 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | 3358 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; |
3353 | exec_len = (uint32_t) exec->batch_len; | 3359 | exec_len = (uint32_t) exec->batch_len; |
3354 | 3360 | ||
3355 | trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno); | 3361 | trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1); |
3356 | 3362 | ||
3357 | count = nbox ? nbox : 1; | 3363 | count = nbox ? nbox : 1; |
3358 | 3364 | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4dfeec7cdd42..c3ceffa46ea0 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -725,6 +725,16 @@ void i915_user_irq_put(struct drm_device *dev) | |||
725 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | 725 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); |
726 | } | 726 | } |
727 | 727 | ||
728 | void i915_trace_irq_get(struct drm_device *dev, u32 seqno) | ||
729 | { | ||
730 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
731 | |||
732 | if (dev_priv->trace_irq_seqno == 0) | ||
733 | i915_user_irq_get(dev); | ||
734 | |||
735 | dev_priv->trace_irq_seqno = seqno; | ||
736 | } | ||
737 | |||
728 | static int i915_wait_irq(struct drm_device * dev, int irq_nr) | 738 | static int i915_wait_irq(struct drm_device * dev, int irq_nr) |
729 | { | 739 | { |
730 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 740 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 5567a40816f3..01840d9bc38f 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h | |||
@@ -158,16 +158,17 @@ TRACE_EVENT(i915_gem_request_submit, | |||
158 | TP_ARGS(dev, seqno), | 158 | TP_ARGS(dev, seqno), |
159 | 159 | ||
160 | TP_STRUCT__entry( | 160 | TP_STRUCT__entry( |
161 | __field(struct drm_device *, dev) | 161 | __field(u32, dev) |
162 | __field(u32, seqno) | 162 | __field(u32, seqno) |
163 | ), | 163 | ), |
164 | 164 | ||
165 | TP_fast_assign( | 165 | TP_fast_assign( |
166 | __entry->dev = dev; | 166 | __entry->dev = dev->primary->index; |
167 | __entry->seqno = seqno; | 167 | __entry->seqno = seqno; |
168 | i915_trace_irq_get(dev, seqno); | ||
168 | ), | 169 | ), |
169 | 170 | ||
170 | TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) | 171 | TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) |
171 | ); | 172 | ); |
172 | 173 | ||
173 | TRACE_EVENT(i915_gem_request_flush, | 174 | TRACE_EVENT(i915_gem_request_flush, |
@@ -178,20 +179,20 @@ TRACE_EVENT(i915_gem_request_flush, | |||
178 | TP_ARGS(dev, seqno, flush_domains, invalidate_domains), | 179 | TP_ARGS(dev, seqno, flush_domains, invalidate_domains), |
179 | 180 | ||
180 | TP_STRUCT__entry( | 181 | TP_STRUCT__entry( |
181 | __field(struct drm_device *, dev) | 182 | __field(u32, dev) |
182 | __field(u32, seqno) | 183 | __field(u32, seqno) |
183 | __field(u32, flush_domains) | 184 | __field(u32, flush_domains) |
184 | __field(u32, invalidate_domains) | 185 | __field(u32, invalidate_domains) |
185 | ), | 186 | ), |
186 | 187 | ||
187 | TP_fast_assign( | 188 | TP_fast_assign( |
188 | __entry->dev = dev; | 189 | __entry->dev = dev->primary->index; |
189 | __entry->seqno = seqno; | 190 | __entry->seqno = seqno; |
190 | __entry->flush_domains = flush_domains; | 191 | __entry->flush_domains = flush_domains; |
191 | __entry->invalidate_domains = invalidate_domains; | 192 | __entry->invalidate_domains = invalidate_domains; |
192 | ), | 193 | ), |
193 | 194 | ||
194 | TP_printk("dev=%p, seqno=%u, flush=%04x, invalidate=%04x", | 195 | TP_printk("dev=%u, seqno=%u, flush=%04x, invalidate=%04x", |
195 | __entry->dev, __entry->seqno, | 196 | __entry->dev, __entry->seqno, |
196 | __entry->flush_domains, __entry->invalidate_domains) | 197 | __entry->flush_domains, __entry->invalidate_domains) |
197 | ); | 198 | ); |
@@ -204,16 +205,16 @@ TRACE_EVENT(i915_gem_request_complete, | |||
204 | TP_ARGS(dev, seqno), | 205 | TP_ARGS(dev, seqno), |
205 | 206 | ||
206 | TP_STRUCT__entry( | 207 | TP_STRUCT__entry( |
207 | __field(struct drm_device *, dev) | 208 | __field(u32, dev) |
208 | __field(u32, seqno) | 209 | __field(u32, seqno) |
209 | ), | 210 | ), |
210 | 211 | ||
211 | TP_fast_assign( | 212 | TP_fast_assign( |
212 | __entry->dev = dev; | 213 | __entry->dev = dev->primary->index; |
213 | __entry->seqno = seqno; | 214 | __entry->seqno = seqno; |
214 | ), | 215 | ), |
215 | 216 | ||
216 | TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) | 217 | TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) |
217 | ); | 218 | ); |
218 | 219 | ||
219 | TRACE_EVENT(i915_gem_request_retire, | 220 | TRACE_EVENT(i915_gem_request_retire, |
@@ -223,16 +224,16 @@ TRACE_EVENT(i915_gem_request_retire, | |||
223 | TP_ARGS(dev, seqno), | 224 | TP_ARGS(dev, seqno), |
224 | 225 | ||
225 | TP_STRUCT__entry( | 226 | TP_STRUCT__entry( |
226 | __field(struct drm_device *, dev) | 227 | __field(u32, dev) |
227 | __field(u32, seqno) | 228 | __field(u32, seqno) |
228 | ), | 229 | ), |
229 | 230 | ||
230 | TP_fast_assign( | 231 | TP_fast_assign( |
231 | __entry->dev = dev; | 232 | __entry->dev = dev->primary->index; |
232 | __entry->seqno = seqno; | 233 | __entry->seqno = seqno; |
233 | ), | 234 | ), |
234 | 235 | ||
235 | TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) | 236 | TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) |
236 | ); | 237 | ); |
237 | 238 | ||
238 | TRACE_EVENT(i915_gem_request_wait_begin, | 239 | TRACE_EVENT(i915_gem_request_wait_begin, |
@@ -242,16 +243,16 @@ TRACE_EVENT(i915_gem_request_wait_begin, | |||
242 | TP_ARGS(dev, seqno), | 243 | TP_ARGS(dev, seqno), |
243 | 244 | ||
244 | TP_STRUCT__entry( | 245 | TP_STRUCT__entry( |
245 | __field(struct drm_device *, dev) | 246 | __field(u32, dev) |
246 | __field(u32, seqno) | 247 | __field(u32, seqno) |
247 | ), | 248 | ), |
248 | 249 | ||
249 | TP_fast_assign( | 250 | TP_fast_assign( |
250 | __entry->dev = dev; | 251 | __entry->dev = dev->primary->index; |
251 | __entry->seqno = seqno; | 252 | __entry->seqno = seqno; |
252 | ), | 253 | ), |
253 | 254 | ||
254 | TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) | 255 | TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) |
255 | ); | 256 | ); |
256 | 257 | ||
257 | TRACE_EVENT(i915_gem_request_wait_end, | 258 | TRACE_EVENT(i915_gem_request_wait_end, |
@@ -261,16 +262,16 @@ TRACE_EVENT(i915_gem_request_wait_end, | |||
261 | TP_ARGS(dev, seqno), | 262 | TP_ARGS(dev, seqno), |
262 | 263 | ||
263 | TP_STRUCT__entry( | 264 | TP_STRUCT__entry( |
264 | __field(struct drm_device *, dev) | 265 | __field(u32, dev) |
265 | __field(u32, seqno) | 266 | __field(u32, seqno) |
266 | ), | 267 | ), |
267 | 268 | ||
268 | TP_fast_assign( | 269 | TP_fast_assign( |
269 | __entry->dev = dev; | 270 | __entry->dev = dev->primary->index; |
270 | __entry->seqno = seqno; | 271 | __entry->seqno = seqno; |
271 | ), | 272 | ), |
272 | 273 | ||
273 | TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) | 274 | TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) |
274 | ); | 275 | ); |
275 | 276 | ||
276 | TRACE_EVENT(i915_ring_wait_begin, | 277 | TRACE_EVENT(i915_ring_wait_begin, |
@@ -280,14 +281,14 @@ TRACE_EVENT(i915_ring_wait_begin, | |||
280 | TP_ARGS(dev), | 281 | TP_ARGS(dev), |
281 | 282 | ||
282 | TP_STRUCT__entry( | 283 | TP_STRUCT__entry( |
283 | __field(struct drm_device *, dev) | 284 | __field(u32, dev) |
284 | ), | 285 | ), |
285 | 286 | ||
286 | TP_fast_assign( | 287 | TP_fast_assign( |
287 | __entry->dev = dev; | 288 | __entry->dev = dev->primary->index; |
288 | ), | 289 | ), |
289 | 290 | ||
290 | TP_printk("dev=%p", __entry->dev) | 291 | TP_printk("dev=%u", __entry->dev) |
291 | ); | 292 | ); |
292 | 293 | ||
293 | TRACE_EVENT(i915_ring_wait_end, | 294 | TRACE_EVENT(i915_ring_wait_end, |
@@ -297,14 +298,14 @@ TRACE_EVENT(i915_ring_wait_end, | |||
297 | TP_ARGS(dev), | 298 | TP_ARGS(dev), |
298 | 299 | ||
299 | TP_STRUCT__entry( | 300 | TP_STRUCT__entry( |
300 | __field(struct drm_device *, dev) | 301 | __field(u32, dev) |
301 | ), | 302 | ), |
302 | 303 | ||
303 | TP_fast_assign( | 304 | TP_fast_assign( |
304 | __entry->dev = dev; | 305 | __entry->dev = dev->primary->index; |
305 | ), | 306 | ), |
306 | 307 | ||
307 | TP_printk("dev=%p", __entry->dev) | 308 | TP_printk("dev=%u", __entry->dev) |
308 | ); | 309 | ); |
309 | 310 | ||
310 | #endif /* _I915_TRACE_H_ */ | 311 | #endif /* _I915_TRACE_H_ */ |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ffa39671751f..3c14240cc002 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3095,7 +3095,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
3095 | struct drm_gem_object *bo; | 3095 | struct drm_gem_object *bo; |
3096 | struct drm_i915_gem_object *obj_priv; | 3096 | struct drm_i915_gem_object *obj_priv; |
3097 | int pipe = intel_crtc->pipe; | 3097 | int pipe = intel_crtc->pipe; |
3098 | int plane = intel_crtc->plane; | ||
3099 | uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; | 3098 | uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; |
3100 | uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; | 3099 | uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; |
3101 | uint32_t temp = I915_READ(control); | 3100 | uint32_t temp = I915_READ(control); |
@@ -3182,9 +3181,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
3182 | drm_gem_object_unreference(intel_crtc->cursor_bo); | 3181 | drm_gem_object_unreference(intel_crtc->cursor_bo); |
3183 | } | 3182 | } |
3184 | 3183 | ||
3185 | if ((IS_I965G(dev) || plane == 0)) | ||
3186 | intel_update_fbc(crtc, &crtc->mode); | ||
3187 | |||
3188 | mutex_unlock(&dev->struct_mutex); | 3184 | mutex_unlock(&dev->struct_mutex); |
3189 | 3185 | ||
3190 | intel_crtc->cursor_addr = addr; | 3186 | intel_crtc->cursor_addr = addr; |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index fa304e136010..663ab6de0b58 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -223,7 +223,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
223 | 223 | ||
224 | connector = &intel_output->base; | 224 | connector = &intel_output->base; |
225 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, | 225 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, |
226 | DRM_MODE_CONNECTOR_DVID); | 226 | DRM_MODE_CONNECTOR_HDMIA); |
227 | drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); | 227 | drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); |
228 | 228 | ||
229 | intel_output->type = INTEL_OUTPUT_HDMI; | 229 | intel_output->type = INTEL_OUTPUT_HDMI; |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index c64eab493fb0..9ca917931afb 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1082,7 +1082,8 @@ intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mo | |||
1082 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); | 1082 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); |
1083 | 1083 | ||
1084 | /* Ensure TV refresh is close to desired refresh */ | 1084 | /* Ensure TV refresh is close to desired refresh */ |
1085 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 10) | 1085 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) |
1086 | < 1000) | ||
1086 | return MODE_OK; | 1087 | return MODE_OK; |
1087 | return MODE_CLOCK_RANGE; | 1088 | return MODE_CLOCK_RANGE; |
1088 | } | 1089 | } |
diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h index 03087e7b9190..9a537aa07968 100644 --- a/drivers/usb/gadget/r8a66597-udc.h +++ b/drivers/usb/gadget/r8a66597-udc.h | |||
@@ -131,31 +131,48 @@ static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset) | |||
131 | } | 131 | } |
132 | 132 | ||
133 | static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, | 133 | static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, |
134 | unsigned long offset, u16 *buf, | 134 | unsigned long offset, |
135 | unsigned char *buf, | ||
135 | int len) | 136 | int len) |
136 | { | 137 | { |
138 | unsigned long fifoaddr = r8a66597->reg + offset; | ||
139 | unsigned int data; | ||
140 | int i; | ||
141 | |||
137 | if (r8a66597->pdata->on_chip) { | 142 | if (r8a66597->pdata->on_chip) { |
138 | unsigned long fifoaddr = r8a66597->reg + offset; | 143 | /* 32-bit accesses for on_chip controllers */ |
139 | unsigned long count; | 144 | |
140 | union { | 145 | /* aligned buf case */ |
141 | unsigned long dword; | 146 | if (len >= 4 && !((unsigned long)buf & 0x03)) { |
142 | unsigned char byte[4]; | 147 | insl(fifoaddr, buf, len / 4); |
143 | } data; | 148 | buf += len & ~0x03; |
144 | unsigned char *pb; | 149 | len &= 0x03; |
145 | int i; | 150 | } |
146 | 151 | ||
147 | count = len / 4; | 152 | /* unaligned buf case */ |
148 | insl(fifoaddr, buf, count); | 153 | for (i = 0; i < len; i++) { |
149 | 154 | if (!(i & 0x03)) | |
150 | if (len & 0x00000003) { | 155 | data = inl(fifoaddr); |
151 | data.dword = inl(fifoaddr); | 156 | |
152 | pb = (unsigned char *)buf + count * 4; | 157 | buf[i] = (data >> ((i & 0x03) * 8)) & 0xff; |
153 | for (i = 0; i < (len & 0x00000003); i++) | ||
154 | pb[i] = data.byte[i]; | ||
155 | } | 158 | } |
156 | } else { | 159 | } else { |
157 | len = (len + 1) / 2; | 160 | /* 16-bit accesses for external controllers */ |
158 | insw(r8a66597->reg + offset, buf, len); | 161 | |
162 | /* aligned buf case */ | ||
163 | if (len >= 2 && !((unsigned long)buf & 0x01)) { | ||
164 | insw(fifoaddr, buf, len / 2); | ||
165 | buf += len & ~0x01; | ||
166 | len &= 0x01; | ||
167 | } | ||
168 | |||
169 | /* unaligned buf case */ | ||
170 | for (i = 0; i < len; i++) { | ||
171 | if (!(i & 0x01)) | ||
172 | data = inw(fifoaddr); | ||
173 | |||
174 | buf[i] = (data >> ((i & 0x01) * 8)) & 0xff; | ||
175 | } | ||
159 | } | 176 | } |
160 | } | 177 | } |
161 | 178 | ||
@@ -166,38 +183,40 @@ static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, | |||
166 | } | 183 | } |
167 | 184 | ||
168 | static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, | 185 | static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, |
169 | unsigned long offset, u16 *buf, | 186 | unsigned long offset, |
187 | unsigned char *buf, | ||
170 | int len) | 188 | int len) |
171 | { | 189 | { |
172 | unsigned long fifoaddr = r8a66597->reg + offset; | 190 | unsigned long fifoaddr = r8a66597->reg + offset; |
191 | int adj = 0; | ||
192 | int i; | ||
173 | 193 | ||
174 | if (r8a66597->pdata->on_chip) { | 194 | if (r8a66597->pdata->on_chip) { |
175 | unsigned long count; | 195 | /* 32-bit access only if buf is 32-bit aligned */ |
176 | unsigned char *pb; | 196 | if (len >= 4 && !((unsigned long)buf & 0x03)) { |
177 | int i; | 197 | outsl(fifoaddr, buf, len / 4); |
178 | 198 | buf += len & ~0x03; | |
179 | count = len / 4; | 199 | len &= 0x03; |
180 | outsl(fifoaddr, buf, count); | ||
181 | |||
182 | if (len & 0x00000003) { | ||
183 | pb = (unsigned char *)buf + count * 4; | ||
184 | for (i = 0; i < (len & 0x00000003); i++) { | ||
185 | if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND) | ||
186 | outb(pb[i], fifoaddr + i); | ||
187 | else | ||
188 | outb(pb[i], fifoaddr + 3 - i); | ||
189 | } | ||
190 | } | 200 | } |
191 | } else { | 201 | } else { |
192 | int odd = len & 0x0001; | 202 | /* 16-bit access only if buf is 16-bit aligned */ |
193 | 203 | if (len >= 2 && !((unsigned long)buf & 0x01)) { | |
194 | len = len / 2; | 204 | outsw(fifoaddr, buf, len / 2); |
195 | outsw(fifoaddr, buf, len); | 205 | buf += len & ~0x01; |
196 | if (unlikely(odd)) { | 206 | len &= 0x01; |
197 | buf = &buf[len]; | ||
198 | outb((unsigned char)*buf, fifoaddr); | ||
199 | } | 207 | } |
200 | } | 208 | } |
209 | |||
210 | /* adjust fifo address in the little endian case */ | ||
211 | if (!(r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)) { | ||
212 | if (r8a66597->pdata->on_chip) | ||
213 | adj = 0x03; /* 32-bit wide */ | ||
214 | else | ||
215 | adj = 0x01; /* 16-bit wide */ | ||
216 | } | ||
217 | |||
218 | for (i = 0; i < len; i++) | ||
219 | outb(buf[i], fifoaddr + adj - (i & adj)); | ||
201 | } | 220 | } |
202 | 221 | ||
203 | static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, | 222 | static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, |
diff --git a/fs/ecryptfs/Kconfig b/fs/ecryptfs/Kconfig index 8aadb99b7634..1cd6d9d3e29a 100644 --- a/fs/ecryptfs/Kconfig +++ b/fs/ecryptfs/Kconfig | |||
@@ -1,8 +1,9 @@ | |||
1 | config ECRYPT_FS | 1 | config ECRYPT_FS |
2 | tristate "eCrypt filesystem layer support (EXPERIMENTAL)" | 2 | tristate "eCrypt filesystem layer support (EXPERIMENTAL)" |
3 | depends on EXPERIMENTAL && KEYS && NET | 3 | depends on EXPERIMENTAL && KEYS && CRYPTO |
4 | select CRYPTO_ECB | 4 | select CRYPTO_ECB |
5 | select CRYPTO_CBC | 5 | select CRYPTO_CBC |
6 | select CRYPTO_MD5 | ||
6 | help | 7 | help |
7 | Encrypted filesystem that operates on the VFS layer. See | 8 | Encrypted filesystem that operates on the VFS layer. See |
8 | <file:Documentation/filesystems/ecryptfs.txt> to learn more about | 9 | <file:Documentation/filesystems/ecryptfs.txt> to learn more about |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 101fe4c7b1ee..c6ac85d6c701 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/key.h> | 35 | #include <linux/key.h> |
36 | #include <linux/parser.h> | 36 | #include <linux/parser.h> |
37 | #include <linux/fs_stack.h> | 37 | #include <linux/fs_stack.h> |
38 | #include <linux/ima.h> | ||
38 | #include "ecryptfs_kernel.h" | 39 | #include "ecryptfs_kernel.h" |
39 | 40 | ||
40 | /** | 41 | /** |
@@ -118,6 +119,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | |||
118 | const struct cred *cred = current_cred(); | 119 | const struct cred *cred = current_cred(); |
119 | struct ecryptfs_inode_info *inode_info = | 120 | struct ecryptfs_inode_info *inode_info = |
120 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); | 121 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); |
122 | int opened_lower_file = 0; | ||
121 | int rc = 0; | 123 | int rc = 0; |
122 | 124 | ||
123 | mutex_lock(&inode_info->lower_file_mutex); | 125 | mutex_lock(&inode_info->lower_file_mutex); |
@@ -134,9 +136,12 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | |||
134 | "for lower_dentry [0x%p] and lower_mnt [0x%p]; " | 136 | "for lower_dentry [0x%p] and lower_mnt [0x%p]; " |
135 | "rc = [%d]\n", lower_dentry, lower_mnt, rc); | 137 | "rc = [%d]\n", lower_dentry, lower_mnt, rc); |
136 | inode_info->lower_file = NULL; | 138 | inode_info->lower_file = NULL; |
137 | } | 139 | } else |
140 | opened_lower_file = 1; | ||
138 | } | 141 | } |
139 | mutex_unlock(&inode_info->lower_file_mutex); | 142 | mutex_unlock(&inode_info->lower_file_mutex); |
143 | if (opened_lower_file) | ||
144 | ima_counts_get(inode_info->lower_file); | ||
140 | return rc; | 145 | return rc; |
141 | } | 146 | } |
142 | 147 | ||
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 63976c0ccc25..99ea196f071f 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -1180,7 +1180,7 @@ static int nfs4_init_client(struct nfs_client *clp, | |||
1180 | 1, flags & NFS_MOUNT_NORESVPORT); | 1180 | 1, flags & NFS_MOUNT_NORESVPORT); |
1181 | if (error < 0) | 1181 | if (error < 0) |
1182 | goto error; | 1182 | goto error; |
1183 | memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr)); | 1183 | strlcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr)); |
1184 | 1184 | ||
1185 | error = nfs_idmap_new(clp); | 1185 | error = nfs_idmap_new(clp); |
1186 | if (error < 0) { | 1186 | if (error < 0) { |
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index 2636c26d56fa..fa3408f20112 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c | |||
@@ -121,7 +121,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, | |||
121 | 121 | ||
122 | mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); | 122 | mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); |
123 | if (IS_ERR(mnt_path)) | 123 | if (IS_ERR(mnt_path)) |
124 | return mnt; | 124 | return ERR_CAST(mnt_path); |
125 | mountdata->mnt_path = mnt_path; | 125 | mountdata->mnt_path = mnt_path; |
126 | maxbuflen = mnt_path - 1 - page2; | 126 | maxbuflen = mnt_path - 1 - page2; |
127 | 127 | ||
@@ -132,15 +132,15 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, | |||
132 | if (buf->len <= 0 || buf->len >= maxbuflen) | 132 | if (buf->len <= 0 || buf->len >= maxbuflen) |
133 | continue; | 133 | continue; |
134 | 134 | ||
135 | mountdata->addr = (struct sockaddr *)&addr; | ||
136 | |||
137 | if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len)) | 135 | if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len)) |
138 | continue; | 136 | continue; |
139 | mountdata->addrlen = nfs_parse_server_name(buf->data, | 137 | |
140 | buf->len, | 138 | mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len, |
141 | mountdata->addr, mountdata->addrlen); | 139 | (struct sockaddr *)&addr, sizeof(addr)); |
142 | if (mountdata->addrlen == 0) | 140 | if (mountdata->addrlen == 0) |
143 | continue; | 141 | continue; |
142 | |||
143 | mountdata->addr = (struct sockaddr *)&addr; | ||
144 | rpc_set_port(mountdata->addr, NFS_PORT); | 144 | rpc_set_port(mountdata->addr, NFS_PORT); |
145 | 145 | ||
146 | memcpy(page2, buf->data, buf->len); | 146 | memcpy(page2, buf->data, buf->len); |
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index e27c6cef18f2..0156c01c212c 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c | |||
@@ -127,12 +127,6 @@ nfs4_schedule_state_renewal(struct nfs_client *clp) | |||
127 | } | 127 | } |
128 | 128 | ||
129 | void | 129 | void |
130 | nfs4_renewd_prepare_shutdown(struct nfs_server *server) | ||
131 | { | ||
132 | cancel_delayed_work(&server->nfs_client->cl_renewd); | ||
133 | } | ||
134 | |||
135 | void | ||
136 | nfs4_kill_renewd(struct nfs_client *clp) | 130 | nfs4_kill_renewd(struct nfs_client *clp) |
137 | { | 131 | { |
138 | cancel_delayed_work_sync(&clp->cl_renewd); | 132 | cancel_delayed_work_sync(&clp->cl_renewd); |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 29786d3b9326..6dabf6feec94 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -728,22 +728,24 @@ static void nfs_umount_begin(struct super_block *sb) | |||
728 | unlock_kernel(); | 728 | unlock_kernel(); |
729 | } | 729 | } |
730 | 730 | ||
731 | static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(int flags) | 731 | static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int version) |
732 | { | 732 | { |
733 | struct nfs_parsed_mount_data *data; | 733 | struct nfs_parsed_mount_data *data; |
734 | 734 | ||
735 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 735 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
736 | if (data) { | 736 | if (data) { |
737 | data->flags = flags; | ||
738 | data->rsize = NFS_MAX_FILE_IO_SIZE; | 737 | data->rsize = NFS_MAX_FILE_IO_SIZE; |
739 | data->wsize = NFS_MAX_FILE_IO_SIZE; | 738 | data->wsize = NFS_MAX_FILE_IO_SIZE; |
740 | data->acregmin = NFS_DEF_ACREGMIN; | 739 | data->acregmin = NFS_DEF_ACREGMIN; |
741 | data->acregmax = NFS_DEF_ACREGMAX; | 740 | data->acregmax = NFS_DEF_ACREGMAX; |
742 | data->acdirmin = NFS_DEF_ACDIRMIN; | 741 | data->acdirmin = NFS_DEF_ACDIRMIN; |
743 | data->acdirmax = NFS_DEF_ACDIRMAX; | 742 | data->acdirmax = NFS_DEF_ACDIRMAX; |
743 | data->mount_server.port = NFS_UNSPEC_PORT; | ||
744 | data->nfs_server.port = NFS_UNSPEC_PORT; | 744 | data->nfs_server.port = NFS_UNSPEC_PORT; |
745 | data->nfs_server.protocol = XPRT_TRANSPORT_TCP; | ||
745 | data->auth_flavors[0] = RPC_AUTH_UNIX; | 746 | data->auth_flavors[0] = RPC_AUTH_UNIX; |
746 | data->auth_flavor_len = 1; | 747 | data->auth_flavor_len = 1; |
748 | data->version = version; | ||
747 | data->minorversion = 0; | 749 | data->minorversion = 0; |
748 | } | 750 | } |
749 | return data; | 751 | return data; |
@@ -776,15 +778,13 @@ static int nfs_verify_server_address(struct sockaddr *addr) | |||
776 | * Select between a default port value and a user-specified port value. | 778 | * Select between a default port value and a user-specified port value. |
777 | * If a zero value is set, then autobind will be used. | 779 | * If a zero value is set, then autobind will be used. |
778 | */ | 780 | */ |
779 | static void nfs_set_default_port(struct sockaddr *sap, const int parsed_port, | 781 | static void nfs_set_port(struct sockaddr *sap, int *port, |
780 | const unsigned short default_port) | 782 | const unsigned short default_port) |
781 | { | 783 | { |
782 | unsigned short port = default_port; | 784 | if (*port == NFS_UNSPEC_PORT) |
785 | *port = default_port; | ||
783 | 786 | ||
784 | if (parsed_port != NFS_UNSPEC_PORT) | 787 | rpc_set_port(sap, *port); |
785 | port = parsed_port; | ||
786 | |||
787 | rpc_set_port(sap, port); | ||
788 | } | 788 | } |
789 | 789 | ||
790 | /* | 790 | /* |
@@ -1475,7 +1475,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args, | |||
1475 | args->mount_server.addrlen = args->nfs_server.addrlen; | 1475 | args->mount_server.addrlen = args->nfs_server.addrlen; |
1476 | } | 1476 | } |
1477 | request.salen = args->mount_server.addrlen; | 1477 | request.salen = args->mount_server.addrlen; |
1478 | nfs_set_default_port(request.sap, args->mount_server.port, 0); | 1478 | nfs_set_port(request.sap, &args->mount_server.port, 0); |
1479 | 1479 | ||
1480 | /* | 1480 | /* |
1481 | * Now ask the mount server to map our export path | 1481 | * Now ask the mount server to map our export path |
@@ -1711,8 +1711,6 @@ static int nfs_validate_mount_data(void *options, | |||
1711 | 1711 | ||
1712 | if (!(data->flags & NFS_MOUNT_TCP)) | 1712 | if (!(data->flags & NFS_MOUNT_TCP)) |
1713 | args->nfs_server.protocol = XPRT_TRANSPORT_UDP; | 1713 | args->nfs_server.protocol = XPRT_TRANSPORT_UDP; |
1714 | else | ||
1715 | args->nfs_server.protocol = XPRT_TRANSPORT_TCP; | ||
1716 | /* N.B. caller will free nfs_server.hostname in all cases */ | 1714 | /* N.B. caller will free nfs_server.hostname in all cases */ |
1717 | args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); | 1715 | args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); |
1718 | args->namlen = data->namlen; | 1716 | args->namlen = data->namlen; |
@@ -1767,7 +1765,7 @@ static int nfs_validate_mount_data(void *options, | |||
1767 | goto out_v4_not_compiled; | 1765 | goto out_v4_not_compiled; |
1768 | #endif | 1766 | #endif |
1769 | 1767 | ||
1770 | nfs_set_default_port(sap, args->nfs_server.port, 0); | 1768 | nfs_set_port(sap, &args->nfs_server.port, 0); |
1771 | 1769 | ||
1772 | nfs_set_mount_transport_protocol(args); | 1770 | nfs_set_mount_transport_protocol(args); |
1773 | 1771 | ||
@@ -1848,9 +1846,10 @@ nfs_compare_remount_data(struct nfs_server *nfss, | |||
1848 | data->acdirmin != nfss->acdirmin / HZ || | 1846 | data->acdirmin != nfss->acdirmin / HZ || |
1849 | data->acdirmax != nfss->acdirmax / HZ || | 1847 | data->acdirmax != nfss->acdirmax / HZ || |
1850 | data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) || | 1848 | data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) || |
1849 | data->nfs_server.port != nfss->port || | ||
1851 | data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen || | 1850 | data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen || |
1852 | memcmp(&data->nfs_server.address, &nfss->nfs_client->cl_addr, | 1851 | !rpc_cmp_addr(&data->nfs_server.address, |
1853 | data->nfs_server.addrlen) != 0) | 1852 | &nfss->nfs_client->cl_addr)) |
1854 | return -EINVAL; | 1853 | return -EINVAL; |
1855 | 1854 | ||
1856 | return 0; | 1855 | return 0; |
@@ -1893,6 +1892,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) | |||
1893 | data->acdirmin = nfss->acdirmin / HZ; | 1892 | data->acdirmin = nfss->acdirmin / HZ; |
1894 | data->acdirmax = nfss->acdirmax / HZ; | 1893 | data->acdirmax = nfss->acdirmax / HZ; |
1895 | data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ; | 1894 | data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ; |
1895 | data->nfs_server.port = nfss->port; | ||
1896 | data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen; | 1896 | data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen; |
1897 | memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr, | 1897 | memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr, |
1898 | data->nfs_server.addrlen); | 1898 | data->nfs_server.addrlen); |
@@ -2106,7 +2106,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
2106 | }; | 2106 | }; |
2107 | int error = -ENOMEM; | 2107 | int error = -ENOMEM; |
2108 | 2108 | ||
2109 | data = nfs_alloc_parsed_mount_data(NFS_MOUNT_VER3 | NFS_MOUNT_TCP); | 2109 | data = nfs_alloc_parsed_mount_data(3); |
2110 | mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL); | 2110 | mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL); |
2111 | if (data == NULL || mntfh == NULL) | 2111 | if (data == NULL || mntfh == NULL) |
2112 | goto out_free_fh; | 2112 | goto out_free_fh; |
@@ -2331,7 +2331,7 @@ static int nfs4_validate_text_mount_data(void *options, | |||
2331 | { | 2331 | { |
2332 | struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; | 2332 | struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; |
2333 | 2333 | ||
2334 | nfs_set_default_port(sap, args->nfs_server.port, NFS_PORT); | 2334 | nfs_set_port(sap, &args->nfs_server.port, NFS_PORT); |
2335 | 2335 | ||
2336 | nfs_validate_transport_protocol(args); | 2336 | nfs_validate_transport_protocol(args); |
2337 | 2337 | ||
@@ -2376,7 +2376,6 @@ static int nfs4_validate_mount_data(void *options, | |||
2376 | if (data == NULL) | 2376 | if (data == NULL) |
2377 | goto out_no_data; | 2377 | goto out_no_data; |
2378 | 2378 | ||
2379 | args->version = 4; | ||
2380 | switch (data->version) { | 2379 | switch (data->version) { |
2381 | case 1: | 2380 | case 1: |
2382 | if (data->host_addrlen > sizeof(args->nfs_server.address)) | 2381 | if (data->host_addrlen > sizeof(args->nfs_server.address)) |
@@ -2660,7 +2659,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type, | |||
2660 | struct nfs_parsed_mount_data *data; | 2659 | struct nfs_parsed_mount_data *data; |
2661 | int error = -ENOMEM; | 2660 | int error = -ENOMEM; |
2662 | 2661 | ||
2663 | data = nfs_alloc_parsed_mount_data(0); | 2662 | data = nfs_alloc_parsed_mount_data(4); |
2664 | if (data == NULL) | 2663 | if (data == NULL) |
2665 | goto out_free_data; | 2664 | goto out_free_data; |
2666 | 2665 | ||
@@ -2690,7 +2689,6 @@ static void nfs4_kill_super(struct super_block *sb) | |||
2690 | dprintk("--> %s\n", __func__); | 2689 | dprintk("--> %s\n", __func__); |
2691 | nfs_super_return_all_delegations(sb); | 2690 | nfs_super_return_all_delegations(sb); |
2692 | kill_anon_super(sb); | 2691 | kill_anon_super(sb); |
2693 | nfs4_renewd_prepare_shutdown(server); | ||
2694 | nfs_fscache_release_super_cookie(sb); | 2692 | nfs_fscache_release_super_cookie(sb); |
2695 | nfs_free_server(server); | 2693 | nfs_free_server(server); |
2696 | dprintk("<-- %s\n", __func__); | 2694 | dprintk("<-- %s\n", __func__); |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 381854461b28..c2e30eea74dc 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -186,19 +186,37 @@ xfs_destroy_ioend( | |||
186 | } | 186 | } |
187 | 187 | ||
188 | /* | 188 | /* |
189 | * If the end of the current ioend is beyond the current EOF, | ||
190 | * return the new EOF value, otherwise zero. | ||
191 | */ | ||
192 | STATIC xfs_fsize_t | ||
193 | xfs_ioend_new_eof( | ||
194 | xfs_ioend_t *ioend) | ||
195 | { | ||
196 | xfs_inode_t *ip = XFS_I(ioend->io_inode); | ||
197 | xfs_fsize_t isize; | ||
198 | xfs_fsize_t bsize; | ||
199 | |||
200 | bsize = ioend->io_offset + ioend->io_size; | ||
201 | isize = MAX(ip->i_size, ip->i_new_size); | ||
202 | isize = MIN(isize, bsize); | ||
203 | return isize > ip->i_d.di_size ? isize : 0; | ||
204 | } | ||
205 | |||
206 | /* | ||
189 | * Update on-disk file size now that data has been written to disk. | 207 | * Update on-disk file size now that data has been written to disk. |
190 | * The current in-memory file size is i_size. If a write is beyond | 208 | * The current in-memory file size is i_size. If a write is beyond |
191 | * eof i_new_size will be the intended file size until i_size is | 209 | * eof i_new_size will be the intended file size until i_size is |
192 | * updated. If this write does not extend all the way to the valid | 210 | * updated. If this write does not extend all the way to the valid |
193 | * file size then restrict this update to the end of the write. | 211 | * file size then restrict this update to the end of the write. |
194 | */ | 212 | */ |
213 | |||
195 | STATIC void | 214 | STATIC void |
196 | xfs_setfilesize( | 215 | xfs_setfilesize( |
197 | xfs_ioend_t *ioend) | 216 | xfs_ioend_t *ioend) |
198 | { | 217 | { |
199 | xfs_inode_t *ip = XFS_I(ioend->io_inode); | 218 | xfs_inode_t *ip = XFS_I(ioend->io_inode); |
200 | xfs_fsize_t isize; | 219 | xfs_fsize_t isize; |
201 | xfs_fsize_t bsize; | ||
202 | 220 | ||
203 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); | 221 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); |
204 | ASSERT(ioend->io_type != IOMAP_READ); | 222 | ASSERT(ioend->io_type != IOMAP_READ); |
@@ -206,16 +224,10 @@ xfs_setfilesize( | |||
206 | if (unlikely(ioend->io_error)) | 224 | if (unlikely(ioend->io_error)) |
207 | return; | 225 | return; |
208 | 226 | ||
209 | bsize = ioend->io_offset + ioend->io_size; | ||
210 | |||
211 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 227 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
212 | 228 | isize = xfs_ioend_new_eof(ioend); | |
213 | isize = MAX(ip->i_size, ip->i_new_size); | 229 | if (isize) { |
214 | isize = MIN(isize, bsize); | ||
215 | |||
216 | if (ip->i_d.di_size < isize) { | ||
217 | ip->i_d.di_size = isize; | 230 | ip->i_d.di_size = isize; |
218 | ip->i_update_core = 1; | ||
219 | xfs_mark_inode_dirty_sync(ip); | 231 | xfs_mark_inode_dirty_sync(ip); |
220 | } | 232 | } |
221 | 233 | ||
@@ -404,10 +416,16 @@ xfs_submit_ioend_bio( | |||
404 | struct bio *bio) | 416 | struct bio *bio) |
405 | { | 417 | { |
406 | atomic_inc(&ioend->io_remaining); | 418 | atomic_inc(&ioend->io_remaining); |
407 | |||
408 | bio->bi_private = ioend; | 419 | bio->bi_private = ioend; |
409 | bio->bi_end_io = xfs_end_bio; | 420 | bio->bi_end_io = xfs_end_bio; |
410 | 421 | ||
422 | /* | ||
423 | * If the I/O is beyond EOF we mark the inode dirty immediately | ||
424 | * but don't update the inode size until I/O completion. | ||
425 | */ | ||
426 | if (xfs_ioend_new_eof(ioend)) | ||
427 | xfs_mark_inode_dirty_sync(XFS_I(ioend->io_inode)); | ||
428 | |||
411 | submit_bio(WRITE, bio); | 429 | submit_bio(WRITE, bio); |
412 | ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP)); | 430 | ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP)); |
413 | bio_put(bio); | 431 | bio_put(bio); |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 629370974e57..eff61e2732af 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -176,14 +176,7 @@ xfs_file_fsync( | |||
176 | struct dentry *dentry, | 176 | struct dentry *dentry, |
177 | int datasync) | 177 | int datasync) |
178 | { | 178 | { |
179 | struct inode *inode = dentry->d_inode; | 179 | struct xfs_inode *ip = XFS_I(dentry->d_inode); |
180 | struct xfs_inode *ip = XFS_I(inode); | ||
181 | int error; | ||
182 | |||
183 | /* capture size updates in I/O completion before writing the inode. */ | ||
184 | error = filemap_fdatawait(inode->i_mapping); | ||
185 | if (error) | ||
186 | return error; | ||
187 | 180 | ||
188 | xfs_iflags_clear(ip, XFS_ITRUNCATED); | 181 | xfs_iflags_clear(ip, XFS_ITRUNCATED); |
189 | return -xfs_fsync(ip); | 182 | return -xfs_fsync(ip); |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index da0159d99f82..cd42ef78f6b5 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -57,19 +57,22 @@ | |||
57 | #include <linux/fiemap.h> | 57 | #include <linux/fiemap.h> |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * Bring the atime in the XFS inode uptodate. | 60 | * Bring the timestamps in the XFS inode uptodate. |
61 | * Used before logging the inode to disk or when the Linux inode goes away. | 61 | * |
62 | * Used before writing the inode to disk. | ||
62 | */ | 63 | */ |
63 | void | 64 | void |
64 | xfs_synchronize_atime( | 65 | xfs_synchronize_times( |
65 | xfs_inode_t *ip) | 66 | xfs_inode_t *ip) |
66 | { | 67 | { |
67 | struct inode *inode = VFS_I(ip); | 68 | struct inode *inode = VFS_I(ip); |
68 | 69 | ||
69 | if (!(inode->i_state & I_CLEAR)) { | 70 | ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec; |
70 | ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec; | 71 | ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec; |
71 | ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec; | 72 | ip->i_d.di_ctime.t_sec = (__int32_t)inode->i_ctime.tv_sec; |
72 | } | 73 | ip->i_d.di_ctime.t_nsec = (__int32_t)inode->i_ctime.tv_nsec; |
74 | ip->i_d.di_mtime.t_sec = (__int32_t)inode->i_mtime.tv_sec; | ||
75 | ip->i_d.di_mtime.t_nsec = (__int32_t)inode->i_mtime.tv_nsec; | ||
73 | } | 76 | } |
74 | 77 | ||
75 | /* | 78 | /* |
@@ -106,32 +109,20 @@ xfs_ichgtime( | |||
106 | if ((flags & XFS_ICHGTIME_MOD) && | 109 | if ((flags & XFS_ICHGTIME_MOD) && |
107 | !timespec_equal(&inode->i_mtime, &tv)) { | 110 | !timespec_equal(&inode->i_mtime, &tv)) { |
108 | inode->i_mtime = tv; | 111 | inode->i_mtime = tv; |
109 | ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; | ||
110 | ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; | ||
111 | sync_it = 1; | 112 | sync_it = 1; |
112 | } | 113 | } |
113 | if ((flags & XFS_ICHGTIME_CHG) && | 114 | if ((flags & XFS_ICHGTIME_CHG) && |
114 | !timespec_equal(&inode->i_ctime, &tv)) { | 115 | !timespec_equal(&inode->i_ctime, &tv)) { |
115 | inode->i_ctime = tv; | 116 | inode->i_ctime = tv; |
116 | ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec; | ||
117 | ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec; | ||
118 | sync_it = 1; | 117 | sync_it = 1; |
119 | } | 118 | } |
120 | 119 | ||
121 | /* | 120 | /* |
122 | * We update the i_update_core field _after_ changing | 121 | * Update complete - now make sure everyone knows that the inode |
123 | * the timestamps in order to coordinate properly with | 122 | * is dirty. |
124 | * xfs_iflush() so that we don't lose timestamp updates. | ||
125 | * This keeps us from having to hold the inode lock | ||
126 | * while doing this. We use the SYNCHRONIZE macro to | ||
127 | * ensure that the compiler does not reorder the update | ||
128 | * of i_update_core above the timestamp updates above. | ||
129 | */ | 123 | */ |
130 | if (sync_it) { | 124 | if (sync_it) |
131 | SYNCHRONIZE(); | ||
132 | ip->i_update_core = 1; | ||
133 | xfs_mark_inode_dirty_sync(ip); | 125 | xfs_mark_inode_dirty_sync(ip); |
134 | } | ||
135 | } | 126 | } |
136 | 127 | ||
137 | /* | 128 | /* |
@@ -506,10 +497,8 @@ xfs_vn_getattr( | |||
506 | stat->gid = ip->i_d.di_gid; | 497 | stat->gid = ip->i_d.di_gid; |
507 | stat->ino = ip->i_ino; | 498 | stat->ino = ip->i_ino; |
508 | stat->atime = inode->i_atime; | 499 | stat->atime = inode->i_atime; |
509 | stat->mtime.tv_sec = ip->i_d.di_mtime.t_sec; | 500 | stat->mtime = inode->i_mtime; |
510 | stat->mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; | 501 | stat->ctime = inode->i_ctime; |
511 | stat->ctime.tv_sec = ip->i_d.di_ctime.t_sec; | ||
512 | stat->ctime.tv_nsec = ip->i_d.di_ctime.t_nsec; | ||
513 | stat->blocks = | 502 | stat->blocks = |
514 | XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks); | 503 | XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks); |
515 | 504 | ||
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 49e4a6aea73c..072050f8d346 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -667,7 +667,7 @@ start: | |||
667 | xip->i_new_size = new_size; | 667 | xip->i_new_size = new_size; |
668 | 668 | ||
669 | if (likely(!(ioflags & IO_INVIS))) | 669 | if (likely(!(ioflags & IO_INVIS))) |
670 | xfs_ichgtime(xip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 670 | file_update_time(file); |
671 | 671 | ||
672 | /* | 672 | /* |
673 | * If the offset is beyond the size of the file, we have a couple | 673 | * If the offset is beyond the size of the file, we have a couple |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index bdd41c8c342f..18a4b8e11df2 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -977,6 +977,28 @@ xfs_fs_inode_init_once( | |||
977 | } | 977 | } |
978 | 978 | ||
979 | /* | 979 | /* |
980 | * Dirty the XFS inode when mark_inode_dirty_sync() is called so that | ||
981 | * we catch unlogged VFS level updates to the inode. Care must be taken | ||
982 | * here - the transaction code calls mark_inode_dirty_sync() to mark the | ||
983 | * VFS inode dirty in a transaction and clears the i_update_core field; | ||
984 | * it must clear the field after calling mark_inode_dirty_sync() to | ||
985 | * correctly indicate that the dirty state has been propagated into the | ||
986 | * inode log item. | ||
987 | * | ||
988 | * We need the barrier() to maintain correct ordering between unlogged | ||
989 | * updates and the transaction commit code that clears the i_update_core | ||
990 | * field. This requires all updates to be completed before marking the | ||
991 | * inode dirty. | ||
992 | */ | ||
993 | STATIC void | ||
994 | xfs_fs_dirty_inode( | ||
995 | struct inode *inode) | ||
996 | { | ||
997 | barrier(); | ||
998 | XFS_I(inode)->i_update_core = 1; | ||
999 | } | ||
1000 | |||
1001 | /* | ||
980 | * Attempt to flush the inode, this will actually fail | 1002 | * Attempt to flush the inode, this will actually fail |
981 | * if the inode is pinned, but we dirty the inode again | 1003 | * if the inode is pinned, but we dirty the inode again |
982 | * at the point when it is unpinned after a log write, | 1004 | * at the point when it is unpinned after a log write, |
@@ -1126,7 +1148,7 @@ xfs_fs_put_super( | |||
1126 | } | 1148 | } |
1127 | 1149 | ||
1128 | STATIC int | 1150 | STATIC int |
1129 | xfs_fs_sync_super( | 1151 | xfs_fs_sync_fs( |
1130 | struct super_block *sb, | 1152 | struct super_block *sb, |
1131 | int wait) | 1153 | int wait) |
1132 | { | 1154 | { |
@@ -1134,23 +1156,23 @@ xfs_fs_sync_super( | |||
1134 | int error; | 1156 | int error; |
1135 | 1157 | ||
1136 | /* | 1158 | /* |
1137 | * Treat a sync operation like a freeze. This is to work | 1159 | * Not much we can do for the first async pass. Writing out the |
1138 | * around a race in sync_inodes() which works in two phases | 1160 | * superblock would be counter-productive as we are going to redirty |
1139 | * - an asynchronous flush, which can write out an inode | 1161 | * when writing out other data and metadata (and writing out a single |
1140 | * without waiting for file size updates to complete, and a | 1162 | * block is quite fast anyway). |
1141 | * synchronous flush, which wont do anything because the | 1163 | * |
1142 | * async flush removed the inode's dirty flag. Also | 1164 | * Try to asynchronously kick off quota syncing at least. |
1143 | * sync_inodes() will not see any files that just have | ||
1144 | * outstanding transactions to be flushed because we don't | ||
1145 | * dirty the Linux inode until after the transaction I/O | ||
1146 | * completes. | ||
1147 | */ | 1165 | */ |
1148 | if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE)) | 1166 | if (!wait) { |
1149 | error = xfs_quiesce_data(mp); | 1167 | xfs_qm_sync(mp, SYNC_TRYLOCK); |
1150 | else | 1168 | return 0; |
1151 | error = xfs_sync_fsdata(mp, 0); | 1169 | } |
1170 | |||
1171 | error = xfs_quiesce_data(mp); | ||
1172 | if (error) | ||
1173 | return -error; | ||
1152 | 1174 | ||
1153 | if (unlikely(laptop_mode)) { | 1175 | if (laptop_mode) { |
1154 | int prev_sync_seq = mp->m_sync_seq; | 1176 | int prev_sync_seq = mp->m_sync_seq; |
1155 | 1177 | ||
1156 | /* | 1178 | /* |
@@ -1169,7 +1191,7 @@ xfs_fs_sync_super( | |||
1169 | mp->m_sync_seq != prev_sync_seq); | 1191 | mp->m_sync_seq != prev_sync_seq); |
1170 | } | 1192 | } |
1171 | 1193 | ||
1172 | return -error; | 1194 | return 0; |
1173 | } | 1195 | } |
1174 | 1196 | ||
1175 | STATIC int | 1197 | STATIC int |
@@ -1539,10 +1561,11 @@ xfs_fs_get_sb( | |||
1539 | static const struct super_operations xfs_super_operations = { | 1561 | static const struct super_operations xfs_super_operations = { |
1540 | .alloc_inode = xfs_fs_alloc_inode, | 1562 | .alloc_inode = xfs_fs_alloc_inode, |
1541 | .destroy_inode = xfs_fs_destroy_inode, | 1563 | .destroy_inode = xfs_fs_destroy_inode, |
1564 | .dirty_inode = xfs_fs_dirty_inode, | ||
1542 | .write_inode = xfs_fs_write_inode, | 1565 | .write_inode = xfs_fs_write_inode, |
1543 | .clear_inode = xfs_fs_clear_inode, | 1566 | .clear_inode = xfs_fs_clear_inode, |
1544 | .put_super = xfs_fs_put_super, | 1567 | .put_super = xfs_fs_put_super, |
1545 | .sync_fs = xfs_fs_sync_super, | 1568 | .sync_fs = xfs_fs_sync_fs, |
1546 | .freeze_fs = xfs_fs_freeze, | 1569 | .freeze_fs = xfs_fs_freeze, |
1547 | .statfs = xfs_fs_statfs, | 1570 | .statfs = xfs_fs_statfs, |
1548 | .remount_fs = xfs_fs_remount, | 1571 | .remount_fs = xfs_fs_remount, |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 320be6aea492..961df0a22c78 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -309,11 +309,15 @@ xfs_sync_attr( | |||
309 | STATIC int | 309 | STATIC int |
310 | xfs_commit_dummy_trans( | 310 | xfs_commit_dummy_trans( |
311 | struct xfs_mount *mp, | 311 | struct xfs_mount *mp, |
312 | uint log_flags) | 312 | uint flags) |
313 | { | 313 | { |
314 | struct xfs_inode *ip = mp->m_rootip; | 314 | struct xfs_inode *ip = mp->m_rootip; |
315 | struct xfs_trans *tp; | 315 | struct xfs_trans *tp; |
316 | int error; | 316 | int error; |
317 | int log_flags = XFS_LOG_FORCE; | ||
318 | |||
319 | if (flags & SYNC_WAIT) | ||
320 | log_flags |= XFS_LOG_SYNC; | ||
317 | 321 | ||
318 | /* | 322 | /* |
319 | * Put a dummy transaction in the log to tell recovery | 323 | * Put a dummy transaction in the log to tell recovery |
@@ -331,13 +335,12 @@ xfs_commit_dummy_trans( | |||
331 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | 335 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); |
332 | xfs_trans_ihold(tp, ip); | 336 | xfs_trans_ihold(tp, ip); |
333 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 337 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
334 | /* XXX(hch): ignoring the error here.. */ | ||
335 | error = xfs_trans_commit(tp, 0); | 338 | error = xfs_trans_commit(tp, 0); |
336 | |||
337 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 339 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
338 | 340 | ||
341 | /* the log force ensures this transaction is pushed to disk */ | ||
339 | xfs_log_force(mp, 0, log_flags); | 342 | xfs_log_force(mp, 0, log_flags); |
340 | return 0; | 343 | return error; |
341 | } | 344 | } |
342 | 345 | ||
343 | int | 346 | int |
@@ -385,7 +388,20 @@ xfs_sync_fsdata( | |||
385 | else | 388 | else |
386 | XFS_BUF_ASYNC(bp); | 389 | XFS_BUF_ASYNC(bp); |
387 | 390 | ||
388 | return xfs_bwrite(mp, bp); | 391 | error = xfs_bwrite(mp, bp); |
392 | if (error) | ||
393 | return error; | ||
394 | |||
395 | /* | ||
396 | * If this is a data integrity sync make sure all pending buffers | ||
397 | * are flushed out for the log coverage check below. | ||
398 | */ | ||
399 | if (flags & SYNC_WAIT) | ||
400 | xfs_flush_buftarg(mp->m_ddev_targp, 1); | ||
401 | |||
402 | if (xfs_log_need_covered(mp)) | ||
403 | error = xfs_commit_dummy_trans(mp, flags); | ||
404 | return error; | ||
389 | 405 | ||
390 | out_brelse: | 406 | out_brelse: |
391 | xfs_buf_relse(bp); | 407 | xfs_buf_relse(bp); |
@@ -419,14 +435,16 @@ xfs_quiesce_data( | |||
419 | /* push non-blocking */ | 435 | /* push non-blocking */ |
420 | xfs_sync_data(mp, 0); | 436 | xfs_sync_data(mp, 0); |
421 | xfs_qm_sync(mp, SYNC_TRYLOCK); | 437 | xfs_qm_sync(mp, SYNC_TRYLOCK); |
422 | xfs_filestream_flush(mp); | ||
423 | 438 | ||
424 | /* push and block */ | 439 | /* push and block till complete */ |
425 | xfs_sync_data(mp, SYNC_WAIT); | 440 | xfs_sync_data(mp, SYNC_WAIT); |
426 | xfs_qm_sync(mp, SYNC_WAIT); | 441 | xfs_qm_sync(mp, SYNC_WAIT); |
427 | 442 | ||
443 | /* drop inode references pinned by filestreams */ | ||
444 | xfs_filestream_flush(mp); | ||
445 | |||
428 | /* write superblock and hoover up shutdown errors */ | 446 | /* write superblock and hoover up shutdown errors */ |
429 | error = xfs_sync_fsdata(mp, 0); | 447 | error = xfs_sync_fsdata(mp, SYNC_WAIT); |
430 | 448 | ||
431 | /* flush data-only devices */ | 449 | /* flush data-only devices */ |
432 | if (mp->m_rtdev_targp) | 450 | if (mp->m_rtdev_targp) |
@@ -570,8 +588,6 @@ xfs_sync_worker( | |||
570 | /* dgc: errors ignored here */ | 588 | /* dgc: errors ignored here */ |
571 | error = xfs_qm_sync(mp, SYNC_TRYLOCK); | 589 | error = xfs_qm_sync(mp, SYNC_TRYLOCK); |
572 | error = xfs_sync_fsdata(mp, SYNC_TRYLOCK); | 590 | error = xfs_sync_fsdata(mp, SYNC_TRYLOCK); |
573 | if (xfs_log_need_covered(mp)) | ||
574 | error = xfs_commit_dummy_trans(mp, XFS_LOG_FORCE); | ||
575 | } | 591 | } |
576 | mp->m_sync_seq++; | 592 | mp->m_sync_seq++; |
577 | wake_up(&mp->m_wait_single_sync_task); | 593 | wake_up(&mp->m_wait_single_sync_task); |
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 7465f9ee125f..ab89a7e94a0f 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -206,10 +206,10 @@ xfs_swap_extents( | |||
206 | * process that the file was not changed out from | 206 | * process that the file was not changed out from |
207 | * under it. | 207 | * under it. |
208 | */ | 208 | */ |
209 | if ((sbp->bs_ctime.tv_sec != ip->i_d.di_ctime.t_sec) || | 209 | if ((sbp->bs_ctime.tv_sec != VFS_I(ip)->i_ctime.tv_sec) || |
210 | (sbp->bs_ctime.tv_nsec != ip->i_d.di_ctime.t_nsec) || | 210 | (sbp->bs_ctime.tv_nsec != VFS_I(ip)->i_ctime.tv_nsec) || |
211 | (sbp->bs_mtime.tv_sec != ip->i_d.di_mtime.t_sec) || | 211 | (sbp->bs_mtime.tv_sec != VFS_I(ip)->i_mtime.tv_sec) || |
212 | (sbp->bs_mtime.tv_nsec != ip->i_d.di_mtime.t_nsec)) { | 212 | (sbp->bs_mtime.tv_nsec != VFS_I(ip)->i_mtime.tv_nsec)) { |
213 | error = XFS_ERROR(EBUSY); | 213 | error = XFS_ERROR(EBUSY); |
214 | goto out_unlock; | 214 | goto out_unlock; |
215 | } | 215 | } |
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index fa913e459442..41ad537c49e9 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c | |||
@@ -854,6 +854,7 @@ xfs_dir2_leaf_getdents( | |||
854 | */ | 854 | */ |
855 | ra_want = howmany(bufsize + mp->m_dirblksize, | 855 | ra_want = howmany(bufsize + mp->m_dirblksize, |
856 | mp->m_sb.sb_blocksize) - 1; | 856 | mp->m_sb.sb_blocksize) - 1; |
857 | ASSERT(ra_want >= 0); | ||
857 | 858 | ||
858 | /* | 859 | /* |
859 | * If we don't have as many as we want, and we haven't | 860 | * If we don't have as many as we want, and we haven't |
@@ -1088,7 +1089,8 @@ xfs_dir2_leaf_getdents( | |||
1088 | */ | 1089 | */ |
1089 | ptr += length; | 1090 | ptr += length; |
1090 | curoff += length; | 1091 | curoff += length; |
1091 | bufsize -= length; | 1092 | /* bufsize may have just been a guess; don't go negative */ |
1093 | bufsize = bufsize > length ? bufsize - length : 0; | ||
1092 | } | 1094 | } |
1093 | 1095 | ||
1094 | /* | 1096 | /* |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c1dc7ef5a1d8..b92a4fa2a0a1 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -3068,9 +3068,9 @@ xfs_iflush_int( | |||
3068 | SYNCHRONIZE(); | 3068 | SYNCHRONIZE(); |
3069 | 3069 | ||
3070 | /* | 3070 | /* |
3071 | * Make sure to get the latest atime from the Linux inode. | 3071 | * Make sure to get the latest timestamps from the Linux inode. |
3072 | */ | 3072 | */ |
3073 | xfs_synchronize_atime(ip); | 3073 | xfs_synchronize_times(ip); |
3074 | 3074 | ||
3075 | if (XFS_TEST_ERROR(be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC, | 3075 | if (XFS_TEST_ERROR(be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC, |
3076 | mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { | 3076 | mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 0b38b9a869ec..41555de1d1db 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -504,7 +504,7 @@ void xfs_ichgtime(xfs_inode_t *, int); | |||
504 | void xfs_lock_inodes(xfs_inode_t **, int, uint); | 504 | void xfs_lock_inodes(xfs_inode_t **, int, uint); |
505 | void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); | 505 | void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); |
506 | 506 | ||
507 | void xfs_synchronize_atime(xfs_inode_t *); | 507 | void xfs_synchronize_times(xfs_inode_t *); |
508 | void xfs_mark_inode_dirty_sync(xfs_inode_t *); | 508 | void xfs_mark_inode_dirty_sync(xfs_inode_t *); |
509 | 509 | ||
510 | #if defined(XFS_INODE_TRACE) | 510 | #if defined(XFS_INODE_TRACE) |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 47d5b663c37e..9794b876d6ff 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -232,6 +232,15 @@ xfs_inode_item_format( | |||
232 | nvecs = 1; | 232 | nvecs = 1; |
233 | 233 | ||
234 | /* | 234 | /* |
235 | * Make sure the linux inode is dirty. We do this before | ||
236 | * clearing i_update_core as the VFS will call back into | ||
237 | * XFS here and set i_update_core, so we need to dirty the | ||
238 | * inode first so that the ordering of i_update_core and | ||
239 | * unlogged modifications still works as described below. | ||
240 | */ | ||
241 | xfs_mark_inode_dirty_sync(ip); | ||
242 | |||
243 | /* | ||
235 | * Clear i_update_core if the timestamps (or any other | 244 | * Clear i_update_core if the timestamps (or any other |
236 | * non-transactional modification) need flushing/logging | 245 | * non-transactional modification) need flushing/logging |
237 | * and we're about to log them with the rest of the core. | 246 | * and we're about to log them with the rest of the core. |
@@ -263,14 +272,9 @@ xfs_inode_item_format( | |||
263 | } | 272 | } |
264 | 273 | ||
265 | /* | 274 | /* |
266 | * Make sure to get the latest atime from the Linux inode. | 275 | * Make sure to get the latest timestamps from the Linux inode. |
267 | */ | 276 | */ |
268 | xfs_synchronize_atime(ip); | 277 | xfs_synchronize_times(ip); |
269 | |||
270 | /* | ||
271 | * make sure the linux inode is dirty | ||
272 | */ | ||
273 | xfs_mark_inode_dirty_sync(ip); | ||
274 | 278 | ||
275 | vecp->i_addr = (xfs_caddr_t)&ip->i_d; | 279 | vecp->i_addr = (xfs_caddr_t)&ip->i_d; |
276 | vecp->i_len = sizeof(struct xfs_icdinode); | 280 | vecp->i_len = sizeof(struct xfs_icdinode); |
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index b68f9107e26c..62efab2f3839 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -59,6 +59,7 @@ xfs_bulkstat_one_iget( | |||
59 | { | 59 | { |
60 | xfs_icdinode_t *dic; /* dinode core info pointer */ | 60 | xfs_icdinode_t *dic; /* dinode core info pointer */ |
61 | xfs_inode_t *ip; /* incore inode pointer */ | 61 | xfs_inode_t *ip; /* incore inode pointer */ |
62 | struct inode *inode; | ||
62 | int error; | 63 | int error; |
63 | 64 | ||
64 | error = xfs_iget(mp, NULL, ino, | 65 | error = xfs_iget(mp, NULL, ino, |
@@ -72,6 +73,7 @@ xfs_bulkstat_one_iget( | |||
72 | ASSERT(ip->i_imap.im_blkno != 0); | 73 | ASSERT(ip->i_imap.im_blkno != 0); |
73 | 74 | ||
74 | dic = &ip->i_d; | 75 | dic = &ip->i_d; |
76 | inode = VFS_I(ip); | ||
75 | 77 | ||
76 | /* xfs_iget returns the following without needing | 78 | /* xfs_iget returns the following without needing |
77 | * further change. | 79 | * further change. |
@@ -83,16 +85,19 @@ xfs_bulkstat_one_iget( | |||
83 | buf->bs_uid = dic->di_uid; | 85 | buf->bs_uid = dic->di_uid; |
84 | buf->bs_gid = dic->di_gid; | 86 | buf->bs_gid = dic->di_gid; |
85 | buf->bs_size = dic->di_size; | 87 | buf->bs_size = dic->di_size; |
88 | |||
86 | /* | 89 | /* |
87 | * We are reading the atime from the Linux inode because the | 90 | * We need to read the timestamps from the Linux inode because |
88 | * dinode might not be uptodate. | 91 | * the VFS keeps writing directly into the inode structure instead |
92 | * of telling us about the updates. | ||
89 | */ | 93 | */ |
90 | buf->bs_atime.tv_sec = VFS_I(ip)->i_atime.tv_sec; | 94 | buf->bs_atime.tv_sec = inode->i_atime.tv_sec; |
91 | buf->bs_atime.tv_nsec = VFS_I(ip)->i_atime.tv_nsec; | 95 | buf->bs_atime.tv_nsec = inode->i_atime.tv_nsec; |
92 | buf->bs_mtime.tv_sec = dic->di_mtime.t_sec; | 96 | buf->bs_mtime.tv_sec = inode->i_mtime.tv_sec; |
93 | buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec; | 97 | buf->bs_mtime.tv_nsec = inode->i_mtime.tv_nsec; |
94 | buf->bs_ctime.tv_sec = dic->di_ctime.t_sec; | 98 | buf->bs_ctime.tv_sec = inode->i_ctime.tv_sec; |
95 | buf->bs_ctime.tv_nsec = dic->di_ctime.t_nsec; | 99 | buf->bs_ctime.tv_nsec = inode->i_ctime.tv_nsec; |
100 | |||
96 | buf->bs_xflags = xfs_ip2xflags(ip); | 101 | buf->bs_xflags = xfs_ip2xflags(ip); |
97 | buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog; | 102 | buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog; |
98 | buf->bs_extents = dic->di_nextents; | 103 | buf->bs_extents = dic->di_nextents; |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index a434f287962d..b572f7e840e0 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -2476,12 +2476,6 @@ xfs_reclaim( | |||
2476 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); | 2476 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); |
2477 | 2477 | ||
2478 | /* | 2478 | /* |
2479 | * Make sure the atime in the XFS inode is correct before freeing the | ||
2480 | * Linux inode. | ||
2481 | */ | ||
2482 | xfs_synchronize_atime(ip); | ||
2483 | |||
2484 | /* | ||
2485 | * If we have nothing to flush with this inode then complete the | 2479 | * If we have nothing to flush with this inode then complete the |
2486 | * teardown now, otherwise break the link between the xfs inode and the | 2480 | * teardown now, otherwise break the link between the xfs inode and the |
2487 | * linux inode and clean up the xfs inode later. This avoids flushing | 2481 | * linux inode and clean up the xfs inode later. This avoids flushing |
diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 4ea4510e2996..8bf765c4f58d 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c | |||
@@ -833,12 +833,15 @@ static void early_alloc(struct early_log *log) | |||
833 | */ | 833 | */ |
834 | rcu_read_lock(); | 834 | rcu_read_lock(); |
835 | object = create_object((unsigned long)log->ptr, log->size, | 835 | object = create_object((unsigned long)log->ptr, log->size, |
836 | log->min_count, GFP_KERNEL); | 836 | log->min_count, GFP_ATOMIC); |
837 | if (!object) | ||
838 | goto out; | ||
837 | spin_lock_irqsave(&object->lock, flags); | 839 | spin_lock_irqsave(&object->lock, flags); |
838 | for (i = 0; i < log->trace_len; i++) | 840 | for (i = 0; i < log->trace_len; i++) |
839 | object->trace[i] = log->trace[i]; | 841 | object->trace[i] = log->trace[i]; |
840 | object->trace_len = log->trace_len; | 842 | object->trace_len = log->trace_len; |
841 | spin_unlock_irqrestore(&object->lock, flags); | 843 | spin_unlock_irqrestore(&object->lock, flags); |
844 | out: | ||
842 | rcu_read_unlock(); | 845 | rcu_read_unlock(); |
843 | } | 846 | } |
844 | 847 | ||