Merge tag 'v2.6.35-rc4' into drm-testing

This commit is contained in:
Dave Airlie 2010-07-07 18:37:34 +10:00
Родитель 023eb571a1 815c4163b6
Коммит 6dbe746571
49 изменённых файлов: 514 добавлений и 602 удалений

Просмотреть файл

@ -2111,11 +2111,18 @@ F: drivers/edac/i5000_edac.c
EDAC-I5400
M: Mauro Carvalho Chehab <mchehab@redhat.com>
L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
L: linux-edac@vger.kernel.org
W: bluesmoke.sourceforge.net
S: Maintained
F: drivers/edac/i5400_edac.c
EDAC-I7CORE
M: Mauro Carvalho Chehab <mchehab@redhat.com>
L: linux-edac@vger.kernel.org
W: bluesmoke.sourceforge.net
S: Maintained
F: drivers/edac/i7core_edac.c linux/edac_mce.h drivers/edac/edac_mce.c
EDAC-I82975X
M: Ranganathan Desikan <ravi@jetztechnologies.com>
M: "Arvind R." <arvind@jetztechnologies.com>

Просмотреть файл

@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 35
EXTRAVERSION = -rc3
EXTRAVERSION = -rc4
NAME = Sheep on Meth
# *DOCUMENTATION*
@ -883,80 +883,10 @@ PHONY += $(vmlinux-dirs)
$(vmlinux-dirs): prepare scripts
$(Q)$(MAKE) $(build)=$@
# Build the kernel release string
#
# The KERNELRELEASE value built here is stored in the file
# include/config/kernel.release, and is used when executing several
# make targets, such as "make install" or "make modules_install."
#
# The eventual kernel release string consists of the following fields,
# shown in a hierarchical format to show how smaller parts are concatenated
# to form the larger and final value, with values coming from places like
# the Makefile, kernel config options, make command line options and/or
# SCM tag information.
#
# $(KERNELVERSION)
# $(VERSION) eg, 2
# $(PATCHLEVEL) eg, 6
# $(SUBLEVEL) eg, 18
# $(EXTRAVERSION) eg, -rc6
# $(localver-full)
# $(localver)
# localversion* (files without backups, containing '~')
# $(CONFIG_LOCALVERSION) (from kernel config setting)
# $(LOCALVERSION) (from make command line, if provided)
# $(localver-extra)
# $(scm-identifier) (unique SCM tag, if one exists)
# ./scripts/setlocalversion (only with CONFIG_LOCALVERSION_AUTO)
# .scmversion (only with CONFIG_LOCALVERSION_AUTO)
# + (only without CONFIG_LOCALVERSION_AUTO
# and without LOCALVERSION= and
# repository is at non-tagged commit)
#
# For kernels without CONFIG_LOCALVERSION_AUTO compiled from an SCM that has
# been revised beyond a tagged commit, `+' is appended to the version string
# when not overridden by using "make LOCALVERSION=". This indicates that the
# kernel is not a vanilla release version and has been modified.
pattern = ".*/localversion[^~]*"
string = $(shell cat /dev/null \
`find $(objtree) $(srctree) -maxdepth 1 -regex $(pattern) | sort -u`)
localver = $(subst $(space),, $(string) \
$(patsubst "%",%,$(CONFIG_LOCALVERSION)))
# scripts/setlocalversion is called to create a unique identifier if the source
# is managed by a known SCM and the repository has been revised since the last
# tagged (release) commit. The format of the identifier is determined by the
# SCM's implementation.
#
# .scmversion is used when generating rpm packages so we do not loose
# the version information from the SCM when we do the build of the kernel
# from the copied source
ifeq ($(wildcard .scmversion),)
scm-identifier = $(shell $(CONFIG_SHELL) \
$(srctree)/scripts/setlocalversion $(srctree))
else
scm-identifier = $(shell cat .scmversion 2> /dev/null)
endif
ifdef CONFIG_LOCALVERSION_AUTO
localver-extra = $(scm-identifier)
else
ifneq ($(scm-identifier),)
ifeq ("$(origin LOCALVERSION)", "undefined")
localver-extra = +
endif
endif
endif
localver-full = $(localver)$(LOCALVERSION)$(localver-extra)
# Store (new) KERNELRELASE string in include/config/kernel.release
kernelrelease = $(KERNELVERSION)$(localver-full)
include/config/kernel.release: include/config/auto.conf FORCE
$(Q)rm -f $@
$(Q)echo $(kernelrelease) > $@
$(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) scripts/setlocalversion $(srctree))" > $@
# Things we need to do before we recursively start building the kernel

Просмотреть файл

@ -955,7 +955,8 @@ config XSCALE_PMU
default y
config CPU_HAS_PMU
depends on CPU_V6 || CPU_V7 || XSCALE_PMU
depends on (CPU_V6 || CPU_V7 || XSCALE_PMU) && \
(!ARCH_OMAP3 || OMAP3_EMU)
default y
bool

Просмотреть файл

@ -21,8 +21,8 @@ struct pxa2xx_udc_mach_info {
* here. Note that sometimes the signals go through inverters...
*/
bool gpio_vbus_inverted;
u16 gpio_vbus; /* high == vbus present */
int gpio_vbus; /* high == vbus present */
bool gpio_pullup_inverted;
u16 gpio_pullup; /* high == pullup activated */
int gpio_pullup; /* high == pullup activated */
};

Просмотреть файл

@ -91,7 +91,11 @@ extern void release_thread(struct task_struct *);
unsigned long get_wchan(struct task_struct *p);
#if __LINUX_ARM_ARCH__ == 6
#define cpu_relax() smp_mb()
#else
#define cpu_relax() barrier()
#endif
/*
* Create a new kernel thread

Просмотреть файл

@ -201,7 +201,7 @@ armpmu_event_update(struct perf_event *event,
{
int shift = 64 - 32;
s64 prev_raw_count, new_raw_count;
s64 delta;
u64 delta;
again:
prev_raw_count = atomic64_read(&hwc->prev_count);

Просмотреть файл

@ -115,6 +115,8 @@ static struct platform_device physmap_flash_device = {
/* USB */
#if defined(CONFIG_USB_ULPI)
#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
@ -244,10 +246,20 @@ static struct mxc_usbh_platform_data usbh2_pdata = {
.flags = MXC_EHCI_POWER_PINS_ENABLED,
};
static struct platform_device *devices[] __initdata = {
&smsc91x_device,
&physmap_flash_device,
};
static void lilly1131_usb_init(void)
{
usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
mxc_register_device(&mxc_usbh1, &usbh1_pdata);
mxc_register_device(&mxc_usbh2, &usbh2_pdata);
}
#else
static inline void lilly1131_usb_init(void) {}
#endif /* CONFIG_USB_ULPI */
/* SPI */
@ -279,6 +291,11 @@ static struct spi_board_info mc13783_dev __initdata = {
.platform_data = &mc13783_pdata,
};
static struct platform_device *devices[] __initdata = {
&smsc91x_device,
&physmap_flash_device,
};
static int mx31lilly_baseboard;
core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444);
@ -321,13 +338,7 @@ static void __init mx31lilly_board_init(void)
platform_add_devices(devices, ARRAY_SIZE(devices));
/* USB */
usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
mxc_register_device(&mxc_usbh1, &usbh1_pdata);
mxc_register_device(&mxc_usbh2, &usbh2_pdata);
lilly1131_usb_init();
}
static void __init mx31lilly_timer_init(void)

Просмотреть файл

@ -697,7 +697,7 @@ static struct i2c_board_info __initdata mioa701_pi2c_devices[] = {
};
/* Board I2C devices. */
static struct i2c_board_info __initdata mioa701_i2c_devices[] = {
static struct i2c_board_info mioa701_i2c_devices[] = {
{
I2C_BOARD_INFO("mt9m111", 0x5d),
},

Просмотреть файл

@ -3,8 +3,9 @@
*
* Support for the Zipit Z2 Handheld device.
*
* Author: Ken McGuire
* Created: Jan 25, 2009
* Copyright (C) 2009-2010 Marek Vasut <marek.vasut@gmail.com>
*
* Based on research and code by: Ken McGuire
* Based on mainstone.c as modified for the Zipit Z2.
*
* This program is free software; you can redistribute it and/or modify
@ -157,21 +158,14 @@ static struct mtd_partition z2_flash_parts[] = {
{
.name = "U-Boot Bootloader",
.offset = 0x0,
.size = 0x20000,
},
{
.name = "Linux Kernel",
.offset = 0x20000,
.size = 0x220000,
},
{
.name = "Filesystem",
.offset = 0x240000,
.size = 0x5b0000,
},
{
.size = 0x40000,
}, {
.name = "U-Boot Environment",
.offset = 0x7f0000,
.offset = 0x40000,
.size = 0x60000,
}, {
.name = "Flash",
.offset = 0x60000,
.size = MTDPART_SIZ_FULL,
},
};

Просмотреть файл

@ -18,6 +18,7 @@ config REALVIEW_EB_ARM11MP
bool "Support ARM11MPCore tile"
depends on MACH_REALVIEW_EB
select CPU_V6
select ARCH_HAS_BARRIERS if SMP
help
Enable support for the ARM11MPCore tile on the Realview platform.
@ -35,6 +36,7 @@ config MACH_REALVIEW_PB11MP
select CPU_V6
select ARM_GIC
select HAVE_PATA_PLATFORM
select ARCH_HAS_BARRIERS if SMP
help
Include support for the ARM(R) RealView MPCore Platform Baseboard.
PB11MPCore is a platform with an on-board ARM11MPCore and has

Просмотреть файл

@ -0,0 +1,8 @@
/*
* Barriers redefined for RealView ARM11MPCore platforms with L220 cache
* controller to work around hardware errata causing the outer_sync()
* operation to deadlock the system.
*/
#define mb() dsb()
#define rmb() dmb()
#define wmb() mb()

Просмотреть файл

@ -32,6 +32,7 @@
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
#include <asm/pgtable.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/localtimer.h>
@ -457,7 +458,7 @@ static void __init realview_eb_init(void)
MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.phys_io = REALVIEW_EB_UART0_BASE,
.phys_io = REALVIEW_EB_UART0_BASE & SECTION_MASK,
.io_pg_offst = (IO_ADDRESS(REALVIEW_EB_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,

Просмотреть файл

@ -32,6 +32,7 @@
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
#include <asm/pgtable.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>
@ -351,7 +352,7 @@ static void __init realview_pb1176_init(void)
MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.phys_io = REALVIEW_PB1176_UART0_BASE,
.phys_io = REALVIEW_PB1176_UART0_BASE & SECTION_MASK,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PB1176_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_pb1176_fixup,

Просмотреть файл

@ -32,6 +32,7 @@
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
#include <asm/pgtable.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/localtimer.h>
@ -373,7 +374,7 @@ static void __init realview_pb11mp_init(void)
MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.phys_io = REALVIEW_PB11MP_UART0_BASE,
.phys_io = REALVIEW_PB11MP_UART0_BASE & SECTION_MASK,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PB11MP_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,

Просмотреть файл

@ -31,6 +31,7 @@
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
#include <asm/pgtable.h>
#include <asm/hardware/gic.h>
#include <asm/mach/arch.h>
@ -323,7 +324,7 @@ static void __init realview_pba8_init(void)
MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.phys_io = REALVIEW_PBA8_UART0_BASE,
.phys_io = REALVIEW_PBA8_UART0_BASE & SECTION_MASK,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PBA8_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,

Просмотреть файл

@ -31,6 +31,7 @@
#include <asm/mach-types.h>
#include <asm/pmu.h>
#include <asm/smp_twd.h>
#include <asm/pgtable.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>
@ -409,7 +410,7 @@ static void __init realview_pbx_init(void)
MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.phys_io = REALVIEW_PBX_UART0_BASE,
.phys_io = REALVIEW_PBX_UART0_BASE & SECTION_MASK,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PBX_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_pbx_fixup,

Просмотреть файл

@ -10,6 +10,7 @@
#include <linux/amba/clcd.h>
#include <asm/clkdev.h>
#include <asm/pgtable.h>
#include <asm/hardware/arm_timer.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/gic.h>
@ -236,7 +237,7 @@ static void ct_ca9x4_init(void)
}
MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4")
.phys_io = V2M_UART0,
.phys_io = V2M_UART0 & SECTION_MASK,
.io_pg_offst = (__MMIO_P2V(V2M_UART0) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100,
.map_io = ct_ca9x4_map_io,

Просмотреть файл

@ -735,6 +735,25 @@ config NEEDS_SYSCALL_FOR_CMPXCHG
Forget about fast user space cmpxchg support.
It is just not possible.
config DMA_CACHE_RWFO
bool "Enable read/write for ownership DMA cache maintenance"
depends on CPU_V6 && SMP
default y
help
The Snoop Control Unit on ARM11MPCore does not detect the
cache maintenance operations and the dma_{map,unmap}_area()
functions may leave stale cache entries on other CPUs. By
enabling this option, Read or Write For Ownership in the ARMv6
DMA cache maintenance functions is performed. These LDR/STR
instructions change the cache line state to shared or modified
so that the cache operation has the desired effect.
Note that the workaround is only valid on processors that do
not perform speculative loads into the D-cache. For such
processors, if cache maintenance operations are not broadcast
in hardware, other workarounds are needed (e.g. cache
maintenance broadcasting in software via FIQ).
config OUTER_CACHE
bool
@ -794,6 +813,8 @@ config ARM_L1_CACHE_SHIFT
config ARM_DMA_MEM_BUFFERABLE
bool "Use non-cacheable memory for DMA" if CPU_V6 && !CPU_V7
depends on !(MACH_REALVIEW_PB1176 || REALVIEW_EB_ARM11MP || \
MACH_REALVIEW_PB11MP)
default y if CPU_V6 || CPU_V7
help
Historically, the kernel has used strongly ordered mappings to

Просмотреть файл

@ -211,8 +211,9 @@ v6_dma_inv_range:
mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line
#endif
1:
#ifdef CONFIG_SMP
str r0, [r0] @ write for ownership
#ifdef CONFIG_DMA_CACHE_RWFO
ldr r2, [r0] @ read for ownership
str r2, [r0] @ write for ownership
#endif
#ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c6, 1 @ invalidate D line
@ -234,7 +235,7 @@ v6_dma_inv_range:
v6_dma_clean_range:
bic r0, r0, #D_CACHE_LINE_SIZE - 1
1:
#ifdef CONFIG_SMP
#ifdef CONFIG_DMA_CACHE_RWFO
ldr r2, [r0] @ read for ownership
#endif
#ifdef HARVARD_CACHE
@ -257,7 +258,7 @@ v6_dma_clean_range:
ENTRY(v6_dma_flush_range)
bic r0, r0, #D_CACHE_LINE_SIZE - 1
1:
#ifdef CONFIG_SMP
#ifdef CONFIG_DMA_CACHE_RWFO
ldr r2, [r0] @ read for ownership
str r2, [r0] @ write for ownership
#endif
@ -283,9 +284,13 @@ ENTRY(v6_dma_map_area)
add r1, r1, r0
teq r2, #DMA_FROM_DEVICE
beq v6_dma_inv_range
#ifndef CONFIG_DMA_CACHE_RWFO
b v6_dma_clean_range
#else
teq r2, #DMA_TO_DEVICE
beq v6_dma_clean_range
b v6_dma_flush_range
#endif
ENDPROC(v6_dma_map_area)
/*
@ -295,6 +300,11 @@ ENDPROC(v6_dma_map_area)
* - dir - DMA direction
*/
ENTRY(v6_dma_unmap_area)
#ifndef CONFIG_DMA_CACHE_RWFO
add r1, r1, r0
teq r2, #DMA_TO_DEVICE
bne v6_dma_inv_range
#endif
mov pc, lr
ENDPROC(v6_dma_unmap_area)

Просмотреть файл

@ -24,15 +24,6 @@
#include <asm/tlbflush.h>
#include <asm/sizes.h>
/* Sanity check size */
#if (CONSISTENT_DMA_SIZE % SZ_2M)
#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB"
#endif
#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
static u64 get_coherent_dma_mask(struct device *dev)
{
u64 mask = ISA_DMA_THRESHOLD;
@ -123,6 +114,15 @@ static void __dma_free_buffer(struct page *page, size_t size)
}
#ifdef CONFIG_MMU
/* Sanity check size */
#if (CONSISTENT_DMA_SIZE % SZ_2M)
#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB"
#endif
#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
/*
* These are the page tables (2MB each) covering uncached, DMA consistent allocations
*/

Просмотреть файл

@ -2,8 +2,9 @@
# Makefile for code common across different PXA processor families
#
obj-y := dma.o pmu.o
obj-y := dma.o
obj-$(CONFIG_ARCH_PXA) += pmu.o
obj-$(CONFIG_GENERIC_GPIO) += gpio.o
obj-$(CONFIG_PXA3xx) += mfp.o
obj-$(CONFIG_ARCH_MMP) += mfp.o

Просмотреть файл

@ -102,8 +102,8 @@ static const u64 amd_perfmon_event_map[] =
[PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
[PERF_COUNT_HW_CACHE_REFERENCES] = 0x0080,
[PERF_COUNT_HW_CACHE_MISSES] = 0x0081,
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4,
[PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5,
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2,
[PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3,
};
static u64 amd_pmu_event_map(int hw_event)

Просмотреть файл

@ -526,6 +526,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
{
struct task_struct *tsk = current;
int user_icebp = 0;
unsigned long dr6;
int si_code;
@ -534,6 +535,14 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
/* Filter out all the reserved bits which are preset to 1 */
dr6 &= ~DR6_RESERVED;
/*
* If dr6 has no reason to give us about the origin of this trap,
* then it's very likely the result of an icebp/int01 trap.
* User wants a sigtrap for that.
*/
if (!dr6 && user_mode(regs))
user_icebp = 1;
/* Catch kmemcheck conditions first of all! */
if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
return;
@ -575,7 +584,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
regs->flags &= ~X86_EFLAGS_TF;
}
si_code = get_si_code(tsk->thread.debugreg6);
if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS))
if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp)
send_sigtrap(tsk, regs, error_code, si_code);
preempt_conditional_cli(regs);

Просмотреть файл

@ -4257,10 +4257,12 @@ static int ppc440spe_adma_setup_irqs(struct ppc440spe_adma_device *adev,
struct ppc440spe_adma_chan *chan,
int *initcode)
{
struct of_device *ofdev;
struct device_node *np;
int ret;
np = container_of(adev->dev, struct of_device, dev)->node;
ofdev = container_of(adev->dev, struct of_device, dev);
np = ofdev->dev.of_node;
if (adev->id != PPC440SPE_XOR_ID) {
adev->err_irq = irq_of_parse_and_map(np, 1);
if (adev->err_irq == NO_IRQ) {

Просмотреть файл

@ -1233,10 +1233,28 @@ static void __init i7core_xeon_pci_fixup(struct pci_id_table *table)
for (i = 0; i < MAX_SOCKET_BUSES; i++)
pcibios_scan_specific_bus(255-i);
}
pci_dev_put(pdev);
table++;
}
}
static unsigned i7core_pci_lastbus(void)
{
int last_bus = 0, bus;
struct pci_bus *b = NULL;
while ((b = pci_find_next_bus(b)) != NULL) {
bus = b->number;
debugf0("Found bus %d\n", bus);
if (bus > last_bus)
last_bus = bus;
}
debugf0("Last bus %d\n", last_bus);
return last_bus;
}
/*
* i7core_get_devices Find and perform 'get' operation on the MCH's
* device/functions we want to reference for this driver
@ -1244,7 +1262,8 @@ static void __init i7core_xeon_pci_fixup(struct pci_id_table *table)
* Need to 'get' device 16 func 1 and func 2
*/
int i7core_get_onedevice(struct pci_dev **prev, int devno,
struct pci_id_descr *dev_descr, unsigned n_devs)
struct pci_id_descr *dev_descr, unsigned n_devs,
unsigned last_bus)
{
struct i7core_dev *i7core_dev;
@ -1291,10 +1310,7 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno,
}
bus = pdev->bus->number;
if (bus == 0x3f)
socket = 0;
else
socket = 255 - bus;
socket = last_bus - bus;
i7core_dev = get_i7core_dev(socket);
if (!i7core_dev) {
@ -1358,17 +1374,21 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno,
static int i7core_get_devices(struct pci_id_table *table)
{
int i, rc;
int i, rc, last_bus;
struct pci_dev *pdev = NULL;
struct pci_id_descr *dev_descr;
last_bus = i7core_pci_lastbus();
while (table && table->descr) {
dev_descr = table->descr;
for (i = 0; i < table->n_devs; i++) {
pdev = NULL;
do {
rc = i7core_get_onedevice(&pdev, i, &dev_descr[i],
table->n_devs);
rc = i7core_get_onedevice(&pdev, i,
&dev_descr[i],
table->n_devs,
last_bus);
if (rc < 0) {
if (i == 0) {
i = table->n_devs;
@ -1927,21 +1947,26 @@ fail:
* 0 for FOUND a device
* < 0 for error code
*/
static int probed = 0;
static int __devinit i7core_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
int dev_idx = id->driver_data;
int rc;
struct i7core_dev *i7core_dev;
/* get the pci devices we want to reserve for our use */
mutex_lock(&i7core_edac_lock);
/*
* All memory controllers are allocated at the first pass.
*/
if (unlikely(dev_idx >= 1))
if (unlikely(probed >= 1)) {
mutex_unlock(&i7core_edac_lock);
return -EINVAL;
/* get the pci devices we want to reserve for our use */
mutex_lock(&i7core_edac_lock);
}
probed++;
rc = i7core_get_devices(pci_dev_table);
if (unlikely(rc < 0))
@ -2013,6 +2038,8 @@ static void __devexit i7core_remove(struct pci_dev *pdev)
i7core_dev->socket);
}
}
probed--;
mutex_unlock(&i7core_edac_lock);
}

Просмотреть файл

@ -9,19 +9,13 @@
*
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/i2c.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <linux/power_supply.h>
#include <linux/slab.h>
#include <linux/z2_battery.h>
#define Z2_DEFAULT_NAME "Z2"

Просмотреть файл

@ -128,13 +128,12 @@ xfs_nfs_get_inode(
return ERR_PTR(-ESTALE);
/*
* The XFS_IGET_BULKSTAT means that an invalid inode number is just
* fine and not an indication of a corrupted filesystem. Because
* clients can send any kind of invalid file handle, e.g. after
* a restore on the server we have to deal with this case gracefully.
* The XFS_IGET_UNTRUSTED means that an invalid inode number is just
* fine and not an indication of a corrupted filesystem as clients can
* send invalid file handles and we have to handle it gracefully..
*/
error = xfs_iget(mp, NULL, ino, XFS_IGET_BULKSTAT,
XFS_ILOCK_SHARED, &ip, 0);
error = xfs_iget(mp, NULL, ino, XFS_IGET_UNTRUSTED,
XFS_ILOCK_SHARED, &ip);
if (error) {
/*
* EINVAL means the inode cluster doesn't exist anymore.

Просмотреть файл

@ -679,10 +679,9 @@ xfs_ioc_bulkstat(
error = xfs_bulkstat_single(mp, &inlast,
bulkreq.ubuffer, &done);
else /* XFS_IOC_FSBULKSTAT */
error = xfs_bulkstat(mp, &inlast, &count,
(bulkstat_one_pf)xfs_bulkstat_one, NULL,
error = xfs_bulkstat(mp, &inlast, &count, xfs_bulkstat_one,
sizeof(xfs_bstat_t), bulkreq.ubuffer,
BULKSTAT_FG_QUICK, &done);
&done);
if (error)
return -error;

Просмотреть файл

@ -237,15 +237,12 @@ xfs_bulkstat_one_compat(
xfs_ino_t ino, /* inode number to get data for */
void __user *buffer, /* buffer to place output in */
int ubsize, /* size of buffer */
void *private_data, /* my private data */
xfs_daddr_t bno, /* starting bno of inode cluster */
int *ubused, /* bytes used by me */
void *dibuff, /* on-disk inode buffer */
int *stat) /* BULKSTAT_RV_... */
{
return xfs_bulkstat_one_int(mp, ino, buffer, ubsize,
xfs_bulkstat_one_fmt_compat, bno,
ubused, dibuff, stat);
xfs_bulkstat_one_fmt_compat,
ubused, stat);
}
/* copied from xfs_ioctl.c */
@ -298,13 +295,11 @@ xfs_compat_ioc_bulkstat(
int res;
error = xfs_bulkstat_one_compat(mp, inlast, bulkreq.ubuffer,
sizeof(compat_xfs_bstat_t),
NULL, 0, NULL, NULL, &res);
sizeof(compat_xfs_bstat_t), 0, &res);
} else if (cmd == XFS_IOC_FSBULKSTAT_32) {
error = xfs_bulkstat(mp, &inlast, &count,
xfs_bulkstat_one_compat, NULL,
sizeof(compat_xfs_bstat_t), bulkreq.ubuffer,
BULKSTAT_FG_QUICK, &done);
xfs_bulkstat_one_compat, sizeof(compat_xfs_bstat_t),
bulkreq.ubuffer, &done);
} else
error = XFS_ERROR(EINVAL);
if (error)

Просмотреть файл

@ -1632,10 +1632,7 @@ xfs_qm_dqusage_adjust(
xfs_ino_t ino, /* inode number to get data for */
void __user *buffer, /* not used */
int ubsize, /* not used */
void *private_data, /* not used */
xfs_daddr_t bno, /* starting block of inode cluster */
int *ubused, /* not used */
void *dip, /* on-disk inode pointer (not used) */
int *res) /* result code value */
{
xfs_inode_t *ip;
@ -1660,7 +1657,7 @@ xfs_qm_dqusage_adjust(
* the case in all other instances. It's OK that we do this because
* quotacheck is done only at mount time.
*/
if ((error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_EXCL, &ip, bno))) {
if ((error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_EXCL, &ip))) {
*res = BULKSTAT_RV_NOTHING;
return error;
}
@ -1796,12 +1793,13 @@ xfs_qm_quotacheck(
* Iterate thru all the inodes in the file system,
* adjusting the corresponding dquot counters in core.
*/
if ((error = xfs_bulkstat(mp, &lastino, &count,
xfs_qm_dqusage_adjust, NULL,
structsz, NULL, BULKSTAT_FG_IGET, &done)))
error = xfs_bulkstat(mp, &lastino, &count,
xfs_qm_dqusage_adjust,
structsz, NULL, &done);
if (error)
break;
} while (! done);
} while (!done);
/*
* We've made all the changes that we need to make incore.
@ -1889,14 +1887,14 @@ xfs_qm_init_quotainos(
mp->m_sb.sb_uquotino != NULLFSINO) {
ASSERT(mp->m_sb.sb_uquotino > 0);
if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
0, 0, &uip, 0)))
0, 0, &uip)))
return XFS_ERROR(error);
}
if (XFS_IS_OQUOTA_ON(mp) &&
mp->m_sb.sb_gquotino != NULLFSINO) {
ASSERT(mp->m_sb.sb_gquotino > 0);
if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
0, 0, &gip, 0))) {
0, 0, &gip))) {
if (uip)
IRELE(uip);
return XFS_ERROR(error);

Просмотреть файл

@ -262,7 +262,7 @@ xfs_qm_scall_trunc_qfiles(
}
if ((flags & XFS_DQ_USER) && mp->m_sb.sb_uquotino != NULLFSINO) {
error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 0, 0, &qip, 0);
error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 0, 0, &qip);
if (!error) {
error = xfs_truncate_file(mp, qip);
IRELE(qip);
@ -271,7 +271,7 @@ xfs_qm_scall_trunc_qfiles(
if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) &&
mp->m_sb.sb_gquotino != NULLFSINO) {
error2 = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0);
error2 = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip);
if (!error2) {
error2 = xfs_truncate_file(mp, qip);
IRELE(qip);
@ -417,12 +417,12 @@ xfs_qm_scall_getqstat(
}
if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
0, 0, &uip, 0) == 0)
0, 0, &uip) == 0)
tempuqip = B_TRUE;
}
if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) {
if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
0, 0, &gip, 0) == 0)
0, 0, &gip) == 0)
tempgqip = B_TRUE;
}
if (uip) {
@ -1109,10 +1109,7 @@ xfs_qm_internalqcheck_adjust(
xfs_ino_t ino, /* inode number to get data for */
void __user *buffer, /* not used */
int ubsize, /* not used */
void *private_data, /* not used */
xfs_daddr_t bno, /* starting block of inode cluster */
int *ubused, /* not used */
void *dip, /* not used */
int *res) /* bulkstat result code */
{
xfs_inode_t *ip;
@ -1134,7 +1131,7 @@ xfs_qm_internalqcheck_adjust(
ipreleased = B_FALSE;
again:
lock_flags = XFS_ILOCK_SHARED;
if ((error = xfs_iget(mp, NULL, ino, 0, lock_flags, &ip, bno))) {
if ((error = xfs_iget(mp, NULL, ino, 0, lock_flags, &ip))) {
*res = BULKSTAT_RV_NOTHING;
return (error);
}
@ -1205,15 +1202,15 @@ xfs_qm_internalqcheck(
* Iterate thru all the inodes in the file system,
* adjusting the corresponding dquot counters
*/
if ((error = xfs_bulkstat(mp, &lastino, &count,
xfs_qm_internalqcheck_adjust, NULL,
0, NULL, BULKSTAT_FG_IGET, &done))) {
break;
}
} while (! done);
error = xfs_bulkstat(mp, &lastino, &count,
xfs_qm_internalqcheck_adjust,
0, NULL, &done);
if (error) {
cmn_err(CE_DEBUG, "Bulkstat returned error 0x%x", error);
break;
}
} while (!done);
cmn_err(CE_DEBUG, "Checking results against system dquots");
for (i = 0; i < qmtest_hashmask; i++) {
xfs_dqtest_t *d, *n;

Просмотреть файл

@ -69,7 +69,9 @@ xfs_swapext(
goto out;
}
if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) {
if (!(file->f_mode & FMODE_WRITE) ||
!(file->f_mode & FMODE_READ) ||
(file->f_flags & O_APPEND)) {
error = XFS_ERROR(EBADF);
goto out_put_file;
}
@ -81,6 +83,7 @@ xfs_swapext(
}
if (!(tmp_file->f_mode & FMODE_WRITE) ||
!(tmp_file->f_mode & FMODE_READ) ||
(tmp_file->f_flags & O_APPEND)) {
error = XFS_ERROR(EBADF);
goto out_put_tmp_file;

Просмотреть файл

@ -1203,6 +1203,63 @@ error0:
return error;
}
STATIC int
xfs_imap_lookup(
struct xfs_mount *mp,
struct xfs_trans *tp,
xfs_agnumber_t agno,
xfs_agino_t agino,
xfs_agblock_t agbno,
xfs_agblock_t *chunk_agbno,
xfs_agblock_t *offset_agbno,
int flags)
{
struct xfs_inobt_rec_incore rec;
struct xfs_btree_cur *cur;
struct xfs_buf *agbp;
xfs_agino_t startino;
int error;
int i;
error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
if (error) {
xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: "
"xfs_ialloc_read_agi() returned "
"error %d, agno %d",
error, agno);
return error;
}
/*
* derive and lookup the exact inode record for the given agino. If the
* record cannot be found, then it's an invalid inode number and we
* should abort.
*/
cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);
startino = agino & ~(XFS_IALLOC_INODES(mp) - 1);
error = xfs_inobt_lookup(cur, startino, XFS_LOOKUP_EQ, &i);
if (!error) {
if (i)
error = xfs_inobt_get_rec(cur, &rec, &i);
if (!error && i == 0)
error = EINVAL;
}
xfs_trans_brelse(tp, agbp);
xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
if (error)
return error;
/* for untrusted inodes check it is allocated first */
if ((flags & XFS_IGET_UNTRUSTED) &&
(rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino)))
return EINVAL;
*chunk_agbno = XFS_AGINO_TO_AGBNO(mp, rec.ir_startino);
*offset_agbno = agbno - *chunk_agbno;
return 0;
}
/*
* Return the location of the inode in imap, for mapping it into a buffer.
*/
@ -1235,8 +1292,11 @@ xfs_imap(
if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
#ifdef DEBUG
/* no diagnostics for bulkstat, ino comes from userspace */
if (flags & XFS_IGET_BULKSTAT)
/*
* Don't output diagnostic information for untrusted inodes
* as they can be invalid without implying corruption.
*/
if (flags & XFS_IGET_UNTRUSTED)
return XFS_ERROR(EINVAL);
if (agno >= mp->m_sb.sb_agcount) {
xfs_fs_cmn_err(CE_ALERT, mp,
@ -1263,6 +1323,23 @@ xfs_imap(
return XFS_ERROR(EINVAL);
}
blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog;
/*
* For bulkstat and handle lookups, we have an untrusted inode number
* that we have to verify is valid. We cannot do this just by reading
* the inode buffer as it may have been unlinked and removed leaving
* inodes in stale state on disk. Hence we have to do a btree lookup
* in all cases where an untrusted inode number is passed.
*/
if (flags & XFS_IGET_UNTRUSTED) {
error = xfs_imap_lookup(mp, tp, agno, agino, agbno,
&chunk_agbno, &offset_agbno, flags);
if (error)
return error;
goto out_map;
}
/*
* If the inode cluster size is the same as the blocksize or
* smaller we get to the buffer by simple arithmetics.
@ -1277,24 +1354,6 @@ xfs_imap(
return 0;
}
blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog;
/*
* If we get a block number passed from bulkstat we can use it to
* find the buffer easily.
*/
if (imap->im_blkno) {
offset = XFS_INO_TO_OFFSET(mp, ino);
ASSERT(offset < mp->m_sb.sb_inopblock);
cluster_agbno = xfs_daddr_to_agbno(mp, imap->im_blkno);
offset += (agbno - cluster_agbno) * mp->m_sb.sb_inopblock;
imap->im_len = XFS_FSB_TO_BB(mp, blks_per_cluster);
imap->im_boffset = (ushort)(offset << mp->m_sb.sb_inodelog);
return 0;
}
/*
* If the inode chunks are aligned then use simple maths to
* find the location. Otherwise we have to do a btree
@ -1304,50 +1363,13 @@ xfs_imap(
offset_agbno = agbno & mp->m_inoalign_mask;
chunk_agbno = agbno - offset_agbno;
} else {
xfs_btree_cur_t *cur; /* inode btree cursor */
xfs_inobt_rec_incore_t chunk_rec;
xfs_buf_t *agbp; /* agi buffer */
int i; /* temp state */
error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
if (error) {
xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: "
"xfs_ialloc_read_agi() returned "
"error %d, agno %d",
error, agno);
return error;
}
cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);
error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i);
if (error) {
xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: "
"xfs_inobt_lookup() failed");
goto error0;
}
error = xfs_inobt_get_rec(cur, &chunk_rec, &i);
if (error) {
xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: "
"xfs_inobt_get_rec() failed");
goto error0;
}
if (i == 0) {
#ifdef DEBUG
xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: "
"xfs_inobt_get_rec() failed");
#endif /* DEBUG */
error = XFS_ERROR(EINVAL);
}
error0:
xfs_trans_brelse(tp, agbp);
xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
error = xfs_imap_lookup(mp, tp, agno, agino, agbno,
&chunk_agbno, &offset_agbno, flags);
if (error)
return error;
chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_rec.ir_startino);
offset_agbno = agbno - chunk_agbno;
}
out_map:
ASSERT(agbno >= chunk_agbno);
cluster_agbno = chunk_agbno +
((offset_agbno / blks_per_cluster) * blks_per_cluster);

Просмотреть файл

@ -259,7 +259,6 @@ xfs_iget_cache_miss(
xfs_trans_t *tp,
xfs_ino_t ino,
struct xfs_inode **ipp,
xfs_daddr_t bno,
int flags,
int lock_flags)
{
@ -272,7 +271,7 @@ xfs_iget_cache_miss(
if (!ip)
return ENOMEM;
error = xfs_iread(mp, tp, ip, bno, flags);
error = xfs_iread(mp, tp, ip, flags);
if (error)
goto out_destroy;
@ -358,8 +357,6 @@ out_destroy:
* within the file system for the inode being requested.
* lock_flags -- flags indicating how to lock the inode. See the comment
* for xfs_ilock() for a list of valid values.
* bno -- the block number starting the buffer containing the inode,
* if known (as by bulkstat), else 0.
*/
int
xfs_iget(
@ -368,8 +365,7 @@ xfs_iget(
xfs_ino_t ino,
uint flags,
uint lock_flags,
xfs_inode_t **ipp,
xfs_daddr_t bno)
xfs_inode_t **ipp)
{
xfs_inode_t *ip;
int error;
@ -397,7 +393,7 @@ again:
read_unlock(&pag->pag_ici_lock);
XFS_STATS_INC(xs_ig_missed);
error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip, bno,
error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip,
flags, lock_flags);
if (error)
goto out_error_or_again;

Просмотреть файл

@ -177,7 +177,7 @@ xfs_imap_to_bp(
if (unlikely(XFS_TEST_ERROR(!di_ok, mp,
XFS_ERRTAG_ITOBP_INOTOBP,
XFS_RANDOM_ITOBP_INOTOBP))) {
if (iget_flags & XFS_IGET_BULKSTAT) {
if (iget_flags & XFS_IGET_UNTRUSTED) {
xfs_trans_brelse(tp, bp);
return XFS_ERROR(EINVAL);
}
@ -787,7 +787,6 @@ xfs_iread(
xfs_mount_t *mp,
xfs_trans_t *tp,
xfs_inode_t *ip,
xfs_daddr_t bno,
uint iget_flags)
{
xfs_buf_t *bp;
@ -797,11 +796,9 @@ xfs_iread(
/*
* Fill in the location information in the in-core inode.
*/
ip->i_imap.im_blkno = bno;
error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags);
if (error)
return error;
ASSERT(bno == 0 || bno == ip->i_imap.im_blkno);
/*
* Get pointers to the on-disk inode and the buffer containing it.

Просмотреть файл

@ -442,7 +442,7 @@ static inline void xfs_ifunlock(xfs_inode_t *ip)
* xfs_iget.c prototypes.
*/
int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
uint, uint, xfs_inode_t **, xfs_daddr_t);
uint, uint, xfs_inode_t **);
void xfs_iput(xfs_inode_t *, uint);
void xfs_iput_new(xfs_inode_t *, uint);
void xfs_ilock(xfs_inode_t *, uint);
@ -500,7 +500,7 @@ do { \
* Flags for xfs_iget()
*/
#define XFS_IGET_CREATE 0x1
#define XFS_IGET_BULKSTAT 0x2
#define XFS_IGET_UNTRUSTED 0x2
int xfs_inotobp(struct xfs_mount *, struct xfs_trans *,
xfs_ino_t, struct xfs_dinode **,
@ -509,7 +509,7 @@ int xfs_itobp(struct xfs_mount *, struct xfs_trans *,
struct xfs_inode *, struct xfs_dinode **,
struct xfs_buf **, uint);
int xfs_iread(struct xfs_mount *, struct xfs_trans *,
struct xfs_inode *, xfs_daddr_t, uint);
struct xfs_inode *, uint);
void xfs_dinode_to_disk(struct xfs_dinode *,
struct xfs_icdinode *);
void xfs_idestroy_fork(struct xfs_inode *, int);

Просмотреть файл

@ -49,24 +49,40 @@ xfs_internal_inum(
(ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino)));
}
STATIC int
xfs_bulkstat_one_iget(
xfs_mount_t *mp, /* mount point for filesystem */
xfs_ino_t ino, /* inode number to get data for */
xfs_daddr_t bno, /* starting bno of inode cluster */
xfs_bstat_t *buf, /* return buffer */
/*
* Return stat information for one inode.
* Return 0 if ok, else errno.
*/
int
xfs_bulkstat_one_int(
struct xfs_mount *mp, /* mount point for filesystem */
xfs_ino_t ino, /* inode to get data for */
void __user *buffer, /* buffer to place output in */
int ubsize, /* size of buffer */
bulkstat_one_fmt_pf formatter, /* formatter, copy to user */
int *ubused, /* bytes used by me */
int *stat) /* BULKSTAT_RV_... */
{
xfs_icdinode_t *dic; /* dinode core info pointer */
xfs_inode_t *ip; /* incore inode pointer */
struct xfs_icdinode *dic; /* dinode core info pointer */
struct xfs_inode *ip; /* incore inode pointer */
struct inode *inode;
int error;
struct xfs_bstat *buf; /* return buffer */
int error = 0; /* error value */
*stat = BULKSTAT_RV_NOTHING;
if (!buffer || xfs_internal_inum(mp, ino))
return XFS_ERROR(EINVAL);
buf = kmem_alloc(sizeof(*buf), KM_SLEEP | KM_MAYFAIL);
if (!buf)
return XFS_ERROR(ENOMEM);
error = xfs_iget(mp, NULL, ino,
XFS_IGET_BULKSTAT, XFS_ILOCK_SHARED, &ip, bno);
XFS_IGET_UNTRUSTED, XFS_ILOCK_SHARED, &ip);
if (error) {
*stat = BULKSTAT_RV_NOTHING;
return error;
goto out_free;
}
ASSERT(ip != NULL);
@ -127,79 +143,18 @@ xfs_bulkstat_one_iget(
buf->bs_blocks = dic->di_nblocks + ip->i_delayed_blks;
break;
}
xfs_iput(ip, XFS_ILOCK_SHARED);
error = formatter(buffer, ubsize, ubused, buf);
if (!error)
*stat = BULKSTAT_RV_DIDONE;
out_free:
kmem_free(buf);
return error;
}
STATIC void
xfs_bulkstat_one_dinode(
xfs_mount_t *mp, /* mount point for filesystem */
xfs_ino_t ino, /* inode number to get data for */
xfs_dinode_t *dic, /* dinode inode pointer */
xfs_bstat_t *buf) /* return buffer */
{
/*
* The inode format changed when we moved the link count and
* made it 32 bits long. If this is an old format inode,
* convert it in memory to look like a new one. If it gets
* flushed to disk we will convert back before flushing or
* logging it. We zero out the new projid field and the old link
* count field. We'll handle clearing the pad field (the remains
* of the old uuid field) when we actually convert the inode to
* the new format. We don't change the version number so that we
* can distinguish this from a real new format inode.
*/
if (dic->di_version == 1) {
buf->bs_nlink = be16_to_cpu(dic->di_onlink);
buf->bs_projid = 0;
} else {
buf->bs_nlink = be32_to_cpu(dic->di_nlink);
buf->bs_projid = be16_to_cpu(dic->di_projid);
}
buf->bs_ino = ino;
buf->bs_mode = be16_to_cpu(dic->di_mode);
buf->bs_uid = be32_to_cpu(dic->di_uid);
buf->bs_gid = be32_to_cpu(dic->di_gid);
buf->bs_size = be64_to_cpu(dic->di_size);
buf->bs_atime.tv_sec = be32_to_cpu(dic->di_atime.t_sec);
buf->bs_atime.tv_nsec = be32_to_cpu(dic->di_atime.t_nsec);
buf->bs_mtime.tv_sec = be32_to_cpu(dic->di_mtime.t_sec);
buf->bs_mtime.tv_nsec = be32_to_cpu(dic->di_mtime.t_nsec);
buf->bs_ctime.tv_sec = be32_to_cpu(dic->di_ctime.t_sec);
buf->bs_ctime.tv_nsec = be32_to_cpu(dic->di_ctime.t_nsec);
buf->bs_xflags = xfs_dic2xflags(dic);
buf->bs_extsize = be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog;
buf->bs_extents = be32_to_cpu(dic->di_nextents);
buf->bs_gen = be32_to_cpu(dic->di_gen);
memset(buf->bs_pad, 0, sizeof(buf->bs_pad));
buf->bs_dmevmask = be32_to_cpu(dic->di_dmevmask);
buf->bs_dmstate = be16_to_cpu(dic->di_dmstate);
buf->bs_aextents = be16_to_cpu(dic->di_anextents);
buf->bs_forkoff = XFS_DFORK_BOFF(dic);
switch (dic->di_format) {
case XFS_DINODE_FMT_DEV:
buf->bs_rdev = xfs_dinode_get_rdev(dic);
buf->bs_blksize = BLKDEV_IOSIZE;
buf->bs_blocks = 0;
break;
case XFS_DINODE_FMT_LOCAL:
case XFS_DINODE_FMT_UUID:
buf->bs_rdev = 0;
buf->bs_blksize = mp->m_sb.sb_blocksize;
buf->bs_blocks = 0;
break;
case XFS_DINODE_FMT_EXTENTS:
case XFS_DINODE_FMT_BTREE:
buf->bs_rdev = 0;
buf->bs_blksize = mp->m_sb.sb_blocksize;
buf->bs_blocks = be64_to_cpu(dic->di_nblocks);
break;
}
}
/* Return 0 on success or positive error */
STATIC int
xfs_bulkstat_one_fmt(
@ -217,118 +172,17 @@ xfs_bulkstat_one_fmt(
return 0;
}
/*
* Return stat information for one inode.
* Return 0 if ok, else errno.
*/
int /* error status */
xfs_bulkstat_one_int(
xfs_mount_t *mp, /* mount point for filesystem */
xfs_ino_t ino, /* inode number to get data for */
void __user *buffer, /* buffer to place output in */
int ubsize, /* size of buffer */
bulkstat_one_fmt_pf formatter, /* formatter, copy to user */
xfs_daddr_t bno, /* starting bno of inode cluster */
int *ubused, /* bytes used by me */
void *dibuff, /* on-disk inode buffer */
int *stat) /* BULKSTAT_RV_... */
{
xfs_bstat_t *buf; /* return buffer */
int error = 0; /* error value */
xfs_dinode_t *dip; /* dinode inode pointer */
dip = (xfs_dinode_t *)dibuff;
*stat = BULKSTAT_RV_NOTHING;
if (!buffer || xfs_internal_inum(mp, ino))
return XFS_ERROR(EINVAL);
buf = kmem_alloc(sizeof(*buf), KM_SLEEP);
if (dip == NULL) {
/* We're not being passed a pointer to a dinode. This happens
* if BULKSTAT_FG_IGET is selected. Do the iget.
*/
error = xfs_bulkstat_one_iget(mp, ino, bno, buf, stat);
if (error)
goto out_free;
} else {
xfs_bulkstat_one_dinode(mp, ino, dip, buf);
}
error = formatter(buffer, ubsize, ubused, buf);
if (error)
goto out_free;
*stat = BULKSTAT_RV_DIDONE;
out_free:
kmem_free(buf);
return error;
}
int
xfs_bulkstat_one(
xfs_mount_t *mp, /* mount point for filesystem */
xfs_ino_t ino, /* inode number to get data for */
void __user *buffer, /* buffer to place output in */
int ubsize, /* size of buffer */
void *private_data, /* my private data */
xfs_daddr_t bno, /* starting bno of inode cluster */
int *ubused, /* bytes used by me */
void *dibuff, /* on-disk inode buffer */
int *stat) /* BULKSTAT_RV_... */
{
return xfs_bulkstat_one_int(mp, ino, buffer, ubsize,
xfs_bulkstat_one_fmt, bno,
ubused, dibuff, stat);
}
/*
* Test to see whether we can use the ondisk inode directly, based
* on the given bulkstat flags, filling in dipp accordingly.
* Returns zero if the inode is dodgey.
*/
STATIC int
xfs_bulkstat_use_dinode(
xfs_mount_t *mp,
int flags,
xfs_buf_t *bp,
int clustidx,
xfs_dinode_t **dipp)
{
xfs_dinode_t *dip;
unsigned int aformat;
*dipp = NULL;
if (!bp || (flags & BULKSTAT_FG_IGET))
return 1;
dip = (xfs_dinode_t *)
xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog);
/*
* Check the buffer containing the on-disk inode for di_mode == 0.
* This is to prevent xfs_bulkstat from picking up just reclaimed
* inodes that have their in-core state initialized but not flushed
* to disk yet. This is a temporary hack that would require a proper
* fix in the future.
*/
if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC ||
!XFS_DINODE_GOOD_VERSION(dip->di_version) ||
!dip->di_mode)
return 0;
if (flags & BULKSTAT_FG_QUICK) {
*dipp = dip;
return 1;
}
/* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */
aformat = dip->di_aformat;
if ((XFS_DFORK_Q(dip) == 0) ||
(aformat == XFS_DINODE_FMT_LOCAL) ||
(aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_anextents)) {
*dipp = dip;
return 1;
}
return 1;
xfs_bulkstat_one_fmt, ubused, stat);
}
#define XFS_BULKSTAT_UBLEFT(ubleft) ((ubleft) >= statstruct_size)
@ -342,10 +196,8 @@ xfs_bulkstat(
xfs_ino_t *lastinop, /* last inode returned */
int *ubcountp, /* size of buffer/count returned */
bulkstat_one_pf formatter, /* func that'd fill a single buf */
void *private_data,/* private data for formatter */
size_t statstruct_size, /* sizeof struct filling */
char __user *ubuffer, /* buffer with inode stats */
int flags, /* defined in xfs_itable.h */
int *done) /* 1 if there are more stats to get */
{
xfs_agblock_t agbno=0;/* allocation group block number */
@ -380,14 +232,12 @@ xfs_bulkstat(
int ubelem; /* spaces used in user's buffer */
int ubused; /* bytes used by formatter */
xfs_buf_t *bp; /* ptr to on-disk inode cluster buf */
xfs_dinode_t *dip; /* ptr into bp for specific inode */
/*
* Get the last inode value, see if there's nothing to do.
*/
ino = (xfs_ino_t)*lastinop;
lastino = ino;
dip = NULL;
agno = XFS_INO_TO_AGNO(mp, ino);
agino = XFS_INO_TO_AGINO(mp, ino);
if (agno >= mp->m_sb.sb_agcount ||
@ -612,37 +462,6 @@ xfs_bulkstat(
irbp->ir_startino) +
((chunkidx & nimask) >>
mp->m_sb.sb_inopblog);
if (flags & (BULKSTAT_FG_QUICK |
BULKSTAT_FG_INLINE)) {
int offset;
ino = XFS_AGINO_TO_INO(mp, agno,
agino);
bno = XFS_AGB_TO_DADDR(mp, agno,
agbno);
/*
* Get the inode cluster buffer
*/
if (bp)
xfs_buf_relse(bp);
error = xfs_inotobp(mp, NULL, ino, &dip,
&bp, &offset,
XFS_IGET_BULKSTAT);
if (!error)
clustidx = offset / mp->m_sb.sb_inodesize;
if (XFS_TEST_ERROR(error != 0,
mp, XFS_ERRTAG_BULKSTAT_READ_CHUNK,
XFS_RANDOM_BULKSTAT_READ_CHUNK)) {
bp = NULL;
ubleft = 0;
rval = error;
break;
}
}
}
ino = XFS_AGINO_TO_INO(mp, agno, agino);
bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
@ -658,35 +477,13 @@ xfs_bulkstat(
* when the chunk is used up.
*/
irbp->ir_freecount++;
if (!xfs_bulkstat_use_dinode(mp, flags, bp,
clustidx, &dip)) {
lastino = ino;
continue;
}
/*
* If we need to do an iget, cannot hold bp.
* Drop it, until starting the next cluster.
*/
if ((flags & BULKSTAT_FG_INLINE) && !dip) {
if (bp)
xfs_buf_relse(bp);
bp = NULL;
}
/*
* Get the inode and fill in a single buffer.
* BULKSTAT_FG_QUICK uses dip to fill it in.
* BULKSTAT_FG_IGET uses igets.
* BULKSTAT_FG_INLINE uses dip if we have an
* inline attr fork, else igets.
* See: xfs_bulkstat_one & xfs_dm_bulkstat_one.
* This is also used to count inodes/blks, etc
* in xfs_qm_quotacheck.
*/
ubused = statstruct_size;
error = formatter(mp, ino, ubufp,
ubleft, private_data,
bno, &ubused, dip, &fmterror);
error = formatter(mp, ino, ubufp, ubleft,
&ubused, &fmterror);
if (fmterror == BULKSTAT_RV_NOTHING) {
if (error && error != ENOENT &&
error != EINVAL) {
@ -778,8 +575,7 @@ xfs_bulkstat_single(
*/
ino = (xfs_ino_t)*lastinop;
error = xfs_bulkstat_one(mp, ino, buffer, sizeof(xfs_bstat_t),
NULL, 0, NULL, NULL, &res);
error = xfs_bulkstat_one(mp, ino, buffer, sizeof(xfs_bstat_t), 0, &res);
if (error) {
/*
* Special case way failed, do it the "long" way
@ -788,8 +584,7 @@ xfs_bulkstat_single(
(*lastinop)--;
count = 1;
if (xfs_bulkstat(mp, lastinop, &count, xfs_bulkstat_one,
NULL, sizeof(xfs_bstat_t), buffer,
BULKSTAT_FG_IGET, done))
sizeof(xfs_bstat_t), buffer, done))
return error;
if (count == 0 || (xfs_ino_t)*lastinop != ino)
return error == EFSCORRUPTED ?

Просмотреть файл

@ -27,10 +27,7 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
xfs_ino_t ino,
void __user *buffer,
int ubsize,
void *private_data,
xfs_daddr_t bno,
int *ubused,
void *dip,
int *stat);
/*
@ -40,13 +37,6 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
#define BULKSTAT_RV_DIDONE 1
#define BULKSTAT_RV_GIVEUP 2
/*
* Values for bulkstat flag argument.
*/
#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */
#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */
#define BULKSTAT_FG_INLINE 0x4 /* No iget if inline attrs */
/*
* Return stat information in bulk (by-inode) for the filesystem.
*/
@ -56,10 +46,8 @@ xfs_bulkstat(
xfs_ino_t *lastino, /* last inode returned */
int *count, /* size of buffer/count returned */
bulkstat_one_pf formatter, /* func that'd fill a single buf */
void *private_data, /* private data for formatter */
size_t statstruct_size,/* sizeof struct that we're filling */
char __user *ubuffer,/* buffer with inode stats */
int flags, /* flag to control access method */
int *done); /* 1 if there are more stats to get */
int
@ -82,9 +70,7 @@ xfs_bulkstat_one_int(
void __user *buffer,
int ubsize,
bulkstat_one_fmt_pf formatter,
xfs_daddr_t bno,
int *ubused,
void *dibuff,
int *stat);
int
@ -93,10 +79,7 @@ xfs_bulkstat_one(
xfs_ino_t ino,
void __user *buffer,
int ubsize,
void *private_data,
xfs_daddr_t bno,
int *ubused,
void *dibuff,
int *stat);
typedef int (*inumbers_fmt_pf)(

Просмотреть файл

@ -3198,7 +3198,7 @@ xlog_recover_process_one_iunlink(
int error;
ino = XFS_AGINO_TO_INO(mp, agno, agino);
error = xfs_iget(mp, NULL, ino, 0, 0, &ip, 0);
error = xfs_iget(mp, NULL, ino, 0, 0, &ip);
if (error)
goto fail;

Просмотреть файл

@ -1300,7 +1300,7 @@ xfs_mountfs(
* Get and sanity-check the root inode.
* Save the pointer to it in the mount structure.
*/
error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0);
error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip);
if (error) {
cmn_err(CE_WARN, "XFS: failed to read root inode");
goto out_log_dealloc;

Просмотреть файл

@ -2277,12 +2277,12 @@ xfs_rtmount_inodes(
sbp = &mp->m_sb;
if (sbp->sb_rbmino == NULLFSINO)
return 0;
error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip, 0);
error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip);
if (error)
return error;
ASSERT(mp->m_rbmip != NULL);
ASSERT(sbp->sb_rsumino != NULLFSINO);
error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip, 0);
error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip);
if (error) {
IRELE(mp->m_rbmip);
return error;

Просмотреть файл

@ -62,7 +62,7 @@ xfs_trans_iget(
{
int error;
error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp, 0);
error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp);
if (!error && tp)
xfs_trans_ijoin(tp, *ipp, lock_flags);
return error;

Просмотреть файл

@ -1269,7 +1269,7 @@ xfs_lookup(
if (error)
goto out;
error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp, 0);
error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp);
if (error)
goto out_free_name;

Просмотреть файл

@ -40,7 +40,7 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
const char *modname);
#if defined(CONFIG_DYNAMIC_DEBUG)
extern int ddebug_remove_module(char *mod_name);
extern int ddebug_remove_module(const char *mod_name);
#define __dynamic_dbg_enabled(dd) ({ \
int __ret = 0; \
@ -73,7 +73,7 @@ extern int ddebug_remove_module(char *mod_name);
#else
static inline int ddebug_remove_module(char *mod)
static inline int ddebug_remove_module(const char *mod)
{
return 0;
}

Просмотреть файл

@ -2062,6 +2062,12 @@ static void dynamic_debug_setup(struct _ddebug *debug, unsigned int num)
#endif
}
static void dynamic_debug_remove(struct _ddebug *debug)
{
if (debug)
ddebug_remove_module(debug->modname);
}
static void *module_alloc_update_bounds(unsigned long size)
{
void *ret = module_alloc(size);
@ -2124,6 +2130,8 @@ static noinline struct module *load_module(void __user *umod,
void *ptr = NULL; /* Stops spurious gcc warning */
unsigned long symoffs, stroffs, *strmap;
void __percpu *percpu;
struct _ddebug *debug = NULL;
unsigned int num_debug = 0;
mm_segment_t old_fs;
@ -2476,15 +2484,9 @@ static noinline struct module *load_module(void __user *umod,
kfree(strmap);
strmap = NULL;
if (!mod->taints) {
struct _ddebug *debug;
unsigned int num_debug;
if (!mod->taints)
debug = section_objs(hdr, sechdrs, secstrings, "__verbose",
sizeof(*debug), &num_debug);
if (debug)
dynamic_debug_setup(debug, num_debug);
}
err = module_finalize(hdr, sechdrs, mod);
if (err < 0)
@ -2526,10 +2528,13 @@ static noinline struct module *load_module(void __user *umod,
goto unlock;
}
if (debug)
dynamic_debug_setup(debug, num_debug);
/* Find duplicate symbols */
err = verify_export_symbols(mod);
if (err < 0)
goto unlock;
goto ddebug;
list_add_rcu(&mod->list, &modules);
mutex_unlock(&module_mutex);
@ -2557,6 +2562,8 @@ static noinline struct module *load_module(void __user *umod,
mutex_lock(&module_mutex);
/* Unlink carefully: kallsyms could be walking list. */
list_del_rcu(&mod->list);
ddebug:
dynamic_debug_remove(debug);
unlock:
mutex_unlock(&module_mutex);
synchronize_sched();

Просмотреть файл

@ -692,7 +692,7 @@ static void ddebug_table_free(struct ddebug_table *dt)
* Called in response to a module being unloaded. Removes
* any ddebug_table's which point at the module.
*/
int ddebug_remove_module(char *mod_name)
int ddebug_remove_module(const char *mod_name)
{
struct ddebug_table *dt, *nextdt;
int ret = -ENOENT;

Просмотреть файл

@ -44,7 +44,7 @@ rpm-pkg rpm: $(objtree)/kernel.spec FORCE
fi
$(MAKE) clean
$(PREV) ln -sf $(srctree) $(KERNELPATH)
$(CONFIG_SHELL) $(srctree)/scripts/setlocalversion > $(objtree)/.scmversion
$(CONFIG_SHELL) $(srctree)/scripts/setlocalversion --scm-only > $(objtree)/.scmversion
$(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/.
$(PREV) rm $(KERNELPATH)
rm -f $(objtree)/.scmversion

Просмотреть файл

@ -10,21 +10,52 @@
#
usage() {
echo "Usage: $0 [srctree]" >&2
echo "Usage: $0 [--scm-only] [srctree]" >&2
exit 1
}
cd "${1:-.}" || usage
scm_only=false
srctree=.
if test "$1" = "--scm-only"; then
scm_only=true
shift
fi
if test $# -gt 0; then
srctree=$1
shift
fi
if test $# -gt 0 -o ! -d "$srctree"; then
usage
fi
# Check for git and a git repo.
if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
scm_version()
{
local short=false
# If we are at a tagged commit (like "v2.6.30-rc6"), we ignore it,
# because this version is defined in the top level Makefile.
cd "$srctree"
if test -e .scmversion; then
cat "$_"
return
fi
if test "$1" = "--short"; then
short=true
fi
# Check for git and a git repo.
if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
# If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
# it, because this version is defined in the top level Makefile.
if [ -z "`git describe --exact-match 2>/dev/null`" ]; then
# If we are past a tagged commit (like "v2.6.30-rc5-302-g72357d5"),
# we pretty print it.
# If only the short version is requested, don't bother
# running further git commands
if $short; then
echo "+"
return
fi
# If we are past a tagged commit (like
# "v2.6.30-rc5-302-g72357d5"), we pretty print it.
if atag="`git describe 2>/dev/null`"; then
echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
@ -49,11 +80,11 @@ if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
fi
# All done with git
exit
fi
return
fi
# Check for mercurial and a mercurial repo.
if hgid=`hg id 2>/dev/null`; then
# Check for mercurial and a mercurial repo.
if hgid=`hg id 2>/dev/null`; then
tag=`printf '%s' "$hgid" | cut -d' ' -f2`
# Do we have an untagged version?
@ -69,14 +100,68 @@ if hgid=`hg id 2>/dev/null`; then
esac
# All done with mercurial
exit
fi
return
fi
# Check for svn and a svn repo.
if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then
# Check for svn and a svn repo.
if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then
rev=`echo $rev | awk '{print $NF}'`
printf -- '-svn%s' "$rev"
# All done with svn
return
fi
}
collect_files()
{
local file res
for file; do
case "$file" in
*\~*)
continue
;;
esac
if test -e "$file"; then
res="$res$(cat "$file")"
fi
done
echo "$res"
}
if $scm_only; then
scm_version
exit
fi
if test -e include/config/auto.conf; then
source "$_"
else
echo "Error: kernelrelease not valid - run 'make prepare' to update it"
exit 1
fi
# localversion* files in the build and source directory
res="$(collect_files localversion*)"
if test ! "$srctree" -ef .; then
res="$res$(collect_files "$srctree"/localversion*)"
fi
# CONFIG_LOCALVERSION and LOCALVERSION (if set)
res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"
# scm version string if not at a tagged commit
if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
# full scm version string
res="$res$(scm_version)"
else
# apped a plus sign if the repository is not in a clean tagged
# state and LOCALVERSION= is not specified
if test "${LOCALVERSION+set}" != "set"; then
scm=$(scm_version --short)
res="$res${scm:++}"
fi
fi
echo "$res"

Просмотреть файл

@ -7,6 +7,15 @@
#include "util.h"
#include "debug.h"
/* Skip "." and ".." directories */
static int filter(const struct dirent *dir)
{
if (dir->d_name[0] == '.')
return 0;
else
return 1;
}
int find_all_tid(int pid, pid_t ** all_tid)
{
char name[256];
@ -16,7 +25,7 @@ int find_all_tid(int pid, pid_t ** all_tid)
int i;
sprintf(name, "/proc/%d/task", pid);
items = scandir(name, &namelist, NULL, NULL);
items = scandir(name, &namelist, filter, NULL);
if (items <= 0)
return -ENOENT;
*all_tid = malloc(sizeof(pid_t) * items);