2.6.32.17-rc1 -stable review
Subsystems (67)
cover 2.6.32.17-rc1 -stable review
This is the start of the stable review cycle for the 2.6.32.17 release. There are 165 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let us know. If anyone is a maintainer of the proper subsystem, and wants to add a Signed-off-by: line to the patch, please respond with it.
Responses should be made by August 1, 2010, 18:00:00 UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.32.17-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
Makefile | 2 +- arch/arm/kernel/kprobes-decode.c | 5 +- arch/arm/mach-omap2/board-rx51-peripherals.c | 17 +- arch/arm/mach-realview/Kconfig | 2 + arch/arm/mach-realview/include/mach/barriers.h | 8 + arch/ia64/mm/tlb.c | 2 +- arch/mips/include/asm/mipsregs.h | 9 +- arch/mips/math-emu/cp1emu.c | 15 +- arch/sparc/include/asm/stat.h | 4 +- arch/x86/include/asm/msr-index.h | 1 + arch/x86/include/asm/suspend_32.h | 2 + arch/x86/include/asm/suspend_64.h | 2 + arch/x86/include/asm/system.h | 2 +- arch/x86/kernel/acpi/cstate.c | 9 + arch/x86/kernel/acpi/sleep.c | 2 - arch/x86/kernel/apic/apic.c | 2 +- arch/x86/kernel/hpet.c | 2 +- arch/x86/kernel/pci-calgary_64.c | 17 +- arch/x86/kvm/mmu.c | 5 + arch/x86/kvm/svm.c | 99 ++++++- arch/x86/power/cpu.c | 4 + drivers/acpi/processor_idle.c | 2 +- drivers/acpi/sleep.c | 157 +---------- drivers/base/firmware_class.c | 26 ++- drivers/char/agp/amd64-agp.c | 27 +- drivers/char/tpm/tpm.h | 1 + drivers/char/tpm/tpm_tis.c | 9 +- drivers/cpufreq/cpufreq.c | 11 +- drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_gem.c | 10 + drivers/gpu/drm/i915/i915_reg.h | 64 ++++ drivers/gpu/drm/i915/intel_display.c | 4 +- drivers/gpu/drm/radeon/r200.c | 2 + drivers/gpu/drm/radeon/radeon_atombios.c | 9 + drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 1 + drivers/hwmon/coretemp.c | 32 ++- drivers/hwmon/it87.c | 22 ++ drivers/hwmon/k8temp.c | 12 +- drivers/ide/cmd640.c | 6 +- drivers/ide/ide-taskfile.c | 6 +- drivers/infiniband/ulp/ipoib/ipoib_main.c | 4 +- drivers/input/keyboard/twl4030_keypad.c | 17 +- drivers/input/serio/i8042-x86ia64io.h | 7 + drivers/media/dvb/dvb-core/dvb_net.c | 12 +- drivers/media/dvb/ttpci/Kconfig | 5 +- drivers/media/video/cx23885/cx23885-i2c.c | 12 +- drivers/media/video/cx88/cx88-i2c.c | 16 +- drivers/media/video/uvc/uvc_driver.c | 30 ++- drivers/media/video/uvc/uvcvideo.h | 7 +- drivers/mmc/host/sdhci-s3c.c | 20 ++ drivers/net/cpmac.c | 3 +- drivers/net/cxgb3/ael1002.c | 2 +- drivers/net/dm9000.c | 38 ++- drivers/net/forcedeth.c | 2 +- drivers/net/igb/e1000_82575.c | 13 +- drivers/net/igb/e1000_hw.h | 2 + drivers/net/igb/e1000_mac.c | 17 +- drivers/net/sky2.c | 19 +- drivers/net/wireless/ath/ath5k/attach.c | 1 + drivers/net/wireless/ath/ath5k/base.c | 7 +- drivers/net/wireless/ath/ath9k/initvals.h | 8 +- drivers/net/wireless/ath/ath9k/main.c | 7 +- drivers/net/wireless/hostap/hostap_cs.c | 10 + drivers/net/wireless/hostap/hostap_hw.c | 13 + drivers/net/wireless/hostap/hostap_wlan.h | 2 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 1 + drivers/net/wireless/iwlwifi/iwl-tx.c | 5 + drivers/net/wireless/libertas/if_sdio.c | 22 ++ drivers/net/wireless/p54/p54pci.c | 2 + drivers/pci/pci.c | 1 + drivers/platform/x86/eeepc-laptop.c | 18 ++ drivers/rtc/rtc-ds1307.c | 4 +- drivers/scsi/aacraid/commctrl.c | 4 +- drivers/serial/cpm_uart/cpm_uart_core.c | 143 +++++---- drivers/ssb/driver_chipcommon.c | 3 + drivers/ssb/driver_chipcommon_pmu.c | 17 +- drivers/ssb/pci.c | 46 +++- drivers/ssb/sprom.c | 15 + drivers/staging/rtl8192su/r8192U_core.c | 4 + drivers/usb/core/driver.c | 15 +- drivers/usb/core/quirks.c | 7 + drivers/usb/gadget/u_serial.c | 16 +- drivers/usb/misc/sisusbvga/sisusb.c | 5 +- drivers/usb/serial/ftdi_sio.c | 9 + drivers/usb/serial/ftdi_sio_ids.h | 15 + drivers/usb/serial/option.c | 4 + drivers/usb/serial/sierra.c | 1 + drivers/virtio/virtio_pci.c | 3 + fs/btrfs/ioctl.c | 4 +- fs/cifs/cifsfs.c | 6 +- fs/cifs/dns_resolve.c | 69 +++++ fs/cifs/dns_resolve.h | 4 +- fs/cifs/inode.c | 4 + fs/cifs/sess.c | 10 +- fs/ecryptfs/messaging.c | 17 +- fs/ext4/dir.c | 12 +- fs/ext4/ext4.h | 157 +++++++++-- fs/ext4/ext4_extents.h | 3 +- fs/ext4/ext4_jbd2.c | 2 +- fs/ext4/ext4_jbd2.h | 6 +- fs/ext4/extents.c | 251 ++++++++++++---- fs/ext4/file.c | 6 +- fs/ext4/fsync.c | 49 +++- fs/ext4/ialloc.c | 98 +++---- fs/ext4/inode.c | 360 ++++++++++++++--------- fs/ext4/ioctl.c | 37 +++- fs/ext4/mballoc.c | 138 ++++++--- fs/ext4/migrate.c | 37 ++-- fs/ext4/move_extent.c | 28 +- fs/ext4/namei.c | 24 +- fs/ext4/resize.c | 3 +- fs/ext4/super.c | 67 ++--- fs/ext4/xattr.c | 28 +- fs/gfs2/acl.c | 170 +++++++---- fs/gfs2/acl.h | 24 +-- fs/gfs2/xattr.c | 18 -- fs/jbd2/checkpoint.c | 15 + fs/jbd2/commit.c | 19 +- fs/nfs/nfs4xdr.c | 4 +- fs/nfs/super.c | 22 ++- include/acpi/processor.h | 3 +- include/linux/acpi.h | 1 - include/linux/ethtool.h | 2 + include/linux/fb.h | 4 +- include/linux/firmware.h | 1 + include/linux/ieee80211.h | 2 + include/linux/jbd2.h | 1 + include/linux/mmc/sdio.h | 2 + include/linux/ssb/ssb.h | 1 + include/linux/ssb/ssb_driver_chipcommon.h | 2 + include/linux/ssb/ssb_regs.h | 3 +- include/math-emu/op-common.h | 2 +- kernel/futex.c | 17 +- kernel/irq/manage.c | 3 + kernel/module.c | 4 +- kernel/sched.c | 9 +- net/core/ethtool.c | 43 ++- net/core/neighbour.c | 5 +- net/ipv4/tcp_output.c | 3 + net/ipv6/netfilter/ip6t_REJECT.c | 6 +- net/mac80211/mlme.c | 17 +- net/mac80211/rx.c | 5 + net/mac80211/scan.c | 21 +- net/netfilter/ipvs/ip_vs_conn.c | 4 + net/sunrpc/xprtsock.c | 38 ++- scripts/mod/modpost.c | 2 +- sound/pci/echoaudio/echoaudio.c | 4 +- sound/pci/hda/patch_realtek.c | 1 + sound/soc/codecs/wm8776.c | 1 - tools/perf/util/callchain.h | 3 + 150 files changed, 2122 insertions(+), 1027 deletions(-)
PATCH 1/165 virtio-pci: disable msi at startup
2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Michael S. Tsirkin <[email protected]>
commit b03214d559471359e2a85ae256686381d0672f29 upstream.
virtio-pci resets the device at startup by writing to the status register, but this does not clear the pci config space, specifically msi enable status which affects register layout.
This breaks things like kdump when they try to use e.g. virtio-blk.
Fix by forcing msi off at startup. Since pci.c already has
a routine to do this, we export and use it instead of duplicating code.
--- drivers/pci/pci.c | 1 + drivers/virtio/virtio_pci.c | 3 +++ 2 files changed, 4 insertions(+)
drivers/pci/pci.c +1 -0
@@ -2046,6 +2046,7 @@ void pci_msi_off(struct pci_dev *dev)pci_write_config_word (dev, pos +PCI_MSIX_FLAGS , control); } } +EXPORT_SYMBOL_GPL (pci_msi_off);#ifndef HAVE_ARCH_PCI_SET_DMA_MASK /*
drivers/virtio/virtio_pci.c +3 -0
@@ -635,6 +635,9 @@ static int __devinit virtio_pci_probe(stINIT_LIST_HEAD (&vp_dev->virtqueues);spin_lock_init (&vp_dev->lock); +/* Disable MSI/MSIX to bring device to a known good state. */ +pci_msi_off (pci_dev); +/* enable the device */ err =pci_enable_device (pci_dev);if (err)
PATCH 2/165 ssb: Handle Netbook devices where the SPROM address is changed
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Christoph Fritz <[email protected]>
For some Netbook computers with Broadcom BCM4312 wireless interfaces, the SPROM has been moved to a new location. When the ssb driver tries to read the old location, the systems hangs when trying to read a non-existent location. Such freezes are particularly bad as they do not log the failure.
This patch is modified from commit da1fdb02d9200ff28b6f3a380d21930335fe5429 with some pieces from other mainline changes so that it can be applied to stable 2.6.34.Y.
--- drivers/ssb/driver_chipcommon.c | 3 + drivers/ssb/driver_chipcommon_pmu.c | 17 ++++------- drivers/ssb/pci.c | 46 ++++++++++++++++++++++++++---- drivers/ssb/sprom.c | 15 +++++++++ include/linux/ssb/ssb.h | 1 include/linux/ssb/ssb_driver_chipcommon.h | 2 + include/linux/ssb/ssb_regs.h | 3 + 7 files changed, 70 insertions(+), 17 deletions(-)
drivers/ssb/driver_chipcommon.c +3 -0
@@ -233,6 +233,9 @@ void ssb_chipcommon_init(struct ssb_chip {if (!cc->dev)return ;/* We don't have a ChipCommon */ +if (cc->dev->id.revision >=11 ) + cc->status =chipco_read32 (cc,SSB_CHIPCO_CHIPSTAT ); + ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);ssb_pmu_init (cc);chipco_powercontrol_init (cc);ssb_chipco_set_clockmode (cc,SSB_CLKMODE_FAST );
drivers/ssb/driver_chipcommon_pmu.c +7 -10
@@ -495,9 +495,9 @@ static void ssb_pmu_resources_init(strucchipco_write32 (cc,SSB_CHIPCO_PMU_MAXRES_MSK , max_msk); } +/* http://bcm-v4.sipsolutions.net/802.11/SSB/PmuInit */ void ssb_pmu_init (struct ssb_chipcommon *cc) { -struct ssb_bus *bus = cc->dev->bus;u32 pmucap;if (!(cc->capabilities &SSB_CHIPCO_CAP_PMU ))
@@ -509,15 +509,12 @@ void ssb_pmu_init(struct ssb_chipcommon ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev, pmucap); -if (cc->pmu.rev >=1 ) { -if ((bus->chip_id ==0x4325 ) && (bus->chip_rev <2 )) { -chipco_mask32 (cc,SSB_CHIPCO_PMU_CTL , - ~SSB_CHIPCO_PMU_CTL_NOILPONW ); - }else { -chipco_set32 (cc,SSB_CHIPCO_PMU_CTL , -SSB_CHIPCO_PMU_CTL_NOILPONW ); - } - } +if (cc->pmu.rev ==1 ) +chipco_mask32 (cc,SSB_CHIPCO_PMU_CTL , + ~SSB_CHIPCO_PMU_CTL_NOILPONW ); +else +chipco_set32 (cc,SSB_CHIPCO_PMU_CTL , +SSB_CHIPCO_PMU_CTL_NOILPONW );ssb_pmu_pll_init (cc);ssb_pmu_resources_init (cc); }
drivers/ssb/pci.c +40 -6
89 lines not on this page · raw message
drivers/ssb/sprom.c +15 -0
@@ -179,3 +179,18 @@ const struct ssb_sprom *ssb_get_fallback {return fallback_sprom; } + +/* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ +bool ssb_is_sprom_available (struct ssb_bus *bus) +{ +/* status register only exists on chipcomon rev >= 11 and we need check +for >= 31 only */ +/* this routine differs from specs as we do not access SPROM directly +on PCMCIA */ +if (bus->bustype ==SSB_BUSTYPE_PCI && + bus->chipco.dev &&/* can be unavailible! */ + bus->chipco.dev->id.revision >=31 ) +return bus->chipco.capabilities &SSB_CHIPCO_CAP_SPROM ; + +return true; +}
include/linux/ssb/ssb.h +1 -0
@@ -302,6 +302,7 @@ struct ssb_bus {u16 chip_id;u16 chip_rev;u16 sprom_size;/* number of words in sprom */ +u16 sprom_offset;u8 chip_package;/* List of devices (cores) on the backplane. */
include/linux/ssb/ssb_driver_chipcommon.h +2 -0
@@ -46,6 +46,7 @@#define SSB_PLLTYPE_7 0x00038000/* 25Mhz, 4 dividers */ #define SSB_CHIPCO_CAP_PCTL 0x00040000/* Power Control */ #define SSB_CHIPCO_CAP_OTPS 0x00380000/* OTP size */ +#define SSB_CHIPCO_CAP_SPROM 0x40000000/* SPROM present */ #define SSB_CHIPCO_CAP_OTPS_SHIFT 19#define SSB_CHIPCO_CAP_OTPS_BASE 5#define SSB_CHIPCO_CAP_JTAGM 0x00400000/* JTAG master present */
@@ -564,6 +565,7 @@ struct ssb_chipcommon_pmu {struct ssb_chipcommon {struct ssb_device *dev;u32 capabilities; +u32 status;/* Fast Powerup Delay constant */ u16 fast_pwrup_delay;struct ssb_chipcommon_pmu pmu;
include/linux/ssb/ssb_regs.h +2 -1
@@ -170,7 +170,8 @@#define SSB_SPROMSIZE_WORDS_R4 220#define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16))#define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16)) -#define SSB_SPROM_BASE 0x1000 +#define SSB_SPROM_BASE1 0x1000 +#define SSB_SPROM_BASE31 0x0800#define SSB_SPROM_REVISION 0x107E#define SSB_SPROM_REVISION_REV 0x00FF/* SPROM Revision number */ #define SSB_SPROM_REVISION_CRC 0xFF00/* SPROM CRC8 value */
PATCH 3/165 hwmon: (k8temp) Bypass core swapping on single-core processors
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jean Delvare <[email protected]>
commit cd4de21f7e65a8cd04860f5661b3c18648ee52a1 upstream.
Commit a2e066bba2aad6583e3ff648bf28339d6c9f0898 introduced core swapping for CPU models 64 and later. I recently had a report about a Sempron 3200+, model 95, for which this patch broke temperature reading. It happens that this is a single-core processor, so the effect of the swapping was to read a temperature value for a core that didn't exist, leading to an incorrect value (-49 degrees C.)
Disabling core swapping on singe-core processors should fix this.
Additional comment from Andreas:
The BKDG says
Thermal Sensor Core Select (ThermSenseCoreSel)-Bit 2. This bit selects the CPU whose temperature is reported in the CurTemp field. This bit only applies to dual core processors. For single core processors CPU0 Thermal Sensor is always selected.
k8temp_probe() correctly detected that SEL_CORE can't be used on single core CPU. Thus k8temp did never update the temperature values stored in temp[1][x] and -49 degrees was reported. For single core CPUs we must use the values read into temp[0][x].
--- drivers/hwmon/k8temp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/k8temp.c +1 -1
@@ -120,7 +120,7 @@ static ssize_t show_temp(struct device *int temp;struct k8temp_data *data =k8temp_update_device (dev); -if (data->swap_core_select) +if (data->swap_core_select && (data->sensorsp &SEL_CORE )) core = core ?0 :1 ; temp =TEMP_FROM_REG (data->temp[core][place]) + data->temp_offset;
PATCH 4/165 hwmon: (k8temp) Fix temperature reporting for ASB1 processor revisions
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andreas Herrmann <[email protected]>
commit d535bad90dad4eb42ec6528043fcfb53627d4f89 upstream.
Reported temperature for ASB1 CPUs is too high.
Add ASB1 CPU revisions (these are also non-desktop variants) to the list of CPUs for which the temperature fixup is not required.
Example: (from LENOVO ThinkPad Edge 13, 01972NG, system was idle)
Current kernel reports
$ sensors k8temp-pci-00c3 Adapter: PCI adapter Core0 Temp: +74.0 C Core0 Temp: +70.0 C Core1 Temp: +69.0 C Core1 Temp: +70.0 C
With this patch I have
$ sensors k8temp-pci-00c3 Adapter: PCI adapter Core0 Temp: +54.0 C Core0 Temp: +51.0 C Core1 Temp: +48.0 C Core1 Temp: +49.0 C
--- drivers/hwmon/k8temp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/hwmon/k8temp.c +6 -4
@@ -180,11 +180,13 @@ static int __devinit k8temp_probe(struct }if ((model >=0x69 ) && - !(model ==0xc1 || model ==0x6c || model ==0x7c )) { + !(model ==0xc1 || model ==0x6c || model ==0x7c || + model ==0x6b || model ==0x6f || model ==0x7f )) {/* -* RevG desktop CPUs (i.e. no socket S1G1 parts) -* need additional offset, otherwise reported -* temperature is below ambient temperature +* RevG desktop CPUs (i.e. no socket S1G1 or +* ASB1 parts) need additional offset, +* otherwise reported temperature is below +* ambient temperature */ data->temp_offset =21000 ; }
PATCH 5/165 hwmon: (coretemp) Properly label the sensors
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jean Delvare <[email protected]>
commit 3f4f09b4be35d38d6e2bf22c989443e65e70fc4c upstream.
Don't assume that CPU entry number and core ID always match. It worked in the simple cases (single CPU, no HT) but fails on multi-CPU systems.
--- drivers/hwmon/coretemp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/hwmon/coretemp.c +5 -1
@@ -53,6 +53,7 @@ struct coretemp_data {struct mutex update_lock;const char *name;u32 id; +u16 core_id;char valid;/* zero until following fields are valid */ unsigned long last_updated;/* in jiffies */ int temp;
@@ -75,7 +76,7 @@ static ssize_t show_name(struct device *if (attr->index ==SHOW_NAME ) ret =sprintf (buf,"%s\n" , data->name);else /* show label */ - ret =sprintf (buf,"Core %d\n" , data->id); + ret =sprintf (buf,"Core %d\n" , data->core_id);return ret; }
@@ -255,6 +256,9 @@ static int __devinit coretemp_probe(stru } data->id = pdev->id; +#ifdef CONFIG_SMP + data->core_id = c->cpu_core_id; +#endif data->name ="coretemp" ;mutex_init (&data->update_lock);
PATCH 6/165 hwmon: (coretemp) Skip duplicate CPU entries
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jean Delvare <[email protected]>
commit d883b9f0977269d519469da72faec6a7f72cb489 upstream.
On hyper-threaded CPUs, each core appears twice in the CPU list. Skip the second entry to avoid duplicate sensors.
--- drivers/hwmon/coretemp.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-)
drivers/hwmon/coretemp.c +25 -1
@@ -356,6 +356,10 @@ struct pdev_entry {struct list_head list;struct platform_device *pdev;unsigned int cpu; +#ifdef CONFIG_SMP +u16 phys_proc_id; +u16 cpu_core_id; +#endif };static LIST_HEAD (pdev_list);
@@ -366,6 +370,22 @@ static int __cpuinit coretemp_device_addint err;struct platform_device *pdev;struct pdev_entry *pdev_entry; +#ifdef CONFIG_SMP +struct cpuinfo_x86 *c = &cpu_data (cpu); +#endif + +mutex_lock (&pdev_list_mutex); + +#ifdef CONFIG_SMP +/* Skip second HT entry of each core */ +list_for_each_entry (pdev_entry, &pdev_list, list) { +if (c->phys_proc_id == pdev_entry->phys_proc_id && + c->cpu_core_id == pdev_entry->cpu_core_id) { + err =0 ;/* Not an error */ + goto exit; + } + } +#endif pdev =platform_device_alloc (DRVNAME , cpu);if (!pdev) {
@@ -389,7 +409,10 @@ static int __cpuinit coretemp_device_add pdev_entry->pdev = pdev; pdev_entry->cpu = cpu; -mutex_lock (&pdev_list_mutex); +#ifdef CONFIG_SMP + pdev_entry->phys_proc_id = c->phys_proc_id; + pdev_entry->cpu_core_id = c->cpu_core_id; +#endif list_add_tail (&pdev_entry->list, &pdev_list);mutex_unlock (&pdev_list_mutex);
@@ -400,6 +423,7 @@ exit_device_free: exit_device_put:platform_device_put (pdev); exit: +mutex_unlock (&pdev_list_mutex);return err; }
PATCH 7/165 hwmon: (it87) Fix in7 on IT8720F
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jean Delvare <[email protected]>
commit 436cad2a41a40c6c32bd9152b63d17eeb1f7c99b upstream.
The IT8720F has no VIN7 pin, so VCCH should always be routed internally to VIN7 with an internal divider. Curiously, there still is a configuration bit to control this, which means it can be set incorrectly. And even more curiously, many boards out there are improperly configured, even though the IT8720F datasheet claims that the internal routing of VCCH to VIN7 is the default setting. So we force the internal routing in this case.
It turns out that all boards with the wrong setting are from Gigabyte, so I suspect a BIOS bug. But it's easy enough to workaround in the driver, so let's do it.
--- drivers/hwmon/it87.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
drivers/hwmon/it87.c +22 -0
@@ -80,6 +80,13 @@ superio_inb(int reg)return inb (VAL ); } +static inline void +superio_outb (int reg,int val) +{ +outb (reg,REG ); +outb (val,VAL ); +} +static int superio_inw (int reg) {int val;
@@ -1036,6 +1043,21 @@ static int __init it87_find(unsigned sho sio_data->vid_value =superio_inb (IT87_SIO_VID_REG ); reg =superio_inb (IT87_SIO_PINX2_REG ); +/* +* The IT8720F has no VIN7 pin, so VCCH should always be +* routed internally to VIN7 with an internal divider. +* Curiously, there still is a configuration bit to control +* this, which means it can be set incorrectly. And even +* more curiously, many boards out there are improperly +* configured, even though the IT8720F datasheet claims +* that the internal routing of VCCH to VIN7 is the default +* setting. So we force the internal routing in this case. +*/ +if (sio_data->type == it8720 && !(reg & (1 <<1 ))) { + reg |= (1 <<1 ); +superio_outb (IT87_SIO_PINX2_REG , reg); +pr_notice ("it87: Routing internal VCCH to in7\n" ); + }if (reg & (1 <<0 ))pr_info ("it87: in3 is VCC (+5V)\n" );if (reg & (1 <<1 ))
PATCH 8/165 cifs: remove bogus first_time check in NTLMv2 session setup code
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jeff Layton <[email protected]>
commit 8a224d489454b7457105848610cfebebdec5638d upstream.
This bug appears to be the result of a cut-and-paste mistake from the NTLMv1 code. The function to generate the MAC key was commented out, but not the conditional above it. The conditional then ended up causing the session setup key not to be copied to the buffer unless this was the first session on the socket, and that made all but the first NTLMv2 session setup fail.
Fix this by removing the conditional and all of the commented clutter that made it difficult to see.
--- fs/cifs/sess.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-)
fs/cifs/sess.c +1 -9
@@ -723,15 +723,7 @@ ssetup_ntlmssp_authenticate:/* calculate session key */ setup_ntlmv2_rsp (ses, v2_sess_key, nls_cp); -if (first_time)/* should this be moved into common code -with similar ntlmv2 path? */ -/* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key, -response BB FIXME, v2_sess_key); */ - -/* copy session key */ - -/* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE); -bcc_ptr += LM2_SESS_KEY_SIZE; */ +/* FIXME: calculate MAC key */ memcpy (bcc_ptr, (char *)v2_sess_key,sizeof (struct ntlmv2_resp )); bcc_ptr +=sizeof (struct ntlmv2_resp );
PATCH 9/165 cifs: dont attempt busy-file rename unless its in same directory
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jeff Layton <[email protected]>
commit ed0e3ace576d297a5c7015401db1060bbf677b94 upstream.
Busy-file renames don't actually work across directories, so we need to limit this code to renames within the same dir.
This fixes the bug detailed here:
https://bugzilla.redhat.com/show_bug.cgi?id=591938
--- fs/cifs/inode.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/cifs/inode.c +4 -0
@@ -1284,6 +1284,10 @@ cifs_do_rename(int xid, struct dentry *fif (rc ==0 || rc != -ETXTBSY )return rc; +/* open-file renames don't work across directories */ +if (to_dentry->d_parent != from_dentry->d_parent) +return rc; +/* open the file to be renamed -- we need DELETE perms */ rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, CREATE_NOT_DIR, &srcfid, &oplock, NULL,
PATCH 10/165 CIFS: Fix a malicious redirect problem in the DNS lookup code
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: David Howells <[email protected]>
commit 4c0c03ca54f72fdd5912516ad0a23ec5cf01bda7 upstream.
Fix the security problem in the CIFS filesystem DNS lookup code in which a malicious redirect could be installed by a random user by simply adding a result record into one of their keyrings with add_key() and then invoking a CIFS CFS lookup [CVE-2010-2524].
This is done by creating an internal keyring specifically for the caching of DNS lookups. To enforce the use of this keyring, the module init routine creates a set of override credentials with the keyring installed as the thread keyring and instructs request_key() to only install lookup result keys in that keyring.
The override is then applied around the call to request_key().
This has some additional benefits when a kernel service uses this module to request a key:
(1) The result keys are owned by root, not the user that caused the lookup.
(2) The result keys don't pop up in the user's keyrings.
(3) The result keys don't come out of the quota of the user that caused the lookup.
The keyring can be viewed as root by doing cat /proc/keys:
2a0ca6c3 I----- 1 perm 1f030000 0 0 keyring .dns_resolver: 1/4
It can then be listed with 'keyctl list' by root.
# keyctl list 0x2a0ca6c3 1 key in keyring: 726766307: --alswrv 0 0 dns_resolver: foo.bar.com
--- fs/cifs/cifsfs.c | 6 ++-- fs/cifs/dns_resolve.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/dns_resolve.h | 4 +- 3 files changed, 74 insertions(+), 5 deletions(-)
fs/cifs/cifsfs.c +3 -3
@@ -1033,7 +1033,7 @@ init_cifs(void) goto out_unregister_filesystem;#endif #ifdef CONFIG_CIFS_DFS_UPCALL - rc =register_key_type (&key_type_dns_resolver); + rc =cifs_init_dns_resolver ();if (rc) goto out_unregister_key_type;#endif
@@ -1045,7 +1045,7 @@ init_cifs(void) out_unregister_resolver_key: #ifdef CONFIG_CIFS_DFS_UPCALL -unregister_key_type (&key_type_dns_resolver); +cifs_exit_dns_resolver (); out_unregister_key_type:#endif #ifdef CONFIG_CIFS_UPCALL
@@ -1071,7 +1071,7 @@ exit_cifs(void)cifs_proc_clean ();#ifdef CONFIG_CIFS_DFS_UPCALL cifs_dfs_release_automount_timer (); -unregister_key_type (&key_type_dns_resolver); +cifs_exit_dns_resolver ();#endif #ifdef CONFIG_CIFS_UPCALL unregister_key_type (&cifs_spnego_key_type);
fs/cifs/dns_resolve.c +69 -0
99 lines not on this page · raw message
fs/cifs/dns_resolve.h +2 -2
@@ -24,8 +24,8 @@#define _DNS_RESOLVE_H#ifdef __KERNEL__ -#include <linux/key-type.h> -extern struct key_type key_type_dns_resolver; +extern int __init cifs_init_dns_resolver (void ); +extern void __exit cifs_exit_dns_resolver(void);extern int dns_resolve_server_name_to_ip (const char *unc,char **ip_addr);#endif /* KERNEL */
PATCH 11/165 ALSA: hda - Add Macbook 5,2 quirk
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Luke Yelavich <[email protected]>
commit 3bfea98ff73d377ffce0d4c7f938b7ef958cdb35 upstream.
Set Macbook 5,2 (106b:4a00) hardware to use ALC885_MB5
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -8942,6 +8942,7 @@ static struct snd_pci_quirk alc882_ssid_SND_PCI_QUIRK (0x106b ,0x3800 ,"MacbookPro 4,1" ,ALC885_MBP3 ),SND_PCI_QUIRK (0x106b ,0x3e00 ,"iMac 24 Aluminum" ,ALC885_IMAC24 ),SND_PCI_QUIRK (0x106b ,0x3f00 ,"Macbook 5,1" ,ALC885_MB5 ), + SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),/* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, * so apparently no perfect solution yet */
PATCH 12/165 cpmac: do not leak struct net_device on phy_connect errors
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Florian Fainelli <[email protected]>
commit ed770f01360b392564650bf1553ce723fa46afec upstream.
If the call to phy_connect fails, we will return directly instead of freeing the previously allocated struct net_device.
--- drivers/net/cpmac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/cpmac.c +2 -1
@@ -1176,7 +1176,8 @@ static int __devinit cpmac_probe(structif (netif_msg_drv (priv))printk (KERN_ERR "%s: Could not attach to PHY\n" , dev->name); -return PTR_ERR (priv->phy); + rc =PTR_ERR (priv->phy); + goto fail; }if ((rc =register_netdev (dev))) {
PATCH 13/165 sky2: enable rx/tx in sky2_phy_reinit()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Brandon Philips <[email protected]>
commit 38000a94a902e94ca8b5498f7871c6316de8957a upstream.
sky2_phy_reinit is called by the ethtool helpers sky2_set_settings, sky2_nway_reset and sky2_set_pauseparam when netif_running.
However, at the end of sky2_phy_init GM_GP_CTRL has GM_GPCR_RX_ENA and GM_GPCR_TX_ENA cleared. So, doing these commands causes the device to stop working:
$ ethtool -r eth0 $ ethtool -A eth0 autoneg off
Fix this issue by enabling Rx/Tx after running sky2_phy_init in sky2_phy_reinit.
--- drivers/net/sky2.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
drivers/net/sky2.c +14 -5
@@ -704,11 +704,24 @@ static void sky2_phy_power_down(struct ssky2_write8 (hw,B2_TST_CTRL1 ,TST_CFG_WRITE_OFF ); } +/* Enable Rx/Tx */ +static void sky2_enable_rx_tx (struct sky2_port *sky2) +{ +struct sky2_hw *hw = sky2->hw; +unsigned port = sky2->port; +u16 reg; + + reg =gma_read16 (hw, port,GM_GP_CTRL ); + reg |=GM_GPCR_RX_ENA |GM_GPCR_TX_ENA ; +gma_write16 (hw, port,GM_GP_CTRL , reg); +} +/* Force a renegotiation */ static void sky2_phy_reinit (struct sky2_port *sky2) {spin_lock_bh (&sky2->phy_lock);sky2_phy_init (sky2->hw, sky2->port); +sky2_enable_rx_tx (sky2);spin_unlock_bh (&sky2->phy_lock); }
@@ -1929,7 +1942,6 @@ static void sky2_link_up(struct sky2_por {struct sky2_hw *hw = sky2->hw;unsigned port = sky2->port; -u16 reg;static const char *fc_name[] = { [FC_NONE ] ="none" , [FC_TX ] ="tx" ,
@@ -1937,10 +1949,7 @@ static void sky2_link_up(struct sky2_por [FC_BOTH ] ="both" , }; -/* enable Rx/Tx */ - reg =gma_read16 (hw, port,GM_GP_CTRL ); - reg |=GM_GPCR_RX_ENA |GM_GPCR_TX_ENA ; -gma_write16 (hw, port,GM_GP_CTRL , reg); +sky2_enable_rx_tx (sky2);gm_phy_write (hw, port,PHY_MARV_INT_MASK ,PHY_M_DEF_MSK );
PATCH 14/165 igb: change how we handle alternate mac addresses
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alexander Duyck <[email protected]>
commit 22896639af98ebc721a94ed71fc3acf2fb4a24dc upstream.
This patch allows us to treat the alternate mac address as though it is the physical address on the adapter. This is accomplished by letting the alt_mac_address function to only fail on an NVM error. If no errors occur and the alternate mac address is not present then RAR0 is read as the default mac address.
--- drivers/net/igb/e1000_82575.c | 13 +++++++++++-- drivers/net/igb/e1000_hw.h | 2 ++ drivers/net/igb/e1000_mac.c | 17 +++++++++-------- 3 files changed, 22 insertions(+), 10 deletions(-)
drivers/net/igb/e1000_82575.c +11 -2
@@ -1168,9 +1168,18 @@ static s32 igb_read_mac_addr_82575(struc {s32 ret_val =0 ; -if (igb_check_alt_mac_addr (hw)) - ret_val =igb_read_mac_addr (hw); +/* +* If there's an alternate MAC address place it in RAR0 +* so that it will override the Si installed default perm +* address. +*/ + ret_val =igb_check_alt_mac_addr (hw); +if (ret_val) + goto out; + ret_val =igb_read_mac_addr (hw); + +out:return ret_val; }
drivers/net/igb/e1000_hw.h +2 -0
@@ -53,6 +53,8 @@ struct e1000_hw;#define E1000_FUNC_1 1 +#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3 +enum e1000_mac_type { e1000_undefined =0 , e1000_82575,
drivers/net/igb/e1000_mac.c +9 -8
@@ -185,13 +185,12 @@ s32 igb_check_alt_mac_addr(struct e1000_ }if (nvm_alt_mac_addr_offset ==0xFFFF ) { - ret_val = -(E1000_NOT_IMPLEMENTED ); +/* There is no Alternate MAC Address */ goto out; }if (hw->bus.func ==E1000_FUNC_1 ) - nvm_alt_mac_addr_offset +=ETH_ALEN /sizeof (u16); - + nvm_alt_mac_addr_offset +=E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 ;for (i =0 ; i <ETH_ALEN ; i +=2 ) { offset = nvm_alt_mac_addr_offset + (i >>1 ); ret_val = hw->nvm.ops.read (hw, offset,1 , &nvm_data);
@@ -206,14 +205,16 @@ s32 igb_check_alt_mac_addr(struct e1000_/* if multicast bit is set, the alternate address will not be used */ if (alt_mac_addr[0 ] &0x01 ) { - ret_val = -(E1000_NOT_IMPLEMENTED ); +hw_dbg ("Ignoring Alternate Mac Address with MC bit set\n" ); goto out; } -for (i =0 ; i <ETH_ALEN ; i++) - hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i]; - - hw->mac.ops.rar_set (hw, hw->mac.perm_addr,0 ); +/* +* We have a valid alternate MAC address, and we want to treat it the +* same as the normal permanent MAC address stored by the HW into the +* RAR. Do this by mapping this address into RAR0. +*/ + hw->mac.ops.rar_set (hw, alt_mac_addr,0 ); out:return ret_val;
PATCH 15/165 sparc: Fix use of uid16_t and gid16_t in asm/stat.h
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Rob Landley <[email protected]>
commit 7469a9acf919d36836f6c635099d8edc9be4528a upstream.
--- arch/sparc/include/asm/stat.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/sparc/include/asm/stat.h +2 -2
@@ -53,8 +53,8 @@ struct stat {ino_t st_ino;mode_t st_mode;short st_nlink; -uid16_t st_uid; -gid16_t st_gid; +unsigned short st_uid; +unsigned short st_gid;unsigned short st_rdev;off_t st_size;time_t st_atime;
PATCH 16/165 math-emu: correct test for downshifting fraction in _FP_FROM_INT()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Mikael Pettersson <[email protected]>
commit f8324e20f8289dffc646d64366332e05eaacab25 upstream.
The kernel's math-emu code contains a macro _FP_FROM_INT() which is used to convert an integer to a raw normalized floating-point value. It does this basically in three steps:
1. Compute the exponent from the number of leading zero bits.
2. Downshift large fractions to put the MSB in the right position for normalized fractions.
3. Upshift small fractions to put the MSB in the right position.
There is an boundary error in step 2, causing a fraction with its MSB exactly one bit above the normalized MSB position to not be downshifted. This results in a non-normalized raw float, which when packed becomes a massively inaccurate representation for that input.
The impact of this depends on a number of arch-specific factors, but it is known to have broken emulation of FXTOD instructions on UltraSPARC III, which was originally reported as GCC bug 44631
<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44631>.
Any arch which uses math-emu to emulate conversions from integers to same-size floats may be affected.
The fix is simple: the exponent comparison used to determine if the fraction should be downshifted must be "<=" not "<".
I'm sending a kernel module to test this as a reply to this message. There are also SPARC user-space test cases in the GCC bug entry.
--- include/math-emu/op-common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/math-emu/op-common.h +1 -1
@@ -799,7 +799,7 @@ do { \ X##_e -= (_FP_W_TYPE_SIZE - rsize); \ X##_e = rsize - X##_e - 1; \ \ - if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e) \ + if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs <= X##_e) \ __FP_FRAC_SRS_1(ur_, (X##_e - _FP_WFRACBITS_##fs + 1), rsize);\ _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ if ((_FP_WFRACBITS_##fs - X##_e - 1) > 0) \
PATCH 17/165 NFSv4: Fix an embarassing typo in encode_attrs()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Trond Myklebust <[email protected]>
commit d3f6baaa34c54040b3ef30950e59b54ac0624b21 upstream.
Apparently, we have never been able to set the atime correctly from the NFSv4 client.
--- fs/nfs/nfs4xdr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/nfs/nfs4xdr.c +2 -2
@@ -840,8 +840,8 @@ static void encode_attrs(struct xdr_stre bmval1 |=FATTR4_WORD1_TIME_ACCESS_SET ; *p++ =cpu_to_be32 (NFS4_SET_TO_CLIENT_TIME ); *p++ =cpu_to_be32 (0 ); - *p++ =cpu_to_be32 (iap->ia_mtime.tv_sec); - *p++ =cpu_to_be32 (iap->ia_mtime.tv_nsec); + *p++ =cpu_to_be32 (iap->ia_atime.tv_sec); + *p++ =cpu_to_be32 (iap->ia_atime.tv_nsec); }else if (iap->ia_valid &ATTR_ATIME ) { bmval1 |=FATTR4_WORD1_TIME_ACCESS_SET ;
PATCH 18/165 NFSv4: Ensure that /proc/self/mountinfo displays the minor version number
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Trond Myklebust <[email protected]>
commit 0be8189f2c87fcc747d6a4a657a0b6e2161b2318 upstream.
Currently, we do not display the minor version mount parameter in the /proc mount info.
--- fs/nfs/super.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
fs/nfs/super.c +18 -4
@@ -534,6 +534,22 @@ static void nfs_show_mountd_options(stru } } +#ifdef CONFIG_NFS_V4 +static void nfs_show_nfsv4_options (struct seq_file *m,struct nfs_server *nfss, +int showdefaults) +{ +struct nfs_client *clp = nfss->nfs_client; + +seq_printf (m,",clientaddr=%s" , clp->cl_ipaddr); +seq_printf (m,",minorversion=%u" , clp->cl_minorversion); +} +#else +static void nfs_show_nfsv4_options (struct seq_file *m,struct nfs_server *nfss, +int showdefaults) +{ +} +#endif +/* * Describe the mount options in force on this server representation */
@@ -595,11 +611,9 @@ static void nfs_show_mount_options(strucif (version !=4 )nfs_show_mountd_options (m, nfss, showdefaults); +else +nfs_show_nfsv4_options (m, nfss, showdefaults); -#ifdef CONFIG_NFS_V4 -if (clp->rpc_ops->version ==4 ) -seq_printf (m,",clientaddr=%s" , clp->cl_ipaddr); -#endif if (nfss->options &NFS_OPTION_FSCACHE )seq_printf (m,",fsc" ); }
PATCH 19/165 SUNRPC: Fix a re-entrancy bug in xs_tcp_read_calldir()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Trond Myklebust <[email protected]>
commit b76ce56192bcf618013fb9aecd83488cffd645cc upstream.
If the attempt to read the calldir fails, then instead of storing the read bytes, we currently discard them. This leads to a garbage final result when upon re-entry to the same routine, we read the remaining bytes.
Fixes the regression in bugzilla number 16213. Please see
https://bugzilla.kernel.org/show_bug.cgi?id=16213
--- net/sunrpc/xprtsock.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-)
net/sunrpc/xprtsock.c +22 -16
@@ -238,7 +238,8 @@ struct sock_xprt {* State of TCP reply receive */ __be32 tcp_fraghdr, - tcp_xid; + tcp_xid, + tcp_calldir;u32 tcp_offset, tcp_reclen;
@@ -961,7 +962,7 @@ static inline void xs_tcp_read_calldir(s {size_t len, used;u32 offset; -__be32 calldir; +char *p;/* * We want transport->tcp_offset to be 8 at the end of this routine
@@ -970,26 +971,33 @@ static inline void xs_tcp_read_calldir(s* transport->tcp_offset is 4 (after having already read the xid). */ offset = transport->tcp_offset -sizeof (transport->tcp_xid); - len =sizeof (calldir) - offset; + len =sizeof (transport->tcp_calldir) - offset;dprintk ("RPC: reading CALL/REPLY flag (%Zu bytes)\n" , len); - used =xdr_skb_read_bits (desc, &calldir, len); + p = ((char *) &transport->tcp_calldir) + offset; + used =xdr_skb_read_bits (desc, p, len); transport->tcp_offset += used;if (used != len)return ; transport->tcp_flags &= ~TCP_RCV_READ_CALLDIR ; - transport->tcp_flags |=TCP_RCV_COPY_CALLDIR ; - transport->tcp_flags |=TCP_RCV_COPY_DATA ;/* * We don't yet have the XDR buffer, so we will write the calldir * out after we get the buffer from the 'struct rpc_rqst' */ -if (ntohl (calldir) ==RPC_REPLY ) +switch (ntohl (transport->tcp_calldir)) { +case RPC_REPLY : + transport->tcp_flags |=TCP_RCV_COPY_CALLDIR ; + transport->tcp_flags |=TCP_RCV_COPY_DATA ; transport->tcp_flags |=TCP_RPC_REPLY ; -else +break ; +case RPC_CALL : + transport->tcp_flags |=TCP_RCV_COPY_CALLDIR ; + transport->tcp_flags |=TCP_RCV_COPY_DATA ; transport->tcp_flags &= ~TCP_RPC_REPLY ; -dprintk ("RPC: reading %s CALL/REPLY flag %08x\n" , - (transport->tcp_flags &TCP_RPC_REPLY ) ? -"reply for" :"request with" , calldir); +break ; +default : +dprintk ("RPC: invalid request message type\n" ); +xprt_force_disconnect (&transport->xprt); + }xs_tcp_check_fraghdr (transport); }
@@ -1009,12 +1017,10 @@ static inline void xs_tcp_read_common(st/* * Save the RPC direction in the XDR buffer */ -__be32 calldir = transport->tcp_flags &TCP_RPC_REPLY ? -htonl (RPC_REPLY ) :0 ; -memcpy (rcvbuf->head[0 ].iov_base + transport->tcp_copied, - &calldir,sizeof (calldir)); - transport->tcp_copied +=sizeof (calldir); + &transport->tcp_calldir, +sizeof (transport->tcp_calldir)); + transport->tcp_copied +=sizeof (transport->tcp_calldir); transport->tcp_flags &= ~TCP_RCV_COPY_CALLDIR ; }
PATCH 20/165 ath5k: drop warning on jumbo frames
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Luis R. Rodriguez <[email protected]>
commit 9637e516d16a58b13f6098cfe899e22963132be3 upstream.
Jumbo frames are not supported, and if they are seen it is likely a bogus frame so just silently discard them instead of warning on them all time. Also, instead of dropping them immediately though move the check *after* we check for all sort of frame errors. This should enable us to discard these frames if the hardware picks other bogus items first. Lets see if we still get those jumbo counters increasing still with this.
Jumbo frames would happen if we tell hardware we can support a small 802.11 chunks of DMA'd frame, hardware would split RX'd frames into parts and we'd have to reconstruct them in software. This is done with USB due to the bulk size but with ath5k we already provide a good limit to hardware and this should not be happening.
This is reported quite often and if it fills the logs then this needs to be addressed and to avoid spurious reports.
--- drivers/net/wireless/ath/ath5k/base.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/net/wireless/ath/ath5k/base.c +2 -5
@@ -1818,11 +1818,6 @@ ath5k_tasklet_rx(unsigned long data)return ; } -if (unlikely (rs.rs_more)) { -ATH5K_WARN (sc,"unsupported jumbo\n" ); - goto next; - } -if (unlikely (rs.rs_status)) {if (rs.rs_status &AR5K_RXERR_PHY ) goto next;
@@ -1852,6 +1847,8 @@ ath5k_tasklet_rx(unsigned long data) sc->opmode != NL80211_IFTYPE_MONITOR) goto next; } +if (unlikely (rs.rs_more)) + goto next; accept: next_skb =ath5k_rx_skb_alloc (sc, &next_skb_addr);
PATCH 21/165 ath9k: re-enable ps by default for new single chip families
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Luis R. Rodriguez <[email protected]>
commit 14acdde6e527950f66c084dbf19bad6fbfcaeedc upstream.
The newer single chip hardware family of chipsets have not been experiencing issues with power saving set by default with recent fixes merged (even into stable). The remaining issues are only reported with AR5416 and since enabling PS by default can increase power savings considerably best to take advantage of that feature as this has been tested properly.
For more details on this issue see the bug report:
http://bugzilla.kernel.org/show_bug.cgi?id=14267
We leave AR5416 with PS disabled by default, that seems to require some more work.
--- drivers/net/wireless/ath/ath9k/main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/ath9k/main.c +6 -1
@@ -1538,6 +1538,8 @@ bad_no_ah:void ath_set_hw_capab (struct ath_softc *sc,struct ieee80211_hw *hw) { +struct ath_hw *ah = sc->sc_ah; + hw->flags =IEEE80211_HW_RX_INCLUDES_FCS |IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM |
@@ -1558,7 +1560,10 @@ void ath_set_hw_capab(struct ath_softc *BIT (NL80211_IFTYPE_ADHOC ) |BIT (NL80211_IFTYPE_MESH_POINT ); - hw->wiphy->ps_default = false; +if (AR_SREV_5416 (ah)) + hw->wiphy->ps_default = false; +else + hw->wiphy->ps_default = true; hw->queues =4 ; hw->max_rates =4 ;
PATCH 22/165 ath9k: Avoid corrupt frames being forwarded to mac80211.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Vivek Natarajan <[email protected]>
commit 3a37495268ab45507b4cab9d4cb18c5496ab7a10 upstream.
If bit 29 is set, MAC H/W can attempt to decrypt the received aggregate with WEP or TKIP, eventhough the received frame may be a CRC failed corrupted frame. If this bit is set, H/W obeys key type in keycache. If it is not set and if the key type in keycache is neither open nor AES, H/W forces key type to be open. But bit 29 should be set to 1 for AsyncFIFO feature to encrypt/decrypt the aggregate with WEP or TKIP.
--- drivers/net/wireless/ath/ath9k/initvals.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/wireless/ath/ath9k/initvals.h +4 -4
@@ -2762,7 +2762,7 @@ static const u32 ar9280Common_9280_2[][2 { 0x00008258, 0x00000000 }, { 0x0000825c, 0x400000ff }, { 0x00008260, 0x00080922 }, - { 0x00008264, 0xa8a00010 }, + { 0x00008264, 0x88a00010 }, { 0x00008270, 0x00000000 }, { 0x00008274, 0x40000000 }, { 0x00008278, 0x003e4180 },
@@ -3935,7 +3935,7 @@ static const u_int32_t ar9285Common_9285 { 0x00008258, 0x00000000 }, { 0x0000825c, 0x400000ff }, { 0x00008260, 0x00080922 }, - { 0x00008264, 0xa8a00010 }, + { 0x00008264, 0x88a00010 }, { 0x00008270, 0x00000000 }, { 0x00008274, 0x40000000 }, { 0x00008278, 0x003e4180 },
@@ -5072,7 +5072,7 @@ static const u_int32_t ar9287Common_9287 { 0x00008258, 0x00000000 }, { 0x0000825c, 0x400000ff }, { 0x00008260, 0x00080922 }, - { 0x00008264, 0xa8a00010 }, + { 0x00008264, 0x88a00010 }, { 0x00008270, 0x00000000 }, { 0x00008274, 0x40000000 }, { 0x00008278, 0x003e4180 },
@@ -6864,7 +6864,7 @@ static const u_int32_t ar9271Common_9271 { 0x00008258, 0x00000000 }, { 0x0000825c, 0x400000ff }, { 0x00008260, 0x00080922 }, - { 0x00008264, 0xa8a00010 }, + { 0x00008264, 0x88a00010 }, { 0x00008270, 0x00000000 }, { 0x00008274, 0x40000000 }, { 0x00008278, 0x003e4180 },
PATCH 23/165 hostap: Protect against initialization interrupt
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Tim Gardner <[email protected]>
commit d6a574ff6bfb842bdb98065da053881ff527be46 upstream.
Use an irq spinlock to hold off the IRQ handler until enough early card init is complete such that the handler can run without faulting.
--- drivers/net/wireless/hostap/hostap_cs.c | 10 ++++++++++ drivers/net/wireless/hostap/hostap_hw.c | 13 +++++++++++++ drivers/net/wireless/hostap/hostap_wlan.h | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-)
drivers/net/wireless/hostap/hostap_cs.c +10 -0
@@ -626,6 +626,7 @@ static int prism2_config(struct pcmcia_dint ret =1 ;int last_fn, last_ret;struct hostap_cs_priv *hw_priv; +unsigned long flags;PDEBUG (DEBUG_FLOW ,"prism2_config()\n" );
@@ -661,6 +662,12 @@ static int prism2_config(struct pcmcia_d link->dev_node = &hw_priv->node;/* +* Make sure the IRQ handler cannot proceed until at least +* dev->base_addr is initialized. +*/ +spin_lock_irqsave (&local->irq_init_lock, flags); + +/* * Allocate an interrupt line. Note that this does not assign a * handler to the interrupt, unless the 'Handler' member of the * irq structure is initialized.
@@ -686,6 +693,8 @@ static int prism2_config(struct pcmcia_d dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; +spin_unlock_irqrestore (&local->irq_init_lock, flags); +/* Finally, report what we've done */ printk (KERN_INFO "%s: index 0x%02x: " , dev_info, link->conf.ConfigIndex);
@@ -715,6 +724,7 @@ static int prism2_config(struct pcmcia_dreturn ret; cs_failed: +spin_unlock_irqrestore (&local->irq_init_lock, flags);cs_error (link, last_fn, last_ret); failed:
drivers/net/wireless/hostap/hostap_hw.c +13 -0
@@ -2621,6 +2621,18 @@ static irqreturn_t prism2_interrupt(int iface =netdev_priv (dev); local = iface->local; +/* Detect early interrupt before driver is fully configued */ +spin_lock (&local->irq_init_lock); +if (!dev->base_addr) { +if (net_ratelimit ()) { +printk (KERN_DEBUG "%s: Interrupt, but dev not configured\n" , + dev->name); + } +spin_unlock (&local->irq_init_lock); +return IRQ_HANDLED ; + } +spin_unlock (&local->irq_init_lock); +prism2_io_debug_add (dev,PRISM2_IO_DEBUG_CMD_INTERRUPT ,0 ,0 );if (local->func->card_present && !local->func->card_present (local)) {
@@ -3138,6 +3150,7 @@ prism2_init_local_data(struct prism2_helspin_lock_init (&local->cmdlock);spin_lock_init (&local->baplock);spin_lock_init (&local->lock); +spin_lock_init (&local->irq_init_lock);mutex_init (&local->rid_bap_mtx);if (card_idx <0 || card_idx >=MAX_PARM_DEVICES )
drivers/net/wireless/hostap/hostap_wlan.h +1 -1
@@ -654,7 +654,7 @@ struct local_info {rwlock_t iface_lock;/* hostap_interfaces read lock; use write lock * when removing entries from the list. * TX and RX paths can use read lock. */ -spinlock_t cmdlock, baplock, lock; +spinlock_t cmdlock, baplock, lock, irq_init_lock;struct mutex rid_bap_mtx;u16 infofid;/* MAC buffer id for info frame */ /* txfid, intransmitfid, next_txtid, and next_alloc are protected by
PATCH 24/165 TPM: ReadPubEK output struct fix
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Rajiv Andrade <[email protected]>
commit 02a077c52ef7631275a79862ffd9f3dbe9d38bc2 upstream.
This patch adds a missing element of the ReadPubEK command output, that prevents future overflow of this buffer when copying the TPM output result into it.
Prevents a kernel panic in case the user tries to read the pubek from sysfs.
--- drivers/char/tpm/tpm.h | 1 + 1 file changed, 1 insertion(+)
drivers/char/tpm/tpm.h +1 -0
@@ -224,6 +224,7 @@ struct tpm_readpubek_params_out {u8 algorithm[4 ];u8 encscheme[2 ];u8 sigscheme[2 ]; +__be32 paramsize;u8 parameters[12 ];/*assuming RSA*/ __be32 keysize;u8 modulus[256 ];
PATCH 25/165 fb: fix colliding defines for fb flags.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Airlie <[email protected]>
commit b26c949755c06ec79e55a75817210083bd78fc9a upstream.
When I added the flags I must have been using a 25 line terminal and missed the following flags.
The collided with flag has one user in staging despite being in-tree for 5 years.
I'm happy to push this via my drm tree unless someone really wants to do it.
--- include/linux/fb.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/fb.h +2 -2
@@ -784,8 +784,6 @@ struct fb_tile_ops {#define FBINFO_MISC_USEREVENT 0x10000/* event request from userspace */ #define FBINFO_MISC_TILEBLITTING 0x20000/* use tile blitting */ -#define FBINFO_MISC_FIRMWARE 0x40000/* a replaceable firmware -inited framebuffer */ /* A driver may set this flag to indicate that it does want a set_par to be * called every time when fbcon_switch is executed. The advantage is that with
@@ -799,6 +797,8 @@ struct fb_tile_ops {*/ #define FBINFO_MISC_ALWAYS_SETPAR 0x40000 +/* where the fb is a firmware driver, and can be replaced with a proper one */ +#define FBINFO_MISC_FIRMWARE 0x80000/* * Host and GPU endianness differ. */
PATCH 26/165 iwlwifi: cancel scan watchdog in iwl_bg_abort_scan
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: John W. Linville <[email protected]>
commit a69b03e941abae00380fc6bc1877fb797a1b31e6 upstream.
Avoids this:
WARNING: at net/mac80211/scan.c:312 ieee80211_scan_completed+0x5f/0x1f1 [mac80211]() Hardware name: Latitude E5400 Modules linked in: aes_x86_64 aes_generic fuse ipt_MASQUERADE iptable_nat
nf_nat rfcomm sco bridge stp llc bnep l2cap sunrpc cpufreq_ondemand acpi_cpufreq freq_table xt_physdev ip6t_REJECT nf_conntrack_ipv6 ip6table_filter ip6_tables ipv6 kvm_intel kvm uinput arc4 ecb snd_hda_codec_intelhdmi snd_hda_codec_idt snd_hda_intel iwlagn snd_hda_codec snd_hwdep snd_seq snd_seq_device iwlcore snd_pcm dell_wmi sdhci_pci sdhci iTCO_wdt tg3 dell_laptop mmc_core i2c_i801 wmi mac80211 snd_timer iTCO_vendor_support btusb joydev dcdbas cfg80211 bluetooth snd soundcore microcode rfkill snd_page_alloc firewire_ohci firewire_core crc_itu_t yenta_socket rsrc_nonstatic i915 drm_kms_helper drm i2c_algo_bit i2c_core video output [last unloaded: scsi_wait_scan]
Pid: 979, comm: iwlagn Tainted: G W 2.6.33.3-85.fc13.x86_64 #1
Call Trace: [<ffffffff8104b558>] warn_slowpath_common+0x77/0x8f [<ffffffff8104b57f>] warn_slowpath_null+0xf/0x11 [<ffffffffa01bb7d9>] ieee80211_scan_completed+0x5f/0x1f1 [mac80211] [<ffffffffa02a23f0>] iwl_bg_scan_completed+0xbb/0x17a [iwlcore] [<ffffffff81060d3d>] worker_thread+0x1a4/0x232 [<ffffffffa02a2335>] ? iwl_bg_scan_completed+0x0/0x17a [iwlcore] [<ffffffff81064817>] ? autoremove_wake_function+0x0/0x34 [<ffffffff81060b99>] ? worker_thread+0x0/0x232 [<ffffffff810643c7>] kthread+0x7a/0x82 [<ffffffff8100a924>] kernel_thread_helper+0x4/0x10 [<ffffffff8106434d>] ? kthread+0x0/0x82 [<ffffffff8100a920>] ? kernel_thread_helper+0x0/0x10
Reported here:
https://bugzilla.redhat.com/show_bug.cgi?id=590436
--- drivers/net/wireless/iwlwifi/iwl-scan.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/iwlwifi/iwl-scan.c +1 -0
@@ -799,6 +799,7 @@ void iwl_bg_abort_scan(struct work_strucmutex_lock (&priv->mutex); +cancel_delayed_work_sync (&priv->scan_check);set_bit (STATUS_SCAN_ABORTING , &priv->status);iwl_send_scan_abort (priv);
PATCH 27/165 mac80211: do not wip out old supported rates
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Stanislaw Gruszka <[email protected]>
commit f0b058b61711ebf5be94d6865ca7b2c259b71d37 upstream.
Use old supported rates, if AP do not provide supported rates information element in a new managment frame.
--- net/mac80211/scan.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
net/mac80211/scan.c +11 -10
@@ -62,7 +62,7 @@ ieee80211_bss_info_update(struct ieee802 bool beacon) {struct ieee80211_bss *bss; -int clen; +int clen, srlen;s32 signal =0 ;if (local->hw.flags &IEEE80211_HW_SIGNAL_DBM )
@@ -94,23 +94,24 @@ ieee80211_bss_info_update(struct ieee802if (bss->dtim_period ==0 ) bss->dtim_period =1 ; - bss->supp_rates_len =0 ; +/* replace old supported rates if we get new values */ + srlen =0 ;if (elems->supp_rates) { - clen =IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; + clen =IEEE80211_MAX_SUPP_RATES ;if (clen > elems->supp_rates_len) clen = elems->supp_rates_len; -memcpy (&bss->supp_rates[bss->supp_rates_len], elems->supp_rates, - clen); - bss->supp_rates_len += clen; +memcpy (bss->supp_rates, elems->supp_rates, clen); + srlen += clen; }if (elems->ext_supp_rates) { - clen =IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; + clen =IEEE80211_MAX_SUPP_RATES - srlen;if (clen > elems->ext_supp_rates_len) clen = elems->ext_supp_rates_len; -memcpy (&bss->supp_rates[bss->supp_rates_len], - elems->ext_supp_rates, clen); - bss->supp_rates_len += clen; +memcpy (bss->supp_rates + srlen, elems->ext_supp_rates, clen); + srlen += clen; } +if (srlen) + bss->supp_rates_len = srlen; bss->wmm_used = elems->wmm_param || elems->wmm_info;
PATCH 28/165 mac80211: Handle mesh action frames in ieee80211_rx_h_action
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Javier Cardona <[email protected]>
commit 1cb561f83793191cf86a2db3948d28f5f42df9ff upstream.
This fixes the problem introduced in commit 8404080568613d93ad7cf0a16dfb68 which broke mesh peer link establishment.
changes:
v2 Added missing break (Johannes)
v3 Broke original patch into two (Johannes)
--- include/linux/ieee80211.h | 2 ++ net/mac80211/rx.c | 5 +++++ 2 files changed, 7 insertions(+)
include/linux/ieee80211.h +2 -0
@@ -1098,6 +1098,8 @@ enum ieee80211_category {WLAN_CATEGORY_SA_QUERY =8 ,WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION =9 ,WLAN_CATEGORY_WMM =17 , +WLAN_CATEGORY_MESH_PLINK =30 ,/* Pending ANA approval */ +WLAN_CATEGORY_MESH_PATH_SEL =32 ,/* Pending ANA approval */ WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED =126 , WLAN_CATEGORY_VENDOR_SPECIFIC = 127, };
net/mac80211/rx.c +5 -0
@@ -1818,6 +1818,11 @@ ieee80211_rx_h_action(struct ieee80211_rreturn RX_CONTINUE ; }break ; +case WLAN_CATEGORY_MESH_PLINK : +case WLAN_CATEGORY_MESH_PATH_SEL : +if (ieee80211_vif_is_mesh (&sdata->vif)) +return ieee80211_mesh_rx_mgmt (sdata, rx->skb); +break ;default :/* do not process rejected action frames */ if (mgmt->u.action.category &0x80 )
PATCH 29/165 Btrfs: fix checks in BTRFS_IOC_CLONE_RANGE
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit 2ebc3464781ad24474abcbd2274e6254689853b5 upstream.
1. The BTRFS_IOC_CLONE and BTRFS_IOC_CLONE_RANGE ioctls should check whether the donor file is append-only before writing to it.
2. The BTRFS_IOC_CLONE_RANGE ioctl appears to have an integer overflow that allows a user to specify an out-of-bounds range to copy from the source file (if off + len wraps around). I haven't been able to successfully exploit this, but I'd imagine that a clever attacker could use this to read things he shouldn't. Even if it's not exploitable, it couldn't hurt to be safe.
--- fs/btrfs/ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/btrfs/ioctl.c +2 -2
@@ -947,7 +947,7 @@ static noinline long btrfs_ioctl_clone(s*/ /* the destination must be opened for writing */ -if (!(file->f_mode &FMODE_WRITE )) +if (!(file->f_mode &FMODE_WRITE ) || (file->f_flags &O_APPEND ))return -EINVAL ; ret =mnt_want_write (file->f_path.mnt);
@@ -1000,7 +1000,7 @@ static noinline long btrfs_ioctl_clone(s/* determine range to clone */ ret = -EINVAL ; -if (off >= src->i_size || off + len > src->i_size) +if (off + len > src->i_size || off + len < off) goto out_unlock;if (len ==0 ) olen = len = src->i_size - off;
PATCH 30/165 p54pci: add Symbol AP-300 minipci adapters pciid
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Joerg Albert <[email protected]>
commit 50900f1698f68127e54c67fdfe829e4a97b1be2b upstream.
--- drivers/net/wireless/p54/p54pci.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/p54/p54pci.c +2 -0
@@ -40,6 +40,8 @@ static struct pci_device_id p54p_table[] { PCI_DEVICE(0x1260, 0x3877) },/* Intersil PRISM Javelin/Xbow Wireless LAN adapter */ { PCI_DEVICE(0x1260, 0x3886) }, +/* Intersil PRISM Xbow Wireless LAN adapter (Symbol AP-300) */ + { PCI_DEVICE(0x1260, 0xffff) }, { }, };
PATCH 31/165 dynamic debug: move ddebug_remove_module() down into free_module()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jason Baron <[email protected]>
commit b82bab4bbe9efa7bc7177fc20620fff19bd95484 upstream.
The command
echo "file ec.c +p" >/sys/kernel/debug/dynamic_debug/control
causes an oops.
Move the call to ddebug_remove_module() down into free_module(). In this way it should be called from all error paths. Currently, we are missing the remove if the module init routine fails.
--- kernel/module.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/module.c +3 -1
@@ -870,7 +870,6 @@ SYSCALL_DEFINE2(delete_module, const chamutex_lock (&module_mutex);/* Store the name of the last unloaded module for diagnostic purposes */ strlcpy (last_unloaded_module, mod->name,sizeof (last_unloaded_module)); -ddebug_remove_module (mod->name);free_module (mod); out:
@@ -1533,6 +1532,9 @@ static void free_module(struct module *mremove_sect_attrs (mod);mod_kobject_remove (mod); +/* Remove dynamic debug info */ +ddebug_remove_module (mod->name); +/* Arch-specific cleanup. */ module_arch_cleanup (mod);
PATCH 32/165 i915: fix lock imbalance on error path...
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Daniel J Blueman <[email protected]>
commit f953c9353f5fe6e98fa7f32f51060a74d845b5f8 upstream.
While investigating Intel i5 Arrandale GPU lockups with -rc4, I noticed a lock imbalance.
--- drivers/gpu/drm/i915/i915_drv.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/i915/i915_drv.c +1 -0
@@ -192,6 +192,7 @@ int i965_reset(struct drm_device *dev, u } }else {DRM_ERROR ("Error occurred. Don't know how to reset this chip.\n" ); +mutex_unlock (&dev->struct_mutex);return -ENODEV ; }
PATCH 33/165 drm/i915: Define MI_ARB_STATE bits
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Keith Packard <[email protected]>
commit 45503ded966c98e604c9667c0b458d40666b9ef3 upstream.
The i915 memory arbiter has a register full of configuration bits which are currently not defined in the driver header file.
--- drivers/gpu/drm/i915/i915_reg.h | 64 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+)
drivers/gpu/drm/i915/i915_reg.h +64 -0
@@ -307,6 +307,70 @@#define LM_BURST_LENGTH 0x00000700#define LM_FIFO_WATERMARK 0x0000001F#define MI_ARB_STATE 0x020e4/* 915+ only */ +#define MI_ARB_MASK_SHIFT 16/* shift for enable bits */ + +/* Make render/texture TLB fetches lower priorty than associated data +* fetches. This is not turned on by default +*/ +#define MI_ARB_RENDER_TLB_LOW_PRIORITY (1 << 15) + +/* Isoch request wait on GTT enable (Display A/B/C streams). +* Make isoch requests stall on the TLB update. May cause +* display underruns (test mode only) +*/ +#define MI_ARB_ISOCH_WAIT_GTT (1 << 14) + +/* Block grant count for isoch requests when block count is +* set to a finite value. +*/ +#define MI_ARB_BLOCK_GRANT_MASK (3 << 12) +#define MI_ARB_BLOCK_GRANT_8 (0 << 12)/* for 3 display planes */ +#define MI_ARB_BLOCK_GRANT_4 (1 << 12)/* for 2 display planes */ +#define MI_ARB_BLOCK_GRANT_2 (2 << 12)/* for 1 display plane */ +#define MI_ARB_BLOCK_GRANT_0 (3 << 12)/* don't use */ + +/* Enable render writes to complete in C2/C3/C4 power states. +* If this isn't enabled, render writes are prevented in low +* power states. That seems bad to me. +*/ +#define MI_ARB_C3_LP_WRITE_ENABLE (1 << 11) + +/* This acknowledges an async flip immediately instead +* of waiting for 2TLB fetches. +*/ +#define MI_ARB_ASYNC_FLIP_ACK_IMMEDIATE (1 << 10) + +/* Enables non-sequential data reads through arbiter +*/ +#define MI_ARB_DUAL_DATA_PHASE_DISABLE (1 << 9) + +/* Disable FSB snooping of cacheable write cycles from binner/render +* command stream +*/ +#define MI_ARB_CACHE_SNOOP_DISABLE (1 << 8) + +/* Arbiter time slice for non-isoch streams */ +#define MI_ARB_TIME_SLICE_MASK (7 << 5) +#define MI_ARB_TIME_SLICE_1 (0 << 5) +#define MI_ARB_TIME_SLICE_2 (1 << 5) +#define MI_ARB_TIME_SLICE_4 (2 << 5) +#define MI_ARB_TIME_SLICE_6 (3 << 5) +#define MI_ARB_TIME_SLICE_8 (4 << 5) +#define MI_ARB_TIME_SLICE_10 (5 << 5) +#define MI_ARB_TIME_SLICE_14 (6 << 5) +#define MI_ARB_TIME_SLICE_16 (7 << 5) + +/* Low priority grace period page size */ +#define MI_ARB_LOW_PRIORITY_GRACE_4KB (0 << 4)/* default */ +#define MI_ARB_LOW_PRIORITY_GRACE_8KB (1 << 4) + +/* Disable display A/B trickle feed */ +#define MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE (1 << 2) + +/* Set display plane priority */ +#define MI_ARB_DISPLAY_PRIORITY_A_B (0 << 0)/* display A > display B */ +#define MI_ARB_DISPLAY_PRIORITY_B_A (1 << 0)/* display B > display A */ +#define CACHE_MODE_0 0x02120/* 915+ only */ #define CM0_MASK_SHIFT 16#define CM0_IZ_OPT_DISABLE (1<<6)
PATCH 34/165 drm/i915: enable low power render writes on GEN3 hardware.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Airlie <[email protected]>
commit 944001201ca0196bcdb088129e5866a9f379d08c upstream.
A lot of 945GMs have had stability issues for a long time, this manifested as X hangs, blitter engine hangs, and lots of crashes.
one such report is at:
https://bugs.freedesktop.org/show_bug.cgi?id=20560
along with numerous distro bugzillas.
This only took a week of digging and hair ripping to figure out.
Tracked down and tested on a 945GM Lenovo T60,
previously running
x11perf -copypixwin500
or
x11perf -copywinpix500
repeatedly would cause the GPU to wedge within 4 or 5 tries, with random busy bits set.
After this patch no hangs were observed.
--- drivers/gpu/drm/i915/i915_gem.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/gpu/drm/i915/i915_gem.c +10 -0
@@ -4697,6 +4697,16 @@ i915_gem_load(struct drm_device *dev)list_add (&dev_priv->mm.shrink_list, &shrink_list);spin_unlock (&shrink_list_lock); +/* On GEN3 we really need to make sure the ARB C3 LP bit is set */ +if (IS_I915G (dev) ||IS_I915GM (dev) ||IS_I945G (dev) ||IS_I945GM (dev) ||IS_G33 (dev)) { +u32 tmp =I915_READ (MI_ARB_STATE ); +if (!(tmp &MI_ARB_C3_LP_WRITE_ENABLE )) { +/* arb state is a masked write, so set bit + bit in mask */ + tmp =MI_ARB_C3_LP_WRITE_ENABLE | (MI_ARB_C3_LP_WRITE_ENABLE <<MI_ARB_MASK_SHIFT ); +I915_WRITE (MI_ARB_STATE , tmp); + } + } +/* Old X drivers will take 0-2 for front, back, depth buffers */ dev_priv->fence_reg_start =3 ;
PATCH 35/165 drm/i915: Make G4X-style PLL search more permissive
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Adam Jackson <[email protected]>
commit 6ba770dc5c334aff1c055c8728d34656e0f091e2 upstream.
Fixes an Ironlake laptop with a 68.940MHz 1280x800 panel and 120MHz SSC reference clock.
More generally, the 0.488% tolerance used before is just too tight to reliably find a PLL setting. I extracted the search algorithm and modified it to find the dot clocks with maximum error over the valid range for the given output type:
http://people.freedesktop.org/~ajax/intel_g4x_find_best_pll.c
This gave:
Worst dotclock for Ironlake DAC refclk is 350000kHz (error 0.00571) Worst dotclock for Ironlake SL-LVDS refclk is 102321kHz (error 0.00524) Worst dotclock for Ironlake DL-LVDS refclk is 219642kHz (error 0.00488) Worst dotclock for Ironlake SL-LVDS SSC refclk is 84374kHz (error 0.00529) Worst dotclock for Ironlake DL-LVDS SSC refclk is 183035kHz (error 0.00488) Worst dotclock for G4X SDVO refclk is 267600kHz (error 0.00448) Worst dotclock for G4X HDMI refclk is 334400kHz (error 0.00478) Worst dotclock for G4X SL-LVDS refclk is 95571kHz (error 0.00449) Worst dotclock for G4X DL-LVDS refclk is 224000kHz (error 0.00510)
--- drivers/gpu/drm/i915/intel_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/intel_display.c +2 -2
@@ -785,8 +785,8 @@ intel_g4x_find_best_PLL(const intel_limiintel_clock_t clock;int max_n;bool found; -/* approximately equals target * 0.00488 */ -int err_most = (target >>8 ) + (target >>10 ); +/* approximately equals target * 0.00585 */ +int err_most = (target >>8 ) + (target >>9 ); found = false;if (intel_pipe_has_type (crtc,INTEL_OUTPUT_LVDS )) {
PATCH 36/165 drm/radeon/r200: handle more hw tex coord types
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Roland Scheidegger <[email protected]>
commit 688acaa2897462e4c5e2482496e2868db0760809 upstream.
Code did not handle projected 2d and depth coordinates, meaning potentially set 3d or cube special handling might stick.
(Not sure what depth coord actually does, but I guess handling it like a normal coordinate is the right thing to do.)
Might be related to https://bugs.freedesktop.org/show_bug.cgi?id=26428
--- drivers/gpu/drm/radeon/r200.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/radeon/r200.c +2 -0
@@ -368,6 +368,8 @@ int r200_packet0_check(struct radeon_cs_/* 2D, 3D, CUBE */ switch (tmp) {case 0 : +case 3 : +case 4 :case 5 :case 6 :case 7 :
PATCH 37/165 drm/radeon/kms: add quirk for ASUS HD 3600 board
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alex Deucher <[email protected]>
commit e153b70b89770968a704eda0b55707c6066b2d44 upstream.
Connector is actually DVI rather than HDMI.
--- drivers/gpu/drm/radeon/radeon_atombios.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/gpu/drm/radeon/radeon_atombios.c +9 -0
@@ -161,6 +161,15 @@ static bool radeon_atom_apply_quirks(str } } +/* ASUS HD 3600 board lists the DVI port as HDMI */ +if ((dev->pdev->device ==0x9598 ) && + (dev->pdev->subsystem_vendor ==0x1043 ) && + (dev->pdev->subsystem_device ==0x01e4 )) { +if (*connector_type ==DRM_MODE_CONNECTOR_HDMIA ) { + *connector_type =DRM_MODE_CONNECTOR_DVII ; + } + } +/* ASUS HD 3450 board lists the DVI port as HDMI */ if ((dev->pdev->device == 0x95C5) && (dev->pdev->subsystem_vendor == 0x1043) &&
PATCH 38/165 drm/radeon/kms: fix legacy LVDS dpms sequence
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alex Deucher <[email protected]>
commit 15cb02c0a0338ee724bf23e31c7c410ecbffeeba upstream.
Add delay after turning off the LVDS encoder.
Fixes:
https://bugzilla.kernel.org/show_bug.cgi?id=16389
--- drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/radeon/radeon_legacy_encoders.c +1 -0
@@ -89,6 +89,7 @@ static void radeon_legacy_lvds_dpms(struudelay (panel_pwr_delay *1000 );WREG32 (RADEON_LVDS_GEN_CNTL , lvds_gen_cntl);WREG32_PLL (RADEON_PIXCLKS_CNTL , pixclks_cntl); +udelay (panel_pwr_delay *1000 );break ; }
PATCH 39/165 tpm_tis: fix subsequent suspend failures
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Rajiv Andrade <[email protected]>
commit 59f6fbe4291fcc078ba26ce4edf8373a7620a13a upstream.
Fix subsequent suspends by issuing tpm_continue_selftest during resume. Otherwise, the tpm chip seems to be not fully initialized and will reject the save state command during suspend, thus preventing the whole system to suspend.
Addresses https://bugzilla.kernel.org/show_bug.cgi?id=16256
--- drivers/char/tpm/tpm_tis.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/char/tpm/tpm_tis.c +8 -1
@@ -622,7 +622,14 @@ static int tpm_tis_pnp_suspend(struct pnstatic int tpm_tis_pnp_resume (struct pnp_dev *dev) { -return tpm_pm_resume (&dev->dev); +struct tpm_chip *chip =pnp_get_drvdata (dev); +int ret; + + ret =tpm_pm_resume (&dev->dev); +if (!ret) +tpm_continue_selftest (chip); + +return ret; }static struct pnp_device_id tpm_pnp_tbl[]__devinitdata = {
PATCH 40/165 ipvs: Add missing locking during connection table hashing and unhashing
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Sven Wegener <[email protected]>
commit aea9d711f3d68c656ad31ab578ecfb0bb5cd7f97 upstream.
The code that hashes and unhashes connections from the connection table is missing locking of the connection being modified, which opens up a race condition and results in memory corruption when this race condition is hit.
Here is what happens in pretty verbose form:
CPU 0 CPU 1
------------ ------------
An active connection is terminated and
we schedule ip_vs_conn_expire() on this
CPU to expire this connection.
IRQ assignment is changed to this CPU, but the expire timer stays scheduled on the other CPU.
New connection from same ip:port comes in right before the timer expires, we find the inactive connection in our connection table and get a reference to it. We proper lock the connection in tcp_state_transition() and read the connection flags in set_tcp_state().
ip_vs_conn_expire() gets called, we
unhash the connection from our
connection table and remove the hashed
flag in ip_vs_conn_unhash(), without
proper locking!
While still holding proper locks we write the connection flags in set_tcp_state() and this sets the hashed flag again.
ip_vs_conn_expire() fails to expire the
connection, because the other CPU has
incremented the reference count. We try
to re-insert the connection into our
connection table, but this fails inip_vs_conn_hash(), because the hashed
flag has been set by the other CPU. We
re-schedule execution ofip_vs_conn_expire(). Now this connection
has the hashed flag set, but isn't
actually hashed in our connection table
and has a dangling list_head.
We drop the reference we held on the connection and schedule the expire timer for timeouting the connection on this CPU. Further packets won't be able to find this connection in our connection table.
ip_vs_conn_expire() gets called again, we think it's already hashed, but the list_head is dangling and while removing the connection from our connection table we write to the memory location where this list_head points to.
The result will probably be a kernel oops at some other point in time.
This race condition is pretty subtle, but it can be triggered remotely. It needs the IRQ assignment change or another circumstance where packets coming from the same ip:port for the same service are being processed on different CPUs. And it involves hitting the exact time at which ip_vs_conn_expire() gets called. It can be avoided by making sure that all packets from one connection are always processed on the same CPU and can be made harder to exploit by changing the connection timeouts to some custom values.
--- net/netfilter/ipvs/ip_vs_conn.c | 4 ++++ 1 file changed, 4 insertions(+)
net/netfilter/ipvs/ip_vs_conn.c +4 -0
@@ -146,6 +146,7 @@ static inline int ip_vs_conn_hash(struct hash =ip_vs_conn_hashkey (cp->af, cp->protocol, &cp->caddr, cp->cport);ct_write_lock (hash); +spin_lock (&cp->lock);if (!(cp->flags &IP_VS_CONN_F_HASHED )) {list_add (&cp->c_list, &ip_vs_conn_tab[hash]);
@@ -158,6 +159,7 @@ static inline int ip_vs_conn_hash(struct ret =0 ; } +spin_unlock (&cp->lock);ct_write_unlock (hash);return ret;
@@ -177,6 +179,7 @@ static inline int ip_vs_conn_unhash(stru hash =ip_vs_conn_hashkey (cp->af, cp->protocol, &cp->caddr, cp->cport);ct_write_lock (hash); +spin_lock (&cp->lock);if (cp->flags &IP_VS_CONN_F_HASHED ) {list_del (&cp->c_list);
@@ -186,6 +189,7 @@ static inline int ip_vs_conn_unhash(stru }else ret =0 ; +spin_unlock (&cp->lock);ct_write_unlock (hash);return ret;
PATCH 41/165 netfilter: ip6t_REJECT: fix a dst leak in ipv6 REJECT
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Eric Dumazet <[email protected]>
commit 499031ac8a3df6738f6186ded9da853e8ea18253 upstream.
We should release dst if dst->error is set.
Bug introduced in 2.6.14 by commit e104411b82f5c ([XFRM]: Always release dst_entry on error in xfrm_lookup)
--- net/ipv6/netfilter/ip6t_REJECT.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/ipv6/netfilter/ip6t_REJECT.c +4 -2
@@ -95,9 +95,11 @@ static void send_reset(struct net *net, fl.fl_ip_dport = otcph.source;security_skb_classify_flow (oldskb, &fl); dst =ip6_route_output (net,NULL , &fl); -if (dst ==NULL ) +if (dst ==NULL || dst->error) { +dst_release (dst);return ; -if (dst->error ||xfrm_lookup (net, &dst, &fl,NULL ,0 )) + } +if (xfrm_lookup (net, &dst, &fl,NULL ,0 ))return ; hh_len = (dst->dev->hard_header_len +15 )&~15 ;
PATCH 42/165 SCSI: aacraid: Eliminate use after free
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Julia Lawall <[email protected]>
commit 8a52da632ceb9d8b776494563df579e87b7b586b upstream.
The debugging code using the freed structure is moved before the kfree.
A simplified version of the semantic match that finds this problem is as
follows: (http://coccinelle.lip6.fr/)
// <smpl>
@free@
expression E;
position p;
@@
kfree@p(E)
@@
expression free.E, subE<=free.E, E1;
position free.p;
@@
kfree@p(E)
...
(
subE = E1
|
* E
)
// </smpl>
--- drivers/scsi/aacraid/commctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/aacraid/commctrl.c +2 -2
@@ -655,9 +655,9 @@ static int aac_send_raw_srb(struct aac_d/* Does this really need to be GFP_DMA? */ p =kmalloc (usg->sg[i].count,GFP_KERNEL |__GFP_DMA);if (!p) { -kfree (usg); -dprintk ((KERN_DEBUG "aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n" , +dprintk ((KERN_DEBUG "aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n" , usg->sg[i].count,i,usg->count)); +kfree (usg); rcode = -ENOMEM ; goto cleanup; }
PATCH 43/165 amd64-agp: Probe unknown AGP devices the right way
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ben Hutchings <[email protected]>
commit 6fd024893911dcb51b4a0aa71971db5ba38f7071 upstream.
The current initialisation code probes 'unsupported' AGP devices simply by calling its own probe function. It does not lock these devices or even check whether another driver is already bound to them.
We must use the device core to manage this. So if the specific device id table didn't match anything and agp_try_unsupported=1, switch the device id table and call driver_attach() again.
--- drivers/char/agp/amd64-agp.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-)
drivers/char/agp/amd64-agp.c +15 -12
@@ -499,6 +499,10 @@ static int __devinit agp_amd64_probe(stru8 cap_ptr;int err; +/* The Highlander principle */ +if (agp_bridges_found) +return -ENODEV ; + cap_ptr =pci_find_capability (pdev,PCI_CAP_ID_AGP );if (!cap_ptr)return -ENODEV ;
@@ -562,6 +566,8 @@ static void __devexit agp_amd64_remove(s amd64_aperture_sizes[bridge->aperture_size_idx].size);agp_remove_bridge (bridge);agp_put_bridge (bridge); + + agp_bridges_found--; }#ifdef CONFIG_PM
@@ -709,6 +715,11 @@ static struct pci_device_id agp_amd64_pcMODULE_DEVICE_TABLE (pci, agp_amd64_pci_table); +static DEFINE_PCI_DEVICE_TABLE (agp_amd64_pci_promisc_table) = { + {PCI_DEVICE_CLASS (0 ,0 ) }, + { } +}; +static struct pci_driver agp_amd64_pci_driver = { .name ="agpgart-amd64" , .id_table = agp_amd64_pci_table,
@@ -733,7 +744,6 @@ int __init agp_amd64_init(void)return err;if (agp_bridges_found ==0 ) { -struct pci_dev *dev;if (!agp_try_unsupported && !agp_try_unsupported_boot) { printk(KERN_INFO PFX "No supported AGP bridge found.\n");#ifdef MODULE
@@ -749,17 +759,10 @@ int __init agp_amd64_init(void)return -ENODEV ;/* Look for any AGP bridge */ - dev =NULL ; - err = -ENODEV ; -for_each_pci_dev (dev) { -if (!pci_find_capability (dev,PCI_CAP_ID_AGP )) -continue ; -/* Only one bridge supported right now */ -if (agp_amd64_probe (dev,NULL ) ==0 ) { - err =0 ; -break ; - } - } + agp_amd64_pci_driver.id_table = agp_amd64_pci_promisc_table; + err =driver_attach (&agp_amd64_pci_driver.driver); +if (err ==0 && agp_bridges_found ==0 ) + err = -ENODEV ; }return err; }
PATCH 44/165 perf: Resurrect flat callchains
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Frederic Weisbecker <[email protected]>
commit 97aa1052739c6a06cb6b0467dbf410613d20bc97 upstream.
Initialize the callchain radix tree root correctly.
When we walk through the parents, we must stop after the root, but since it wasn't well initialized, its parent pointer was random.
Also the number of hits was random because uninitialized, hence it was part of the callchain while the root doesn't contain anything.
This fixes segfaults and percentages followed by empty callchains while running:
perf report -g flat
--- tools/perf/util/callchain.h | 3 +++ 1 file changed, 3 insertions(+)
tools/perf/util/callchain.h +3 -0
@@ -48,6 +48,9 @@ static inline void callchain_init(structINIT_LIST_HEAD (&node->brothers);INIT_LIST_HEAD (&node->children);INIT_LIST_HEAD (&node->val); + + node->parent =NULL ; + node->hit =0 ; }static inline u64 cumul_hits (struct callchain_node *node)
PATCH 45/165 x86: Fix vsyscall on gcc 4.5 with -Os
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andi Kleen <[email protected]>
commit 124482935fb7fb9303c8a8ab930149c6a93d9910 upstream.
This fixes the -Os breaks with gcc 4.5 bug. rdtsc_barrier needs to be force inlined, otherwise user space will jump into kernel space and kill init.
This also addresses http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44129
I believe.
LKML-Reference: <[email protected]>
--- arch/x86/include/asm/system.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/system.h +1 -1
@@ -449,7 +449,7 @@ void stop_this_cpu(void *dummy);* * (Could use an alternative three way for this if there was one.) */ -static inline void rdtsc_barrier (void ) +static __always_inline void rdtsc_barrier(void) {alternative (ASM_NOP3 ,"mfence" ,X86_FEATURE_MFENCE_RDTSC );alternative (ASM_NOP3 ,"lfence" ,X86_FEATURE_LFENCE_RDTSC );
PATCH 46/165 x86, Calgary: Increase max PHB number
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Darrick J. Wong <[email protected]>
commit 499a00e92dd9a75395081f595e681629eb1eebad upstream.
Newer systems (x3950M2) can have 48 PHBs per chassis and 8 chassis, so bump the limits up and provide an explanation of the requirements for each class.
LKML-Reference: <[email protected]>
--- arch/x86/kernel/pci-calgary_64.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
arch/x86/kernel/pci-calgary_64.c +10 -5
@@ -102,11 +102,16 @@ int use_calgary __read_mostly = 0;#define PMR_SOFTSTOPFAULT 0x40000000#define PMR_HARDSTOP 0x20000000 -#define MAX_NUM_OF_PHBS 8/* how many PHBs in total? */ -#define MAX_NUM_CHASSIS 8/* max number of chassis */ -/* MAX_PHB_BUS_NUM is the maximal possible dev->bus->number */ -#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2) -#define PHBS_PER_CALGARY 4 +/* +* The maximum PHB bus number. +* x3950M2 (rare): 8 chassis, 48 PHBs per chassis = 384 +* x3950M2: 4 chassis, 48 PHBs per chassis = 192 +* x3950 (PCIE): 8 chassis, 32 PHBs per chassis = 256 +* x3950 (PCIX): 8 chassis, 16 PHBs per chassis = 128 +*/ +#define MAX_PHB_BUS_NUM 384 + +#define PHBS_PER_CALGARY 4/* register offsets in Calgary's internal register space */ static const unsigned long tar_offsets[] = {
PATCH 47/165 x86, Calgary: Limit the max PHB number to 256
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Darrick J. Wong <[email protected]>
commit d596043d71ff0d7b3d0bead19b1d68c55f003093 upstream.
The x3950 family can have as many as 256 PCI buses in a single system, so change the limits to the maximum. Since there can only be 256 PCI buses in one domain, we no longer need the BUG_ON check.
LKML-Reference: <[email protected]>
--- arch/x86/kernel/pci-calgary_64.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
arch/x86/kernel/pci-calgary_64.c +1 -3
@@ -109,7 +109,7 @@ int use_calgary __read_mostly = 0;* x3950 (PCIE): 8 chassis, 32 PHBs per chassis = 256 * x3950 (PCIX): 8 chassis, 16 PHBs per chassis = 128 */ -#define MAX_PHB_BUS_NUM 384 +#define MAX_PHB_BUS_NUM 256#define PHBS_PER_CALGARY 4
@@ -1058,8 +1058,6 @@ static int __init calgary_init_one(strucstruct iommu_table *tbl;int ret; -BUG_ON (dev->bus->number >=MAX_PHB_BUS_NUM ); - bbar =busno_to_bbar (dev->bus->number); ret =calgary_setup_tar (dev, bbar);if (ret)
PATCH 48/165 sched: Prevent compiler from optimising the sched_avg_update() loop
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Will Deacon <[email protected]>
commit 0d98bb2656e9bd2dfda2d089db1fe1dbdab41504 upstream.
GCC 4.4.1 on ARM has been observed to replace the while loop in sched_avg_update with a call to uldivmod, resulting in the following build failure at link-time:
kernel/built-in.o: In function `sched_avg_update':
kernel/sched.c:1261: undefined reference to __aeabi_uldivmod' kernel/sched.c:1261: undefined reference to __aeabi_uldivmod'
make: *** [.tmp_vmlinux1] Error 1
This patch introduces a fake data hazard to the loop body to prevent the compiler optimising the loop away.
--- kernel/sched.c | 6 ++++++ 1 file changed, 6 insertions(+)
kernel/sched.c +6 -0
@@ -1261,6 +1261,12 @@ static void sched_avg_update(struct rq *s64 period =sched_avg_period ();while ((s64)(rq->clock - rq->age_stamp) > period) { +/* +* Inline assembly required to prevent the compiler +* optimising this loop into a divmod call. +* See __iter_div_u64_rem() for another example of this. +*/ + asm("" :"+rm" (rq->age_stamp)); rq->age_stamp += period; rq->rt_avg /=2 ; }
PATCH 49/165 sched: Fix over-scheduling bug
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alex,Shi <[email protected]>
commit 3c93717cfa51316e4dbb471e7c0f9d243359d5f8 upstream.
Commit e70971591 ("sched: Optimize unused cgroup configuration") introduced an imbalanced scheduling bug.
If we do not use CGROUP, function update_h_load won't update h_load. When the system has a large number of tasks far more than logical CPU number, the incorrect cfs_rq[cpu]->h_load value will cause load_balance() to pull too many tasks to the local CPU from the busiest CPU. So the busiest CPU keeps going in a round robin. That will hurt performance.
The issue was found originally by a scientific calculation workload that developed by Yanmin. With that commit, the workload performance drops about 40%.
CPU before after
00 : 2 : 7 01 : 1 : 7 02 : 11 : 6 03 : 12 : 7 04 : 6 : 6 05 : 11 : 7 06 : 10 : 6 07 : 12 : 7 08 : 11 : 6 09 : 12 : 6 10 : 1 : 6 11 : 1 : 6 12 : 6 : 6 13 : 2 : 6 14 : 2 : 6 15 : 1 : 6
LKML-Reference: <1276754893.9452.5442.camel@debian>
--- kernel/sched.c | 3 --- 1 file changed, 3 deletions(-)
kernel/sched.c +0 -3
@@ -1717,9 +1717,6 @@ static void update_shares_locked(structstatic void update_h_load (long cpu) { -if (root_task_group_empty ()) -return ; -walk_tg_tree (tg_load_down, tg_nop, (void *)cpu); }
PATCH 50/165 genirq: Deal with desc->set_type() changing desc->chip
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Thomas Gleixner <[email protected]>
commit 4673247562e39a17e09440fa1400819522ccd446 upstream.
The set_type() function can change the chip implementation when the trigger mode changes. That might result in using an non-initialized irq chip when called from __setup_irq() or when called via set_irq_type() on an already enabled irq.
The set_irq_type() function should not be called on an enabled irq, but because we forgot to put a check into it, we have a bunch of users which grew the habit of doing that and it never blew up as the function is serialized via desc->lock against all users of desc->chip and they never hit the non-initialized irq chip issue.
The easy fix for the __setup_irq() issue would be to move the irq_chip_set_defaults(desc->chip) call after the trigger setting to make sure that a chip change is covered.
But as we have already users, which do the type setting after request_irq(), the safe fix for now is to call irq_chip_set_defaults() from __irq_set_trigger() when desc->set_type() changed the irq chip.
It needs a deeper analysis whether we should refuse to change the chip on an already enabled irq, but that'd be a large scale change to fix all the existing users. So that's neither stable nor 2.6.35 material.
--- kernel/irq/manage.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/irq/manage.c +3 -0
@@ -436,6 +436,9 @@ int __irq_set_trigger(struct irq_desc *d/* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */ desc->status &= ~(IRQ_LEVEL |IRQ_TYPE_SENSE_MASK ); desc->status |= flags; + +if (chip != desc->chip) +irq_chip_set_defaults (desc->chip); }return ret;
PATCH 51/165 serial: cpm_uart: implement the cpm_uart_early_write() function for console poll
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dongdong Deng <[email protected]>
commit 8cd774ad30c22b9d89823f1f05d845f4cdaba9e8 upstream.
The cpm_uart_early_write() function which was used for console poll isn't implemented in the cpm uart driver.
Implementing this function both fixes the build when CONFIG_CONSOLE_POLL is set and allows kgdboc to work via the cpm uart.
--- drivers/serial/cpm_uart/cpm_uart_core.c | 143 +++++++++++++++++--------------- 1 file changed, 79 insertions(+), 64 deletions(-)
drivers/serial/cpm_uart/cpm_uart_core.c +79 -64
@@ -930,6 +930,83 @@ static void cpm_uart_config_port(struct } } +#if defined(CONFIG_CONSOLE_POLL ) || defined(CONFIG_SERIAL_CPM_CONSOLE ) +/* +* Write a string to the serial port +* Note that this is called with interrupts already disabled +*/ +static void cpm_uart_early_write (struct uart_cpm_port *pinfo, +const char *string,u_int count) +{ +unsigned int i; +cbd_t __iomem *bdp, *bdbase; +unsigned char *cpm_outp_addr; + +/* Get the address of the host memory buffer. +*/ + bdp = pinfo->tx_cur; + bdbase = pinfo->tx_bd_base; + +/* +* Now, do each character. This is not as bad as it looks +* since this is a holding FIFO and not a transmitting FIFO. +* We could add the complexity of filling the entire transmit +* buffer, but we would just wait longer between accesses...... +*/ +for (i =0 ; i < count; i++, string++) { +/* Wait for transmitter fifo to empty. +* Ready indicates output is ready, and xmt is doing +* that, not that it is ready for us to send. +*/ +while ((in_be16 (&bdp->cbd_sc) &BD_SC_READY ) !=0 ) + ; + +/* Send the character out. +* If the buffer address is in the CPM DPRAM, don't +* convert it. +*/ + cpm_outp_addr =cpm2cpu_addr (in_be32 (&bdp->cbd_bufaddr), + pinfo); + *cpm_outp_addr = *string; + +out_be16 (&bdp->cbd_datlen,1 ); +setbits16 (&bdp->cbd_sc,BD_SC_READY ); + +if (in_be16 (&bdp->cbd_sc) &BD_SC_WRAP ) + bdp = bdbase; +else + bdp++; + +/* if a LF, also do CR... */ +if (*string ==10 ) { +while ((in_be16 (&bdp->cbd_sc) &BD_SC_READY ) !=0 ) + ; + + cpm_outp_addr =cpm2cpu_addr (in_be32 (&bdp->cbd_bufaddr), + pinfo); + *cpm_outp_addr =13 ; + +out_be16 (&bdp->cbd_datlen,1 ); +setbits16 (&bdp->cbd_sc,BD_SC_READY ); + +if (in_be16 (&bdp->cbd_sc) &BD_SC_WRAP ) + bdp = bdbase; +else + bdp++; + } + } + +/* +* Finally, Wait for transmitter & holding register to empty +* and restore the IER +*/ +while ((in_be16 (&bdp->cbd_sc) &BD_SC_READY ) !=0 ) + ; + + pinfo->tx_cur = bdp; +} +#endif +#ifdef CONFIG_CONSOLE_POLL /* Serial polling routines for writing and reading from the uart while * in an interrupt or debug context.
@@ -999,7 +1076,7 @@ static void cpm_put_poll_char(struct uarstatic char ch[2 ]; ch[0 ] = (char )c; - cpm_uart_early_write(pinfo->port.line, ch, 1); + cpm_uart_early_write(pinfo, ch, 1); }#endif /* CONFIG_CONSOLE_POLL */
@@ -1130,9 +1207,6 @@ static void cpm_uart_console_write(struc u_int count) {struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; -unsigned int i; -cbd_t __iomem *bdp, *bdbase; -unsigned char *cp;unsigned long flags;int nolock = oops_in_progress;
@@ -1142,66 +1216,7 @@ static void cpm_uart_console_write(strucspin_lock_irqsave (&pinfo->port.lock, flags); } -/* Get the address of the host memory buffer. -*/ - bdp = pinfo->tx_cur; - bdbase = pinfo->tx_bd_base; - -/* -* Now, do each character. This is not as bad as it looks -* since this is a holding FIFO and not a transmitting FIFO. -* We could add the complexity of filling the entire transmit -* buffer, but we would just wait longer between accesses...... -*/ -for (i =0 ; i < count; i++, s++) { -/* Wait for transmitter fifo to empty. -* Ready indicates output is ready, and xmt is doing -* that, not that it is ready for us to send. -*/ -while ((in_be16 (&bdp->cbd_sc) &BD_SC_READY ) !=0 ) - ; - -/* Send the character out. -* If the buffer address is in the CPM DPRAM, don't -* convert it. -*/ - cp =cpm2cpu_addr (in_be32 (&bdp->cbd_bufaddr), pinfo); - *cp = *s; - -out_be16 (&bdp->cbd_datlen,1 ); -setbits16 (&bdp->cbd_sc,BD_SC_READY ); - -if (in_be16 (&bdp->cbd_sc) &BD_SC_WRAP ) - bdp = bdbase; -else - bdp++; - -/* if a LF, also do CR... */ -if (*s ==10 ) { -while ((in_be16 (&bdp->cbd_sc) &BD_SC_READY ) !=0 ) - ; - - cp =cpm2cpu_addr (in_be32 (&bdp->cbd_bufaddr), pinfo); - *cp =13 ; - -out_be16 (&bdp->cbd_datlen,1 ); -setbits16 (&bdp->cbd_sc,BD_SC_READY ); - -if (in_be16 (&bdp->cbd_sc) &BD_SC_WRAP ) - bdp = bdbase; -else - bdp++; - } - } - -/* -* Finally, Wait for transmitter & holding register to empty -* and restore the IER -*/ -while ((in_be16 (&bdp->cbd_sc) &BD_SC_READY ) !=0 ) - ; - - pinfo->tx_cur = bdp; +cpm_uart_early_write (pinfo, s, count);if (unlikely (nolock)) {local_irq_restore (flags);
PATCH 52/165 cmd640: fix kernel oops in test_irq() method
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Sergei Shtylyov <[email protected]>
commit a9ddabc52ce3757a4331d6c1e8bf4065333cc51b upstream.
When implementing the test_iqr() method, I forgot that this driver is not an ordinary PCI driver and also needs to support VLB variant of the chip. Moreover, 'hwif->dev' should be NULL, potentially causing oops in pci_read_config_byte().
--- drivers/ide/cmd640.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/ide/cmd640.c +2 -4
@@ -632,12 +632,10 @@ static void cmd640_init_dev(ide_drive_tstatic int cmd640_test_irq (ide_hwif_t *hwif) { -struct pci_dev *dev =to_pci_dev (hwif->dev);int irq_reg = hwif->channel ?ARTTIM23 :CFR ; -u8 irq_stat, irq_mask = hwif->channel ?ARTTIM23_IDE23INTR : +u8 irq_mask = hwif->channel ?ARTTIM23_IDE23INTR :CFR_IDE01INTR ; - -pci_read_config_byte (dev, irq_reg, &irq_stat); +u8 irq_stat =get_cmd640_reg (irq_reg);return (irq_stat & irq_mask) ?1 :0 ; }
PATCH 53/165 ide: Fix IDE taskfile with cfq scheduler
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Mikulas Patocka <[email protected]>
commit 720fc22a7af79d91ec460c80efa92c65c12d105e upstream.
When ide taskfile access is being used (for example with hdparm --security commands) and cfq scheduler is selected, the scheduler crashes on BUG in cfq_put_request.
The reason is that the cfq scheduler is tracking counts of read and write requests separately; the ide-taskfile subsystem allocates a read request and then flips the flag to make it a write request. The counters in cfq will mismatch.
This patch changes ide-taskfile to allocate the READ or WRITE request as required and don't change the flag later.
--- drivers/ide/ide-taskfile.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/ide/ide-taskfile.c +2 -4
@@ -428,13 +428,11 @@ int ide_raw_taskfile(ide_drive_t *drive, {struct request *rq;int error; +int rw = !(cmd->tf_flags &IDE_TFLAG_WRITE ) ?READ :WRITE ; - rq =blk_get_request (drive->queue,READ , __GFP_WAIT); + rq =blk_get_request (drive->queue, rw, __GFP_WAIT); rq->cmd_type =REQ_TYPE_ATA_TASKFILE ; -if (cmd->tf_flags &IDE_TFLAG_WRITE ) - rq->cmd_flags |=REQ_RW ; -/* * (ks) We transfer currently only whole sectors. * This is suffient for now. But, it would be great,
PATCH 54/165 net/core: neighbour update Oops
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Doug Kehn <[email protected]>
commit 91a72a70594e5212c97705ca6a694bd307f7a26b upstream.
When configuring DMVPN (GRE + openNHRP) and a GRE remote address is configured a kernel Oops is observed. The obserseved Oops is caused by a NULL header_ops pointer (neigh->dev->header_ops) in neigh_update_hhs() when
void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *) = neigh->dev->header_ops->cache_update;
is executed. The dev associated with the NULL header_ops is the GRE interface. This patch guards against the possibility that header_ops is NULL.
This Oops was first observed in kernel version 2.6.26.8.
--- net/core/neighbour.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/core/neighbour.c +4 -1
@@ -945,7 +945,10 @@ static void neigh_update_hhs(struct neig {struct hh_cache *hh;void (*update)(struct hh_cache *,const struct net_device *,const unsigned char *) - = neigh->dev->header_ops->cache_update; + =NULL ; + +if (neigh->dev->header_ops) + update = neigh->dev->header_ops->cache_update;if (update) {for (hh = neigh->hh; hh; hh = hh->hh_next) {
PATCH 55/165 tcp: fix crash in tcp_xmit_retransmit_queue
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ilpo Järvinen <[email protected]>
commit 45e77d314585869dfe43c82679f7e08c9b35b898 upstream.
It can happen that there are no packets in queue while calling tcp_xmit_retransmit_queue(). tcp_write_queue_head() then returns NULL and that gets deref'ed to get sacked into a local var.
There is no work to do if no packets are outstanding so we just exit early.
This oops was introduced by 08ebd1721ab8fd (tcp: remove tp->lost_out guard to make joining diff nicer).
--- net/ipv4/tcp_output.c | 3 +++ 1 file changed, 3 insertions(+)
net/ipv4/tcp_output.c +3 -0
@@ -2037,6 +2037,9 @@ void tcp_xmit_retransmit_queue(struct soint mib_idx;int fwd_rexmitting =0 ; +if (!tp->packets_out) +return ; +if (!tp->lost_out) tp->retransmit_high = tp->snd_una;
PATCH 56/165 rtc: fix ds1388 time corruption
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Joakim Tjernlund <[email protected]>
commit 96fc3a45ea073136566f3c2676cad52f8b39a7df upstream.
The ds1307 driver misreads the ds1388 registers when checking for 12 or 24 hour mode. Instead of checking the hour register it reads the minute register. Therefore the driver thinks minutes >= 40 has the 12HR bit set and resets the minute register by zeroing the high bits. This results in minutes are reset to 0-9, jumping back in time 40 or 50 minutes. The time jump is also written back to the RTC.
--- drivers/rtc/rtc-ds1307.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/rtc/rtc-ds1307.c +2 -2
@@ -775,7 +775,7 @@ static int __devinit ds1307_probe(struct read_rtc:/* read RTC registers */ - tmp = ds1307->read_block_data (ds1307->client,0 ,8 , buf); + tmp = ds1307->read_block_data (ds1307->client, ds1307->offset,8 , buf);if (tmp !=8 ) {pr_debug ("read error %d\n" , tmp); err = -EIO ;
@@ -860,7 +860,7 @@ read_rtc:if (ds1307->regs[DS1307_REG_HOUR ] &DS1307_BIT_PM ) tmp +=12 ;i2c_smbus_write_byte_data (client, -DS1307_REG_HOUR , + ds1307->offset +DS1307_REG_HOUR ,bin2bcd (tmp)); }
PATCH 57/165 ethtool: Fix potential kernel buffer overflow in ETHTOOL_GRXCLSRLALL
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ben Hutchings <[email protected]>
commit db048b69037e7fa6a7d9e95a1271a50dc08ae233 upstream.
On a 32-bit machine, info.rule_cnt >= 0x40000000 leads to integer overflow and the buffer may be smaller than needed. Since ETHTOOL_GRXCLSRLALL is unprivileged, this can presumably be used for at least denial of service.
--- net/core/ethtool.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/core/ethtool.c +3 -2
@@ -244,8 +244,9 @@ static int ethtool_get_rxnfc(struct net_if (info.cmd ==ETHTOOL_GRXCLSRLALL ) {if (info.rule_cnt >0 ) { - rule_buf =kmalloc (info.rule_cnt *sizeof (u32), -GFP_USER ); +if (info.rule_cnt <=KMALLOC_MAX_SIZE /sizeof (u32)) + rule_buf =kmalloc (info.rule_cnt *sizeof (u32), +GFP_USER );if (!rule_buf)return -ENOMEM ; }
PATCH 58/165 sdhci-s3c: add missing remove function
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Marek Szyprowski <[email protected]>
commit 9d51a6b2487724e8713cd2794cf09ffeee5f6932 upstream.
System will crash sooner or later once the memory with the code of the s3c-sdhci.ko module is reused for something else. I really have no idea how the lack of remove function went unnoticed into the mainline code.
--- drivers/mmc/host/sdhci-s3c.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
drivers/mmc/host/sdhci-s3c.c +20 -0
@@ -372,6 +372,26 @@ static int __devinit sdhci_s3c_probe(str static int __devexit sdhci_s3c_remove(struct platform_device *pdev) { +struct sdhci_host *host =platform_get_drvdata (pdev); +struct sdhci_s3c *sc =sdhci_priv (host); +int ptr; + +sdhci_remove_host (host,1 ); + +for (ptr =0 ; ptr <3 ; ptr++) { +clk_disable (sc->clk_bus[ptr]); +clk_put (sc->clk_bus[ptr]); + } +clk_disable (sc->clk_io); +clk_put (sc->clk_io); + +iounmap (host->ioaddr); +release_resource (sc->ioarea); +kfree (sc->ioarea); + +sdhci_free_host (host); +platform_set_drvdata (pdev,NULL ); +return 0 ; }
PATCH 59/165 ASoC: Remove duplicate AUX definition from WM8776
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Mark Brown <[email protected]>
commit 3c0709396df0869786f83e4b2d2d687c70ee886d upstream.
--- sound/soc/codecs/wm8776.c | 1 - 1 file changed, 1 deletion(-)
sound/soc/codecs/wm8776.c +0 -1
@@ -93,7 +93,6 @@ SOC_DAPM_SINGLE("Bypass Switch", WM8776_static const struct snd_soc_dapm_widget wm8776_dapm_widgets[] = {SND_SOC_DAPM_INPUT ("AUX" ), -SND_SOC_DAPM_INPUT ("AUX" ),SND_SOC_DAPM_INPUT ("AIN1" ),SND_SOC_DAPM_INPUT ("AIN2" ),
PATCH 60/165 x86: Fix x2apic preenabled system with kexec
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Yinghai Lu <[email protected]>
commit fd19dce7ac07973f700b0f13fb7f94b951414a4c upstream.
Found one x2apic system kexec loop test failed
when CONFIG_NMI_WATCHDOG=y (old) or CONFIG_LOCKUP_DETECTOR=y (current tip)
first kernel can kexec second kernel, but second kernel can not kexec third one.
it can be duplicated on another system with BIOS preenabled x2apic. First kernel can not kexec second kernel.
It turns out, when kernel boot with pre-enabled x2apic, it will not execute disable_local_APIC on shutdown path.
when init_apic_mappings() is called in setup_arch, it will skip setting of apic_phys when x2apic_mode is set. ( x2apic_mode is much early check_x2apic()) Then later, disable_local_APIC() will bail out early because !apic_phys.
So check !x2apic_mode in x2apic_mode in disable_local_APIC with !apic_phys.
another solution could be updating init_apic_mappings() to set apic_phys even for preenabled x2apic system. Actually even for x2apic system, that lapic address is mapped already in early stage.
BTW: is there any x2apic preenabled system with apicid of boot cpu > 255?
LKML-Reference: <[email protected]>
--- arch/x86/kernel/apic/apic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/apic/apic.c +1 -1
@@ -941,7 +941,7 @@ void disable_local_APIC(void)unsigned int value;/* APIC hasn't been mapped yet */ -if (!apic_phys) +if (!x2apic_mode && !apic_phys)return ;clear_local_APIC ();
PATCH 61/165 IPoIB: Fix world-writable child interface control sysfs attributes
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Or Gerlitz <[email protected]>
commit 7a52b34b07122ff5f45258d47f260f8a525518f0 upstream.
Sumeet Lahorani <[email protected]> reported that the IPoIB child entries are world-writable; however we don't want ordinary users to be able to create and destroy child interfaces, so fix them to be writable only by root.
--- drivers/infiniband/ulp/ipoib/ipoib_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/ulp/ipoib/ipoib_main.c +2 -2
@@ -1163,7 +1163,7 @@ static ssize_t create_child(struct devicreturn ret ? ret : count; } -static DEVICE_ATTR(create_child, S_IWUGO, NULL, create_child); +static DEVICE_ATTR(create_child, S_IWUSR, NULL, create_child); static ssize_t delete_child(struct device *dev, struct device_attribute *attr,
@@ -1183,7 +1183,7 @@ static ssize_t delete_child(struct devicreturn ret ? ret : count; } -static DEVICE_ATTR(delete_child, S_IWUGO, NULL, delete_child); +static DEVICE_ATTR(delete_child, S_IWUSR, NULL, delete_child);int ipoib_add_pkey_attr (struct net_device *dev) {
PATCH 62/165 Input: i8042 - add Gigabyte Spring Peak to dmi_noloop_table
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Kamal Mostafa <[email protected]>
commit 3e1bbc8d5018a05c0793c8a32b777a1396eb4414 upstream.
Gigabyte "Spring Peak" notebook indicates wrong chassis-type, tripping up i8042 and breaking the touchpad. Add this model to i8042_dmi_noloop_table[] to resolve.
--- drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/input/serio/i8042-x86ia64io.h +7 -0
@@ -166,6 +166,13 @@ static const struct dmi_system_id __init }, }, { +/* Gigabyte Spring Peak - defines wrong chassis type */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"GIGABYTE" ), + DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"), + }, + }, + { .matches = {DMI_MATCH (DMI_SYS_VENDOR ,"Hewlett-Packard" ), DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
PATCH 63/165 Input: twl40300-keypad - fix handling of "all ground" rows
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dmitry Torokhov <[email protected]>
commit 3fea60261e73dbf4a51130d40cafcc8465b0f2c3 upstream.
The Nokia RX51 board code (arch/arm/mach-omap2/board-rx51-peripherals.c) defines a key map for the matrix keypad keyboard. The hardware seems to use all of the 8 rows and 8 columns of the keypad, although not all possible locations are used.
The TWL4030 supports keypads with at most 8 rows and 8 columns. Most keys are defined with a row and column number between 0 and 7, except
KEY(0xff, 2, KEY_F9),
KEY(0xff, 4, KEY_F10),
KEY(0xff, 5, KEY_F11),which represent keycodes that should be emitted when entire row is connected to the ground. since the driver handles this case as if we had an extra column in the key matrix. Unfortunately we do not allocate enough space and end up owerwriting some random memory.
--- arch/arm/mach-omap2/board-rx51-peripherals.c | 17 ++++++++++++++--- drivers/input/keyboard/twl4030_keypad.c | 17 +++++++++++------ 2 files changed, 25 insertions(+), 9 deletions(-)
arch/arm/mach-omap2/board-rx51-peripherals.c +14 -3
@@ -37,6 +37,10 @@#define SYSTEM_REV_S_USES_VAUX3 0x8static int board_keymap[] = { +/* +* Note that KEY(x, 8, KEY_XXX) entries represent "entrire row +* connected to the ground" matrix state. +*/ KEY (0 ,0 ,KEY_Q ),KEY (0 ,1 ,KEY_O ),KEY (0 ,2 ,KEY_P ),
@@ -44,6 +48,7 @@ static int board_keymap[] = {KEY (0 ,4 ,KEY_BACKSPACE ),KEY (0 ,6 ,KEY_A ),KEY (0 ,7 ,KEY_S ), +KEY (1 ,0 ,KEY_W ),KEY (1 ,1 ,KEY_D ), KEY(1, 2, KEY_F),
@@ -52,6 +57,7 @@ static int board_keymap[] = {KEY (1 ,5 ,KEY_J ),KEY (1 ,6 ,KEY_K ),KEY (1 ,7 ,KEY_L ), +KEY (2 ,0 ,KEY_E ),KEY (2 ,1 ,KEY_DOT ), KEY(2, 2, KEY_UP),
@@ -59,6 +65,8 @@ static int board_keymap[] = {KEY (2 ,5 ,KEY_Z ),KEY (2 ,6 ,KEY_X ),KEY (2 ,7 ,KEY_C ), +KEY (2 ,8 ,KEY_F9 ), +KEY (3 ,0 ,KEY_R ),KEY (3 ,1 ,KEY_V ), KEY(3, 2, KEY_B),
@@ -67,20 +75,23 @@ static int board_keymap[] = {KEY (3 ,5 ,KEY_SPACE ),KEY (3 ,6 ,KEY_SPACE ),KEY (3 ,7 ,KEY_LEFT ), +KEY (4 ,0 ,KEY_T ),KEY (4 ,1 ,KEY_DOWN ),KEY (4 ,2 ,KEY_RIGHT ),KEY (4 ,4 ,KEY_LEFTCTRL ),KEY (4 ,5 ,KEY_RIGHTALT ),KEY (4 ,6 ,KEY_LEFTSHIFT ), +KEY (4 ,8 ,KEY_10 ), +KEY (5 ,0 ,KEY_Y ), +KEY (5 ,8 ,KEY_11 ), +KEY (6 ,0 ,KEY_U ), +KEY (7 ,0 ,KEY_I ),KEY (7 ,1 ,KEY_F7 ), KEY(7, 2, KEY_F8), -KEY (0xff ,2 ,KEY_F9 ), -KEY (0xff ,4 ,KEY_F10 ), - KEY(0xff, 5, KEY_F11), }; static struct matrix_keymap_data board_map_data = {
drivers/input/keyboard/twl4030_keypad.c +11 -6
@@ -50,8 +50,12 @@*/ #define TWL4030_MAX_ROWS 8/* TWL4030 hard limit */ #define TWL4030_MAX_COLS 8 -#define TWL4030_ROW_SHIFT 3 -#define TWL4030_KEYMAP_SIZE (TWL4030_MAX_ROWS * TWL4030_MAX_COLS) +/* +* Note that we add space for an extra column so that we can handle +* row lines connected to the gnd (see twl4030_col_xlate()). +*/ +#define TWL4030_ROW_SHIFT 4 +#define TWL4030_KEYMAP_SIZE (TWL4030_MAX_ROWS << TWL4030_ROW_SHIFT)struct twl4030_keypad {unsigned short keymap[TWL4030_KEYMAP_SIZE ];
@@ -181,7 +185,7 @@ static int twl4030_read_kp_matrix_state(return ret; } -static int twl4030_is_in_ghost_state (struct twl4030_keypad *kp,u16 *key_state) +static bool twl4030_is_in_ghost_state (struct twl4030_keypad *kp,u16 *key_state) {int i;u16 check =0 ;
@@ -190,12 +194,12 @@ static int twl4030_is_in_ghost_state(stru16 col = key_state[i];if ((col & check) &&hweight16 (col) >1 ) -return 1 ; +return true; check |= col; } -return 0 ; +return false; }static void twl4030_kp_scan (struct twl4030_keypad *kp,bool release_all)
@@ -224,7 +228,8 @@ static void twl4030_kp_scan(struct twl40if (!changed)continue ; -for (col =0 ; col < kp->n_cols; col++) { +/* Extra column handles "all gnd" rows */ +for (col =0 ; col < kp->n_cols +1 ; col++) {int code;if (!(changed & (1 << col)))
PATCH 64/165 ARM: 6201/1: RealView: Do not use outer_sync() on ARM11MPCore boards with L220
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Catalin Marinas <[email protected]>
commit 2503a5ecd86c002506001eba432c524ea009fe7f upstream.
RealView boards with certain revisions of the L220 cache controller (ARM11* processors only) may have issues (hardware deadlock) with the recent changes to the mb() barrier implementation (DSB followed by an L2 cache sync). The patch redefines the RealView ARM11MPCore mandatory barriers without the outer_sync() call.
--- arch/arm/mach-realview/Kconfig | 2 ++ arch/arm/mach-realview/include/mach/barriers.h | 8 ++++++++ 2 files changed, 10 insertions(+)
arch/arm/mach-realview/Kconfig +2 -0
@@ -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
arch/arm/mach-realview/include/mach/barriers.h new file +8 -0
@@ -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()
PATCH 65/165 ARM: 6226/1: fix kprobe bug in ldr instruction emulation
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nicolas Pitre <[email protected]>
commit 0ebe25f90cd99bb1bcf622ec8a841421d48380d6 upstream.
From: Bin Yang <[email protected]>
--- arch/arm/kernel/kprobes-decode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/arm/kernel/kprobes-decode.c +3 -2
@@ -583,13 +583,14 @@ static void __kprobes emulate_ldr(struct {insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0 ];kprobe_opcode_t insn = p->opcode; +long ppc = (long )p->addr +8 ;union reg_pair fnr;int rd = (insn >>12 ) &0xf ;int rn = (insn >>16 ) &0xf ;int rm = insn &0xf ;long rdv; -long rnv = regs->uregs[rn]; -long rmv = regs->uregs[rm];/* rm/rmv may be invalid, don't care. */ +long rnv = (rn ==15 ) ? ppc : regs->uregs[rn]; +long rmv = (rm ==15 ) ? ppc : regs->uregs[rm];long cpsr = regs->ARM_cpsr; fnr.dr =insnslot_llret_3arg_rflags (rnv,0 , rmv, cpsr, i_fn);
PATCH 66/165 x86: Do not try to disable hpet if it hasnt been initialized before
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Stefano Stabellini <[email protected]>
commit ff4878089e1eaeac79d57878ad4ea32910fb4037 upstream.
hpet_disable is called unconditionally on machine reboot if hpet support is compiled in the kernel.hpet_disable only checks if the machine is hpet capable but doesn't make sure that hpet has been initialized.
[ tglx: Made it a one liner and removed the redundant hpet_address check ]
LKML-Reference: <alpine.DEB.2.00.1007211726240.22235@kaball-desktop>
--- arch/x86/kernel/hpet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/hpet.c +1 -1
@@ -949,7 +949,7 @@ fs_initcall(hpet_late_init);void hpet_disable (void ) { -if (is_hpet_capable ()) { +if (is_hpet_capable () && hpet_virt_address) {unsigned long cfg =hpet_readl (HPET_CFG );if (hpet_legacy_int_enabled) {
PATCH 67/165 staging: rtl8192su: add USB VID/PID for HWNUm-300
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Stephane Glondu <[email protected]>
commit 488d3749620779ab2668c0dba2962836e51e3cd6 upstream.
The Hercules Wireless N USB mini (HWNUm-300) uses the RTL8191S chipset and seems to work with this driver.
--- drivers/staging/rtl8192su/r8192U_core.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/staging/rtl8192su/r8192U_core.c +2 -0
@@ -127,6 +127,8 @@ static struct usb_device_id rtl8192_usb_ {USB_DEVICE(0x2001, 0x3301)},/* Zinwell */ {USB_DEVICE(0x5a57, 0x0290)}, +/* Guillemot */ + {USB_DEVICE(0x06f8, 0xe031)},//92SU {USB_DEVICE(0x0bda, 0x8172)}, {}
PATCH 68/165 Staging: rtl8192su: add USB ID for 0bda:8171
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Pavel Roskin <[email protected]>
commit c0087580b8d414f6874cfe93d2653212842fcb44 upstream.
--- drivers/staging/rtl8192su/r8192U_core.c | 1 + 1 file changed, 1 insertion(+)
drivers/staging/rtl8192su/r8192U_core.c +1 -0
@@ -112,6 +112,7 @@ u32 rt_global_debug_component = \static struct usb_device_id rtl8192_usb_id_tbl[] = {/* Realtek */ + {USB_DEVICE (0x0bda ,0x8171 )}, {USB_DEVICE (0x0bda ,0x8192 )}, {USB_DEVICE (0x0bda ,0x8709 )},/* Corega */
PATCH 69/165 USB: obey the sysfs power/wakeup setting
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alan Stern <[email protected]>
commit 48826626263d4a61d06fd8c5805da31f925aefa0 upstream.
This patch (as1403) is a partial reversion of an earlier change (commit 5f677f1d45b2bf08085bbba7394392dfa586fa8e "USB: fix remote wakeup settings during system sleep"). After hearing from a user, I realized that remote wakeup should be enabled during system sleep whenever userspace allows it, and not only if a driver requests it too.
Indeed, there could be a device with no driver, that does nothing but generate a wakeup request when the user presses a button. Such a device should be allowed to do its job.
The problem fixed by the earlier patch -- device generating a wakeup request for no reason, causing system suspend to abort -- was also addressed by a later patch ("USB: don't enable remote wakeup by default", accepted but not yet merged into mainline). The device won't be able to generate the bogus wakeup requests because it will be disabled for remote wakeup by default. Hence this reversion will not re-introduce any old problems.
--- drivers/usb/core/driver.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-)
drivers/usb/core/driver.c +2 -13
@@ -1743,9 +1743,6 @@ int usb_external_resume_device(struct usstatic void choose_wakeup (struct usb_device *udev,pm_message_t msg) { -int w, i; -struct usb_interface *intf; -/* Remote wakeup is needed only when we actually go to sleep. * For things like FREEZE and QUIESCE, if the device is already * autosuspended then its current wakeup setting is okay.
@@ -1755,18 +1752,10 @@ static void choose_wakeup(struct usb_devreturn ; } -/* If remote wakeup is permitted, see whether any interface drivers +/* Allow remote wakeup if it is enabled, even if no interface drivers * actually want it. */ - w =0 ; -if (device_may_wakeup (&udev->dev) && udev->actconfig) { -for (i =0 ; i < udev->actconfig->desc.bNumInterfaces; i++) { - intf = udev->actconfig->interface[i]; - w |= intf->needs_remote_wakeup; - } - } - - udev->do_remote_wakeup = w; + udev->do_remote_wakeup =device_may_wakeup (&udev->dev); }int usb_suspend (struct device *dev,pm_message_t msg)
PATCH 70/165 USB: g_serial: dont set low_latency flag
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jon Povey <[email protected]>
commit 44a0c0190b500ee6bcfc0976fe540f65dee2cd67 upstream.
No longer set low_latency flag as it causes this warning backtrace:
WARNING: at kernel/mutex.c:207 __mutex_lock_slowpath+0x6c/0x288()
Fix associated locking and wakeups.
--- drivers/usb/gadget/u_serial.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-)
drivers/usb/gadget/u_serial.c +2 -13
@@ -535,17 +535,11 @@ recycle:list_move (&req->list, &port->read_pool); } -/* Push from tty to ldisc; this is immediate with low_latency, and -* may trigger callbacks to this driver ... so drop the spinlock. +/* Push from tty to ldisc; without low_latency set this is handled by +* a workqueue, so we won't get callbacks and can hold port_lock */ if (tty && do_push) { -spin_unlock_irq (&port->port_lock);tty_flip_buffer_push (tty); -wake_up_interruptible (&tty->read_wait); -spin_lock_irq (&port->port_lock); - -/* tty may have been closed */ - tty = port->port_tty; }
@@ -783,11 +777,6 @@ static int gs_open(struct tty_struct *tt port->open_count =1 ; port->openclose = false; -/* low_latency means ldiscs work in tasklet context, without -* needing a workqueue schedule ... easier to keep up. -*/ - tty->low_latency =1 ; -/* if connected, start the I/O stream */ if (port->port_usb) {struct gserial *gser = port->port_usb;
PATCH 71/165 USB: g_serial: fix tty cleanup on unload
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jon Povey <[email protected]>
commit b23097b793081358a6d943263c91bae4c955c4e3 upstream.
Call put_tty_driver() in cleanup function, to fix Oops when trying to open gadget serial char device after module unload.
--- drivers/usb/gadget/u_serial.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/gadget/u_serial.c +1 -0
@@ -1183,6 +1183,7 @@ void gserial_cleanup(void) n_ports =0 ;tty_unregister_driver (gs_tty_driver); +put_tty_driver (gs_tty_driver); gs_tty_driver =NULL ;pr_debug ("%s: cleaned up ttyGS* support\n" , __func__);
PATCH 72/165 USB: option: add support for 1da5:4518
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: =?UTF-8?q?=C3=96mer=20Sezgin=20Ugurlu?= <[email protected]>
commit 646d90e2b925578abef5c45853e0b166b6a450bf upstream.
--- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/serial/option.c +2 -0
@@ -316,6 +316,7 @@ static int option_resume(struct usb_ser#define QISDA_PRODUCT_H21_4512 0x4512#define QISDA_PRODUCT_H21_4523 0x4523#define QISDA_PRODUCT_H20_4515 0x4515 +#define QISDA_PRODUCT_H20_4518 0x4518#define QISDA_PRODUCT_H20_4519 0x4519/* TLAYTECH PRODUCTS */
@@ -836,6 +837,7 @@ static struct usb_device_id option_ids[] { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, + { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4518) }, { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) }, { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
PATCH 73/165 USB: Add PID for Sierra 250U to drivers/usb/serial/sierra.c
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: august huber <[email protected]>
commit 9d72c81d657340e54a260a3b621f4a9f5b33829c upstream.
Add VID/PID for Sierra Wireless 250U USB dongle to sierra.c Allows use of 3G radio only
--- drivers/usb/serial/sierra.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/serial/sierra.c +1 -0
@@ -210,6 +210,7 @@ static struct usb_device_id id_table [] { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ + { USB_DEVICE(0x1199, 0x0301) }, /* Sierra Wireless USB Dongle 250U *//* Sierra Wireless C597 */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) },/* Sierra Wireless T598 */
PATCH 74/165 USB: ftdi_sio: support for Signalyzer tools based on FTDI chips
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Colin Leitner <[email protected]>
commit 77dbd74e16b566e9d5eeb4be18ae3ee7d5902bd3 upstream.
ftdi_sio: support for Signalyzer tools based on FTDI chips
This patch adds support for the Xverve Signalyzers.
--- drivers/usb/serial/ftdi_sio.c | 8 ++++++++ drivers/usb/serial/ftdi_sio_ids.h | 9 +++++++++ 2 files changed, 17 insertions(+)
drivers/usb/serial/ftdi_sio.c +8 -0
@@ -743,6 +743,14 @@ static struct usb_device_id id_table_com { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) }, { USB_DEVICE(FTDI_VID, MJSG_HD_RADIO_PID) }, { USB_DEVICE(FTDI_VID, MJSG_XM_RADIO_PID) }, + { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_ST_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SLITE_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH2_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { }, /* Optional parameter entry */ { } /* Terminating entry */ };
drivers/usb/serial/ftdi_sio_ids.h +9 -0
@@ -1024,3 +1024,12 @@#define MJSG_SR_RADIO_PID 0x9379#define MJSG_XM_RADIO_PID 0x937A#define MJSG_HD_RADIO_PID 0x937C + +/* +* Xverve Signalyzer tools (http://www.signalyzer.com/) +*/ +#define XVERVE_SIGNALYZER_ST_PID 0xBCA0 +#define XVERVE_SIGNALYZER_SLITE_PID 0xBCA1 +#define XVERVE_SIGNALYZER_SH2_PID 0xBCA2 +#define XVERVE_SIGNALYZER_SH4_PID 0xBCA4 +
PATCH 75/165 USB: option: Add support for AMOI Skypephone S2
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dennis Jansen <[email protected]>
commit 7595931c986f50b1e197ce7b881563e36a7d041e upstream.
usbserial: Add AMOI Skypephone S2 support.
This patch adds support for the AMOI Skypephone S2 to the usbserial module.
--- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/serial/option.c +2 -0
@@ -226,6 +226,7 @@ static int option_resume(struct usb_ser#define AMOI_PRODUCT_H01 0x0800#define AMOI_PRODUCT_H01A 0x7002#define AMOI_PRODUCT_H02 0x0802 +#define AMOI_PRODUCT_SKYPEPHONE_S2 0x0407#define DELL_VENDOR_ID 0x413C
@@ -504,6 +505,7 @@ static struct usb_device_id option_ids[] { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H02) }, + { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_SKYPEPHONE_S2) }, { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5500_MINICARD) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
PATCH 76/165 USB: adds Artisman USB dongle to list of quirky devices
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Paul Mortier <[email protected]>
commit 47f19c0eedb377ad1ee8114f464d001ec5f96a69 upstream.
When an attempt is made to read the interface strings of the Artisman Watchdog USB dongle (idVendor:idProduct 04b4:0526) an error is written to the dmesg log (uhci_result_common: failed with status 440000) and the dongle resets itself, resulting in a disconnect/reconnect loop.
Adding the dongle to the list of devices in quirks.c, with the same quirk Alan Stern's previous patch for the Saitek Cyborg Gold 3D joystick, stops the device from resetting and allows it to be used with no problems.
--- drivers/usb/core/quirks.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/core/quirks.c +4 -0
@@ -41,6 +41,10 @@ static const struct usb_device_id usb_qu/* Philips PSC805 audio device */ { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Artisman Watchdog Dongle */ + { USB_DEVICE(0x04b4, 0x0526), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, + /* Roland SC-8820 */ { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME },
PATCH 77/165 USB: sisusbvga: Fix for USB 3.0
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Oliver Neukum <[email protected]>
commit 20a12f007feee1cfa761b431047271d1141d8031 upstream.
Super speed is also fast enough to let sisusbvga operate. Therefor expand the checks.
--- drivers/usb/misc/sisusbvga/sisusb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/usb/misc/sisusbvga/sisusb.c +3 -2
@@ -2435,7 +2435,8 @@ sisusb_open(struct inode *inode, struct }if (!sisusb->devinit) { -if (sisusb->sisusb_dev->speed ==USB_SPEED_HIGH ) { +if (sisusb->sisusb_dev->speed ==USB_SPEED_HIGH || + sisusb->sisusb_dev->speed ==USB_SPEED_SUPER ) {if (sisusb_init_gfxdevice (sisusb,0 )) {mutex_unlock (&sisusb->lock);dev_err (&sisusb->sisusb_dev->dev,"Failed to initialize device\n" );
@@ -3167,7 +3168,7 @@ static int sisusb_probe(struct usb_inter sisusb->present =1 ; -if (dev->speed ==USB_SPEED_HIGH ) { +if (dev->speed ==USB_SPEED_HIGH || dev->speed ==USB_SPEED_SUPER ) {int initscreen =1 ;#ifdef INCL_SISUSB_CON if (sisusb_first_vc > 0 &&
PATCH 78/165 USB: add quirk for Broadcom BT dongle
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Oliver Neukum <[email protected]>
commit 63ab71deae67b031045bb28bf8cff45180089f8f upstream.
This device needs to be reset when resuming
--- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/core/quirks.c +3 -0
@@ -68,6 +68,9 @@ static const struct usb_device_id usb_qu/* X-Rite/Gretag-Macbeth Eye-One Pro display colorimeter */ { USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF }, + /* Broadcom BCM92035DGROM BT dongle */ + { USB_DEVICE(0x0a5c, 0x2021), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Action Semiconductor flash disk */ { USB_DEVICE(0x10d6, 0x2200), .driver_info = USB_QUIRK_STRING_FETCH_255 },
PATCH 79/165 USB: FTDI: Add support for the RT System VX-7 radio programming cable
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Corey Minyard <[email protected]>
commit fcc6cb789c77ffee31710eec64efeb25f2124f7a upstream.
RT Systems has put out bunch of ham radio cables based on the FT232RL chip. Each cable type has a unique PID, this adds one for the Yaesu VX-7 radios.
--- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++ 2 files changed, 7 insertions(+)
drivers/usb/serial/ftdi_sio.c +1 -0
@@ -697,6 +697,7 @@ static struct usb_device_id id_table_com { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID), .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
drivers/usb/serial/ftdi_sio_ids.h +6 -0
@@ -703,6 +703,12 @@#define TELLDUS_TELLSTICK_PID 0x0C30/* RF control dongle 433 MHz using FT232RL */ /* +* RT Systems programming cables for various ham radios +*/ +#define RTSYSTEMS_VID 0x2100/* Vendor ID */ +#define RTSYSTEMS_SERIAL_VX7_PID 0x9e52/* Serial converter for VX-7 Radios using FT232RL */ + +/* * Bayer Ascensia Contour blood glucose meter USB-converter cable. * http://winglucofacts.com/cables/ */
PATCH 80/165 ethtool: Fix potential user buffer overflow for ETHTOOL_{G, S}RXFH
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit bf988435bd5b53529f4408a8efb1f433f6ddfda9 upstream.
struct ethtool_rxnfc was originally defined in 2.6.27 for the ETHTOOL_{G,S}RXFH command with only the cmd, flow_type and data fields. It was then extended in 2.6.30 to support various additional commands. These commands should have been defined to use a new structure, but it is too late to change that now.
Since user-space may still be using the old structure definition for the ETHTOOL_{G,S}RXFH commands, and since they do not need the additional fields, only copy the originally defined fields to and from user-space.
--- include/linux/ethtool.h | 2 ++ net/core/ethtool.c | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 9 deletions(-)
include/linux/ethtool.h +2 -0
@@ -357,6 +357,8 @@ struct ethtool_rxnfc {__u32 flow_type;/* The rx flow hash value or the rule DB size */ __u64 data; +/* The following fields are not valid and must not be used for +* the ETHTOOL_{G,X}RXFH commands. */ struct ethtool_rx_flow_spec fs;__u32 rule_cnt;__u32 rule_locs[0 ];
net/core/ethtool.c +29 -9
@@ -216,22 +216,34 @@ static int ethtool_get_drvinfo(struct nereturn 0 ; } -static int ethtool_set_rxnfc (struct net_device *dev,void __user *useraddr) +static int ethtool_set_rxnfc (struct net_device *dev, +u32 cmd,void __user *useraddr) { -struct ethtool_rxnfc cmd; +struct ethtool_rxnfc info; +size_t info_size =sizeof (info);if (!dev->ethtool_ops->set_rxnfc)return -EOPNOTSUPP ; -if (copy_from_user (&cmd, useraddr,sizeof (cmd))) +/* struct ethtool_rxnfc was originally defined for +* ETHTOOL_{G,S}RXFH with only the cmd, flow_type and data +* members. User-space might still be using that +* definition. */ +if (cmd ==ETHTOOL_SRXFH ) + info_size = (offsetof(struct ethtool_rxnfc , data) + +sizeof (info.data)); + +if (copy_from_user (&info, useraddr, info_size))return -EFAULT ; -return dev->ethtool_ops->set_rxnfc (dev, &cmd); +return dev->ethtool_ops->set_rxnfc (dev, &info); } -static int ethtool_get_rxnfc (struct net_device *dev,void __user *useraddr) +static int ethtool_get_rxnfc (struct net_device *dev, +u32 cmd,void __user *useraddr) {struct ethtool_rxnfc info; +size_t info_size =sizeof (info);const struct ethtool_ops *ops = dev->ethtool_ops;int ret;void *rule_buf =NULL ;
@@ -239,7 +251,15 @@ static int ethtool_get_rxnfc(struct net_if (!ops->get_rxnfc)return -EOPNOTSUPP ; -if (copy_from_user (&info, useraddr,sizeof (info))) +/* struct ethtool_rxnfc was originally defined for +* ETHTOOL_{G,S}RXFH with only the cmd, flow_type and data +* members. User-space might still be using that +* definition. */ +if (cmd ==ETHTOOL_GRXFH ) + info_size = (offsetof(struct ethtool_rxnfc , data) + +sizeof (info.data)); + +if (copy_from_user (&info, useraddr, info_size))return -EFAULT ;if (info.cmd ==ETHTOOL_GRXCLSRLALL ) {
@@ -257,7 +277,7 @@ static int ethtool_get_rxnfc(struct net_ goto err_out; ret = -EFAULT ; -if (copy_to_user (useraddr, &info,sizeof (info))) +if (copy_to_user (useraddr, &info, info_size)) goto err_out;if (rule_buf) {
@@ -1112,12 +1132,12 @@ int dev_ethtool(struct net *net, structcase ETHTOOL_GRXCLSRLCNT :case ETHTOOL_GRXCLSRULE :case ETHTOOL_GRXCLSRLALL : - rc =ethtool_get_rxnfc (dev, useraddr); + rc =ethtool_get_rxnfc (dev, ethcmd, useraddr);break ;case ETHTOOL_SRXFH :case ETHTOOL_SRXCLSRLDEL :case ETHTOOL_SRXCLSRLINS : - rc =ethtool_set_rxnfc (dev, useraddr); + rc =ethtool_set_rxnfc (dev, ethcmd, useraddr);break ;case ETHTOOL_GGRO : rc =ethtool_get_gro (dev, useraddr);
PATCH 81/165 ext4: Fix potential quota deadlock
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit d21cd8f163ac44b15c465aab7306db931c606908 upstream (as of v2.6.33-rc2)
We have to delay vfs_dq_claim_space() until allocation context destruction. Currently we have following call-trace:ext4_mb_new_blocks()
/* task is already holding ac->alloc_semp */
->ext4_mb_mark_diskspace_used
->vfs_dq_claim_space() /* acquire dqptr_sem here. Possible deadlock */
->ext4_mb_release_context() /* drop ac->alloc_semp here */
Let's move quota claiming to ext4_da_update_reserve_space()
=======================================================
[ INFO: possible circular locking dependency detected ]
2.6.32-rc7 #18
-------------------------------------------------------
write-truncate-/3465 is trying to acquire lock:
(&s->s_dquot.dqptr_sem){++++..}, at: [<c025e73b>] dquot_claim_space+0x3b/0x1b0
but task is already holding lock:
(&meta_group_info[i]->alloc_sem){++++..}, at: [<c02ce962>] ext4_mb_load_buddy+0xb2/0x370
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #3 (&meta_group_info[i]->alloc_sem){++++..}:
[<c017d04b>] __lock_acquire+0xd7b/0x1260
[<c017d5ea>] lock_acquire+0xba/0xd0
[<c0527191>] down_read+0x51/0x90
[<c02ce962>] ext4_mb_load_buddy+0xb2/0x370
[<c02d0c1c>] ext4_mb_free_blocks+0x46c/0x870
[<c029c9d3>] ext4_free_blocks+0x73/0x130
[<c02c8cfc>] ext4_ext_truncate+0x76c/0x8d0
[<c02a8087>] ext4_truncate+0x187/0x5e0
[<c01e0f7b>] vmtruncate+0x6b/0x70
[<c022ec02>] inode_setattr+0x62/0x190
[<c02a2d7a>] ext4_setattr+0x25a/0x370
[<c022ee81>] notify_change+0x151/0x340
[<c021349d>] do_truncate+0x6d/0xa0
[<c0221034>] may_open+0x1d4/0x200
[<c022412b>] do_filp_open+0x1eb/0x910
[<c021244d>] do_sys_open+0x6d/0x140
[<c021258e>] sys_open+0x2e/0x40
[<c0103100>] sysenter_do_call+0x12/0x32-> #2 (&ei->i_data_sem){++++..}:
[<c017d04b>] __lock_acquire+0xd7b/0x1260
[<c017d5ea>] lock_acquire+0xba/0xd0
[<c0527191>] down_read+0x51/0x90
[<c02a5787>] ext4_get_blocks+0x47/0x450
[<c02a74c1>] ext4_getblk+0x61/0x1d0
[<c02a7a7f>] ext4_bread+0x1f/0xa0
[<c02bcddc>] ext4_quota_write+0x12c/0x310
[<c0262d23>] qtree_write_dquot+0x93/0x120
[<c0261708>] v2_write_dquot+0x28/0x30
[<c025d3fb>] dquot_commit+0xab/0xf0
[<c02be977>] ext4_write_dquot+0x77/0x90
[<c02be9bf>] ext4_mark_dquot_dirty+0x2f/0x50
[<c025e321>] dquot_alloc_inode+0x101/0x180
[<c029fec2>] ext4_new_inode+0x602/0xf00
[<c02ad789>] ext4_create+0x89/0x150
[<c0221ff2>] vfs_create+0xa2/0xc0
[<c02246e7>] do_filp_open+0x7a7/0x910
[<c021244d>] do_sys_open+0x6d/0x140
[<c021258e>] sys_open+0x2e/0x40
[<c0103100>] sysenter_do_call+0x12/0x32-> #1 (&sb->s_type->i_mutex_key#7/4){+.+...}:
[<c017d04b>] __lock_acquire+0xd7b/0x1260
[<c017d5ea>] lock_acquire+0xba/0xd0
[<c0526505>] mutex_lock_nested+0x65/0x2d0
[<c0260c9d>] vfs_load_quota_inode+0x4bd/0x5a0
[<c02610af>] vfs_quota_on_path+0x5f/0x70
[<c02bc812>] ext4_quota_on+0x112/0x190
[<c026345a>] sys_quotactl+0x44a/0x8a0
[<c0103100>] sysenter_do_call+0x12/0x32-> #0 (&s->s_dquot.dqptr_sem){++++..}:
[<c017d361>] __lock_acquire+0x1091/0x1260
[<c017d5ea>] lock_acquire+0xba/0xd0
[<c0527191>] down_read+0x51/0x90
[<c025e73b>] dquot_claim_space+0x3b/0x1b0
[<c02cb95f>] ext4_mb_mark_diskspace_used+0x36f/0x380
[<c02d210a>] ext4_mb_new_blocks+0x34a/0x530
[<c02c83fb>] ext4_ext_get_blocks+0x122b/0x13c0
[<c02a5966>] ext4_get_blocks+0x226/0x450
[<c02a5ff3>] mpage_da_map_blocks+0xc3/0xaa0
[<c02a6ed6>] ext4_da_writepages+0x506/0x790
[<c01de272>] do_writepages+0x22/0x50
[<c01d766d>] __filemap_fdatawrite_range+0x6d/0x80
[<c01d7b9b>] filemap_flush+0x2b/0x30
[<c02a40ac>] ext4_alloc_da_blocks+0x5c/0x60
[<c029e595>] ext4_release_file+0x75/0xb0
[<c0216b59>] __fput+0xf9/0x210
[<c0216c97>] fput+0x27/0x30
[<c02122dc>] filp_close+0x4c/0x80
[<c014510e>] put_files_struct+0x6e/0xd0
[<c01451b7>] exit_files+0x47/0x60
[<c0146a24>] do_exit+0x144/0x710
[<c0147028>] do_group_exit+0x38/0xa0
[<c0159abc>] get_signal_to_deliver+0x2ac/0x410
[<c0102849>] do_notify_resume+0xb9/0x890
[<c01032d2>] work_notifysig+0x13/0x21other info that might help us debug this:
3 locks held by write-truncate-/3465:
#0: (jbd2_handle){+.+...}, at: [<c02e1f8f>] start_this_handle+0x38f/0x5c0
#1: (&ei->i_data_sem){++++..}, at: [<c02a57f6>] ext4_get_blocks+0xb6/0x450
#2: (&meta_group_info[i]->alloc_sem){++++..}, at: [<c02ce962>] ext4_mb_load_buddy+0xb2/0x370stack backtrace: Pid: 3465, comm: write-truncate- Not tainted 2.6.32-rc7 #18 Call Trace: [<c0524cb3>] ? printk+0x1d/0x22 [<c017ac9a>] print_circular_bug+0xca/0xd0 [<c017d361>] __lock_acquire+0x1091/0x1260 [<c016bca2>] ? sched_clock_local+0xd2/0x170 [<c0178fd0>] ? trace_hardirqs_off_caller+0x20/0xd0 [<c017d5ea>] lock_acquire+0xba/0xd0 [<c025e73b>] ? dquot_claim_space+0x3b/0x1b0 [<c0527191>] down_read+0x51/0x90 [<c025e73b>] ? dquot_claim_space+0x3b/0x1b0 [<c025e73b>] dquot_claim_space+0x3b/0x1b0 [<c02cb95f>] ext4_mb_mark_diskspace_used+0x36f/0x380 [<c02d210a>] ext4_mb_new_blocks+0x34a/0x530 [<c02c601d>] ? ext4_ext_find_extent+0x25d/0x280 [<c02c83fb>] ext4_ext_get_blocks+0x122b/0x13c0 [<c016bca2>] ? sched_clock_local+0xd2/0x170 [<c016be60>] ? sched_clock_cpu+0x120/0x160 [<c016beef>] ? cpu_clock+0x4f/0x60 [<c0178fd0>] ? trace_hardirqs_off_caller+0x20/0xd0 [<c052712c>] ? down_write+0x8c/0xa0 [<c02a5966>] ext4_get_blocks+0x226/0x450 [<c016be60>] ? sched_clock_cpu+0x120/0x160 [<c016beef>] ? cpu_clock+0x4f/0x60 [<c017908b>] ? trace_hardirqs_off+0xb/0x10 [<c02a5ff3>] mpage_da_map_blocks+0xc3/0xaa0 [<c01d69cc>] ? find_get_pages_tag+0x16c/0x180 [<c01d6860>] ? find_get_pages_tag+0x0/0x180 [<c02a73bd>] ? __mpage_da_writepage+0x16d/0x1a0 [<c01dfc4e>] ? pagevec_lookup_tag+0x2e/0x40 [<c01ddf1b>] ? write_cache_pages+0xdb/0x3d0 [<c02a7250>] ? __mpage_da_writepage+0x0/0x1a0 [<c02a6ed6>] ext4_da_writepages+0x506/0x790 [<c016beef>] ? cpu_clock+0x4f/0x60 [<c016bca2>] ? sched_clock_local+0xd2/0x170 [<c016be60>] ? sched_clock_cpu+0x120/0x160 [<c016be60>] ? sched_clock_cpu+0x120/0x160 [<c02a69d0>] ? ext4_da_writepages+0x0/0x790 [<c01de272>] do_writepages+0x22/0x50 [<c01d766d>] __filemap_fdatawrite_range+0x6d/0x80 [<c01d7b9b>] filemap_flush+0x2b/0x30 [<c02a40ac>] ext4_alloc_da_blocks+0x5c/0x60 [<c029e595>] ext4_release_file+0x75/0xb0 [<c0216b59>] __fput+0xf9/0x210 [<c0216c97>] fput+0x27/0x30 [<c02122dc>] filp_close+0x4c/0x80 [<c014510e>] put_files_struct+0x6e/0xd0 [<c01451b7>] exit_files+0x47/0x60 [<c0146a24>] do_exit+0x144/0x710 [<c017b163>] ? lock_release_holdtime+0x33/0x210 [<c0528137>] ? _spin_unlock_irq+0x27/0x30 [<c0147028>] do_group_exit+0x38/0xa0 [<c017babb>] ? trace_hardirqs_on+0xb/0x10 [<c0159abc>] get_signal_to_deliver+0x2ac/0x410 [<c0102849>] do_notify_resume+0xb9/0x890 [<c0178fd0>] ? trace_hardirqs_off_caller+0x20/0xd0 [<c017b163>] ? lock_release_holdtime+0x33/0x210 [<c0165b50>] ? autoremove_wake_function+0x0/0x50 [<c017ba54>] ? trace_hardirqs_on_caller+0x134/0x190 [<c017babb>] ? trace_hardirqs_on+0xb/0x10 [<c0300ba4>] ? security_file_permission+0x14/0x20 [<c0215761>] ? vfs_write+0x131/0x190 [<c0214f50>] ? do_sync_write+0x0/0x120 [<c0103115>] ? sysenter_do_call+0x27/0x32 [<c01032d2>] work_notifysig+0x13/0x21
--- fs/ext4/inode.c | 9 +++++++-- fs/ext4/mballoc.c | 6 ------ 2 files changed, 7 insertions(+), 8 deletions(-)
fs/ext4/inode.c +7 -2
@@ -1088,7 +1088,7 @@ static int ext4_calc_metadata_amount(strstatic void ext4_da_update_reserve_space (struct inode *inode,int used) {struct ext4_sb_info *sbi =EXT4_SB (inode->i_sb); -int total, mdb, mdb_free; +int total, mdb, mdb_free, mdb_claim =0 ;spin_lock (&EXT4_I (inode)->i_block_reservation_lock);/* recalculate the number of metablocks still need to be reserved */
@@ -1101,7 +1101,9 @@ static void ext4_da_update_reserve_spaceif (mdb_free) {/* Account for allocated meta_blocks */ - mdb_free -=EXT4_I (inode)->i_allocated_meta_blocks; + mdb_claim =EXT4_I (inode)->i_allocated_meta_blocks; +BUG_ON (mdb_free < mdb_claim); + mdb_free -= mdb_claim;/* update fs dirty blocks counter */ percpu_counter_sub (&sbi->s_dirtyblocks_counter, mdb_free);
@@ -1112,8 +1114,11 @@ static void ext4_da_update_reserve_space/* update per-inode reservations */ BUG_ON (used >EXT4_I (inode)->i_reserved_data_blocks);EXT4_I (inode)->i_reserved_data_blocks -= used; +percpu_counter_sub (&sbi->s_dirtyblocks_counter, used + mdb_claim);spin_unlock (&EXT4_I (inode)->i_block_reservation_lock); +vfs_dq_claim_block (inode, used + mdb_claim); +/* * free those over-booking quota for metadata blocks */
fs/ext4/mballoc.c +0 -6
@@ -2755,12 +2755,6 @@ ext4_mb_mark_diskspace_used(struct ext4_if (!(ac->ac_flags &EXT4_MB_DELALLOC_RESERVED ))/* release all the reserved blocks if non delalloc */ percpu_counter_sub (&sbi->s_dirtyblocks_counter, reserv_blks); -else { -percpu_counter_sub (&sbi->s_dirtyblocks_counter, - ac->ac_b_ex.fe_len); -/* convert reserved quota blocks to real quota blocks */ -vfs_dq_claim_block (ac->ac_inode, ac->ac_b_ex.fe_len); - }if (sbi->s_log_groups_per_flex) { ext4_group_t flex_group = ext4_flex_group(sbi,
PATCH 82/165 ext4: replace BUG() with return -EIO in ext4_ext_get_blocks
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 034fb4c95fc0fed4ec4a50778127b92c6f2aec01 upstream (as of v2.6.33-rc3)
This patch fixes the Kernel BZ #14286. When the address of an extent corresponding to a valid block is corrupted, a -EIO should be reported instead of a BUG(). This situation should not normally not occur except in the case of a corrupted filesystem. If however it does, then the system should not panic directly but depending on the mount time options appropriate action should be taken. If the mount options so permit, the I/O should be gracefully aborted by returning a -EIO.
http://bugzilla.kernel.org/show_bug.cgi?id=14286
--- fs/ext4/extents.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
fs/ext4/extents.c +7 -1
@@ -3196,7 +3196,13 @@ int ext4_ext_get_blocks(handle_t *handle* this situation is possible, though, _during_ tree modification; * this is why assert can't be put in ext4_ext_find_extent() */ -BUG_ON (path[depth].p_ext ==NULL && depth !=0 ); +if (path[depth].p_ext ==NULL && depth !=0 ) { +ext4_error (inode->i_sb, __func__,"bad extent address " +"inode: %lu, iblock: %d, depth: %d" , + inode->i_ino, iblock, depth); + err = -EIO ; + goto out2; + } eh = path[depth].p_hdr; ex = path[depth].p_ext;
PATCH 83/165 ext4, jbd2: Add barriers for file systems with exernal journals
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit cc3e1bea5d87635c519da657303690f5538bb4eb upstream (as of v2.6.33-rc3)
This is a bit complicated because we are trying to optimize when we send barriers to the fs data disk. We could just throw in an extra barrier to the data disk whenever we send a barrier to the journal disk, but that's not always strictly necessary.
We only need to send a barrier during a commit when there are data blocks which are must be written out due to an inode written in ordered mode, or if fsync() depends on the commit to force data blocks to disk. Finally, before we drop transactions from the beginning of the journal during a checkpoint operation, we need to guarantee that any blocks that were flushed out to the data disk are firmly on the rust platter before we drop the transaction from the journal.
Thanks to Oleg Drokin for pointing out this flaw in ext3/ext4.
--- fs/ext4/fsync.c | 16 ++++++++++++++-- fs/jbd2/checkpoint.c | 15 +++++++++++++++ fs/jbd2/commit.c | 19 +++++++++++-------- include/linux/jbd2.h | 1 + 4 files changed, 41 insertions(+), 10 deletions(-)
fs/ext4/fsync.c +14 -2
@@ -88,9 +88,21 @@ int ext4_sync_file(struct file *file, streturn ext4_force_commit (inode->i_sb); commit_tid = datasync ? ei->i_datasync_tid : ei->i_sync_tid; -if (jbd2_log_start_commit (journal, commit_tid)) +if (jbd2_log_start_commit (journal, commit_tid)) { +/* +* When the journal is on a different device than the +* fs data disk, we need to issue the barrier in +* writeback mode. (In ordered mode, the jbd2 layer +* will take care of issuing the barrier. In +* data=journal, all of the data blocks are written to +* the journal device.) +*/ +if (ext4_should_writeback_data (inode) && + (journal->j_fs_dev != journal->j_dev) && + (journal->j_flags &JBD2_BARRIER )) +blkdev_issue_flush (inode->i_sb->s_bdev,NULL );jbd2_log_wait_commit (journal, commit_tid); -else if (journal->j_flags &JBD2_BARRIER ) + }else if (journal->j_flags &JBD2_BARRIER )blkdev_issue_flush (inode->i_sb->s_bdev,NULL );return ret; }
fs/jbd2/checkpoint.c +15 -0
@@ -22,6 +22,7 @@#include <linux/jbd2.h> #include <linux/errno.h> #include <linux/slab.h> +#include <linux/blkdev.h> #include <trace/events/jbd2.h> /*
@@ -515,6 +516,20 @@ int jbd2_cleanup_journal_tail(journal_t journal->j_tail_sequence = first_tid; journal->j_tail = blocknr;spin_unlock (&journal->j_state_lock); + +/* +* If there is an external journal, we need to make sure that +* any data blocks that were recently written out --- perhaps +* by jbd2_log_do_checkpoint() --- are flushed out before we +* drop the transactions from the external journal. It's +* unlikely this will be necessary, especially with a +* appropriately sized journal, but we need this to guarantee +* correctness. Fortunately jbd2_cleanup_journal_tail() +* doesn't get called all that often. +*/ +if ((journal->j_fs_dev != journal->j_dev) && + (journal->j_flags &JBD2_BARRIER )) +blkdev_issue_flush (journal->j_fs_dev,NULL );if (!(journal->j_flags &JBD2_ABORT ))jbd2_journal_update_superblock (journal,1 );return 0 ;
fs/jbd2/commit.c +11 -8
@@ -259,6 +259,7 @@ static int journal_submit_data_buffers(j ret = err;spin_lock (&journal->j_list_lock);J_ASSERT (jinode->i_transaction == commit_transaction); + commit_transaction->t_flushed_data_blocks =1 ; jinode->i_flags &= ~JI_COMMIT_RUNNING ;wake_up_bit (&jinode->i_flags, __JI_COMMIT_RUNNING); }
@@ -708,8 +709,17 @@ start_journal_io: } } -/* Done it all: now write the commit record asynchronously. */ +/* +* If the journal is not located on the file system device, +* then we must flush the file system device before we issue +* the commit record +*/ +if (commit_transaction->t_flushed_data_blocks && + (journal->j_fs_dev != journal->j_dev) && + (journal->j_flags &JBD2_BARRIER )) +blkdev_issue_flush (journal->j_fs_dev,NULL ); +/* Done it all: now write the commit record asynchronously. */ if (JBD2_HAS_INCOMPAT_FEATURE (journal,JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT )) { err = journal_submit_commit_record(journal, commit_transaction,
@@ -720,13 +730,6 @@ start_journal_io:blkdev_issue_flush (journal->j_dev,NULL ); } -/* -* This is the right place to wait for data buffers both for ASYNC -* and !ASYNC commit. If commit is ASYNC, we need to wait only after -* the commit block went to disk (which happens above). If commit is -* SYNC, we need to wait for data buffers before we start writing -* commit block, which happens below in such setting. -*/ err =journal_finish_inode_data_buffers (journal, commit_transaction);if (err) { printk(KERN_WARNING
include/linux/jbd2.h +1 -0
@@ -653,6 +653,7 @@ struct transaction_s* waiting for it to finish. */ unsigned int t_synchronous_commit:1; + unsigned int t_flushed_data_blocks:1;/* * For use by the filesystem to store fs-specific data
PATCH 84/165 ext4: Eliminate potential double free on error path
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit d3533d72e7478a61a3e1936956fc825289a2acf4 upstream (as of v2.6.33-rc3)
b_entry_name and buffer are initially NULL, are initialized within a loop to the result of calling kmalloc, and are freed at the bottom of this loop. The loop contains gotos to cleanup, which also frees b_entry_name and buffer. Some of these gotos are before the reinitializations of b_entry_name and buffer. To maintain the invariant that b_entry_name and buffer are NULL at the top of the loop, and thus acceptable arguments to kfree, these variables are now set to NULL after the kfrees.
This seems to be the simplest solution. A more complicated solution would be to introduce more labels in the error handling code at the end of the function.
A simplified version of the semantic match that finds this problem is as
follows: (http://coccinelle.lip6.fr/)
// <smpl>
@r@
identifier E;
expression E1;
iterator I;
statement S;
@@
*kfree(E);
... when != E = E1
when != I(E,...) S
when != &E*kfree(E);
// </smpl>
--- fs/ext4/xattr.c | 2 ++ 1 file changed, 2 insertions(+)
fs/ext4/xattr.c +2 -0
@@ -1327,6 +1327,8 @@ retry: goto cleanup;kfree (b_entry_name);kfree (buffer); + b_entry_name =NULL ; + buffer =NULL ;brelse (is->iloc.bh);kfree (is);kfree (bs);
PATCH 85/165 ext4: return correct wbc.nr_to_write in ext4_da_writepages
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 2faf2e19dd0e060eeb32442858ef495ac3083277 upstream (as of v2.6.33-rc3)
When ext4_da_writepages increases the nr_to_write in writeback_control then it must always re-base the return value. Originally there was a (misguided) attempt prevent wbc.nr_to_write from going negative. In fact, it's necessary to allow nr_to_write to be negative so that wb_writeback() can correctly calculate how many pages were actually written.
--- fs/ext4/inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/ext4/inode.c +1 -2
@@ -3010,8 +3010,7 @@ retry: out_writepages:if (!no_nrwrite_index_update) wbc->no_nrwrite_index_update =0 ; -if (wbc->nr_to_write > nr_to_writebump) - wbc->nr_to_write -= nr_to_writebump; + wbc->nr_to_write -= nr_to_writebump; wbc->range_start = range_start;trace_ext4_da_writepages_result (inode, wbc, ret, pages_written);return ret;
PATCH 86/165 ext4: Ensure zeroout blocks have no dirty metadata
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 515f41c33a9d44a964264c9511ad2c869af1fac3 upstream (as of v2.6.33-rc3)
This fixes a bug (found by Curt Wohlgemuth) in which new blocks returned from an extent created with ext4_ext_zeroout() can have dirty metadata still associated with them.
--- fs/ext4/extents.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
fs/ext4/extents.c +20 -0
@@ -3029,6 +3029,14 @@ out:return err; } +static void unmap_underlying_metadata_blocks (struct block_device *bdev, +sector_t block,int count) +{ +int i; +for (i =0 ; i < count; i++) +unmap_underlying_metadata (bdev, block + i); +} + static int ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, ext4_lblk_t iblock, unsigned int max_blocks,
@@ -3104,6 +3112,18 @@ out: }else allocated = ret;set_buffer_new (bh_result); +/* +* if we allocated more blocks than requested +* we need to make sure we unmap the extra block +* allocated. The actual needed block will get +* unmapped later when we find the buffer_head marked +* new. +*/ +if (allocated > max_blocks) { +unmap_underlying_metadata_blocks (inode->i_sb->s_bdev, + newblock + max_blocks, + allocated - max_blocks); + } map_out:set_buffer_mapped (bh_result); out1:
PATCH 87/165 ext4: Patch up how we claim metadata blocks for quota purposes
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 0637c6f4135f592f094207c7c21e7c0fc5557834 upstream (as of v2.6.33-rc3)
As reported in Kernel Bugzilla #14936, commit d21cd8f triggered a BUG in the function ext4_da_update_reserve_space() found in fs/ext4/inode.c. The root cause of this BUG() was caused by the fact that ext4_calc_metadata_amount() can severely over-estimate how many metadata blocks will be needed, especially when using direct block-mapped files.
In addition, it can also badly *under* estimate how much space is needed, since ext4_calc_metadata_amount() assumes that the blocks are contiguous, and this is not always true. If the application is writing blocks to a sparse file, the number of metadata blocks necessary can be severly underestimated by the functions ext4_da_reserve_space(), ext4_da_update_reserve_space() and ext4_da_release_space(). This was the cause of the dq_claim_space reports found on kerneloops.org.
Unfortunately, doing this right means that we need to massively over-estimate the amount of free space needed. So in some cases we may need to force the inode to be written to disk asynchronously in to avoid spurious quota failures.
http://bugzilla.kernel.org/show_bug.cgi?id=14936
--- fs/ext4/inode.c | 153 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 82 insertions(+), 71 deletions(-)
fs/ext4/inode.c +82 -71
@@ -1085,43 +1085,47 @@ static int ext4_calc_metadata_amount(strreturn ext4_indirect_calc_metadata_amount (inode, blocks); } +/* +* Called with i_data_sem down, which is important since we can call +* ext4_discard_preallocations() from here. +*/ static void ext4_da_update_reserve_space (struct inode *inode,int used) {struct ext4_sb_info *sbi =EXT4_SB (inode->i_sb); -int total, mdb, mdb_free, mdb_claim =0 ; +struct ext4_inode_info *ei =EXT4_I (inode); +int mdb_free =0 ; -spin_lock (&EXT4_I (inode)->i_block_reservation_lock); -/* recalculate the number of metablocks still need to be reserved */ - total =EXT4_I (inode)->i_reserved_data_blocks - used; - mdb =ext4_calc_metadata_amount (inode, total); - -/* figure out how many metablocks to release */ -BUG_ON (mdb >EXT4_I (inode)->i_reserved_meta_blocks); - mdb_free =EXT4_I (inode)->i_reserved_meta_blocks - mdb; - -if (mdb_free) { -/* Account for allocated meta_blocks */ - mdb_claim =EXT4_I (inode)->i_allocated_meta_blocks; -BUG_ON (mdb_free < mdb_claim); - mdb_free -= mdb_claim; +spin_lock (&ei->i_block_reservation_lock); +if (unlikely (used > ei->i_reserved_data_blocks)) { +ext4_msg (inode->i_sb,KERN_NOTICE ,"%s: ino %lu, used %d " +"with only %d reserved data blocks\n" , + __func__, inode->i_ino, used, + ei->i_reserved_data_blocks); +WARN_ON (1 ); + used = ei->i_reserved_data_blocks; + } + +/* Update per-inode reservations */ + ei->i_reserved_data_blocks -= used; + used += ei->i_allocated_meta_blocks; + ei->i_reserved_meta_blocks -= ei->i_allocated_meta_blocks; + ei->i_allocated_meta_blocks =0 ; +percpu_counter_sub (&sbi->s_dirtyblocks_counter, used); -/* update fs dirty blocks counter */ +if (ei->i_reserved_data_blocks ==0 ) { +/* +* We can release all of the reserved metadata blocks +* only when we have written all of the delayed +* allocation blocks. +*/ + mdb_free = ei->i_allocated_meta_blocks;percpu_counter_sub (&sbi->s_dirtyblocks_counter, mdb_free); -EXT4_I (inode)->i_allocated_meta_blocks =0 ; -EXT4_I (inode)->i_reserved_meta_blocks = mdb; + ei->i_allocated_meta_blocks =0 ; } - -/* update per-inode reservations */ -BUG_ON (used >EXT4_I (inode)->i_reserved_data_blocks); -EXT4_I (inode)->i_reserved_data_blocks -= used; -percpu_counter_sub (&sbi->s_dirtyblocks_counter, used + mdb_claim);spin_unlock (&EXT4_I (inode)->i_block_reservation_lock); -vfs_dq_claim_block (inode, used + mdb_claim); - -/* -* free those over-booking quota for metadata blocks -*/ +/* Update quota subsystem */ +vfs_dq_claim_block (inode, used);if (mdb_free)vfs_dq_release_reservation_block (inode, mdb_free);
@@ -1130,7 +1134,8 @@ static void ext4_da_update_reserve_space* there aren't any writers on the inode, we can discard the * inode's preallocations. */ -if (!total && (atomic_read (&inode->i_writecount) ==0 )) +if ((ei->i_reserved_data_blocks ==0 ) && + (atomic_read (&inode->i_writecount) ==0 ))ext4_discard_preallocations (inode); }
@@ -1843,7 +1848,8 @@ static int ext4_da_reserve_space(struct {int retries =0 ;struct ext4_sb_info *sbi =EXT4_SB (inode->i_sb); -unsigned long md_needed, mdblocks, total =0 ; +struct ext4_inode_info *ei =EXT4_I (inode); +unsigned long md_needed, md_reserved, total =0 ;/* * recalculate the amount of metadata blocks to reserve
@@ -1851,35 +1857,44 @@ static int ext4_da_reserve_space(struct* worse case is one extent per block */ repeat: -spin_lock (&EXT4_I (inode)->i_block_reservation_lock); - total =EXT4_I (inode)->i_reserved_data_blocks + nrblocks; - mdblocks =ext4_calc_metadata_amount (inode, total); -BUG_ON (mdblocks <EXT4_I (inode)->i_reserved_meta_blocks); - - md_needed = mdblocks -EXT4_I (inode)->i_reserved_meta_blocks; +spin_lock (&ei->i_block_reservation_lock); + md_reserved = ei->i_reserved_meta_blocks; + md_needed =ext4_calc_metadata_amount (inode, nrblocks); total = md_needed + nrblocks; -spin_unlock (&EXT4_I (inode)->i_block_reservation_lock); +spin_unlock (&ei->i_block_reservation_lock);/* * Make quota reservation here to prevent quota overflow * later. Real quota accounting is done at pages writeout * time. */ -if (vfs_dq_reserve_block (inode, total)) +if (vfs_dq_reserve_block (inode, total)) { +/* +* We tend to badly over-estimate the amount of +* metadata blocks which are needed, so if we have +* reserved any metadata blocks, try to force out the +* inode and see if we have any better luck. +*/ +if (md_reserved && retries++ <=3 ) + goto retry;return -EDQUOT ; + }if (ext4_claim_free_blocks (sbi, total)) {vfs_dq_release_reservation_block (inode, total);if (ext4_should_retry_alloc (inode->i_sb, &retries)) { + retry: +if (md_reserved) +write_inode_now (inode, (retries ==3 ));yield (); goto repeat; }return -ENOSPC ; } -spin_lock (&EXT4_I (inode)->i_block_reservation_lock); -EXT4_I (inode)->i_reserved_data_blocks += nrblocks; -EXT4_I (inode)->i_reserved_meta_blocks += md_needed; -spin_unlock (&EXT4_I (inode)->i_block_reservation_lock); +spin_lock (&ei->i_block_reservation_lock); + ei->i_reserved_data_blocks += nrblocks; + ei->i_reserved_meta_blocks += md_needed; +spin_unlock (&ei->i_block_reservation_lock);return 0 ;/* success */ }
@@ -1887,49 +1902,45 @@ repeat:static void ext4_da_release_space (struct inode *inode,int to_free) {struct ext4_sb_info *sbi =EXT4_SB (inode->i_sb); -int total, mdb, mdb_free, release; +struct ext4_inode_info *ei =EXT4_I (inode);if (!to_free)return ;/* Nothing to release, exit */ spin_lock (&EXT4_I (inode)->i_block_reservation_lock); -if (!EXT4_I (inode)->i_reserved_data_blocks) { +if (unlikely (to_free > ei->i_reserved_data_blocks)) {/* -* if there is no reserved blocks, but we try to free some -* then the counter is messed up somewhere. -* but since this function is called from invalidate -* page, it's harmless to return without any action +* if there aren't enough reserved blocks, then the +* counter is messed up somewhere. Since this +* function is called from invalidate page, it's +* harmless to return without any action. */ -printk (KERN_INFO "ext4 delalloc try to release %d reserved " -"blocks for inode %lu, but there is no reserved " -"data blocks\n" , to_free, inode->i_ino); -spin_unlock (&EXT4_I (inode)->i_block_reservation_lock); -return ; +ext4_msg (inode->i_sb,KERN_NOTICE ,"ext4_da_release_space: " +"ino %lu, to_free %d with only %d reserved " +"data blocks\n" , inode->i_ino, to_free, + ei->i_reserved_data_blocks); +WARN_ON (1 ); + to_free = ei->i_reserved_data_blocks; } + ei->i_reserved_data_blocks -= to_free; -/* recalculate the number of metablocks still need to be reserved */ - total =EXT4_I (inode)->i_reserved_data_blocks - to_free; - mdb =ext4_calc_metadata_amount (inode, total); - -/* figure out how many metablocks to release */ -BUG_ON (mdb >EXT4_I (inode)->i_reserved_meta_blocks); - mdb_free =EXT4_I (inode)->i_reserved_meta_blocks - mdb; - - release = to_free + mdb_free; - -/* update fs dirty blocks counter for truncate case */ -percpu_counter_sub (&sbi->s_dirtyblocks_counter, release); +if (ei->i_reserved_data_blocks ==0 ) { +/* +* We can release all of the reserved metadata blocks +* only when we have written all of the delayed +* allocation blocks. +*/ + to_free += ei->i_allocated_meta_blocks; + ei->i_allocated_meta_blocks =0 ; + } -/* update per-inode reservations */ -BUG_ON (to_free >EXT4_I (inode)->i_reserved_data_blocks); -EXT4_I (inode)->i_reserved_data_blocks -= to_free; +/* update fs dirty blocks counter */ +percpu_counter_sub (&sbi->s_dirtyblocks_counter, to_free); -BUG_ON (mdb >EXT4_I (inode)->i_reserved_meta_blocks); -EXT4_I (inode)->i_reserved_meta_blocks = mdb;spin_unlock (&EXT4_I (inode)->i_block_reservation_lock); -vfs_dq_release_reservation_block (inode, release); +vfs_dq_release_reservation_block (inode, to_free); } static void ext4_da_page_release_reservation(struct page *page,
PATCH 88/165 ext4: Fix accounting of reserved metadata blocks
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit ee5f4d9cdf32fd99172d11665c592a288c2b1ff4 upstream (as of v2.6.33-rc3)
Commit 0637c6f had a typo which caused the reserved metadata blocks to
not be released correctly. Fix this.
--- fs/ext4/inode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/ext4/inode.c +4 -4
@@ -1118,9 +1118,9 @@ static void ext4_da_update_reserve_space* only when we have written all of the delayed * allocation blocks. */ - mdb_free = ei->i_allocated_meta_blocks; + mdb_free = ei->i_reserved_meta_blocks; + ei->i_reserved_meta_blocks =0 ;percpu_counter_sub (&sbi->s_dirtyblocks_counter, mdb_free); - ei->i_allocated_meta_blocks =0 ; }spin_unlock (&EXT4_I (inode)->i_block_reservation_lock);
@@ -1931,8 +1931,8 @@ static void ext4_da_release_space(struct* only when we have written all of the delayed * allocation blocks. */ - to_free += ei->i_allocated_meta_blocks; - ei->i_allocated_meta_blocks =0 ; + to_free += ei->i_reserved_meta_blocks; + ei->i_reserved_meta_blocks =0 ; }/* update fs dirty blocks counter */
PATCH 89/165 ext4: Calculate metadata requirements more accurately
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 9d0be50230b333005635967f7ecd4897dbfd181b upstream (as of v2.6.33-rc3)
In the past, ext4_calc_metadata_amount(), and its sub-functions ext4_ext_calc_metadata_amount() and ext4_indirect_calc_metadata_amount() badly over-estimated the number of metadata blocks that might be required for delayed allocation blocks. This didn't matter as much when functions which managed the reserved metadata blocks were more aggressive about dropping reserved metadata blocks as delayed allocation blocks were written, but unfortunately they were too aggressive. This was fixed in commit 0637c6f, but as a result the over-estimation by ext4_calc_metadata_amount() would lead to reserving 2-3 times the number of pending delayed allocation blocks as potentially required metadata blocks. So if there are 1 megabytes of blocks which have been not yet been allocation, up to 3 megabytes of space would get reserved out of the user's quota and from the file system free space pool until all of the inode's data blocks have been allocated.
This commit addresses this problem by much more accurately estimating the number of metadata blocks that will be required. It will still somewhat over-estimate the number of blocks needed, since it must make a worst case estimate not knowing which physical blocks will be needed, but it is much more accurate than before.
--- fs/ext4/ext4.h | 2 + fs/ext4/ext4_extents.h | 3 +- fs/ext4/extents.c | 49 ++++++++++++++++++++++++------------- fs/ext4/inode.c | 62 +++++++++++++++++++++++++++-------------------- fs/ext4/super.c | 1 + 5 files changed, 73 insertions(+), 44 deletions(-)
fs/ext4/ext4.h +2 -0
@@ -693,6 +693,8 @@ struct ext4_inode_info {unsigned int i_reserved_meta_blocks;unsigned int i_allocated_meta_blocks;unsigned short i_delalloc_reserved_flag; +sector_t i_da_metadata_calc_last_lblock; +int i_da_metadata_calc_len;/* on-disk additional length */ __u16 i_extra_isize;
fs/ext4/ext4_extents.h +2 -1
@@ -225,7 +225,8 @@ static inline void ext4_ext_mark_initialized(struct ext4_extent *ext) ext->ee_len =cpu_to_le16 (ext4_ext_get_actual_len (ext)); } -extern int ext4_ext_calc_metadata_amount (struct inode *inode,int blocks); +extern int ext4_ext_calc_metadata_amount (struct inode *inode, +sector_t lblocks);extern ext4_fsblk_t ext_pblock (struct ext4_extent *ex);extern ext4_fsblk_t idx_pblock (struct ext4_extent_idx *);extern void ext4_ext_store_pblock (struct ext4_extent *,ext4_fsblk_t );
fs/ext4/extents.c +32 -17
61 lines not on this page · raw message
fs/ext4/inode.c +36 -26
135 lines not on this page · raw message
fs/ext4/super.c +1 -0
@@ -702,6 +702,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) ei->i_reserved_data_blocks =0 ; ei->i_reserved_meta_blocks =0 ; ei->i_allocated_meta_blocks =0 ; + ei->i_da_metadata_calc_len =0 ; ei->i_delalloc_reserved_flag =0 ;spin_lock_init (&(ei->i_block_reservation_lock));#ifdef CONFIG_QUOTA
Signature · 1 line
1.7.1
PATCH 90/165 ext4: Handle -EDQUOT error on write
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 1db913823c0f8360fccbd24ca67eb073966a5ffd upstream (as of v2.6.33-rc6)
We need to release the journal before we do a write_inode. Otherwise we could deadlock.
--- fs/ext4/inode.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-)
fs/ext4/inode.c +18 -14
@@ -1877,24 +1877,12 @@ repeat:* later. Real quota accounting is done at pages writeout * time. */ -if (vfs_dq_reserve_block (inode, md_needed +1 )) { -/* -* We tend to badly over-estimate the amount of -* metadata blocks which are needed, so if we have -* reserved any metadata blocks, try to force out the -* inode and see if we have any better luck. -*/ -if (md_reserved && retries++ <=3 ) - goto retry; +if (vfs_dq_reserve_block (inode, md_needed +1 ))return -EDQUOT ; - }if (ext4_claim_free_blocks (sbi, md_needed +1 )) {vfs_dq_release_reservation_block (inode, md_needed +1 );if (ext4_should_retry_alloc (inode->i_sb, &retries)) { - retry: -if (md_reserved) -write_inode_now (inode, (retries ==3 ));yield (); goto repeat; }
@@ -3075,7 +3063,7 @@ static int ext4_da_write_begin(struct fi loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) { - int ret, retries = 0; + int ret, retries = 0, quota_retries = 0;struct page *page;pgoff_t index;unsigned from, to;
@@ -3134,6 +3122,22 @@ retry:if (ret == -ENOSPC &&ext4_should_retry_alloc (inode->i_sb, &retries)) goto retry; + +if ((ret == -EDQUOT ) && +EXT4_I (inode)->i_reserved_meta_blocks && + (quota_retries++ <3 )) { +/* +* Since we often over-estimate the number of meta +* data blocks required, we may sometimes get a +* spurios out of quota error even though there would +* be enough space once we write the data blocks and +* find out how many meta data blocks were _really_ +* required. So try forcing the inode write to see if +* that helps. +*/ +write_inode_now (inode, (quota_retries ==3 )); + goto retry; + } out:return ret; }
PATCH 91/165 ext4: Fix quota accounting error with fallocate
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 5f634d064c709ea02c3cdaa850a08323a4a4bf28 upstream (as of v2.6.33-rc6)
When we fallocate a region of the file which we had recently written, and which is still in the page cache marked as delayed allocated blocks we need to make sure we don't do the quota update on writepage path. This is because the needed quota updated would have already be done by fallocate.
--- fs/ext4/ext4.h | 2 ++ fs/ext4/extents.c | 21 +++++++++++++++++++++ fs/ext4/inode.c | 44 +++++++++++++++++++++++++++++++------------- 3 files changed, 54 insertions(+), 13 deletions(-)
fs/ext4/ext4.h +2 -0
@@ -1440,6 +1440,8 @@ extern int ext4_block_truncate_page(handextern int ext4_page_mkwrite (struct vm_area_struct *vma,struct vm_fault *vmf);extern qsize_t *ext4_get_reserved_space (struct inode *inode);extern int flush_aio_dio_completed_IO (struct inode *inode); +extern void ext4_da_update_reserve_space (struct inode *inode, +int used,int quota_claim);/* ioctl.c */ extern long ext4_ioctl (struct file *,unsigned int ,unsigned long );extern long ext4_compat_ioctl (struct file *,unsigned int ,unsigned long );
fs/ext4/extents.c +21 -0
@@ -3138,7 +3138,19 @@ out:unmap_underlying_metadata_blocks (inode->i_sb->s_bdev, newblock + max_blocks, allocated - max_blocks); + allocated = max_blocks; } + +/* +* If we have done fallocate with the offset that is already +* delayed allocated, we would have block reservation +* and quota reservation done in the delayed write path. +* But fallocate would have already updated quota and block +* count for this offset. So cancel these reservation +*/ +if (flags &EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE ) +ext4_da_update_reserve_space (inode, allocated,0 ); + map_out:set_buffer_mapped (bh_result); out1:
@@ -3374,9 +3386,18 @@ int ext4_ext_get_blocks(handle_t *handle/* previous routine could use block we allocated */ newblock =ext_pblock (&newex); allocated =ext4_ext_get_actual_len (&newex); +if (allocated > max_blocks) + allocated = max_blocks;set_buffer_new (bh_result);/* +* Update reserved blocks/metadata blocks after successful +* block allocation which had been deferred till now. +*/ +if (flags &EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE ) +ext4_da_update_reserve_space (inode, allocated,1 ); + +/* * Cache the extent and update transaction to commit on fdatasync only * when it is _not_ an uninitialized extent. */
fs/ext4/inode.c +31 -13
75 lines not on this page · raw message
PATCH 92/165 ext4: Drop EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE flag
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 1296cc85c26e94eb865d03f82140f27d598de467 upstream (as of v2.6.33-rc6)
We should update reserve space if it is delalloc buffer and that is indicated by EXT4_GET_BLOCKS_DELALLOC_RESERVE flag. So use EXT4_GET_BLOCKS_DELALLOC_RESERVE in place of EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE
[ Stable note: This fixes a corruption cuased by the following
reproduction case:
rm -f $TEST_FN
touch $TEST_FN
fallocate -n -o 656712 -l 858907 $TEST_FN
dd if=/dev/zero of=$TEST_FN conv=notrunc bs=1 seek=1011020 count=36983 sync
dd if=/dev/zero of=$TEST_FN conv=notrunc bs=1 seek=332121 count=24005 dd if=/dev/zero of=$TEST_FN conv=notrunc bs=1 seek=1040179 count=93319
If the filesystem is then unmounted and e2fsck run forced, the i_blocks field for the file $TEST_FN will be found to be incorrect. ]
--- fs/ext4/ext4.h | 7 ++----- fs/ext4/extents.c | 4 ++-- fs/ext4/inode.c | 8 ++++---- 3 files changed, 8 insertions(+), 11 deletions(-)
fs/ext4/ext4.h +2 -5
@@ -361,14 +361,11 @@ struct ext4_new_group_data {so set the magic i_delalloc_reserve_flag after taking the inode allocation semaphore for */ #define EXT4_GET_BLOCKS_DELALLOC_RESERVE 0x0004 -/* Call ext4_da_update_reserve_space() after successfully -allocating the blocks */ -#define EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE 0x0008/* caller is from the direct IO path, request to creation of an unitialized extents if not allocated, split the uninitialized extent if blocks has been preallocated already*/ -#define EXT4_GET_BLOCKS_DIO 0x0010 -#define EXT4_GET_BLOCKS_CONVERT 0x0020 +#define EXT4_GET_BLOCKS_DIO 0x0008 +#define EXT4_GET_BLOCKS_CONVERT 0x0010#define EXT4_GET_BLOCKS_DIO_CREATE_EXT (EXT4_GET_BLOCKS_DIO|\ EXT4_GET_BLOCKS_CREATE_UNINIT_EXT)/* Convert extent to initialized after direct IO complete */
fs/ext4/extents.c +2 -2
@@ -3148,7 +3148,7 @@ out:* But fallocate would have already updated quota and block * count for this offset. So cancel these reservation */ -if (flags &EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE ) +if (flags &EXT4_GET_BLOCKS_DELALLOC_RESERVE )ext4_da_update_reserve_space (inode, allocated,0 ); map_out:
@@ -3394,7 +3394,7 @@ int ext4_ext_get_blocks(handle_t *handle* Update reserved blocks/metadata blocks after successful * block allocation which had been deferred till now. */ -if (flags &EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE ) +if (flags &EXT4_GET_BLOCKS_DELALLOC_RESERVE )ext4_da_update_reserve_space (inode, allocated,1 );/*
fs/ext4/inode.c +4 -4
@@ -1358,7 +1358,7 @@ int ext4_get_blocks(handle_t *handle, st* reserve space here. */ if ((retval >0 ) && - (flags &EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE )) + (flags &EXT4_GET_BLOCKS_DELALLOC_RESERVE ))ext4_da_update_reserve_space (inode, retval,1 ); }if (flags &EXT4_GET_BLOCKS_DELALLOC_RESERVE )
@@ -2261,10 +2261,10 @@ static int mpage_da_map_blocks(struct mp* variables are updated after the blocks have been allocated. */ new.b_state =0 ; - get_blocks_flags = (EXT4_GET_BLOCKS_CREATE | -EXT4_GET_BLOCKS_DELALLOC_RESERVE ); + get_blocks_flags =EXT4_GET_BLOCKS_CREATE ;if (mpd->b_state & (1 << BH_Delay)) - get_blocks_flags |=EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE ; + get_blocks_flags |=EXT4_GET_BLOCKS_DELALLOC_RESERVE ; + blks =ext4_get_blocks (handle, mpd->inode, next, max_blocks, &new, get_blocks_flags);if (blks <0 ) {
PATCH 93/165 ext4: Use bitops to read/modify EXT4_I(inode)->i_state
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 19f5fb7ad679bb361222c7916086435020c37cce upstream (as of v2.6.33-git11)
At several places we modify EXT4_I(inode)->i_state without holding i_mutex (ext4_release_file, ext4_bmap, ext4_journalled_writepage, ext4_do_update_inode, ...). These modifications are racy and we can lose updates to i_state. So convert handling of i_state to use bitops which are atomic.
--- fs/ext4/ext4.h | 41 +++++++++++++++++++++++++++++------------ fs/ext4/extents.c | 8 ++++---- fs/ext4/file.c | 4 ++-- fs/ext4/ialloc.c | 3 ++- fs/ext4/inode.c | 38 ++++++++++++++++++++------------------ fs/ext4/migrate.c | 6 +++--- fs/ext4/xattr.c | 22 +++++++++++----------- 7 files changed, 71 insertions(+), 51 deletions(-)
fs/ext4/ext4.h +29 -12
@@ -313,17 +313,6 @@ static inline __u32 ext4_mask_flags(umodreturn flags &EXT4_OTHER_FLMASK ; } -/* -* Inode dynamic state flags -*/ -#define EXT4_STATE_JDATA 0x00000001/* journaled data exists */ -#define EXT4_STATE_NEW 0x00000002/* inode is newly created */ -#define EXT4_STATE_XATTR 0x00000004/* has in-inode xattrs */ -#define EXT4_STATE_NO_EXPAND 0x00000008/* No space for expansion */ -#define EXT4_STATE_DA_ALLOC_CLOSE 0x00000010/* Alloc DA blks on close */ -#define EXT4_STATE_EXT_MIGRATE 0x00000020/* Inode is migrating */ -#define EXT4_STATE_DIO_UNWRITTEN 0x00000040/* need convert on dio done*/ -/* Used to pass group descriptor data when online resize is done */ struct ext4_new_group_input {__u32 group;/* Group number for this data */
@@ -624,7 +613,7 @@ struct ext4_inode_info {* near to their parent directory's inode. */ ext4_group_t i_block_group; -__u32 i_state;/* Dynamic state flags for ext4 */ +unsigned long i_state_flags;/* Dynamic state flags */ ext4_lblk_t i_dir_start_lookup;#ifdef CONFIG_EXT4_FS_XATTR
@@ -1044,6 +1033,34 @@ static inline int ext4_valid_inum(struct (ino >=EXT4_FIRST_INO (sb) && ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)); } + +/* +* Inode dynamic state flags +*/ +enum { +EXT4_STATE_JDATA ,/* journaled data exists */ +EXT4_STATE_NEW ,/* inode is newly created */ +EXT4_STATE_XATTR ,/* has in-inode xattrs */ +EXT4_STATE_NO_EXPAND ,/* No space for expansion */ +EXT4_STATE_DA_ALLOC_CLOSE ,/* Alloc DA blks on close */ +EXT4_STATE_EXT_MIGRATE ,/* Inode is migrating */ +EXT4_STATE_DIO_UNWRITTEN ,/* need convert on dio done*/ +}; + +static inline int ext4_test_inode_state (struct inode *inode,int bit) +{ +return test_bit (bit, &EXT4_I (inode)->i_state_flags); +} + +static inline void ext4_set_inode_state (struct inode *inode,int bit) +{ +set_bit (bit, &EXT4_I (inode)->i_state_flags); +} + +static inline void ext4_clear_inode_state (struct inode *inode,int bit) +{ +clear_bit (bit, &EXT4_I (inode)->i_state_flags); +}#else /* Assume that user mode programs are passing in an ext4fs superblock, not * a kernel struct super_block. This will allow us to call the feature-test
fs/ext4/extents.c +4 -4
@@ -3082,7 +3082,7 @@ ext4_ext_handle_uninitialized_extents(haif (io) io->flag =DIO_AIO_UNWRITTEN ;else -EXT4_I (inode)->i_state |=EXT4_STATE_DIO_UNWRITTEN ; +ext4_set_inode_state (inode,EXT4_STATE_DIO_UNWRITTEN ); goto out; }/* async DIO end_io complete, convert the filled extent to written */
@@ -3368,8 +3368,8 @@ int ext4_ext_get_blocks(handle_t *handleif (io) io->flag =DIO_AIO_UNWRITTEN ;else -EXT4_I (inode)->i_state |= -EXT4_STATE_DIO_UNWRITTEN ;; +ext4_set_inode_state (inode, +EXT4_STATE_DIO_UNWRITTEN ); } } err =ext4_ext_insert_extent (handle, inode, path, &newex, flags);
@@ -3745,7 +3745,7 @@ static int ext4_xattr_fiemap(struct inodint error =0 ;/* in-inode? */ -if (EXT4_I (inode)->i_state &EXT4_STATE_XATTR ) { +if (ext4_test_inode_state (inode,EXT4_STATE_XATTR )) {struct ext4_iloc iloc;int offset;/* offset of xattr in inode */
fs/ext4/file.c +2 -2
@@ -35,9 +35,9 @@*/ static int ext4_release_file (struct inode *inode,struct file *filp) { -if (EXT4_I (inode)->i_state &EXT4_STATE_DA_ALLOC_CLOSE ) { +if (ext4_test_inode_state (inode,EXT4_STATE_DA_ALLOC_CLOSE )) {ext4_alloc_da_blocks (inode); -EXT4_I (inode)->i_state &= ~EXT4_STATE_DA_ALLOC_CLOSE ; +ext4_clear_inode_state (inode,EXT4_STATE_DA_ALLOC_CLOSE ); }/* if we are the last writer on the inode, drop the block reservation */ if ((filp->f_mode & FMODE_WRITE) &&
fs/ext4/ialloc.c +2 -1
@@ -1029,7 +1029,8 @@ got: inode->i_generation = sbi->s_next_generation++;spin_unlock (&sbi->s_next_gen_lock); - ei->i_state =EXT4_STATE_NEW ; + ei->i_state_flags =0 ; +ext4_set_inode_state (inode,EXT4_STATE_NEW ); ei->i_extra_isize =EXT4_SB (sb)->s_want_extra_isize;
fs/ext4/inode.c +20 -18
@@ -1348,7 +1348,7 @@ int ext4_get_blocks(handle_t *handle, st* i_data's format changing. Force the migrate * to fail by clearing migrate flags */ -EXT4_I (inode)->i_state &= ~EXT4_STATE_EXT_MIGRATE ; +ext4_clear_inode_state (inode,EXT4_STATE_EXT_MIGRATE ); }/*
@@ -1835,7 +1835,7 @@ static int ext4_journalled_write_end(str new_i_size = pos + copied;if (new_i_size > inode->i_size)i_size_write (inode, pos+copied); -EXT4_I (inode)->i_state |=EXT4_STATE_JDATA ; +ext4_set_inode_state (inode,EXT4_STATE_JDATA );if (new_i_size >EXT4_I (inode)->i_disksize) {ext4_update_i_disksize (inode, new_i_size); ret2 =ext4_mark_inode_dirty (handle, inode);
@@ -2673,7 +2673,7 @@ static int __ext4_journalled_writepage(s ret = err;walk_page_buffers (handle, page_bufs,0 , len,NULL , bput_one); -EXT4_I (inode)->i_state |=EXT4_STATE_JDATA ; +ext4_set_inode_state (inode,EXT4_STATE_JDATA ); out:return ret; }
@@ -3344,7 +3344,8 @@ static sector_t ext4_bmap(struct addressfilemap_write_and_wait (mapping); } -if (EXT4_JOURNAL (inode) &&EXT4_I (inode)->i_state &EXT4_STATE_JDATA ) { +if (EXT4_JOURNAL (inode) && +ext4_test_inode_state (inode,EXT4_STATE_JDATA )) {/* * This is a REALLY heavyweight approach, but the use of * bmap on dirty files is expected to be extremely rare:
@@ -3363,7 +3364,7 @@ static sector_t ext4_bmap(struct address* everything they get. */ -EXT4_I (inode)->i_state &= ~EXT4_STATE_JDATA ; +ext4_clear_inode_state (inode,EXT4_STATE_JDATA ); journal =EXT4_JOURNAL (inode);jbd2_journal_lock_updates (journal); err =jbd2_journal_flush (journal);
@@ -3831,8 +3832,8 @@ static ssize_t ext4_ext_direct_IO(int rwif (ret != -EIOCBQUEUED && ret <=0 && iocb->private) {ext4_free_io_end (iocb->private); iocb->private =NULL ; - }else if (ret >0 && (EXT4_I (inode)->i_state & -EXT4_STATE_DIO_UNWRITTEN )) { + }else if (ret >0 &&ext4_test_inode_state (inode, +EXT4_STATE_DIO_UNWRITTEN )) {int err;/* * for non AIO case, since the IO is already
@@ -3842,7 +3843,7 @@ static ssize_t ext4_ext_direct_IO(int rw offset, ret);if (err <0 ) ret = err; -EXT4_I (inode)->i_state &= ~EXT4_STATE_DIO_UNWRITTEN ; +ext4_clear_inode_state (inode,EXT4_STATE_DIO_UNWRITTEN ); }return ret; }
@@ -4490,7 +4491,7 @@ void ext4_truncate(struct inode *inode)return ;if (inode->i_size ==0 && !test_opt (inode->i_sb,NO_AUTO_DA_ALLOC )) - ei->i_state |=EXT4_STATE_DA_ALLOC_CLOSE ; +ext4_set_inode_state (inode,EXT4_STATE_DA_ALLOC_CLOSE );if (EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL ) {ext4_ext_truncate (inode);
@@ -4776,7 +4777,7 @@ int ext4_get_inode_loc(struct inode *ino {/* We have all inode data except xattrs in memory here. */ return __ext4_get_inode_loc (inode, iloc, - !(EXT4_I (inode)->i_state &EXT4_STATE_XATTR )); + !ext4_test_inode_state (inode,EXT4_STATE_XATTR )); }void ext4_set_inode_flags (struct inode *inode)
@@ -4870,7 +4871,7 @@ struct inode *ext4_iget(struct super_blo } inode->i_nlink =le16_to_cpu (raw_inode->i_links_count); - ei->i_state =0 ; + ei->i_state_flags =0 ; ei->i_dir_start_lookup =0 ; ei->i_dtime =le32_to_cpu (raw_inode->i_dtime);/* We now have enough fields to check if the inode was active or not.
@@ -4953,7 +4954,7 @@ struct inode *ext4_iget(struct super_bloEXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize;if (*magic ==cpu_to_le32 (EXT4_XATTR_MAGIC )) - ei->i_state |=EXT4_STATE_XATTR ; +ext4_set_inode_state (inode,EXT4_STATE_XATTR ); } }else ei->i_extra_isize =0 ;
@@ -5093,7 +5094,7 @@ static int ext4_do_update_inode(handle_t/* For fields not not tracking in the in-memory inode, * initialise them to zero for new inodes. */ -if (ei->i_state &EXT4_STATE_NEW ) +if (ext4_test_inode_state (inode,EXT4_STATE_NEW ))memset (raw_inode,0 ,EXT4_SB (inode->i_sb)->s_inode_size);ext4_get_inode_flags (ei);
@@ -5189,7 +5190,7 @@ static int ext4_do_update_inode(handle_t rc =ext4_handle_dirty_metadata (handle, inode, bh);if (!err) err = rc; - ei->i_state &= ~EXT4_STATE_NEW ; +ext4_clear_inode_state (inode,EXT4_STATE_NEW );ext4_update_inode_fsync_trans (handle, inode,0 ); out_brelse:
@@ -5613,8 +5614,8 @@ static int ext4_expand_extra_isize(struc entry =IFIRST (header);/* No extended attributes present */ -if (!(EXT4_I (inode)->i_state &EXT4_STATE_XATTR ) || - header->h_magic !=cpu_to_le32 (EXT4_XATTR_MAGIC )) { +if (!ext4_test_inode_state (inode,EXT4_STATE_XATTR ) || + header->h_magic !=cpu_to_le32 (EXT4_XATTR_MAGIC )) {memset ((void *)raw_inode +EXT4_GOOD_OLD_INODE_SIZE ,0 , new_extra_isize);EXT4_I (inode)->i_extra_isize = new_extra_isize;
@@ -5658,7 +5659,7 @@ int ext4_mark_inode_dirty(handle_t *hand err =ext4_reserve_inode_write (handle, inode, &iloc);if (ext4_handle_valid (handle) &&EXT4_I (inode)->i_extra_isize < sbi->s_want_extra_isize && - !(EXT4_I (inode)->i_state &EXT4_STATE_NO_EXPAND )) { + !ext4_test_inode_state (inode,EXT4_STATE_NO_EXPAND )) {/* * We need extra buffer credits since we may write into EA block * with this same handle. If journal_extend fails, then it will
@@ -5672,7 +5673,8 @@ int ext4_mark_inode_dirty(handle_t *hand sbi->s_want_extra_isize, iloc, handle);if (ret) { -EXT4_I (inode)->i_state |=EXT4_STATE_NO_EXPAND ; +ext4_set_inode_state (inode, +EXT4_STATE_NO_EXPAND );if (mnt_count !=le16_to_cpu (sbi->s_es->s_mnt_count)) { ext4_warning(inode->i_sb, __func__,
fs/ext4/migrate.c +3 -3
@@ -357,12 +357,12 @@ static int ext4_ext_swap_inode_data(hand* happened after we started the migrate. We need to * fail the migrate */ -if (!(EXT4_I (inode)->i_state &EXT4_STATE_EXT_MIGRATE )) { +if (!ext4_test_inode_state (inode,EXT4_STATE_EXT_MIGRATE )) { retval = -EAGAIN ;up_write (&EXT4_I (inode)->i_data_sem); goto err_out; }else -EXT4_I (inode)->i_state &= ~EXT4_STATE_EXT_MIGRATE ; +ext4_clear_inode_state (inode,EXT4_STATE_EXT_MIGRATE );/* * We have the extent map build with the tmp inode. * Now copy the i_data across
@@ -524,7 +524,7 @@ int ext4_ext_migrate(struct inode *inode* allocation. */ down_read ((&EXT4_I (inode)->i_data_sem)); -EXT4_I (inode)->i_state |=EXT4_STATE_EXT_MIGRATE ; +ext4_set_inode_state (inode,EXT4_STATE_EXT_MIGRATE );up_read ((&EXT4_I (inode)->i_data_sem)); handle =ext4_journal_start (inode,1 );
fs/ext4/xattr.c +11 -11
@@ -267,7 +267,7 @@ ext4_xattr_ibody_get(struct inode *inodevoid *end;int error; -if (!(EXT4_I (inode)->i_state &EXT4_STATE_XATTR )) +if (!ext4_test_inode_state (inode,EXT4_STATE_XATTR ))return -ENODATA ; error =ext4_get_inode_loc (inode, &iloc);if (error)
@@ -393,7 +393,7 @@ ext4_xattr_ibody_list(struct inode *inodvoid *end;int error; -if (!(EXT4_I (inode)->i_state &EXT4_STATE_XATTR )) +if (!ext4_test_inode_state (inode,EXT4_STATE_XATTR ))return 0 ; error =ext4_get_inode_loc (inode, &iloc);if (error)
@@ -903,7 +903,7 @@ ext4_xattr_ibody_find(struct inode *inod is->s.base = is->s.first =IFIRST (header); is->s.here = is->s.first; is->s.end = (void *)raw_inode +EXT4_SB (inode->i_sb)->s_inode_size; -if (EXT4_I (inode)->i_state &EXT4_STATE_XATTR ) { +if (ext4_test_inode_state (inode,EXT4_STATE_XATTR )) { error =ext4_xattr_check_names (IFIRST (header), is->s.end);if (error)return error;
@@ -935,10 +935,10 @@ ext4_xattr_ibody_set(handle_t *handle, s header =IHDR (inode,ext4_raw_inode (&is->iloc));if (!IS_LAST_ENTRY (s->first)) { header->h_magic =cpu_to_le32 (EXT4_XATTR_MAGIC ); -EXT4_I (inode)->i_state |=EXT4_STATE_XATTR ; +ext4_set_inode_state (inode,EXT4_STATE_XATTR ); }else { header->h_magic =cpu_to_le32 (0 ); -EXT4_I (inode)->i_state &= ~EXT4_STATE_XATTR ; +ext4_clear_inode_state (inode,EXT4_STATE_XATTR ); }return 0 ; }
@@ -981,8 +981,8 @@ ext4_xattr_set_handle(handle_t *handle,if (strlen (name) >255 )return -ERANGE ;down_write (&EXT4_I (inode)->xattr_sem); - no_expand =EXT4_I (inode)->i_state &EXT4_STATE_NO_EXPAND ; -EXT4_I (inode)->i_state |=EXT4_STATE_NO_EXPAND ; + no_expand =ext4_test_inode_state (inode,EXT4_STATE_NO_EXPAND ); +ext4_set_inode_state (inode,EXT4_STATE_NO_EXPAND ); error =ext4_get_inode_loc (inode, &is.iloc);if (error)
@@ -992,10 +992,10 @@ ext4_xattr_set_handle(handle_t *handle,if (error) goto cleanup; -if (EXT4_I (inode)->i_state &EXT4_STATE_NEW ) { +if (ext4_test_inode_state (inode,EXT4_STATE_NEW )) {struct ext4_inode *raw_inode =ext4_raw_inode (&is.iloc);memset (raw_inode,0 ,EXT4_SB (inode->i_sb)->s_inode_size); -EXT4_I (inode)->i_state &= ~EXT4_STATE_NEW ; +ext4_clear_inode_state (inode,EXT4_STATE_NEW ); } error =ext4_xattr_ibody_find (inode, &i, &is);
@@ -1047,7 +1047,7 @@ ext4_xattr_set_handle(handle_t *handle,ext4_xattr_update_super_block (handle, inode->i_sb); inode->i_ctime =ext4_current_time (inode);if (!value) -EXT4_I (inode)->i_state &= ~EXT4_STATE_NO_EXPAND ; +ext4_clear_inode_state (inode,EXT4_STATE_NO_EXPAND ); error =ext4_mark_iloc_dirty (handle, inode, &is.iloc);/* * The bh is consumed by ext4_mark_iloc_dirty, even with
@@ -1062,7 +1062,7 @@ cleanup:brelse (is.iloc.bh);brelse (bs.bh);if (no_expand ==0 ) -EXT4_I (inode)->i_state &= ~EXT4_STATE_NO_EXPAND ; +ext4_clear_inode_state (inode,EXT4_STATE_NO_EXPAND );up_write (&EXT4_I (inode)->xattr_sem);return error; }
PATCH 94/165 ext4: Fix BUG_ON at fs/buffer.c:652 in no journal mode
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 73b50c1c92666d326b5fa2c945d46509f2f6d91f upstream (as of v2.6.33-git11)
Calls to ext4_handle_dirty_metadata should only pass in an inode pointer for inode-specific metadata, and not for shared metadata blocks such as inode table blocks, block group descriptors, the superblock, etc.
The BUG_ON can get tripped when updating a special device (such as a block device) that is opened (so that i_mapping is set in fs/block_dev.c) and the file system is mounted in no journal mode.
Addresses-Google-Bug: #2404870
--- fs/ext4/ext4_jbd2.c | 2 +- fs/ext4/ialloc.c | 2 +- fs/ext4/inode.c | 6 +++--- fs/ext4/namei.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-)
fs/ext4/ext4_jbd2.c +1 -1
@@ -89,7 +89,7 @@ int __ext4_handle_dirty_metadata(const cext4_journal_abort_handle (where, __func__, bh, handle, err); }else { -if (inode && bh) +if (inode)mark_buffer_dirty_inode (bh, inode);else mark_buffer_dirty (bh);
fs/ext4/ialloc.c +1 -1
@@ -904,7 +904,7 @@ repeat_in_this_group:BUFFER_TRACE (inode_bitmap_bh,"call ext4_handle_dirty_metadata" ); err =ext4_handle_dirty_metadata (handle, - inode, +NULL , inode_bitmap_bh);if (err) goto fail;
fs/ext4/inode.c +3 -3
@@ -5158,7 +5158,7 @@ static int ext4_do_update_inode(handle_t EXT4_FEATURE_RO_COMPAT_LARGE_FILE); sb->s_dirt =1 ;ext4_handle_sync (handle); - err =ext4_handle_dirty_metadata (handle, inode, + err =ext4_handle_dirty_metadata (handle,NULL ,EXT4_SB (sb)->s_sbh); } }
@@ -5187,7 +5187,7 @@ static int ext4_do_update_inode(handle_t }BUFFER_TRACE (bh,"call ext4_handle_dirty_metadata" ); - rc =ext4_handle_dirty_metadata (handle, inode, bh); + rc =ext4_handle_dirty_metadata (handle,NULL , bh);if (!err) err = rc;ext4_clear_inode_state (inode,EXT4_STATE_NEW );
@@ -5741,7 +5741,7 @@ static int ext4_pin_inode(handle_t *hand err =jbd2_journal_get_write_access (handle, iloc.bh);if (!err) err =ext4_handle_dirty_metadata (handle, - inode, +NULL , iloc.bh);brelse (iloc.bh); }
fs/ext4/namei.c +2 -2
@@ -2024,7 +2024,7 @@ int ext4_orphan_add(handle_t *handle, st/* Insert this inode at the head of the on-disk orphan list... */ NEXT_ORPHAN (inode) =le32_to_cpu (EXT4_SB (sb)->s_es->s_last_orphan);EXT4_SB (sb)->s_es->s_last_orphan =cpu_to_le32 (inode->i_ino); - err =ext4_handle_dirty_metadata (handle, inode,EXT4_SB (sb)->s_sbh); + err =ext4_handle_dirty_metadata (handle,NULL ,EXT4_SB (sb)->s_sbh); rc =ext4_mark_iloc_dirty (handle, inode, &iloc);if (!err) err = rc;
@@ -2096,7 +2096,7 @@ int ext4_orphan_del(handle_t *handle, stif (err) goto out_brelse; sbi->s_es->s_last_orphan =cpu_to_le32 (ino_next); - err =ext4_handle_dirty_metadata (handle, inode, sbi->s_sbh); + err =ext4_handle_dirty_metadata (handle,NULL , sbi->s_sbh); }else {struct ext4_iloc iloc2; struct inode *i_prev =
PATCH 95/165 ext4: Add flag to files with blocks intentionally past EOF
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit c8d46e41bc744c8fa0092112af3942fcd46c8b18 upstream (as of v2.6.33-git11)
fallocate() may potentially instantiate blocks past EOF, depending on the flags used when it is called.
e2fsck currently has a test for blocks past i_size, and it sometimes trips up - noticeably on xfstests 013 which runs fsstress.
This patch from Jiayang does fix it up - it (along with e2fsprogs updates and other patches recently from Aneesh) has survived many fsstress runs in a row.
--- fs/ext4/ext4.h | 6 ++++-- fs/ext4/extents.c | 22 +++++++++++++++++++++- fs/ext4/inode.c | 9 ++++++++- fs/ext4/ioctl.c | 9 +++++++++ 4 files changed, 42 insertions(+), 4 deletions(-)
fs/ext4/ext4.h +4 -2
@@ -284,10 +284,12 @@ struct flex_groups {#define EXT4_TOPDIR_FL 0x00020000/* Top of directory hierarchies*/ #define EXT4_HUGE_FILE_FL 0x00040000/* Set to each huge file */ #define EXT4_EXTENTS_FL 0x00080000/* Inode uses extents */ +#define EXT4_EA_INODE_FL 0x00200000/* Inode used for large EA */ +#define EXT4_EOFBLOCKS_FL 0x00400000/* Blocks allocated beyond EOF */ #define EXT4_RESERVED_FL 0x80000000/* reserved for ext4 lib */ -#define EXT4_FL_USER_VISIBLE 0x000BDFFF/* User visible flags */ -#define EXT4_FL_USER_MODIFIABLE 0x000B80FF/* User modifiable flags */ +#define EXT4_FL_USER_VISIBLE 0x004BDFFF/* User visible flags */ +#define EXT4_FL_USER_MODIFIABLE 0x004B80FF/* User modifiable flags */ /* Flags that should be inherited by new inodes from their parent. */ #define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\
fs/ext4/extents.c +21 -1
@@ -3191,7 +3191,7 @@ int ext4_ext_get_blocks(handle_t *handle {struct ext4_ext_path *path =NULL ;struct ext4_extent_header *eh; -struct ext4_extent newex, *ex; +struct ext4_extent newex, *ex, *last_ex;ext4_fsblk_t newblock;int err =0 , depth, ret, cache_type;unsigned int allocated =0 ;
@@ -3372,6 +3372,19 @@ int ext4_ext_get_blocks(handle_t *handle EXT4_STATE_DIO_UNWRITTEN); } } + +if (unlikely (EXT4_I (inode)->i_flags &EXT4_EOFBLOCKS_FL )) { +if (eh->eh_entries) { + last_ex =EXT_LAST_EXTENT (eh); +if (iblock + ar.len >le32_to_cpu (last_ex->ee_block) + +ext4_ext_get_actual_len (last_ex)) +EXT4_I (inode)->i_flags &= ~EXT4_EOFBLOCKS_FL ; + }else { +WARN_ON (eh->eh_entries ==0 ); +ext4_error (inode->i_sb, __func__, +"inode#%lu, eh->eh_entries = 0!" , inode->i_ino); + } + } err =ext4_ext_insert_extent (handle, inode, path, &newex, flags);if (err) {/* free data blocks we just allocated */
@@ -3505,6 +3518,13 @@ static void ext4_falloc_update_inode(stri_size_write (inode, new_size);if (new_size >EXT4_I (inode)->i_disksize)ext4_update_i_disksize (inode, new_size); + }else { +/* +* Mark that we allocate beyond EOF so the subsequent truncate +* can proceed even if the new size is the same as i_size. +*/ +if (new_size >i_size_read (inode)) +EXT4_I (inode)->i_flags |=EXT4_EOFBLOCKS_FL ; } }
fs/ext4/inode.c +8 -1
@@ -4490,6 +4490,8 @@ void ext4_truncate(struct inode *inode)if (!ext4_can_truncate (inode))return ; +EXT4_I (inode)->i_flags &= ~EXT4_EOFBLOCKS_FL ; +if (inode->i_size ==0 && !test_opt (inode->i_sb,NO_AUTO_DA_ALLOC ))ext4_set_inode_state (inode,EXT4_STATE_DA_ALLOC_CLOSE );
@@ -5345,7 +5347,9 @@ int ext4_setattr(struct dentry *dentry, }if (S_ISREG (inode->i_mode) && - attr->ia_valid &ATTR_SIZE && attr->ia_size < inode->i_size) { + attr->ia_valid &ATTR_SIZE && + (attr->ia_size < inode->i_size || + (EXT4_I (inode)->i_flags &EXT4_EOFBLOCKS_FL ))) {handle_t *handle; handle =ext4_journal_start (inode,3 );
@@ -5376,6 +5380,9 @@ int ext4_setattr(struct dentry *dentry, goto err_out; } } +/* ext4_truncate will clear the flag */ +if ((EXT4_I (inode)->i_flags &EXT4_EOFBLOCKS_FL )) +ext4_truncate (inode); } rc =inode_setattr (inode, attr);
fs/ext4/ioctl.c +9 -0
@@ -92,6 +92,15 @@ long ext4_ioctl(struct file *filp, unsig flags &= ~EXT4_EXTENTS_FL ; } +if (flags &EXT4_EOFBLOCKS_FL ) { +/* we don't support adding EOFBLOCKS flag */ +if (!(oldflags &EXT4_EOFBLOCKS_FL )) { + err = -EOPNOTSUPP ; + goto flags_out; + } + }else if (oldflags &EXT4_EOFBLOCKS_FL ) +ext4_truncate (inode); + handle =ext4_journal_start (inode,1 );if (IS_ERR (handle)) { err =PTR_ERR (handle);
PATCH 96/165 ext4: Fix fencepost error in chosing choosing group vs file preallocation.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit cc483f102c3f703e853c96f95a654f0106fb2603 upstream (as of v2.6.33-git11)
The ext4 multiblock allocator decides whether to use group or file preallocation based on the file size. When the file size reaches s_mb_stream_request (default is 16 blocks), it changes to use a file-specific preallocation. This is cool, but it has a tiny problem.
See a simple script:
mkfs.ext4 -b 1024 /dev/sda8 1000000
mount -t ext4 -o nodelalloc /dev/sda8 /mnt/ext4
for((i=0;i<5;i++))
do
cat /mnt/4096>>/mnt/ext4/a #4096 is a file with 4096 characters.
cat /mnt/4096>>/mnt/ext4/b
done
debuge4fs -R 'stat a' /dev/sda8|grep BLOCKS -A 1
And you get
BLOCKS:
(0-14):8705-8719, (15):2356, (16-19):8465-8468
So there are 3 extents, a bit strange for the lonely 15th logical block. As we write to the 16 blocks, we choose file preallocation in ext4_mb_group_or_file, but in ext4_mb_normalize_request, we meet with the 16*1024 range, so no preallocation will be carried. file b then reserves the space after '2356', so when when write 16, we start from another part.
This patch just change the check in ext4_mb_group_or_file, so that for the lonely 15 we will still use group preallocation. After the patch, we will get:
debuge4fs -R 'stat a' /dev/sda8|grep BLOCKS -A 1 BLOCKS:
(0-15):8705-8720, (16-19):8465-8468
Looks more sane. Thanks.
--- fs/ext4/mballoc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/mballoc.c +1 -1
@@ -3938,7 +3938,7 @@ static void ext4_mb_group_or_file(struct/* don't use group allocation for large files */ size =max (size, isize); -if (size >= sbi->s_mb_stream_request) { +if (size > sbi->s_mb_stream_request) { ac->ac_flags |=EXT4_MB_STREAM_ALLOC ;return ; }
PATCH 97/165 ext4: fix error handling in migrate
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit f39490bcd1691d65dc33689222a12e1fc13dd824 upstream (as of v2.6.33-git11)
Set i_nlink to zero for temporary inode from very beginning. otherwise we may fail to start new journal handle and this inode will be unreferenced but with i_nlink == 1 Since we hold inode reference it can not be pruned.
Also add missed journal_start retval check.
--- fs/ext4/migrate.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-)
fs/ext4/migrate.c +14 -15
@@ -494,14 +494,10 @@ int ext4_ext_migrate(struct inode *inode }i_size_write (tmp_inode,i_size_read (inode));/* -* We don't want the inode to be reclaimed -* if we got interrupted in between. We have -* this tmp inode carrying reference to the -* data blocks of the original file. We set -* the i_nlink to zero at the last stage after -* switching the original file to extent format +* Set the i_nlink to zero so it will be deleted later +* when we drop inode reference. */ - tmp_inode->i_nlink =1 ; + tmp_inode->i_nlink =0 ;ext4_ext_tree_init (handle, tmp_inode);ext4_orphan_add (handle, tmp_inode);
@@ -528,6 +524,16 @@ int ext4_ext_migrate(struct inode *inodeup_read ((&EXT4_I (inode)->i_data_sem)); handle =ext4_journal_start (inode,1 ); +if (IS_ERR (handle)) { +/* +* It is impossible to update on-disk structures without +* a handle, so just rollback in-core changes and live other +* work to orphan_list_cleanup() +*/ +ext4_orphan_del (NULL , tmp_inode); + retval =PTR_ERR (handle); + goto out; + } ei =EXT4_I (inode); i_data = ei->i_data;
@@ -609,15 +615,8 @@ err_out:/* Reset the extent details */ ext4_ext_tree_init (handle, tmp_inode); - -/* -* Set the i_nlink to zero so that -* generic_drop_inode really deletes the -* inode -*/ - tmp_inode->i_nlink =0 ; -ext4_journal_stop (handle); +out:unlock_new_inode (tmp_inode);iput (tmp_inode);
PATCH 98/165 ext4: explicitly remove inode from orphan list after failed direct io
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit da1dafca84413145f5ac59998b4cdd06fb89f721 upstream (as of v2.6.33-git11)
Otherwise non-empty orphan list will be triggered on umount.
--- fs/ext4/inode.c | 3 +++ 1 file changed, 3 insertions(+)
fs/ext4/inode.c +3 -0
@@ -3480,6 +3480,9 @@ retry:* but cannot extend i_size. Bail out and pretend * the write failed... */ ret =PTR_ERR (handle); +if (inode->i_nlink) +ext4_orphan_del (NULL , inode); + goto out; }if (inode->i_nlink)
PATCH 99/165 ext4: Handle non empty on-disk orphan link
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 6e3617e579e070d3655a93ee9ed7149113e795e0 upstream (as of v2.6.33-git11)
In case of truncate errors we explicitly remove inode from in-core orphan list via orphan_del(NULL, inode) without modifying the on-disk list.
But later on, the same inode may be inserted in the orphan list again which will result the on-disk linked list getting corrupted. If inode i_dtime contains valid value, then skip on-disk list modification.
--- fs/ext4/namei.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/ext4/namei.c +8 -0
@@ -2020,6 +2020,13 @@ int ext4_orphan_add(handle_t *handle, st err =ext4_reserve_inode_write (handle, inode, &iloc);if (err) goto out_unlock; +/* +* Due to previous errors inode may be already a part of on-disk +* orphan list. If so skip on-disk list modification. +*/ +if (NEXT_ORPHAN (inode) &&NEXT_ORPHAN (inode) <= + (le32_to_cpu (EXT4_SB (sb)->s_es->s_inodes_count))) + goto mem_insert;/* Insert this inode at the head of the on-disk orphan list... */ NEXT_ORPHAN (inode) =le32_to_cpu (EXT4_SB (sb)->s_es->s_last_orphan);
@@ -2037,6 +2044,7 @@ int ext4_orphan_add(handle_t *handle, st* * This is safe: on error we're going to ignore the orphan list * anyway on the next recovery. */ +mem_insert:if (!err)list_add (&EXT4_I (inode)->i_orphan, &EXT4_SB (sb)->s_orphan);
PATCH 100/165 ext4: make "offset" consistent in ext4_check_dir_entry()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit b8b8afe236e97b6359d46d3a3f8c46455e192271 upstream (as of v2.6.33-git11)
The callers of ext4_check_dir_entry() usually pass in the "file offset" (ext4_readdir, htree_dirblock_to_tree, search_dirblock, ext4_dx_find_entry, empty_dir), but a few callers (add_dirent_to_buf, ext4_delete_entry) only pass in the buffer offset.
To accomodate those last two (which would be hard to fix otherwise), this patch changes ext4_check_dir_entry() to print the physical block number and the relative offset as well as the passed-in offset.
--- fs/ext4/dir.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
fs/ext4/dir.c +5 -3
@@ -84,9 +84,11 @@ int ext4_check_dir_entry(const char *funif (error_msg !=NULL )ext4_error (dir->i_sb, function, -"bad entry in directory #%lu: %s - " -"offset=%u, inode=%u, rec_len=%d, name_len=%d" , - dir->i_ino, error_msg, offset, +"bad entry in directory #%lu: %s - block=%llu" +"offset=%u(%u), inode=%u, rec_len=%d, name_len=%d" , + dir->i_ino, error_msg, + (unsigned long long ) bh->b_blocknr, + (unsigned ) (offset%bh->b_size), offset,le32_to_cpu (de->inode), rlen, de->name_len);return error_msg ==NULL ?1 :0 ;
PATCH 101/165 ext4: Fix insertion point of extent in mext_insert_across_blocks()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 5fd5249aa36fad98c9fd5edced352939e54f9324 upstream (as of v2.6.33-git11)
If the leaf node has 2 extent space or fewer and EXT4_IOC_MOVE_EXT ioctl is called with the file offset where after the 2nd extent covers, mext_insert_across_blocks() always tries to insert extent into the first extent. As a result, the file gets corrupted because of wrong extent order. The patch fixes this problem.
--- fs/ext4/move_extent.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/ext4/move_extent.c +4 -0
@@ -252,6 +252,7 @@ mext_insert_across_blocks(handle_t *hand } o_start->ee_len = start_ext->ee_len; + eblock =le32_to_cpu (start_ext->ee_block); new_flag =1 ; } else if (start_ext->ee_len && new_ext->ee_len &&
@@ -262,6 +263,7 @@ mext_insert_across_blocks(handle_t *hand* orig |------------------------------| */ o_start->ee_len = start_ext->ee_len; + eblock =le32_to_cpu (start_ext->ee_block); new_flag =1 ; } else if (!start_ext->ee_len && new_ext->ee_len &&
@@ -502,6 +504,7 @@ mext_leaf_block(handle_t *handle, struct le32_to_cpu(oext->ee_block) + oext_alen) { start_ext.ee_len =cpu_to_le16 (le32_to_cpu (new_ext.ee_block) -le32_to_cpu (oext->ee_block)); + start_ext.ee_block = oext->ee_block;copy_extent_status (oext, &start_ext); } else if (oext > EXT_FIRST_EXTENT(orig_path[depth].p_hdr)) { prev_ext = oext -1 ;
@@ -515,6 +518,7 @@ mext_leaf_block(handle_t *handle, struct start_ext.ee_len =cpu_to_le16 (ext4_ext_get_actual_len (prev_ext) + new_ext_alen); + start_ext.ee_block = oext->ee_block;copy_extent_status (prev_ext, &start_ext); new_ext.ee_len =0 ; }
PATCH 102/165 ext4: Fix the NULL reference in double_down_write_data_sem()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 7247c0caa23d94a1cb6b307edba9dc45fb0798d4 upstream (as of v2.6.33-git11)
If EXT4_IOC_MOVE_EXT ioctl is called with NULL donor_fd, fget() in ext4_ioctl() gets inappropriate file structure for donor; so we need to do this check earlier, before calling double_down_write_data_sem().
--- fs/ext4/move_extent.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
fs/ext4/move_extent.c +8 -8
@@ -953,14 +953,6 @@ mext_check_arguments(struct inode *orig_unsigned int blkbits = orig_inode->i_blkbits;unsigned int blocksize =1 << blkbits; -/* Regular file check */ -if (!S_ISREG (orig_inode->i_mode) || !S_ISREG (donor_inode->i_mode)) { -ext4_debug ("ext4 move extent: The argument files should be " -"regular file [ino:orig %lu, donor %lu]\n" , - orig_inode->i_ino, donor_inode->i_ino); -return -EINVAL ; - } -if (donor_inode->i_mode & (S_ISUID |S_ISGID )) { ext4_debug("ext4 move extent: suid or sgid is set" " to donor file [ino:orig %lu, donor %lu]\n",
@@ -1207,6 +1199,14 @@ ext4_move_extents(struct file *o_filp, s orig_inode->i_ino, donor_inode->i_ino);return -EINVAL ; } + +/* Regular file check */ +if (!S_ISREG (orig_inode->i_mode) || !S_ISREG (donor_inode->i_mode)) { +ext4_debug ("ext4 move extent: The argument files should be " +"regular file [ino:orig %lu, donor %lu]\n" , + orig_inode->i_ino, donor_inode->i_ino); +return -EINVAL ; + }/* Protect orig and donor inodes against a truncate */ ret1 =mext_inode_double_lock (orig_inode, donor_inode);
PATCH 103/165 ext4: Code cleanup for EXT4_IOC_MOVE_EXT ioctl
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit c437b2733520599a2c6e0dbcdeae611319f84707 upstream (as of v2.6.33-git11)
a) Fix sparse warning in ext4_ioctl()
b) Remove unneeded variable in mext_leaf_block()
c) Fix spelling typo in mext_check_arguments()
--- fs/ext4/ioctl.c | 3 ++- fs/ext4/move_extent.c | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-)
fs/ext4/ioctl.c +2 -1
@@ -258,7 +258,8 @@ setversion_out:if (me.moved_len >0 )file_remove_suid (donor_filp); -if (copy_to_user ((struct move_extent *)arg, &me,sizeof (me))) +if (copy_to_user ((struct move_extent __user *)arg, + &me,sizeof (me))) err = -EFAULT ; mext_out:fput (donor_filp);
fs/ext4/move_extent.c +1 -3
@@ -477,7 +477,6 @@ mext_leaf_block(handle_t *handle, structstruct ext4_extent *oext, *o_start, *o_end, *prev_ext;struct ext4_extent new_ext, start_ext, end_ext;ext4_lblk_t new_ext_end; -ext4_fsblk_t new_phys_end;int oext_alen, new_ext_alen, end_ext_alen;int depth =ext_depth (orig_inode);int ret;
@@ -491,7 +490,6 @@ mext_leaf_block(handle_t *handle, struct new_ext.ee_len = dext->ee_len; new_ext_alen =ext4_ext_get_actual_len (&new_ext); new_ext_end =le32_to_cpu (new_ext.ee_block) + new_ext_alen -1 ; - new_phys_end =ext_pblock (&new_ext) + new_ext_alen -1 ;/* * Case: original extent is first
@@ -932,7 +930,7 @@ out2: }/** -* mext_check_argumants - Check whether move extent can be done +* mext_check_arguments - Check whether move extent can be done * * @orig_inode: original inode * @donor_inode: donor inode
PATCH 104/165 ext4: Fix estimate of # of blocks needed to write indirect-mapped files
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit d330a5befb88875a9b3d2db62f9b74dadf660b13 upstream (as of v2.6.34-rc3)
http://bugzilla.kernel.org/show_bug.cgi?id=15420
--- fs/ext4/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/ext4/inode.c +2 -2
@@ -1060,7 +1060,7 @@ static int ext4_indirect_calc_metadata_a sector_t lblock) {struct ext4_inode_info *ei =EXT4_I (inode); -int dind_mask =EXT4_ADDR_PER_BLOCK (inode->i_sb) -1 ; +sector_t dind_mask = ~((sector_t )EXT4_ADDR_PER_BLOCK (inode->i_sb) -1 );int blk_bits;if (lblock <EXT4_NDIR_BLOCKS )
@@ -1075,7 +1075,7 @@ static int ext4_indirect_calc_metadata_a } ei->i_da_metadata_calc_last_lblock = lblock & dind_mask; ei->i_da_metadata_calc_len =1 ; - blk_bits =roundup_pow_of_two (lblock +1 ); + blk_bits =order_base_2 (lblock);return (blk_bits /EXT4_ADDR_PER_BLOCK_BITS (inode->i_sb)) +1 ; }
PATCH 105/165 ext4: Fixed inode allocator to correctly track a flex_bgs used_dirs
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit c4caae25187ff3f5e837c6f04eb1acc2723c72d3 upstream (as of v2.6.34-rc3)
When used_dirs was introduced for the flex_groups struct, it looks like the accounting was not put into place properly, in some places manipulating free_inodes rather than used_dirs.
--- fs/ext4/ialloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/ext4/ialloc.c +2 -2
@@ -268,7 +268,7 @@ void ext4_free_inode(handle_t *handle, sext4_group_t f; f =ext4_flex_group (sbi, block_group); -atomic_dec (&sbi->s_flex_groups[f].free_inodes); +atomic_dec (&sbi->s_flex_groups[f].used_dirs); } }
@@ -779,7 +779,7 @@ static int ext4_claim_inode(struct superif (sbi->s_log_groups_per_flex) {ext4_group_t f =ext4_flex_group (sbi, group); -atomic_inc (&sbi->s_flex_groups[f].free_inodes); +atomic_inc (&sbi->s_flex_groups[f].used_dirs); } } gdp->bg_checksum =ext4_group_desc_csum (sbi, group, gdp);
PATCH 106/165 ext4: Fix possible lost inode write in no journal mode
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 8b472d739b2ddd8ab7fb278874f696cd95b25a5e upstream (as of v2.6.34-rc6)
In the no-journal case, ext4_write_inode() will fetch the bh and call sync_dirty_buffer() on it. However, if the bh has already been written and the bh reclaimed for some other purpose, AND if the inode is the only one in the inode table block in use, then ext4_get_inode_loc() will not read the inode table block from disk, but as an optimization, fill the block with zero's assuming that its caller will copy in the on-disk version of the inode. This is not done by ext4_write_inode(), so the contents of the inode can simply get lost. The fix is to use __ext4_get_inode_loc() with in_mem set to 0, instead of ext4_get_inode_loc(). Long term the API needs to be fixed so it's obvious why latter is not safe.
Addresses-Google-Bug: #2526446
--- fs/ext4/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/inode.c +1 -1
@@ -5260,7 +5260,7 @@ int ext4_write_inode(struct inode *inode }else {struct ext4_iloc iloc; - err =ext4_get_inode_loc (inode, &iloc); + err =__ext4_get_inode_loc (inode, &iloc,0 );if (err)return err;if (wait)
PATCH 107/165 ext4: Fix buffer head leaks after calls to ext4_get_inode_loc()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit fd2dd9fbaf9e498ec63eef298921e36556f7214c upstream (as of v2.6.34-rc6)
Calls to ext4_get_inode_loc() returns with a reference to a buffer head in iloc->bh. The callers of this function in ext4_write_inode() when in no journal mode and in ext4_xattr_fiemap() don't release the buffer head after using it.
Addresses-Google-Bug: #2548165
--- fs/ext4/extents.c | 1 + fs/ext4/inode.c | 1 + 2 files changed, 2 insertions(+)
fs/ext4/extents.c +1 -0
@@ -3778,6 +3778,7 @@ static int ext4_xattr_fiemap(struct inod physical += offset; length =EXT4_SB (inode->i_sb)->s_inode_size - offset; flags |=FIEMAP_EXTENT_DATA_INLINE ; +brelse (iloc.bh); }else {/* external block */ physical =EXT4_I (inode)->i_file_acl << blockbits; length = inode->i_sb->s_blocksize;
fs/ext4/inode.c +1 -0
@@ -5273,6 +5273,7 @@ int ext4_write_inode(struct inode *inode (unsigned long long)iloc.bh->b_blocknr); err = -EIO ; } +brelse (iloc.bh); }return err; }
PATCH 108/165 ext4: Issue the discard operation *before* releasing the blocks to be reused
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit b90f687018e6d6c77d981b09203780f7001407e5 upstream (as of v2.6.34-rc6)
Otherwise, we can end up having data corruption because the blocks could get reused and then discarded!
https://bugzilla.kernel.org/show_bug.cgi?id=15579
--- fs/ext4/mballoc.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-)
fs/ext4/mballoc.c +11 -13
@@ -2537,6 +2537,17 @@ static void release_blocks_on_commit(joumb_debug (1 ,"gonna free %u blocks in group %u (0x%p):" , entry->count, entry->group, entry); +if (test_opt (sb,DISCARD )) { +ext4_fsblk_t discard_block; + + discard_block = entry->start_blk + +ext4_group_first_block_no (sb, entry->group); +trace_ext4_discard_blocks (sb, + (unsigned long long )discard_block, + entry->count); +sb_issue_discard (sb, discard_block, entry->count); + } + err =ext4_mb_load_buddy (sb, entry->group, &e4b);/* we expect to find existing buddy because it's pinned */ BUG_ON (err !=0 );
@@ -2558,19 +2569,6 @@ static void release_blocks_on_commit(joupage_cache_release (e4b.bd_bitmap_page); }ext4_unlock_group (sb, entry->group); -if (test_opt (sb,DISCARD )) { -ext4_fsblk_t discard_block; -struct ext4_super_block *es =EXT4_SB (sb)->s_es; - - discard_block = (ext4_fsblk_t )entry->group * -EXT4_BLOCKS_PER_GROUP (sb) - + entry->start_blk - +le32_to_cpu (es->s_first_data_block); -trace_ext4_discard_blocks (sb, - (unsigned long long )discard_block, - entry->count); -sb_issue_discard (sb, discard_block, entry->count); - }kmem_cache_free (ext4_free_ext_cachep, entry);ext4_mb_release_desc (&e4b); }
PATCH 109/165 ext4: check missed return value in ext4_sync_file()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 0671e704658b9f26f85e78d51176daa861f955c7 upstream (as of v2.6.34-git13)
--- fs/ext4/fsync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/fsync.c +1 -1
@@ -101,7 +101,7 @@ int ext4_sync_file(struct file *file, st (journal->j_fs_dev != journal->j_dev) && (journal->j_flags & JBD2_BARRIER))blkdev_issue_flush (inode->i_sb->s_bdev,NULL ); -jbd2_log_wait_commit (journal, commit_tid); + ret =jbd2_log_wait_commit (journal, commit_tid); }else if (journal->j_flags &JBD2_BARRIER )blkdev_issue_flush (inode->i_sb->s_bdev,NULL );return ret;
PATCH 110/165 ext4: fix memory leaks in error path handling of ext4_ext_zeroout()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit b720303df7352d4a7a1f61e467e0a124913c0d41 upstream (as of v2.6.34-git13)
When EIO occurs after bio is submitted, there is no memory free operation for bio, which results in memory leakage. And there is also no check against bio_alloc() for bio.
--- fs/ext4/extents.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
fs/ext4/extents.c +8 -7
@@ -2446,7 +2446,7 @@ static void bi_complete(struct bio *bio,/* FIXME!! we need to try to merge to left or right after zero-out */ static int ext4_ext_zeroout (struct inode *inode,struct ext4_extent *ex) { -int ret = -EIO ; +int ret;struct bio *bio;int blkbits, blocksize;sector_t ee_pblock;
@@ -2470,6 +2470,9 @@ static int ext4_ext_zeroout(struct inode len = ee_len; bio =bio_alloc (GFP_NOIO , len); +if (!bio) +return -ENOMEM ; + bio->bi_sector = ee_pblock; bio->bi_bdev = inode->i_sb->s_bdev;
@@ -2497,17 +2500,15 @@ static int ext4_ext_zeroout(struct inodesubmit_bio (WRITE , bio);wait_for_completion (&event); -if (test_bit (BIO_UPTODATE , &bio->bi_flags)) - ret =0 ; -else { - ret = -EIO ; -break ; +if (!test_bit (BIO_UPTODATE , &bio->bi_flags)) { +bio_put (bio); +return -EIO ; }bio_put (bio); ee_len -= done; ee_pblock += done << (blkbits -9 ); } -return ret; +return 0 ; }#define EXT4_EXT_ZERO_LEN 7
PATCH 111/165 ext4: Remove unnecessary call to ext4_get_group_desc() in mballoc
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 62e823a2cba18509ee826d775270e8ef9071b5bc upstream (as of v2.6.34-git13)
--- fs/ext4/mballoc.c | 2 -- 1 file changed, 2 deletions(-)
fs/ext4/mballoc.c +0 -2
@@ -2027,7 +2027,6 @@ repeat:for (i =0 ; i < ngroups; group++, i++) {struct ext4_group_info *grp; -struct ext4_group_desc *desc;if (group == ngroups) group =0 ;
@@ -2050,7 +2049,6 @@ repeat: } ac->ac_groups_scanned++; - desc =ext4_get_group_desc (sb, group,NULL );if (cr ==0 )ext4_mb_simple_scan_group (ac, &e4b); else if (cr == 1 &&
PATCH 112/165 ext4: rename ext4_mb_release_desc() to ext4_mb_unload_buddy()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit e39e07fdfd98be8650385f12a7b81d6adc547510 upstream (as of v2.6.34-git13)
This function cleans up after ext4_mb_load_buddy(), so the renaming makes the code clearer.
--- fs/ext4/mballoc.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
fs/ext4/mballoc.c +12 -12
@@ -1150,7 +1150,7 @@ err:return ret; } -static void ext4_mb_release_desc (struct ext4_buddy *e4b) +static void ext4_mb_unload_buddy (struct ext4_buddy *e4b) {if (e4b->bd_bitmap_page)page_cache_release (e4b->bd_bitmap_page);
@@ -1618,7 +1618,7 @@ int ext4_mb_try_best_found(struct ext4_a }ext4_unlock_group (ac->ac_sb, group); -ext4_mb_release_desc (e4b); +ext4_mb_unload_buddy (e4b);return 0 ; }
@@ -1674,7 +1674,7 @@ int ext4_mb_find_by_goal(struct ext4_allext4_mb_use_best_found (ac, e4b); }ext4_unlock_group (ac->ac_sb, group); -ext4_mb_release_desc (e4b); +ext4_mb_unload_buddy (e4b);return 0 ; }
@@ -2044,7 +2044,7 @@ repeat:if (!ext4_mb_good_group (ac, group, cr)) {/* someone did allocation from this group */ ext4_unlock_group (sb, group); -ext4_mb_release_desc (&e4b); +ext4_mb_unload_buddy (&e4b);continue ; }
@@ -2058,7 +2058,7 @@ repeat:ext4_mb_complex_scan_group (ac, &e4b);ext4_unlock_group (sb, group); -ext4_mb_release_desc (&e4b); +ext4_mb_unload_buddy (&e4b);if (ac->ac_status !=AC_STATUS_CONTINUE )break ;
@@ -2148,7 +2148,7 @@ static int ext4_mb_seq_groups_show(strucext4_lock_group (sb, group);memcpy (&sg,ext4_get_group_info (sb, group), i);ext4_unlock_group (sb, group); -ext4_mb_release_desc (&e4b); +ext4_mb_unload_buddy (&e4b);seq_printf (seq,"#%-5u: %-5u %-5u %-5u [" , group, sg.info.bb_free, sg.info.bb_fragments, sg.info.bb_first_free);
@@ -2568,7 +2568,7 @@ static void release_blocks_on_commit(jou }ext4_unlock_group (sb, entry->group);kmem_cache_free (ext4_free_ext_cachep, entry); -ext4_mb_release_desc (&e4b); +ext4_mb_unload_buddy (&e4b); }mb_debug (1 ,"freed %u blocks in %u structures\n" , count, count2);
@@ -3705,7 +3705,7 @@ out:ext4_unlock_group (sb, group);if (ac)kmem_cache_free (ext4_ac_cachep, ac); -ext4_mb_release_desc (&e4b); +ext4_mb_unload_buddy (&e4b);put_bh (bitmap_bh);return free; }
@@ -3809,7 +3809,7 @@ repeat:if (bitmap_bh ==NULL ) {ext4_error (sb, __func__,"Error in reading block " "bitmap for %u" , group); -ext4_mb_release_desc (&e4b); +ext4_mb_unload_buddy (&e4b);continue ; }
@@ -3818,7 +3818,7 @@ repeat:ext4_mb_release_inode_pa (&e4b, bitmap_bh, pa, ac);ext4_unlock_group (sb, group); -ext4_mb_release_desc (&e4b); +ext4_mb_unload_buddy (&e4b);put_bh (bitmap_bh);list_del (&pa->u.pa_tmp_list);
@@ -4082,7 +4082,7 @@ ext4_mb_discard_lg_preallocations(structext4_mb_release_group_pa (&e4b, pa, ac);ext4_unlock_group (sb, group); -ext4_mb_release_desc (&e4b); +ext4_mb_unload_buddy (&e4b);list_del (&pa->u.pa_tmp_list);call_rcu (&(pa)->u.pa_rcu, ext4_mb_pa_callback); }
@@ -4584,7 +4584,7 @@ do_more:atomic_add (count, &sbi->s_flex_groups[flex_group].free_blocks); } -ext4_mb_release_desc (&e4b); +ext4_mb_unload_buddy (&e4b); *freed += count;
PATCH 113/165 ext4: allow defrag (EXT4_IOC_MOVE_EXT) in 32bit compat mode
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit b684b2ee9409f2890a8b3aea98525bbe5f84e276 upstream (as of v2.6.34-git13)
I have an x86_64 kernel with i386 userspace. e4defrag fails on the EXT4_IOC_MOVE_EXT ioctl because it is not wired up for the compat case. It seems that struct move_extent is compat save, only types with fixed widths are used:
{
__u32 reserved; /* should be zero */
__u32 donor_fd; /* donor file descriptor */
__u64 orig_start; /* logical start offset in block for orig */
__u64 donor_start; /* logical start offset in block for donor */
__u64 len; /* block length to be moved */
__u64 moved_len; /* moved block length */};
Lets just wire up EXT4_IOC_MOVE_EXT for the compat case.
--- fs/ext4/ioctl.c | 2 ++ 1 file changed, 2 insertions(+)
fs/ext4/ioctl.c +2 -0
@@ -375,6 +375,8 @@ long ext4_compat_ioctl(struct file *filebreak ;case EXT4_IOC_GROUP_ADD :break ; +case EXT4_IOC_MOVE_EXT : +break ;default :return -ENOIOCTLCMD ; }
PATCH 114/165 ext4: fix quota accounting in case of fallocate
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 35121c9860316d7799cea0fbc359a9186e7c2747 upstream (as of v2.6.34-git13)
allocated_meta_data is already included in 'used' variable.
--- fs/ext4/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ext4/inode.c +2 -1
@@ -1149,7 +1149,8 @@ void ext4_da_update_reserve_space(struct*/ if (allocated_meta_blocks)vfs_dq_claim_block (inode, allocated_meta_blocks); -vfs_dq_release_reservation_block (inode, mdb_free + used); +vfs_dq_release_reservation_block (inode, mdb_free + used - + allocated_meta_blocks); }/*
PATCH 115/165 ext4: check s_log_groups_per_flex in online resize code
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 42007efd569f1cf3bfb9a61da60ef6c2179508ca upstream (as of v2.6.34-git13)
If groups_per_flex < 2, sbi->s_flex_groups[] doesn't get filled out, and every other access to this first tests s_log_groups_per_flex; same thing needs to happen in resize or we'll wander off into a null pointer when doing an online resize of the file system.
Thanks to Christoph Biedl, who came up with the trivial testcase:
# truncate --size 128M fsfile # mkfs.ext3 -F fsfile # tune2fs -O extents,uninit_bg,dir_index,flex_bg,huge_file,dir_nlink,extra_isize fsfile # e2fsck -yDf -C0 fsfile # truncate --size 132M fsfile # losetup /dev/loop0 fsfile # mount /dev/loop0 mnt # resize2fs -p /dev/loop0
https://bugzilla.kernel.org/show_bug.cgi?id=13549
--- fs/ext4/resize.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ext4/resize.c +2 -1
@@ -930,7 +930,8 @@ int ext4_group_add(struct super_block *spercpu_counter_add (&sbi->s_freeinodes_counter,EXT4_INODES_PER_GROUP (sb)); -if (EXT4_HAS_INCOMPAT_FEATURE (sb,EXT4_FEATURE_INCOMPAT_FLEX_BG )) { +if (EXT4_HAS_INCOMPAT_FEATURE (sb,EXT4_FEATURE_INCOMPAT_FLEX_BG ) && + sbi->s_log_groups_per_flex) {ext4_group_t flex_group; flex_group =ext4_flex_group (sbi, input->group); atomic_add(input->free_blocks_count,
PATCH 116/165 ext4: dont return to userspace after freezing the fs with a mutex held
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 6b0310fbf087ad6e9e3b8392adca97cd77184084 upstream (as of v2.6.34-git13)
ext4_freeze() used jbd2_journal_lock_updates() which takes the j_barrier mutex, and then returns to userspace. The kernel does not like this:
================================================
[ BUG: lock held when returning to user space! ]
------------------------------------------------
lvcreate/1075 is leaving the kernel with locks still held! 1 lock held by lvcreate/1075:
#0: (&journal->j_barrier){+.+...}, at: [<ffffffff811c6214>]jbd2_journal_lock_updates+0xe1/0xf0
Use vfs_check_frozen() added to ext4_journal_start_sb() and ext4_force_commit() instead.
Addresses-Red-Hat-Bugzilla: #568503
--- fs/ext4/super.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
fs/ext4/super.c +10 -10
@@ -227,6 +227,7 @@ handle_t *ext4_journal_start_sb(struct sif (sb->s_flags &MS_RDONLY )return ERR_PTR (-EROFS ); +vfs_check_frozen (sb,SB_FREEZE_WRITE );/* Special case here: if the journal has aborted behind our * backs (eg. EIO in the commit thread), then we still need to * take the FS itself readonly cleanly. */
@@ -3391,8 +3392,10 @@ int ext4_force_commit(struct super_blockreturn 0 ; journal =EXT4_SB (sb)->s_journal; -if (journal) +if (journal) { +vfs_check_frozen (sb,SB_FREEZE_WRITE ); ret =ext4_journal_force_commit (journal); + }return ret; }
@@ -3441,18 +3444,16 @@ static int ext4_freeze(struct super_bloc* the journal. */ error =jbd2_journal_flush (journal); -if (error <0 ) { - out: -jbd2_journal_unlock_updates (journal); -return error; - } +if (error <0 ) + goto out;/* Journal blocked and flushed, clear needs_recovery flag. */ EXT4_CLEAR_INCOMPAT_FEATURE (sb,EXT4_FEATURE_INCOMPAT_RECOVER ); error =ext4_commit_super (sb,1 ); -if (error) - goto out; -return 0 ; +out: +/* we rely on s_frozen to stop further updates */ +jbd2_journal_unlock_updates (EXT4_SB (sb)->s_journal); +return error; }/*
@@ -3469,7 +3470,6 @@ static int ext4_unfreeze(struct super_blEXT4_SET_INCOMPAT_FEATURE (sb,EXT4_FEATURE_INCOMPAT_RECOVER );ext4_commit_super (sb,1 );unlock_super (sb); -jbd2_journal_unlock_updates (EXT4_SB (sb)->s_journal);return 0 ; }
Re: [Stable-review] [116/165] ext4: dont return to userspace after freezing the fs with a mutex held
We have reports about this patch breaking lvm snapshhots. Eric, there is a patch mentioned which is supposed to fix things but its not upstream, yet. Do you know what happened to that?
-Stefan
PATCH] ext4: fix freeze deadlock under IO
Commit 6b0310fbf087ad6 caused a regression resulting in deadlocks when freezing a filesystem which had active IO; the vfs_check_frozen level (SB_FREEZE_WRITE) did not let the freeze-related IO syncing through. Duh.
Changing the test to FREEZE_TRANS should let the normal freeze syncing get through the fs, but still block any transactions from starting once the fs is completely frozen.
I tested this by running fsstress in the background while periodically snapshotting the fs and running fsck on the result. I ran into occasional deadlocks, but different ones. I think this is a fine fix for the problem at hand, and the other deadlocky things will need more investigation.
---
fs/ext4/super.c +0 -0
@@ -241,7 +241,7 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int
nblocks)
if (sb->s_flags & MS_RDONLY)
return ERR_PTR(-EROFS);
- vfs_check_frozen(sb, SB_FREEZE_WRITE);
+ vfs_check_frozen(sb, SB_FREEZE_TRANS);
/* Special case here: if the journal has aborted behind our
* backs (eg. EIO in the commit thread), then we still need to
* take the FS itself readonly cleanly. */
@@ -3491,7 +3491,7 @@ int ext4_force_commit(struct super_block *sb)
journal = EXT4_SB(sb)->s_journal;
if (journal) {
- vfs_check_frozen(sb, SB_FREEZE_WRITE);
+ vfs_check_frozen(sb, SB_FREEZE_TRANS);
ret = ext4_journal_force_commit(journal);
}
Quoted 91 lines · Greg KH
2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit
6b0310fbf087ad6e9e3b8392adca97cd77184084upstream (as of v2.6.34-git13)
ext4_freeze()usedjbd2_journal_lock_updates()which takes thej_barriermutex, and then returns to userspace. The kernel does not like this:================================================
[ BUG: lock held when returning to user space! ]
------------------------------------------------
lvcreate/1075 is leaving the kernel with locks still held! 1 lock held by lvcreate/1075:
#0: (&journal->j_barrier){+.+...}, at: [<ffffffff811c6214>]jbd2_journal_lock_updates+0xe1/0xf0Use
vfs_check_frozen()added toext4_journal_start_sb()andext4_force_commit()instead.Addresses-Red-Hat-Bugzilla: #568503
Signed-off-by Eric Sandeen <[email protected]>Signed-off-by "Theodore Ts'o" <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- fs/ext4/super.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)fs/ext4/super.c +10
-10@@ -227,6 +227,7 @@ handle_t *ext4_journal_start_sb(struct sif (sb->s_flags &MS_RDONLY )return ERR_PTR (-EROFS ); +vfs_check_frozen (sb,SB_FREEZE_WRITE );/* Special case here: if the journal has aborted behind our * backs (eg. EIO in the commit thread), then we still need to * take the FS itself readonly cleanly. */ @@ -3391,8 +3392,10 @@ int ext4_force_commit(struct super_blockreturn 0 ; journal =EXT4_SB (sb)->s_journal; -if (journal) +if (journal) { +vfs_check_frozen (sb,SB_FREEZE_WRITE ); ret =ext4_journal_force_commit (journal); + }return ret; }@@ -3441,18 +3444,16 @@ static int ext4_freeze(struct super_bloc* the journal. */ error =jbd2_journal_flush (journal); -if (error <0 ) { - out: -jbd2_journal_unlock_updates (journal); -return error; - } +if (error <0 ) + goto out;/* Journal blocked and flushed, clear needs_recovery flag. */ EXT4_CLEAR_INCOMPAT_FEATURE (sb,EXT4_FEATURE_INCOMPAT_RECOVER ); error =ext4_commit_super (sb,1 ); -if (error) - goto out; -return 0 ; +out: +/* we rely on s_frozen to stop further updates */ +jbd2_journal_unlock_updates (EXT4_SB (sb)->s_journal); +return error; }/* @@ -3469,7 +3470,6 @@ static int ext4_unfreeze(struct super_blEXT4_SET_INCOMPAT_FEATURE (sb,EXT4_FEATURE_INCOMPAT_RECOVER );ext4_commit_super (sb,1 );unlock_super (sb); -jbd2_journal_unlock_updates (EXT4_SB (sb)->s_journal);return 0 ; }_______________________________________________
Stable-review mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable-review
Re: [Stable-review] [116/165] ext4: dont return to userspace after freezing the fs with a mutex held
Quoted 3 lines · Stefan Bader
We have reports about this patch breaking lvm snapshhots. Eric, there is a patch mentioned which is supposed to fix things but its not upstream, yet. Do you know what happened to that?
right, patch below is needed to fix things.
Ted just acked it on the list recently; Greg, I'd either drop 116/165 for now, or include the patch below which should be upstream soon...
-Eric
Quoted 141 lines
-Stefan
PATCH] ext4: fix freeze deadlock under IO
Commit
6b0310fbf087ad6caused a regression resulting in deadlocks when freezing a filesystem which had active IO; thevfs_check_frozenlevel (SB_FREEZE_WRITE) did not let the freeze-related IO syncing through. Duh.Changing the test to
FREEZE_TRANSshould let the normal freeze syncing get through the fs, but still block any transactions from starting once the fs is completely frozen.I tested this by running fsstress in the background while periodically snapshotting the fs and running fsck on the result. I ran into occasional deadlocks, but different ones. I think this is a fine fix for the problem at hand, and the other deadlocky things will need more investigation.
Reported-by Phillip Susi <[email protected]>Signed-off-by Eric Sandeen <[email protected]>---
fs/ext4/super.c +1
-1@@ -241,7 +241,7 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)if (sb->s_flags &MS_RDONLY )return ERR_PTR (-EROFS ); -vfs_check_frozen (sb,SB_FREEZE_WRITE ); +vfs_check_frozen (sb,SB_FREEZE_TRANS );/* Special case here: if the journal has aborted behind our * backs (eg. EIO in the commit thread), then we still need to fs/ext4/super.c +1
-1* take the FS itself readonly cleanly. */ @@ -3491,7 +3491,7 @@ int ext4_force_commit(struct super_block *sb) journal =EXT4_SB (sb)->s_journal;if (journal) { -vfs_check_frozen (sb,SB_FREEZE_WRITE ); +vfs_check_frozen (sb,SB_FREEZE_TRANS ); ret =ext4_journal_force_commit (journal); }Quoted 91 lines · Greg KH
2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit
6b0310fbf087ad6e9e3b8392adca97cd77184084upstream (as of v2.6.34-git13)
ext4_freeze()usedjbd2_journal_lock_updates()which takes thej_barriermutex, and then returns to userspace. The kernel does not like this:================================================
[ BUG: lock held when returning to user space! ]
------------------------------------------------
lvcreate/1075 is leaving the kernel with locks still held! 1 lock held by lvcreate/1075:
#0: (&journal->j_barrier){+.+...}, at: [<ffffffff811c6214>]jbd2_journal_lock_updates+0xe1/0xf0Use
vfs_check_frozen()added toext4_journal_start_sb()andext4_force_commit()instead.Addresses-Red-Hat-Bugzilla: #568503
Signed-off-by Eric Sandeen <[email protected]>Signed-off-by "Theodore Ts'o" <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- fs/ext4/super.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)fs/ext4/super.c +10
-10@@ -227,6 +227,7 @@ handle_t *ext4_journal_start_sb(struct sif (sb->s_flags &MS_RDONLY )return ERR_PTR (-EROFS ); +vfs_check_frozen (sb,SB_FREEZE_WRITE );/* Special case here: if the journal has aborted behind our * backs (eg. EIO in the commit thread), then we still need to * take the FS itself readonly cleanly. */ @@ -3391,8 +3392,10 @@ int ext4_force_commit(struct super_blockreturn 0 ; journal =EXT4_SB (sb)->s_journal; -if (journal) +if (journal) { +vfs_check_frozen (sb,SB_FREEZE_WRITE ); ret =ext4_journal_force_commit (journal); + }return ret; }@@ -3441,18 +3444,16 @@ static int ext4_freeze(struct super_bloc* the journal. */ error =jbd2_journal_flush (journal); -if (error <0 ) { - out: -jbd2_journal_unlock_updates (journal); -return error; - } +if (error <0 ) + goto out;/* Journal blocked and flushed, clear needs_recovery flag. */ EXT4_CLEAR_INCOMPAT_FEATURE (sb,EXT4_FEATURE_INCOMPAT_RECOVER ); error =ext4_commit_super (sb,1 ); -if (error) - goto out; -return 0 ; +out: +/* we rely on s_frozen to stop further updates */ +jbd2_journal_unlock_updates (EXT4_SB (sb)->s_journal); +return error; }/* @@ -3469,7 +3470,6 @@ static int ext4_unfreeze(struct super_blEXT4_SET_INCOMPAT_FEATURE (sb,EXT4_FEATURE_INCOMPAT_RECOVER );ext4_commit_super (sb,1 );unlock_super (sb); -jbd2_journal_unlock_updates (EXT4_SB (sb)->s_journal);return 0 ; }_______________________________________________
Stable-review mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable-review
Re: [stable] [Stable-review] [116/165] ext4: dont return to userspace after freezing the fs with a mutex held
Quoted 9 lines · Eric Sandeen
Quoted 3 lines · Stefan Bader
We have reports about this patch breaking lvm snapshhots. Eric, there is a patch mentioned which is supposed to fix things but its not upstream, yet. Do you know what happened to that?
right, patch below is needed to fix things.
Ted just acked it on the list recently; Greg, I'd either drop 116/165 for now, or include the patch below which should be upstream soon...
I can't take anything that isn't upstream yet.
And I just released with this patch in the kernel, should I do a revert and do a new release?
thanks,
greg k-h
Re: [stable] [Stable-review] [116/165] ext4: dont return to userspace after freezing the fs with a mutex held
Quoted 8 lines · Greg KH
Quoted 7 lines · Eric Sandeen
Quoted 3 lines · Stefan Bader
We have reports about this patch breaking lvm snapshhots. Eric, there is a patch mentioned which is supposed to fix things but its not upstream, yet. Do you know what happened to that?
right, patch below is needed to fix things.
Quoted 7 lines
Quoted 2 lines
Ted just acked it on the list recently; Greg, I'd either drop 116/165 for now, or include the patch below which should be upstream soon...
I can't take anything that isn't upstream yet.
And I just released with this patch in the kernel, should I do a revert and do a new release?
Any answers on this?
Signature · 4 lines
"One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh
Re: [stable] [Stable-review] [116/165] ext4: dont return to userspace after freezing the fs with a mutex held
Quoted 12 lines · Henrique de Moraes Holschuh
Quoted 11 lines · Greg KH
Quoted 9 lines · Eric Sandeen
Quoted 3 lines · Stefan Bader
We have reports about this patch breaking lvm snapshhots. Eric, there is a patch mentioned which is supposed to fix things but its not upstream, yet. Do you know what happened to that?
right, patch below is needed to fix things.
Ted just acked it on the list recently; Greg, I'd either drop 116/165 for now, or include the patch below which should be upstream soon...
Quoted 6 lines
Quoted 4 lines
I can't take anything that isn't upstream yet.
And I just released with this patch in the kernel, should I do a revert and do a new release?
Any answers on this?
Nope :(
Re: [stable] [Stable-review] [116/165] ext4: dont return to userspace after freezing the fs with a mutex held
In reply to Henrique de Moraes HolschuhQuoted 8 lines · Henrique de Moraes Holschuh
Quoted 7 lines · Greg KH
Quoted 6 lines · Eric Sandeen
Quoted 3 lines · Stefan Bader
We have reports about this patch breaking lvm snapshhots. Eric, there is a patch mentioned which is supposed to fix things but its not upstream, yet. Do you know what happened to that?
right, patch below is needed to fix things.
Quoted 9 lines
Quoted 6 lines
Quoted 2 lines
Ted just acked it on the list recently; Greg, I'd either drop 116/165 for now, or include the patch below which should be upstream soon...
I can't take anything that isn't upstream yet.
And I just released with this patch in the kernel, should I do a revert and do a new release?
Any answers on this?
Yes, I'd revert it for now, I'm afraid, if the other patch isn't upstream yet.
Sorry about that,
-Eric
Re: [stable] [Stable-review] [116/165] ext4: dont return to userspace after freezing the fs with a mutex held
Quoted 19 lines · Eric Sandeen
Quoted 8 lines · Henrique de Moraes Holschuh
Quoted 7 lines · Greg KH
Quoted 6 lines · Eric Sandeen
Quoted 3 lines · Stefan Bader
We have reports about this patch breaking lvm snapshhots. Eric, there is a patch mentioned which is supposed to fix things but its not upstream, yet. Do you know what happened to that?
right, patch below is needed to fix things.
Quoted 9 lines
Quoted 6 lines
Quoted 2 lines
Ted just acked it on the list recently; Greg, I'd either drop 116/165 for now, or include the patch below which should be upstream soon...
I can't take anything that isn't upstream yet.
And I just released with this patch in the kernel, should I do a revert and do a new release?
Any answers on this?
Quoted 6 lines
Yes, I'd revert it for now, I'm afraid, if the other patch isn't upstream yet.
Sorry about that,
-Eric
Upstream as of now (same SHA1 as in linux-next):
Quoted 1 line
From
437f88cc031ffe7f37f3e705367f4fe1f4be8b0fMon Sep 17 00:00:00 2001
From: Eric Sandeen <[email protected]>
Date: Sun, 1 Aug 2010 17:33:29 -0400
Subject: [PATCH] (pre-stable) ext4: fix freeze deadlock under IO
-Stefan
Re: [stable] [Stable-review] [116/165] ext4: dont return to userspace after freezing the fs with a mutex held
Quoted 25 lines · Stefan Bader
Quoted 24 lines · Eric Sandeen
Quoted 8 lines · Henrique de Moraes Holschuh
Quoted 7 lines · Greg KH
Quoted 6 lines · Eric Sandeen
Quoted 3 lines · Stefan Bader
We have reports about this patch breaking lvm snapshhots. Eric, there is a patch mentioned which is supposed to fix things but its not upstream, yet. Do you know what happened to that?
right, patch below is needed to fix things.
Quoted 9 lines
Quoted 6 lines
Quoted 2 lines
Ted just acked it on the list recently; Greg, I'd either drop 116/165 for now, or include the patch below which should be upstream soon...
I can't take anything that isn't upstream yet.
And I just released with this patch in the kernel, should I do a revert and do a new release?
Any answers on this?
Yes, I'd revert it for now, I'm afraid, if the other patch isn't upstream yet.
Sorry about that,
Quoted 8 lines
Quoted 1 line
-Eric
Upstream as of now (same SHA1 as in linux-next):
Quoted 1 line
From
437f88cc031ffe7f37f3e705367f4fe1f4be8b0fMon Sep 17 00:00:00 2001From: Eric Sandeen <[email protected]>
Date: Sun, 1 Aug 2010 17:33:29 -0400
Subject: [PATCH] (pre-stable) ext4: fix freeze deadlock under IO
It looks like I can't drop the original one, as this patch builds on it. So I'll just queue this one up.
Should it also go into other -stable releases (like .35 and/or .34 -stable?)
thanks,
greg k-h
Re: [stable] [Stable-review] [116/165] ext4: dont return to userspace after freezing the fs with a mutex held
Quoted 31 lines · Greg KH
Quoted 30 lines · Stefan Bader
Quoted 19 lines · Eric Sandeen
Quoted 8 lines · Henrique de Moraes Holschuh
Quoted 7 lines · Greg KH
Quoted 6 lines · Eric Sandeen
Quoted 3 lines · Stefan Bader
We have reports about this patch breaking lvm snapshhots. Eric, there is a patch mentioned which is supposed to fix things but its not upstream, yet. Do you know what happened to that?
right, patch below is needed to fix things.
Quoted 9 lines
Quoted 6 lines
Quoted 2 lines
Ted just acked it on the list recently; Greg, I'd either drop 116/165 for now, or include the patch below which should be upstream soon...
I can't take anything that isn't upstream yet.
And I just released with this patch in the kernel, should I do a revert and do a new release?
Any answers on this?
Quoted 6 lines
Yes, I'd revert it for now, I'm afraid, if the other patch isn't upstream yet.
Sorry about that,
-Eric
Upstream as of now (same SHA1 as in linux-next):
Quoted 1 line
From
437f88cc031ffe7f37f3e705367f4fe1f4be8b0fMon Sep 17 00:00:00 2001
Quoted 9 lines
Quoted 3 lines
From: Eric Sandeen <[email protected]>
Date: Sun, 1 Aug 2010 17:33:29 -0400
Subject: [PATCH] (pre-stable) ext4: fix freeze deadlock under IOIt looks like I can't drop the original one, as this patch builds on it. So I'll just queue this one up.
Should it also go into other -stable releases (like .35 and/or .34 -stable?)
Final call would be Eric/Ted but as far as I can see:
.34: not for now (patch that causes regression not backported there (yet)) .35: yes (offending patch has been in 2.6.35-rc1)
-Stefan
Quoted 3 lines
thanks,
greg k-h
Re: [stable] [Stable-review] [116/165] ext4: dont return to userspace after freezing the fs with a mutex held
Quoted 35 lines · Stefan Bader
Quoted 34 lines · Greg KH
Quoted 23 lines · Stefan Bader
Quoted 22 lines · Eric Sandeen
Quoted 8 lines · Henrique de Moraes Holschuh
Quoted 7 lines · Greg KH
Quoted 6 lines · Eric Sandeen
Quoted 3 lines · Stefan Bader
We have reports about this patch breaking lvm snapshhots. Eric, there is a patch mentioned which is supposed to fix things but its not upstream, yet. Do you know what happened to that?
right, patch below is needed to fix things.
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
Ted just acked it on the list recently; Greg, I'd either drop 116/165 for now, or include the patch below which should be upstream soon...
I can't take anything that isn't upstream yet.
And I just released with this patch in the kernel, should I do a revert and do a new release?
Any answers on this?
Yes, I'd revert it for now, I'm afraid, if the other patch isn't upstream yet.
Sorry about that,
Quoted 7 lines
Quoted 1 line
-Eric
Upstream as of now (same SHA1 as in linux-next):
Quoted 1 line
From
437f88cc031ffe7f37f3e705367f4fe1f4be8b0fMon Sep 17 00:00:00 2001From: Eric Sandeen <[email protected]>
Date: Sun, 1 Aug 2010 17:33:29 -0400
Subject: [PATCH] (pre-stable) ext4: fix freeze deadlock under IOIt looks like I can't drop the original one, as this patch builds on it. So I'll just queue this one up.
Quoted 7 lines
Quoted 2 lines
Should it also go into other -stable releases (like .35 and/or .34 -stable?)
Final call would be Eric/Ted but as far as I can see:
.34: not for now (patch that causes regression not backported there (yet)) .35: yes (offending patch has been in 2.6.35-rc1)
As long as the 2 patches go together it should be fine, I don't think there are other significant dependencies.
It's also not really an urgent one to fix; returning to userspace w/ a lock held is pretty icky but in practice has not been an actual problem AFAIK; most people use lvm to freeze/unfreeze and it all gets cleaned up....
-Eric
Quoted 6 lines
-Stefan
Quoted 3 lines
thanks,
greg k-h
Ted Ts'o
maintainerRe: [Stable-review] [stable] [116/165] ext4: dont return to userspace after freezing the fs with a mutex held
Quoted 8 lines · Eric Sandeen
As long as the 2 patches go together it should be fine, I don't think there are other significant dependencies.
It's also not really an urgent one to fix; returning to userspace w/ a lock held is pretty icky but in practice has not been an actual problem AFAIK; most people use lvm to freeze/unfreeze and it all gets cleaned up....
Agreed.
I do plan to be uploading stable updates for 2.6.35.x that include the changes that got pulled for 2.6.35-rc1, and I'll update 2.6.34 and 2.6.32, as well, with 2.6.34 including the updates that somehow didn't all make it to stable last time. (I'm thinking about also including an ftp upload since for some reason some mail server between me at [email protected] seems to be dropping mail messages when they get blasted out using git send-email. :-/ )
I'm at Linuxcon this week though, so I probably won't get to it until sometime next week.
- Ted
Re: [stable] [Stable-review] [116/165] ext4: dont return to userspace after freezing the fs with a mutex held
In reply to Stefan BaderQuoted 25 lines · Stefan Bader
Quoted 24 lines · Eric Sandeen
Quoted 8 lines · Henrique de Moraes Holschuh
Quoted 7 lines · Greg KH
Quoted 6 lines · Eric Sandeen
Quoted 3 lines · Stefan Bader
We have reports about this patch breaking lvm snapshhots. Eric, there is a patch mentioned which is supposed to fix things but its not upstream, yet. Do you know what happened to that?
right, patch below is needed to fix things.
Quoted 9 lines
Quoted 6 lines
Quoted 2 lines
Ted just acked it on the list recently; Greg, I'd either drop 116/165 for now, or include the patch below which should be upstream soon...
I can't take anything that isn't upstream yet.
And I just released with this patch in the kernel, should I do a revert and do a new release?
Any answers on this?
Yes, I'd revert it for now, I'm afraid, if the other patch isn't upstream yet.
Sorry about that,
Quoted 8 lines
Quoted 1 line
-Eric
Upstream as of now (same SHA1 as in linux-next):
Quoted 1 line
From
437f88cc031ffe7f37f3e705367f4fe1f4be8b0fMon Sep 17 00:00:00 2001From: Eric Sandeen <[email protected]>
Date: Sun, 1 Aug 2010 17:33:29 -0400
Subject: [PATCH] (pre-stable) ext4: fix freeze deadlock under IO
That is a patch from 2010, are you sure this is what you are looking for?
confused,
greg k-h
PATCH 117/165 ext4: stop issuing discards if not supported by device
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit a30eec2a8650a77f754e84b2e15f062fe652baa7 upstream (as of v2.6.34-git13)
Turn off issuance of discard requests if the device does not support it - similar to the action we take for barriers. This will save a little computation time if a non-discardable device is mounted with -o discard, and also makes it obvious that it's not doing what was asked at mount time ...
--- fs/ext4/mballoc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
fs/ext4/mballoc.c +7 -1
@@ -2536,6 +2536,7 @@ static void release_blocks_on_commit(jou entry->count, entry->group, entry);if (test_opt (sb,DISCARD )) { +int ret;ext4_fsblk_t discard_block; discard_block = entry->start_blk +
@@ -2543,7 +2544,12 @@ static void release_blocks_on_commit(joutrace_ext4_discard_blocks (sb, (unsigned long long )discard_block, entry->count); -sb_issue_discard (sb, discard_block, entry->count); + ret =sb_issue_discard (sb, discard_block, entry->count); +if (ret ==EOPNOTSUPP ) { +ext4_warning (sb, __func__, +"discard not supported, disabling" ); +clear_opt (EXT4_SB (sb)->s_mount_opt,DISCARD ); + } } err =ext4_mb_load_buddy (sb, entry->group, &e4b);
PATCH 118/165 ext4: dont scan/accumulate more pages than mballoc will allocate
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit c445e3e0a5c2804524dec6e55f66d63f6bc5bc3e upstream (as of v2.6.34-git13)
There was a bug reported on RHEL5 that a 10G dd on a 12G box had a very, very slow sync after that.
At issue was the loop in write_cache_pages scanning all the way to the end of the 10G file, even though the subsequent call to mpage_da_submit_io would only actually write a smallish amt; then we went back to the write_cache_pages loop ... wasting tons of time in calling __mpage_da_writepage for thousands of pages we would just revisit (many times) later.
Upstream it's not such a big issue for sys_sync because we get to the loop with a much smaller nr_to_write, which limits the loop.
However, talking with Aneesh he realized that fsync upstream still gets here with a very large nr_to_write and we face the same problem.
This patch makes mpage_add_bh_to_extent stop the loop after we've accumulated 2048 pages, by setting mpd->io_done = 1; which ultimately causes the write_cache_pages loop to break.
Repeating the test with a dirty_ratio of 80 (to leave something for fsync to do), I don't see huge IO performance gains, but the reduction in cpu usage is striking: 80% usage with stock, and 2% with the below patch. Instrumenting the loop in write_cache_pages clearly shows that we are wasting time here.
Eventually we need to change mpage_da_map_pages() also submit its I/O to the block layer, subsuming mpage_da_submit_io(), and then change it call ext4_get_blocks() multiple times.
--- fs/ext4/inode.c | 9 +++++++++ 1 file changed, 9 insertions(+)
fs/ext4/inode.c +9 -0
@@ -2361,6 +2361,15 @@ static void mpage_add_bh_to_extent(strucsector_t next;int nrblocks = mpd->b_size >> mpd->inode->i_blkbits; +/* +* XXX Don't go larger than mballoc is willing to allocate +* This is a stopgap solution. We eventually need to fold +* mpage_da_submit_io() into this function and then call +* ext4_get_blocks() multiple times in a loop +*/ +if (nrblocks >=8 *1024 *1024 /mpd->inode->i_sb->s_blocksize) + goto flush_it; +/* check if thereserved journal credits might overflow */ if (!(EXT4_I (mpd->inode)->i_flags &EXT4_EXTENTS_FL )) {if (nrblocks >=EXT4_MAX_TRANS_DATA ) {
PATCH 119/165 ext4: Do not zero out uninitialized extents beyond i_size
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 21ca087a3891efab4d45488db8febee474d26c68 upstream (as of v2.6.34-git13)
The extents code will sometimes zero out blocks and mark them as initialized instead of splitting an extent into several smaller ones. This optimization however, causes problems if the extent is beyond i_size because fsck will complain if there are uninitialized blocks after i_size as this can not be distinguished from an inode that has an incorrect i_size field.
https://bugzilla.kernel.org/show_bug.cgi?id=15742
--- fs/ext4/extents.c | 67 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 16 deletions(-)
fs/ext4/extents.c +51 -16
@@ -2533,11 +2533,21 @@ static int ext4_ext_convert_to_initializstruct ext4_extent *ex2 =NULL ;struct ext4_extent *ex3 =NULL ;struct ext4_extent_header *eh; -ext4_lblk_t ee_block; +ext4_lblk_t ee_block, eof_block;unsigned int allocated, ee_len, depth;ext4_fsblk_t newblock;int err =0 ;int ret =0 ; +int may_zeroout; + +ext_debug ("ext4_ext_convert_to_initialized: inode %lu, logical" +"block %llu, max_blocks %u\n" , inode->i_ino, + (unsigned long long )iblock, max_blocks); + + eof_block = (inode->i_size + inode->i_sb->s_blocksize -1 ) >> + inode->i_sb->s_blocksize_bits; +if (eof_block < iblock + max_blocks) + eof_block = iblock + max_blocks; depth =ext_depth (inode); eh = path[depth].p_hdr;
@@ -2546,16 +2556,23 @@ static int ext4_ext_convert_to_initializ ee_len =ext4_ext_get_actual_len (ex); allocated = ee_len - (iblock - ee_block); newblock = iblock - ee_block +ext_pblock (ex); + ex2 = ex; orig_ex.ee_block = ex->ee_block; orig_ex.ee_len =cpu_to_le16 (ee_len);ext4_ext_store_pblock (&orig_ex,ext_pblock (ex)); +/* +* It is safe to convert extent to initialized via explicit +* zeroout only if extent is fully insde i_size or new_size. +*/ + may_zeroout = ee_block + ee_len <= eof_block; + err =ext4_ext_get_access (handle, inode, path + depth);if (err) goto out;/* If extent has less than 2*EXT4_EXT_ZERO_LEN zerout directly */ -if (ee_len <=2 *EXT4_EXT_ZERO_LEN ) { +if (ee_len <=2 *EXT4_EXT_ZERO_LEN && may_zeroout) { err =ext4_ext_zeroout (inode, &orig_ex);if (err) goto fix_extent_len;
@@ -2586,7 +2603,7 @@ static int ext4_ext_convert_to_initializif (allocated > max_blocks) {unsigned int newdepth;/* If extent has less than EXT4_EXT_ZERO_LEN zerout directly */ -if (allocated <=EXT4_EXT_ZERO_LEN ) { +if (allocated <=EXT4_EXT_ZERO_LEN && may_zeroout) {/* * iblock == ee_block is handled by the zerouout * at the beginning.
@@ -2662,7 +2679,7 @@ static int ext4_ext_convert_to_initializ ex3->ee_len =cpu_to_le16 (allocated - max_blocks);ext4_ext_mark_uninitialized (ex3); err =ext4_ext_insert_extent (handle, inode, path, ex3,0 ); -if (err == -ENOSPC ) { +if (err == -ENOSPC && may_zeroout) { err =ext4_ext_zeroout (inode, &orig_ex);if (err) goto fix_extent_len;
@@ -2686,8 +2703,10 @@ static int ext4_ext_convert_to_initializ* update the extent length after successful insert of the * split extent */ - orig_ex.ee_len =cpu_to_le16 (ee_len - -ext4_ext_get_actual_len (ex3)); + ee_len -=ext4_ext_get_actual_len (ex3); + orig_ex.ee_len =cpu_to_le16 (ee_len); + may_zeroout = ee_block + ee_len <= eof_block; + depth = newdepth;ext4_ext_drop_refs (path); path =ext4_ext_find_extent (inode, iblock, path);
@@ -2711,7 +2730,7 @@ static int ext4_ext_convert_to_initializ* otherwise give the extent a chance to merge to left */ if (le16_to_cpu (orig_ex.ee_len) <=EXT4_EXT_ZERO_LEN && - iblock != ee_block) { + iblock != ee_block && may_zeroout) { err =ext4_ext_zeroout (inode, &orig_ex);if (err) goto fix_extent_len;
@@ -2780,7 +2799,7 @@ static int ext4_ext_convert_to_initializ goto out; insert: err =ext4_ext_insert_extent (handle, inode, path, &newex,0 ); -if (err == -ENOSPC ) { +if (err == -ENOSPC && may_zeroout) { err =ext4_ext_zeroout (inode, &orig_ex);if (err) goto fix_extent_len;
@@ -2840,14 +2859,21 @@ static int ext4_split_unwritten_extents(struct ext4_extent *ex2 =NULL ;struct ext4_extent *ex3 =NULL ;struct ext4_extent_header *eh; -ext4_lblk_t ee_block; +ext4_lblk_t ee_block, eof_block;unsigned int allocated, ee_len, depth;ext4_fsblk_t newblock;int err =0 ; +int may_zeroout; + +ext_debug ("ext4_split_unwritten_extents: inode %lu, logical" +"block %llu, max_blocks %u\n" , inode->i_ino, + (unsigned long long )iblock, max_blocks); + + eof_block = (inode->i_size + inode->i_sb->s_blocksize -1 ) >> + inode->i_sb->s_blocksize_bits; +if (eof_block < iblock + max_blocks) + eof_block = iblock + max_blocks; -ext_debug ("ext4_split_unwritten_extents: inode %lu," -"iblock %llu, max_blocks %u\n" , inode->i_ino, - (unsigned long long )iblock, max_blocks); depth =ext_depth (inode); eh = path[depth].p_hdr; ex = path[depth].p_ext;
@@ -2855,12 +2881,19 @@ static int ext4_split_unwritten_extents( ee_len =ext4_ext_get_actual_len (ex); allocated = ee_len - (iblock - ee_block); newblock = iblock - ee_block +ext_pblock (ex); + ex2 = ex; orig_ex.ee_block = ex->ee_block; orig_ex.ee_len =cpu_to_le16 (ee_len);ext4_ext_store_pblock (&orig_ex,ext_pblock (ex));/* +* It is safe to convert extent to initialized via explicit +* zeroout only if extent is fully insde i_size or new_size. +*/ + may_zeroout = ee_block + ee_len <= eof_block; + +/* * If the uninitialized extent begins at the same logical * block where the write begins, and the write completely * covers the extent, then we don't need to split it.
@@ -2894,7 +2927,7 @@ static int ext4_split_unwritten_extents( ex3->ee_len =cpu_to_le16 (allocated - max_blocks);ext4_ext_mark_uninitialized (ex3); err =ext4_ext_insert_extent (handle, inode, path, ex3, flags); -if (err == -ENOSPC ) { +if (err == -ENOSPC && may_zeroout) { err =ext4_ext_zeroout (inode, &orig_ex);if (err) goto fix_extent_len;
@@ -2918,8 +2951,10 @@ static int ext4_split_unwritten_extents(* update the extent length after successful insert of the * split extent */ - orig_ex.ee_len =cpu_to_le16 (ee_len - -ext4_ext_get_actual_len (ex3)); + ee_len -=ext4_ext_get_actual_len (ex3); + orig_ex.ee_len =cpu_to_le16 (ee_len); + may_zeroout = ee_block + ee_len <= eof_block; + depth = newdepth;ext4_ext_drop_refs (path); path =ext4_ext_find_extent (inode, iblock, path);
@@ -2965,7 +3000,7 @@ static int ext4_split_unwritten_extents( goto out; insert: err =ext4_ext_insert_extent (handle, inode, path, &newex, flags); -if (err == -ENOSPC ) { +if (err == -ENOSPC && may_zeroout) { err =ext4_ext_zeroout (inode, &orig_ex);if (err) goto fix_extent_len;
PATCH 120/165 ext4: clean up inode bitmaps manipulation in ext4_free_inode
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit d17413c08cd2b1dd2bf2cfdbb0f7b736b2b2b15c upstrea (as of v2..34-git13)
- Reorganize locking scheme to batch two atomic operation in to one. This also allow us to state what healthy group must obey following rule ext4_free_inodes_count(sb, gdp) == ext4_count_free(inode_bitmap, NUM);
- Fix possible undefined pointer dereference.
- Even if group descriptor stats aren't accessible we have to update inode bitmaps.
- Move non-group members update out of group_lock.
Note: this commit has been observed to fix fs corruption problems under heavy fs load
--- fs/ext4/ialloc.c | 85 +++++++++++++++++++++++++------------------------------ 1 file changed, 39 insertions(+), 46 deletions(-)
fs/ext4/ialloc.c +39 -46
@@ -244,57 +244,50 @@ void ext4_free_inode(handle_t *handle, sif (fatal) goto error_return; -/* Ok, now we can actually update the inode bitmaps.. */ - cleared =ext4_clear_bit_atomic (ext4_group_lock_ptr (sb, block_group), - bit, bitmap_bh->b_data); -if (!cleared) -ext4_error (sb,"ext4_free_inode" , -"bit already cleared for inode %lu" , ino); -else { - gdp =ext4_get_group_desc (sb, block_group, &bh2); - + fatal = -ESRCH ; + gdp =ext4_get_group_desc (sb, block_group, &bh2); +if (gdp) {BUFFER_TRACE (bh2,"get_write_access" ); fatal =ext4_journal_get_write_access (handle, bh2); -if (fatal) goto error_return; - -if (gdp) { -ext4_lock_group (sb, block_group); - count =ext4_free_inodes_count (sb, gdp) +1 ; -ext4_free_inodes_set (sb, gdp, count); -if (is_directory) { - count =ext4_used_dirs_count (sb, gdp) -1 ; -ext4_used_dirs_set (sb, gdp, count); -if (sbi->s_log_groups_per_flex) { -ext4_group_t f; - - f =ext4_flex_group (sbi, block_group); -atomic_dec (&sbi->s_flex_groups[f].used_dirs); - } - - } - gdp->bg_checksum =ext4_group_desc_csum (sbi, - block_group, gdp); -ext4_unlock_group (sb, block_group); -percpu_counter_inc (&sbi->s_freeinodes_counter); -if (is_directory) -percpu_counter_dec (&sbi->s_dirs_counter); + } +ext4_lock_group (sb, block_group); + cleared =ext4_clear_bit (bit, bitmap_bh->b_data); +if (fatal || !cleared) { +ext4_unlock_group (sb, block_group); + goto out; + } -if (sbi->s_log_groups_per_flex) { -ext4_group_t f; + count =ext4_free_inodes_count (sb, gdp) +1 ; +ext4_free_inodes_set (sb, gdp, count); +if (is_directory) { + count =ext4_used_dirs_count (sb, gdp) -1 ; +ext4_used_dirs_set (sb, gdp, count); +percpu_counter_dec (&sbi->s_dirs_counter); + } + gdp->bg_checksum =ext4_group_desc_csum (sbi, block_group, gdp); +ext4_unlock_group (sb, block_group); - f =ext4_flex_group (sbi, block_group); -atomic_inc (&sbi->s_flex_groups[f].free_inodes); - } - } -BUFFER_TRACE (bh2,"call ext4_handle_dirty_metadata" ); - err =ext4_handle_dirty_metadata (handle,NULL , bh2); -if (!fatal) fatal = err; +percpu_counter_inc (&sbi->s_freeinodes_counter); +if (sbi->s_log_groups_per_flex) { +ext4_group_t f =ext4_flex_group (sbi, block_group); + +atomic_inc (&sbi->s_flex_groups[f].free_inodes); +if (is_directory) +atomic_dec (&sbi->s_flex_groups[f].used_dirs); } -BUFFER_TRACE (bitmap_bh,"call ext4_handle_dirty_metadata" ); - err =ext4_handle_dirty_metadata (handle,NULL , bitmap_bh); -if (!fatal) - fatal = err; - sb->s_dirt =1 ; +BUFFER_TRACE (bh2,"call ext4_handle_dirty_metadata" ); + fatal =ext4_handle_dirty_metadata (handle,NULL , bh2); +out: +if (cleared) { +BUFFER_TRACE (bitmap_bh,"call ext4_handle_dirty_metadata" ); + err =ext4_handle_dirty_metadata (handle,NULL , bitmap_bh); +if (!fatal) + fatal = err; + sb->s_dirt =1 ; + }else +ext4_error (sb,"ext4_free_inode" , +"bit already cleared for inode %lu" , ino); + error_return:brelse (bitmap_bh);ext4_std_error (sb, fatal);
PATCH 121/165 ext4: init statistics after journal recovery
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 84061e07c5fbbbf9dc8aef8fb750fc3a2dfc31f3 upstream (as of v2.6.34-git13)
Currently block/inode/dir counters initialized before journal was recovered. In fact after journal recovery this info will probably change. And freeblocks it critical for correct delalloc mode accounting.
https://bugzilla.kernel.org/show_bug.cgi?id=15768
--- fs/ext4/super.c | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-)
fs/ext4/super.c +18 -23
@@ -2695,24 +2695,6 @@ static int ext4_fill_super(struct super_get_random_bytes (&sbi->s_next_generation,sizeof (u32));spin_lock_init (&sbi->s_next_gen_lock); - err =percpu_counter_init (&sbi->s_freeblocks_counter, -ext4_count_free_blocks (sb)); -if (!err) { - err =percpu_counter_init (&sbi->s_freeinodes_counter, -ext4_count_free_inodes (sb)); - } -if (!err) { - err =percpu_counter_init (&sbi->s_dirs_counter, -ext4_count_dirs (sb)); - } -if (!err) { - err =percpu_counter_init (&sbi->s_dirtyblocks_counter,0 ); - } -if (err) { -ext4_msg (sb,KERN_ERR ,"insufficient memory" ); - goto failed_mount3; - } - sbi->s_stripe =ext4_get_stripe_size (sbi); sbi->s_max_writeback_mb_bump =128 ;
@@ -2832,7 +2814,20 @@ static int ext4_fill_super(struct super_set_task_ioprio (sbi->s_journal->j_task, journal_ioprio); no_journal: - + err =percpu_counter_init (&sbi->s_freeblocks_counter, +ext4_count_free_blocks (sb)); +if (!err) + err =percpu_counter_init (&sbi->s_freeinodes_counter, +ext4_count_free_inodes (sb)); +if (!err) + err =percpu_counter_init (&sbi->s_dirs_counter, +ext4_count_dirs (sb)); +if (!err) + err =percpu_counter_init (&sbi->s_dirtyblocks_counter,0 ); +if (err) { +ext4_msg (sb,KERN_ERR ,"insufficient memory" ); + goto failed_mount_wq; + }if (test_opt (sb,NOBH )) {if (!(test_opt (sb,DATA_FLAGS ) ==EXT4_MOUNT_WRITEBACK_DATA )) { ext4_msg(sb, KERN_WARNING, "Ignoring nobh option - "
@@ -2965,6 +2960,10 @@ failed_mount_wq:jbd2_journal_destroy (sbi->s_journal); sbi->s_journal =NULL ; } +percpu_counter_destroy (&sbi->s_freeblocks_counter); +percpu_counter_destroy (&sbi->s_freeinodes_counter); +percpu_counter_destroy (&sbi->s_dirs_counter); +percpu_counter_destroy (&sbi->s_dirtyblocks_counter); failed_mount3:if (sbi->s_flex_groups) {if (is_vmalloc_addr (sbi->s_flex_groups))
@@ -2972,10 +2971,6 @@ failed_mount3:else kfree (sbi->s_flex_groups); } -percpu_counter_destroy (&sbi->s_freeblocks_counter); -percpu_counter_destroy (&sbi->s_freeinodes_counter); -percpu_counter_destroy (&sbi->s_dirs_counter); -percpu_counter_destroy (&sbi->s_dirtyblocks_counter); failed_mount2:for (i =0 ; i < db_count; i++)brelse (sbi->s_group_desc[i]);
PATCH 122/165 ext4: Remove extraneous newlines in ext4_msg() calls
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit fbe845ddf368f77f86aa7500f8fd2690f54c66a8 upstream (as of v2.6.34-git13)
Addresses-Google-Bug: #2562325
--- fs/ext4/inode.c | 6 +++--- fs/ext4/super.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
fs/ext4/inode.c +3 -3
@@ -2294,7 +2294,7 @@ static int mpage_da_map_blocks(struct mpext4_msg (mpd->inode->i_sb,KERN_CRIT ,"delayed block allocation failed for inode %lu at " "logical offset %llu with max blocks %zd with " -"error %d\n" , mpd->inode->i_ino, +"error %d" , mpd->inode->i_ino, (unsigned long long ) next, mpd->b_size >> mpd->inode->i_blkbits, err); printk(KERN_CRIT "This should not happen!! "
@@ -2956,7 +2956,7 @@ retry:if (IS_ERR (handle)) { ret =PTR_ERR (handle);ext4_msg (inode->i_sb,KERN_CRIT ,"%s: jbd2_start: " -"%ld pages, ino %lu; err %d\n" , __func__, +"%ld pages, ino %lu; err %d" , __func__, wbc->nr_to_write, inode->i_ino, ret); goto out_writepages; }
@@ -3031,7 +3031,7 @@ retry:if (pages_skipped != wbc->pages_skipped)ext4_msg (inode->i_sb,KERN_CRIT ,"This should not happen leaving %s " -"with nr_to_write = %ld ret = %d\n" , +"with nr_to_write = %ld ret = %d" , __func__, wbc->nr_to_write, ret);/* Update index */
fs/ext4/super.c +1 -1
@@ -2902,7 +2902,7 @@ no_journal: err =ext4_setup_system_zone (sb);if (err) {ext4_msg (sb,KERN_ERR ,"failed to initialize system " -"zone (%d)\n" , err); +"zone (%d)" , err); goto failed_mount4; }
PATCH 123/165 ext4: Prevent creation of files larger than RLIMIT_FSIZE using fallocate
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 6d19c42b7cf81c39632b6d4dbc514e8449bcd346 upstream (as of v2.6.34-git13)
Currently using posix_fallocate one can bypass an RLIMIT_FSIZE limit and create a file larger than the limit. Add a check for that.
--- fs/ext4/extents.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/ext4/extents.c +5 -0
@@ -3607,6 +3607,11 @@ long ext4_fallocate(struct inode *inode,*/ credits =ext4_chunk_trans_blocks (inode, max_blocks);mutex_lock (&inode->i_mutex); + ret =inode_newsize_ok (inode, (len + offset)); +if (ret) { +mutex_unlock (&inode->i_mutex); +return ret; + } retry:while (ret >=0 && ret < max_blocks) { block = block + ret;
PATCH 124/165 ext4: check for a good block group before loading buddy pages
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 8a57d9d61a6e361c7bb159dda797672c1df1a691 upstream (as of v2.6.34-git13)
This adds a new field in ext4_group_info to cache the largest available block range in a block group; and don't load the buddy pages until *after* we've done a sanity check on the block group.
With large allocation requests (e.g., fallocate(), 8MiB) and relatively full partitions, it's easy to have no block groups with a block extent large enough to satisfy the input request length. This currently causes the loop during cr == 0 in ext4_mb_regular_allocator() to load the buddy bitmap pages for EVERY block group. That can be a lot of pages. The patch below allows us to call ext4_mb_good_group() BEFORE we load the buddy pages (although we have check again after we lock the block group).
Addresses-Google-Bug: #2578108
Addresses-Google-Bug: #2704453
--- fs/ext4/ext4.h | 1 fs/ext4/mballoc.c | 70 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 58 insertions(+), 13 deletions(-)
fs/ext4/ext4.h +1 -0
@@ -1657,6 +1657,7 @@ struct ext4_group_info {ext4_grpblk_t bb_first_free;/* first free block */ ext4_grpblk_t bb_free;/* total free blocks */ ext4_grpblk_t bb_fragments;/* nr of freespace fragments */ +ext4_grpblk_t bb_largest_free_order;/* order of largest frag in BG */ struct list_head bb_prealloc_list;#ifdef DOUBLE_CHECK void *bb_bitmap;
fs/ext4/mballoc.c +57 -13
160 lines not on this page · raw message
PATCH 125/165 ext4: Show journal_checksum option
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 39a4bade8c1826b658316d66ee81c09b0a4d7d42 upstream (as of v2.6.34-git13)
We failed to show journal_checksum option in /proc/mounts. Fix it.
--- fs/ext4/super.c | 2 ++ 1 file changed, 2 insertions(+)
fs/ext4/super.c +2 -0
@@ -877,6 +877,8 @@ static int ext4_show_options(struct seq_seq_puts (seq,test_opt (sb,BARRIER ) ?"1" :"0" );if (test_opt (sb,JOURNAL_ASYNC_COMMIT ))seq_puts (seq,",journal_async_commit" ); +else if (test_opt (sb,JOURNAL_CHECKSUM )) +seq_puts (seq,",journal_checksum" );if (test_opt (sb,NOBH ))seq_puts (seq,",nobh" );if (test_opt (sb,I_VERSION ))
PATCH 126/165 ext4: Use bitops to read/modify i_flags in struct ext4_inode_info
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 12e9b892002d9af057655d35b44db8ee9243b0dc upstream (as of v2.6.34-git13)
At several places we modify EXT4_I(inode)->i_flags without holding i_mutex (ext4_do_update_inode, ...). These modifications are racy and we can lose updates to i_flags. So convert handling of i_flags to use bitops which are atomic.
https://bugzilla.kernel.org/show_bug.cgi?id=15792
--- fs/ext4/dir.c | 4 - fs/ext4/ext4.h | 109 +++++++++++++++++++++++++++++++++++++++++++------- fs/ext4/ext4_jbd2.h | 6 +- fs/ext4/extents.c | 10 ++-- fs/ext4/file.c | 2 fs/ext4/ialloc.c | 4 - fs/ext4/inode.c | 30 ++++++------- fs/ext4/mballoc.c | 4 - fs/ext4/migrate.c | 2 fs/ext4/move_extent.c | 4 - fs/ext4/namei.c | 10 ++-- fs/ext4/super.c | 1 fs/ext4/xattr.c | 4 - 13 files changed, 135 insertions(+), 55 deletions(-)
fs/ext4/dir.c +2 -2
@@ -111,7 +111,7 @@ static int ext4_readdir(struct file *filif (EXT4_HAS_COMPAT_FEATURE (inode->i_sb,EXT4_FEATURE_COMPAT_DIR_INDEX ) && - ((EXT4_I (inode)->i_flags &EXT4_INDEX_FL ) || + ((ext4_test_inode_flag (inode,EXT4_INODE_INDEX )) || ((inode->i_size >> sb->s_blocksize_bits) ==1 ))) { err =ext4_dx_readdir (filp, dirent, filldir);if (err !=ERR_BAD_DX_DIR ) {
@@ -122,7 +122,7 @@ static int ext4_readdir(struct file *fil* We don't set the inode dirty flag since it's not * critical that it get flushed back to the disk. */ -EXT4_I (filp->f_path.dentry->d_inode)->i_flags &= ~EXT4_INDEX_FL ; +ext4_clear_inode_flag (filp->f_path.dentry->d_inode,EXT4_INODE_INDEX ); } stored =0 ; offset = filp->f_pos & (sb->s_blocksize -1 );
fs/ext4/ext4.h +94 -15
142 lines not on this page · raw message
fs/ext4/ext4_jbd2.h +3 -3
@@ -282,7 +282,7 @@ static inline int ext4_should_journal_dareturn 1 ;if (test_opt (inode->i_sb,DATA_FLAGS ) ==EXT4_MOUNT_JOURNAL_DATA )return 1 ; -if (EXT4_I (inode)->i_flags &EXT4_JOURNAL_DATA_FL ) +if (ext4_test_inode_flag (inode,EXT4_INODE_JOURNAL_DATA ))return 1 ;return 0 ; }
@@ -293,7 +293,7 @@ static inline int ext4_should_order_datareturn 0 ;if (!S_ISREG (inode->i_mode))return 0 ; -if (EXT4_I (inode)->i_flags &EXT4_JOURNAL_DATA_FL ) +if (ext4_test_inode_flag (inode,EXT4_INODE_JOURNAL_DATA ))return 0 ;if (test_opt (inode->i_sb,DATA_FLAGS ) ==EXT4_MOUNT_ORDERED_DATA )return 1 ;
@@ -306,7 +306,7 @@ static inline int ext4_should_writeback_return 0 ;if (EXT4_JOURNAL (inode) ==NULL )return 1 ; -if (EXT4_I (inode)->i_flags &EXT4_JOURNAL_DATA_FL ) +if (ext4_test_inode_flag (inode,EXT4_INODE_JOURNAL_DATA ))return 0 ;if (test_opt (inode->i_sb,DATA_FLAGS ) ==EXT4_MOUNT_WRITEBACK_DATA )return 1 ;
fs/ext4/extents.c +5 -5
@@ -3409,12 +3409,12 @@ int ext4_ext_get_blocks(handle_t *handle } } -if (unlikely (EXT4_I (inode)->i_flags &EXT4_EOFBLOCKS_FL )) { +if (unlikely (ext4_test_inode_flag (inode,EXT4_INODE_EOFBLOCKS ))) {if (eh->eh_entries) { last_ex =EXT_LAST_EXTENT (eh);if (iblock + ar.len >le32_to_cpu (last_ex->ee_block) +ext4_ext_get_actual_len (last_ex)) -EXT4_I (inode)->i_flags &= ~EXT4_EOFBLOCKS_FL ; +ext4_clear_inode_flag (inode,EXT4_INODE_EOFBLOCKS ); }else {WARN_ON (eh->eh_entries ==0 ); ext4_error(inode->i_sb, __func__,
@@ -3560,7 +3560,7 @@ static void ext4_falloc_update_inode(str* can proceed even if the new size is the same as i_size. */ if (new_size >i_size_read (inode)) -EXT4_I (inode)->i_flags |=EXT4_EOFBLOCKS_FL ; +ext4_set_inode_flag (inode,EXT4_INODE_EOFBLOCKS ); } }
@@ -3588,7 +3588,7 @@ long ext4_fallocate(struct inode *inode,* currently supporting (pre)allocate mode for extent-based * files _only_ */ -if (!(EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL )) +if (!(ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS )))return -EOPNOTSUPP ;/* preallocation to directories is currently not supported */
@@ -3838,7 +3838,7 @@ int ext4_fiemap(struct inode *inode, strint error =0 ;/* fallback to generic here if not in extents fmt */ -if (!(EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL )) +if (!(ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS )))return generic_block_fiemap (inode, fieinfo, start, len, ext4_get_block);
fs/ext4/file.c +1 -1
@@ -65,7 +65,7 @@ ext4_file_write(struct kiocb *iocb, cons* is smaller than s_maxbytes, which is for extent-mapped files. */ -if (!(EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL )) { +if (!(ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS ))) {struct ext4_sb_info *sbi =EXT4_SB (inode->i_sb);size_t length =iov_length (iov, nr_segs);
fs/ext4/ialloc.c +2 -2
@@ -497,7 +497,7 @@ static int find_group_orlov(struct superif (S_ISDIR (mode) && ((parent == sb->s_root->d_inode) || - (EXT4_I (parent)->i_flags &EXT4_TOPDIR_FL ))) { + (ext4_test_inode_flag (parent,EXT4_INODE_TOPDIR )))) {int best_ndir = inodes_per_group;int ret =-1 ;
@@ -1044,7 +1044,7 @@ got:if (EXT4_HAS_INCOMPAT_FEATURE (sb,EXT4_FEATURE_INCOMPAT_EXTENTS )) {/* set extent flag only for directory, file and normal symlink*/ if (S_ISDIR (mode) ||S_ISREG (mode) ||S_ISLNK (mode)) { -EXT4_I (inode)->i_flags |=EXT4_EXTENTS_FL ; +ext4_set_inode_flag (inode,EXT4_INODE_EXTENTS );ext4_ext_tree_init (handle, inode); } }
fs/ext4/inode.c +15 -15
@@ -957,7 +957,7 @@ static int ext4_ind_get_blocks(handle_tint count =0 ;ext4_fsblk_t first_block =0 ; -J_ASSERT (!(EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL )); +J_ASSERT (!(ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS )));J_ASSERT (handle !=NULL || (flags &EXT4_GET_BLOCKS_CREATE ) ==0 ); depth =ext4_block_to_path (inode, iblock, offsets, &blocks_to_boundary);
@@ -1085,7 +1085,7 @@ static int ext4_indirect_calc_metadata_a*/ static int ext4_calc_metadata_amount (struct inode *inode,sector_t lblock) { -if (EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL ) +if (ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS ))return ext4_ext_calc_metadata_amount (inode, lblock);return ext4_indirect_calc_metadata_amount (inode, lblock);
@@ -1274,7 +1274,7 @@ int ext4_get_blocks(handle_t *handle, st* file system block. */ down_read ((&EXT4_I (inode)->i_data_sem)); -if (EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL ) { +if (ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS )) { retval =ext4_ext_get_blocks (handle, inode, block, max_blocks, bh,0 ); }else {
@@ -1336,7 +1336,7 @@ int ext4_get_blocks(handle_t *handle, st* We need to check for EXT4 here because migrate * could have changed the inode type in between */ -if (EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL ) { +if (ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS )) { retval =ext4_ext_get_blocks (handle, inode, block, max_blocks, bh, flags); }else {
@@ -2371,7 +2371,7 @@ static void mpage_add_bh_to_extent(struc goto flush_it;/* check if thereserved journal credits might overflow */ -if (!(EXT4_I (mpd->inode)->i_flags &EXT4_EXTENTS_FL )) { +if (!(ext4_test_inode_flag (mpd->inode,EXT4_INODE_EXTENTS ))) {if (nrblocks >=EXT4_MAX_TRANS_DATA ) {/* * With non-extent format we are limited by the journal
@@ -2836,7 +2836,7 @@ static int ext4_da_writepages_trans_bloc* number of contiguous block. So we will limit * number of contiguous block to a sane value */ -if (!(EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL ) && +if (!(ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS )) && (max_blocks >EXT4_MAX_TRANS_DATA )) max_blocks =EXT4_MAX_TRANS_DATA ;
@@ -3872,7 +3872,7 @@ static ssize_t ext4_direct_IO(int rw, ststruct file *file = iocb->ki_filp;struct inode *inode = file->f_mapping->host; -if (EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL ) +if (ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS ))return ext4_ext_direct_IO (rw, iocb, iov, offset, nr_segs);return ext4_ind_direct_IO (rw, iocb, iov, offset, nr_segs);
@@ -4503,12 +4503,12 @@ void ext4_truncate(struct inode *inode)if (!ext4_can_truncate (inode))return ; -EXT4_I (inode)->i_flags &= ~EXT4_EOFBLOCKS_FL ; +ext4_clear_inode_flag (inode,EXT4_INODE_EOFBLOCKS );if (inode->i_size ==0 && !test_opt (inode->i_sb,NO_AUTO_DA_ALLOC ))ext4_set_inode_state (inode,EXT4_STATE_DA_ALLOC_CLOSE ); -if (EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL ) { +if (ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS )) {ext4_ext_truncate (inode);return ; }
@@ -5350,7 +5350,7 @@ int ext4_setattr(struct dentry *dentry, }if (attr->ia_valid &ATTR_SIZE ) { -if (!(EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL )) { +if (!(ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS ))) {struct ext4_sb_info *sbi =EXT4_SB (inode->i_sb);if (attr->ia_size > sbi->s_bitmap_maxbytes) {
@@ -5363,7 +5363,7 @@ int ext4_setattr(struct dentry *dentry,if (S_ISREG (inode->i_mode) && attr->ia_valid &ATTR_SIZE && (attr->ia_size < inode->i_size || - (EXT4_I (inode)->i_flags &EXT4_EOFBLOCKS_FL ))) { + (ext4_test_inode_flag (inode,EXT4_INODE_EOFBLOCKS )))) {handle_t *handle; handle =ext4_journal_start (inode,3 );
@@ -5395,7 +5395,7 @@ int ext4_setattr(struct dentry *dentry, } }/* ext4_truncate will clear the flag */ -if ((EXT4_I (inode)->i_flags &EXT4_EOFBLOCKS_FL )) +if ((ext4_test_inode_flag (inode,EXT4_INODE_EOFBLOCKS )))ext4_truncate (inode); }
@@ -5471,7 +5471,7 @@ static int ext4_indirect_trans_blocks(ststatic int ext4_index_trans_blocks (struct inode *inode,int nrblocks,int chunk) { -if (!(EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL )) +if (!(ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS )))return ext4_indirect_trans_blocks (inode, nrblocks, chunk);return ext4_ext_index_trans_blocks (inode, nrblocks, chunk); }
@@ -5806,9 +5806,9 @@ int ext4_change_inode_journal_flag(struc*/ if (val) -EXT4_I (inode)->i_flags |=EXT4_JOURNAL_DATA_FL ; +ext4_set_inode_flag (inode,EXT4_INODE_JOURNAL_DATA );else -EXT4_I (inode)->i_flags &= ~EXT4_JOURNAL_DATA_FL ; +ext4_clear_inode_flag (inode,EXT4_INODE_JOURNAL_DATA );ext4_set_aops (inode);jbd2_journal_unlock_updates (journal);
fs/ext4/mballoc.c +2 -2
@@ -2008,7 +2008,7 @@ ext4_mb_regular_allocator(struct ext4_al sbi =EXT4_SB (sb); ngroups =ext4_get_groups_count (sb);/* non-extent files are limited to low blocks/groups */ -if (!(EXT4_I (ac->ac_inode)->i_flags &EXT4_EXTENTS_FL )) +if (!(ext4_test_inode_flag (ac->ac_inode,EXT4_INODE_EXTENTS ))) ngroups = sbi->s_blockfile_groups;BUG_ON (ac->ac_status ==AC_STATUS_FOUND );
@@ -3176,7 +3176,7 @@ ext4_mb_use_preallocated(struct ext4_allcontinue ;/* non-extent files can't have physical blocks past 2^32 */ -if (!(EXT4_I (ac->ac_inode)->i_flags &EXT4_EXTENTS_FL ) && +if (!(ext4_test_inode_flag (ac->ac_inode,EXT4_INODE_EXTENTS )) && pa->pa_pstart + pa->pa_len >EXT4_MAX_BLOCK_FILE_PHYS )continue ;
fs/ext4/migrate.c +1 -1
@@ -465,7 +465,7 @@ int ext4_ext_migrate(struct inode *inode*/ if (!EXT4_HAS_INCOMPAT_FEATURE (inode->i_sb,EXT4_FEATURE_INCOMPAT_EXTENTS ) || - (EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL )) + (ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS )))return -EINVAL ;if (S_ISLNK (inode->i_mode) && inode->i_blocks ==0 )
fs/ext4/move_extent.c +2 -2
@@ -975,11 +975,11 @@ mext_check_arguments(struct inode *orig_ }/* Ext4 move extent supports only extent based file */ -if (!(EXT4_I (orig_inode)->i_flags &EXT4_EXTENTS_FL )) { +if (!(ext4_test_inode_flag (orig_inode,EXT4_INODE_EXTENTS ))) {ext4_debug ("ext4 move extent: orig file is not extents " "based file [ino:orig %lu]\n" , orig_inode->i_ino);return -EOPNOTSUPP ; - }else if (!(EXT4_I (donor_inode)->i_flags &EXT4_EXTENTS_FL )) { + }else if (!(ext4_test_inode_flag (donor_inode,EXT4_INODE_EXTENTS ))) {ext4_debug ("ext4 move extent: donor file is not extents " "based file [ino:donor %lu]\n" , donor_inode->i_ino);return -EOPNOTSUPP ;
fs/ext4/namei.c +5 -5
@@ -660,7 +660,7 @@ int ext4_htree_fill_tree(struct file *didxtrace (printk (KERN_DEBUG "In htree_fill_tree, start hash: %x:%x\n" , start_hash, start_minor_hash)); dir = dir_file->f_path.dentry->d_inode; -if (!(EXT4_I (dir)->i_flags &EXT4_INDEX_FL )) { +if (!(ext4_test_inode_flag (dir,EXT4_INODE_INDEX ))) { hinfo.hash_version =EXT4_SB (dir->i_sb)->s_def_hash_version;if (hinfo.hash_version <=DX_HASH_TEA ) hinfo.hash_version +=
@@ -805,7 +805,7 @@ static void ext4_update_dx_flag(struct i {if (!EXT4_HAS_COMPAT_FEATURE (inode->i_sb,EXT4_FEATURE_COMPAT_DIR_INDEX )) -EXT4_I (inode)->i_flags &= ~EXT4_INDEX_FL ; +ext4_clear_inode_flag (inode,EXT4_INODE_INDEX ); }/*
@@ -1424,7 +1424,7 @@ static int make_indexed_dir(handle_t *habrelse (bh);return retval; } -EXT4_I (dir)->i_flags |=EXT4_INDEX_FL ; +ext4_set_inode_flag (dir,EXT4_INODE_INDEX ); data1 = bh2->b_data;memcpy (data1, de, len);
@@ -1497,7 +1497,7 @@ static int ext4_add_entry(handle_t *hand retval =ext4_dx_add_entry (handle, dentry, inode);if (!retval || (retval !=ERR_BAD_DX_DIR ))return retval; -EXT4_I (dir)->i_flags &= ~EXT4_INDEX_FL ; +ext4_clear_inode_flag (dir,EXT4_INODE_INDEX ); dx_fallback++;ext4_mark_inode_dirty (handle, dir); }
@@ -2292,7 +2292,7 @@ retry: } }else {/* clear the extent format for fast symlink */ -EXT4_I (inode)->i_flags &= ~EXT4_EXTENTS_FL ; +ext4_clear_inode_flag (inode,EXT4_INODE_EXTENTS ); inode->i_op = &ext4_fast_symlink_inode_operations;memcpy ((char *)&EXT4_I (inode)->i_data, symname, l); inode->i_size = l-1 ;
fs/ext4/super.c +1 -0
@@ -3999,6 +3999,7 @@ static int __init init_ext4_fs(void) {int err; +ext4_check_flag_values (); err =init_ext4_system_zone ();if (err)return err;
fs/ext4/xattr.c +2 -2
@@ -816,7 +816,7 @@ inserted: EXT4_I(inode)->i_block_group);/* non-extent files can't have physical blocks past 2^32 */ -if (!(EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL )) +if (!(ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS ))) goal = goal &EXT4_MAX_BLOCK_FILE_PHYS ; block = ext4_new_meta_blocks(handle, inode,
@@ -824,7 +824,7 @@ inserted:if (error) goto cleanup; -if (!(EXT4_I (inode)->i_flags &EXT4_EXTENTS_FL )) +if (!(ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS )))BUG_ON (block >EXT4_MAX_BLOCK_FILE_PHYS );ea_idebug (inode,"creating block %d" , block);
PATCH 127/165 ext4: Avoid crashing on NULL ptr dereference on a filesystem error
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit f70f362b4a6fe47c239dbfb3efc0cc2c10e4f09c upstream (as of v2.6.34-git13)
If the EOFBLOCK_FL flag is set when it should not be and the inode is zero length, then eh_entries is zero, and ex is NULL, so dereferencing ex to print ex->ee_block causes a kernel OOPS in ext4_ext_map_blocks().
On top of that, the error message which is printed isn't very helpful. So we fix this by printing something more explanatory which doesn't involve trying to print ex->ee_block.
Addresses-Google-Bug: #2655740
--- fs/ext4/extents.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
fs/ext4/extents.c +7 -4
@@ -3281,8 +3281,8 @@ int ext4_ext_get_blocks(handle_t *handle*/ if (path[depth].p_ext ==NULL && depth !=0 ) {ext4_error (inode->i_sb, __func__,"bad extent address " -"inode: %lu, iblock: %d, depth: %d" , - inode->i_ino, iblock, depth); +"inode: %lu, iblock: %lu, depth: %d" , + inode->i_ino, (unsigned long ) iblock, depth); err = -EIO ; goto out2; }
@@ -3418,8 +3418,11 @@ int ext4_ext_get_blocks(handle_t *handle }else {WARN_ON (eh->eh_entries ==0 );ext4_error (inode->i_sb, __func__, -"inode#%lu, eh->eh_entries = 0!" , inode->i_ino); - } +"inode#%lu, eh->eh_entries = 0 and " +"EOFBLOCKS_FL set" , inode->i_ino); + err = -EIO ; + goto out2; + } } err =ext4_ext_insert_extent (handle, inode, path, &newex, flags);if (err) {
PATCH 128/165 ext4: Clear the EXT4_EOFBLOCKS_FL flag only when warranted
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 786ec7915e530936b9eb2e3d12274145cab7aa7d upstream (as of v2.6.34-git13)
Dimitry Monakhov discovered an edge case where it was possible for the EXT4_EOFBLOCKS_FL flag could get cleared unnecessarily. This is true; I have a test case that can be exercised via downloading and decompressing the file:
wget ftp://ftp.kernel.org/pub/linux/kernel/people/tytso/ext4-testcases/eofblocks-fl-test-case.img.bz2 bunzip2 eofblocks-fl-test-case.img
dd if=/dev/zero of=eofblocks-fl-test-case.img bs=1k seek=17925 bs=1k count=1 conv=notrunc
However, triggering it in real life is highly unlikely since it requires an extremely fragmented sparse file with a hole in exactly the right place in the extent tree. (It actually took quite a bit of work to generate this test case.) Still, it's nice to get even extreme corner cases to be correct, so this patch makes sure that we don't clear the EXT4_EOFBLOCKS_FL incorrectly even in this corner case.
--- fs/ext4/extents.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)
fs/ext4/extents.c +18 -8
@@ -3229,7 +3229,7 @@ int ext4_ext_get_blocks(handle_t *handlestruct ext4_extent_header *eh;struct ext4_extent newex, *ex, *last_ex;ext4_fsblk_t newblock; -int err =0 , depth, ret, cache_type; +int i, err =0 , depth, ret, cache_type;unsigned int allocated =0 ;struct ext4_allocation_request ar;ext4_io_end_t *io =EXT4_I (inode)->cur_aio_dio;
@@ -3410,19 +3410,29 @@ int ext4_ext_get_blocks(handle_t *handle }if (unlikely (ext4_test_inode_flag (inode,EXT4_INODE_EOFBLOCKS ))) { -if (eh->eh_entries) { - last_ex =EXT_LAST_EXTENT (eh); -if (iblock + ar.len >le32_to_cpu (last_ex->ee_block) - +ext4_ext_get_actual_len (last_ex)) -ext4_clear_inode_flag (inode,EXT4_INODE_EOFBLOCKS ); - }else { -WARN_ON (eh->eh_entries ==0 ); +if (unlikely (!eh->eh_entries)) {ext4_error (inode->i_sb, __func__,"inode#%lu, eh->eh_entries = 0 and " "EOFBLOCKS_FL set" , inode->i_ino); err = -EIO ; goto out2; } + last_ex =EXT_LAST_EXTENT (eh); +/* +* If the current leaf block was reached by looking at +* the last index block all the way down the tree, and +* we are extending the inode beyond the last extent +* in the current leaf block, then clear the +* EOFBLOCKS_FL flag. +*/ +for (i = depth-1 ; i >=0 ; i--) { +if (path[i].p_idx !=EXT_LAST_INDEX (path[i].p_hdr)) +break ; + } +if ((i <0 ) && + (iblock + ar.len >le32_to_cpu (last_ex->ee_block) + +ext4_ext_get_actual_len (last_ex))) +ext4_clear_inode_flag (inode,EXT4_INODE_EOFBLOCKS ); } err =ext4_ext_insert_extent (handle, inode, path, &newex, flags);if (err) {
PATCH 129/165 ext4: restart ext4_ext_remove_space() after transaction restart
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 0617b83fa239db9743a18ce6cc0e556f4d0fd567 upstream (as of v2.6.34-git13)
If i_data_sem was internally dropped due to transaction restart, it is necessary to restart path look-up because extents tree was possibly modified by ext4_get_block().
https://bugzilla.kernel.org/show_bug.cgi?id=15827
--- fs/ext4/extents.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
fs/ext4/extents.c +9 -7
@@ -107,11 +107,8 @@ static int ext4_ext_truncate_extend_restif (err <=0 )return err; err =ext4_truncate_restart_trans (handle, inode, needed); -/* -* We have dropped i_data_sem so someone might have cached again -* an extent we are going to truncate. -*/ -ext4_ext_invalidate_cache (inode); +if (err ==0 ) + err = -EAGAIN ;return err; }
@@ -2263,7 +2260,7 @@ static int ext4_ext_remove_space(structint depth =ext_depth (inode);struct ext4_ext_path *path;handle_t *handle; -int i =0 , err =0 ; +int i, err;ext_debug ("truncate since %u\n" , start);
@@ -2272,23 +2269,26 @@ static int ext4_ext_remove_space(structif (IS_ERR (handle))return PTR_ERR (handle); +again:ext4_ext_invalidate_cache (inode);/* * We start scanning from right side, freeing all the blocks * after i_size and walking into the tree depth-wise. */ + depth =ext_depth (inode); path =kzalloc (sizeof (struct ext4_ext_path ) * (depth +1 ),GFP_NOFS );if (path ==NULL ) {ext4_journal_stop (handle);return -ENOMEM ; } + path[0 ].p_depth = depth; path[0 ].p_hdr =ext_inode_hdr (inode);if (ext4_ext_check (inode, path[0 ].p_hdr, depth)) { err = -EIO ; goto out; } - path[0 ].p_depth = depth; + i = err =0 ;while (i >=0 && err ==0 ) {if (i == depth) {
@@ -2382,6 +2382,8 @@ static int ext4_ext_remove_space(struct out:ext4_ext_drop_refs (path);kfree (path); +if (err == -EAGAIN ) + goto again;ext4_journal_stop (handle);return err;
PATCH 130/165 ext4: Conditionally define compat ioctl numbers
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 899ad0cea6ad7ff4ba24b16318edbc3cbbe03fad upstream (as of v2.6.34-git13)
It is unnecessary, and in general impossible, to define the compat ioctl numbers except when building the filesystem with CONFIG_COMPAT defined.
--- fs/ext4/ext4.h | 2 ++ 1 file changed, 2 insertions(+)
fs/ext4/ext4.h +2 -0
@@ -462,6 +462,7 @@ struct ext4_new_group_data {#define EXT4_IOC_ALLOC_DA_BLKS _IO('f', 12)#define EXT4_IOC_MOVE_EXT _IOWR('f', 15, struct move_extent) +#if defined(__KERNEL__) && defined(CONFIG_COMPAT )/* * ioctl commands in 32 bit emulation */
@@ -477,6 +478,7 @@ struct ext4_new_group_data {#endif #define EXT4_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION#define EXT4_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION +#endif /*
PATCH 131/165 ext4: Fix compat EXT4_IOC_ADD_GROUP
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 4d92dc0f00a775dc2e1267b0e00befb783902fe7 upstream (as of v2.6.34-git13)
struct ext4_new_group_input needs to be converted because u64 has only 32-bit alignment on some 32-bit architectures, notably i386.
--- fs/ext4/ext4.h | 16 ++++++++++++++++ fs/ext4/ioctl.c | 25 +++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-)
fs/ext4/ext4.h +16 -0
@@ -29,6 +29,9 @@#include <linux/wait.h> #include <linux/blockgroup_lock.h> #include <linux/percpu_counter.h> +#ifdef __KERNEL__ +#include <linux/compat.h> +#endif /* * The fourth extended filesystem constants/structures
@@ -403,6 +406,18 @@ struct ext4_new_group_input {__u16 unused; }; +#if defined(__KERNEL__) && defined(CONFIG_COMPAT ) +struct compat_ext4_new_group_input { +u32 group; +compat_u64 block_bitmap; +compat_u64 inode_bitmap; +compat_u64 inode_table; +u32 blocks_count; +u16 reserved_blocks; +u16 unused; +}; +#endif +/* The struct ext4_new_group_input in kernel space, with free_blocks_count */ struct ext4_new_group_data {__u32 group;
@@ -473,6 +488,7 @@ struct ext4_new_group_data {#define EXT4_IOC32_GETRSVSZ _IOR('f', 5, int)#define EXT4_IOC32_SETRSVSZ _IOW('f', 6, int)#define EXT4_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) +#define EXT4_IOC32_GROUP_ADD _IOW('f', 8, struct compat_ext4_new_group_input)#ifdef CONFIG_JBD2_DEBUG #define EXT4_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int)#endif
fs/ext4/ioctl.c +23 -2
@@ -373,8 +373,29 @@ long ext4_compat_ioctl(struct file *filecase EXT4_IOC32_SETRSVSZ : cmd =EXT4_IOC_SETRSVSZ ;break ; -case EXT4_IOC_GROUP_ADD : -break ; +case EXT4_IOC32_GROUP_ADD : { +struct compat_ext4_new_group_input __user *uinput; +struct ext4_new_group_input input; +mm_segment_t old_fs; +int err; + + uinput =compat_ptr (arg); + err =get_user (input.group, &uinput->group); + err |=get_user (input.block_bitmap, &uinput->block_bitmap); + err |=get_user (input.inode_bitmap, &uinput->inode_bitmap); + err |=get_user (input.inode_table, &uinput->inode_table); + err |=get_user (input.blocks_count, &uinput->blocks_count); + err |=get_user (input.reserved_blocks, + &uinput->reserved_blocks); +if (err) +return -EFAULT ; + old_fs =get_fs (); +set_fs (KERNEL_DS ); + err =ext4_ioctl (file,EXT4_IOC_GROUP_ADD , + (unsigned long ) &input); +set_fs (old_fs); +return err; + }case EXT4_IOC_MOVE_EXT :break ;default :
PATCH 132/165 ext4: Make fsync sync new parent directories in no-journal mode
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 14ece1028b3ed53ffec1b1213ffc6acaf79ad77c upstream (as of v2.6.34-git13)
Add a new ext4 state to tell us when a file has been newly created; use that state in ext4_sync_file in no-journal mode to tell us when we need to sync the parent directory as well as the inode and data itself. This fixes a problem in which a panic or power failure may lose the entire file even when using fsync, since the parent directory entry is lost.
Addresses-Google-Bug: #2480057
--- fs/ext4/ext4.h | 1 + fs/ext4/fsync.c | 31 +++++++++++++++++++++++++++++-- fs/ext4/namei.c | 2 ++ 3 files changed, 32 insertions(+), 2 deletions(-)
fs/ext4/ext4.h +1 -0
@@ -1142,6 +1142,7 @@ enum {EXT4_STATE_DA_ALLOC_CLOSE ,/* Alloc DA blks on close */ EXT4_STATE_EXT_MIGRATE ,/* Inode is migrating */ EXT4_STATE_DIO_UNWRITTEN ,/* need convert on dio done*/ + EXT4_STATE_NEWENTRY, /* File just added to dir */ };#define EXT4_INODE_BIT_FNS (name, field) \
fs/ext4/fsync.c +29 -2
@@ -35,6 +35,29 @@#include <trace/events/ext4.h> /* +* If we're not journaling and this is a just-created file, we have to +* sync our parent directory (if it was freshly created) since +* otherwise it will only be written by writeback, leaving a huge +* window during which a crash may lose the file. This may apply for +* the parent directory's parent as well, and so on recursively, if +* they are also freshly created. +*/ +static void ext4_sync_parent (struct inode *inode) +{ +struct dentry *dentry =NULL ; + +while (inode &&ext4_test_inode_state (inode,EXT4_STATE_NEWENTRY )) { +ext4_clear_inode_state (inode,EXT4_STATE_NEWENTRY ); + dentry =list_entry (inode->i_dentry.next, + struct dentry, d_alias); +if (!dentry || !dentry->d_parent || !dentry->d_parent->d_inode) +break ; + inode = dentry->d_parent->d_inode; +sync_mapping_buffers (inode->i_mapping); + } +} + +/* * akpm: A new design for ext4_sync_file(). * * This is only called from sys_fsync(), sys_fdatasync() and sys_msync().
@@ -67,8 +90,12 @@ int ext4_sync_file(struct file *file, stif (ret <0 )return ret; -if (!journal) -return simple_fsync (file, dentry, datasync); +if (!journal) { + ret =simple_fsync (file, dentry, datasync); +if (!ret && !list_empty (&inode->i_dentry)) +ext4_sync_parent (inode); +return ret; + }/* * data=writeback,ordered:
fs/ext4/namei.c +2 -0
@@ -1525,6 +1525,8 @@ static int ext4_add_entry(handle_t *hand de->rec_len =ext4_rec_len_to_disk (blocksize, blocksize); retval =add_dirent_to_buf (handle, dentry, inode, de, bh);brelse (bh); +if (retval ==0 ) +ext4_set_inode_state (inode,EXT4_STATE_NEWENTRY );return retval; }
PATCH 133/165 KVM: MMU: Remove user access when allowing kernel access to gpte.w=0 page
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
If cr0.wp=0, we have to allow the guest kernel access to a page with pte.w=0. We do that by setting spte.w=1, since the host cr0.wp must remain set so the host can write protect pages. Once we allow write access, we must remove user access otherwise we mistakenly allow the user to write the page.
--- arch/x86/kvm/mmu.c | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/kvm/mmu.c +3 -0
@@ -1843,6 +1843,9 @@ static int set_spte(struct kvm_vcpu *vcp spte |=PT_WRITABLE_MASK ; +if (!tdp_enabled && !(pte_access &ACC_WRITE_MASK )) + spte &= ~PT_USER_MASK ; +/* * Optimization: for pte sync, if spte was writable the hash * lookup is unnecessary (and expensive). Write protection
PATCH 134/165 KVM: SVM: Handle MCEs early in the vmexit process
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
This patch moves handling of the MC vmexits to an earlier point in the vmexit. The handle_exit function is too late because the vcpu might alreadry have changed its physical cpu.
--- arch/x86/kvm/svm.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
arch/x86/kvm/svm.c +14 -1
@@ -1257,7 +1257,7 @@ static int nm_interception(struct vcpu_sreturn 1 ; } -static int mc_interception (struct vcpu_svm *svm,struct kvm_run *kvm_run) +static void svm_handle_mce (struct vcpu_svm *svm) {/* * On an #MC intercept the MCE handler is not called automatically in
@@ -1267,6 +1267,11 @@ static int mc_interception(struct vcpu_s "int $0x12\n");/* not sure if we ever come back to this point */ +return ; +} + +static int mc_interception (struct vcpu_svm *svm,struct kvm_run *kvm_run) +{return 1 ; }
@@ -2717,6 +2722,14 @@ static void svm_vcpu_run(struct kvm_vcpu vcpu->arch.regs_avail &= ~(1 <<VCPU_EXREG_PDPTR ); vcpu->arch.regs_dirty &= ~(1 <<VCPU_EXREG_PDPTR ); } + +/* +* We need to handle MC intercepts here before the vcpu has a chance to +* change the physical cpu +*/ +if (unlikely (svm->vmcb->control.exit_code == +SVM_EXIT_EXCP_BASE +MC_VECTOR )) +svm_handle_mce (svm); }#undef R
PATCH 135/165 KVM: SVM: Implement workaround for Erratum 383
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
This patch implements a workaround for AMD erratum 383 into KVM. Without this erratum fix it is possible for a guest to kill the host machine. This patch implements the suggested workaround for hypervisors which will be published by the next revision guide update.
[jan: fix overflow warning on i386]
[xiao: fix unused variable warning]
--- arch/x86/include/asm/msr-index.h | 1 arch/x86/kvm/svm.c | 84 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 1 deletion(-)
arch/x86/include/asm/msr-index.h +1 -0
@@ -106,6 +106,7 @@#define MSR_AMD64_PATCH_LOADER 0xc0010020#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140#define MSR_AMD64_OSVW_STATUS 0xc0010141 +#define MSR_AMD64_DC_CFG 0xc0011022#define MSR_AMD64_IBSFETCHCTL 0xc0011030#define MSR_AMD64_IBSFETCHLINAD 0xc0011031#define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032
arch/x86/kvm/svm.c +83 -1
122 lines not on this page · raw message
PATCH 136/165 KVM: MMU: invalidate and flush on spte small->large page size change
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
Always invalidate spte and flush TLBs when changing page size, to make sure different sized translations for the same address are never cached in a CPU's TLB.
Currently the only case where this occurs is when a non-leaf spte pointer is overwritten by a leaf, large spte entry. This can happen after dirty logging is disabled on a memslot, for example.
Noticed by Andrea.
KVM-Stable-Tag
--- arch/x86/kvm/mmu.c | 2 ++ 1 file changed, 2 insertions(+)
arch/x86/kvm/mmu.c +2 -0
@@ -1901,6 +1901,8 @@ static void mmu_set_spte(struct kvm_vcpu child =page_header (pte &PT64_BASE_ADDR_MASK );mmu_page_remove_parent_pte (child, sptep); +__set_spte (sptep, shadow_trap_nonpresent_pte); +kvm_flush_remote_tlbs (vcpu->kvm); }else if (pfn !=spte_to_pfn (*sptep)) {pgprintk ("hfn old %lx new %lx\n" ,spte_to_pfn (*sptep), pfn);
PATCH 137/165 futex: futex_find_get_task remove credentails check
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Michal Hocko <[email protected]>
commit 7a0ea09ad5352efce8fe79ed853150449903b9f5 upstream.
futex_find_get_task is currently used (through lookup_pi_state) from two contexts, futex_requeue and futex_lock_pi_atomic. None of the paths looks it needs the credentials check, though. Different (e)uids shouldn't matter at all because the only thing that is important for shared futex is the accessibility of the shared memory.
The credentail check results in glibc assert failure or process hang (if glibc is compiled without assert support) for shared robust pthread mutex with priority inheritance if a process tries to lock already held lock owned by a process with a different euid:
pthread_mutex_lock.c:312: __pthread_mutex_lock_full: Assertion `(-(e)) != 3 || !robust' failed.
The problem is that futex_lock_pi_atomic which is called when we try to lock already held lock checks the current holder (tid is stored in the futex value) to get the PI state. It uses lookup_pi_state which in turn gets task struct from futex_find_get_task. ESRCH is returned either when the task is not found or if credentials check fails.
futex_lock_pi_atomic simply returns if it gets ESRCH. glibc code, however, doesn't expect that robust lock returns with ESRCH because it should get either success or owner died.
--- kernel/futex.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-)
kernel/futex.c +4 -13
@@ -429,20 +429,11 @@ static void free_pi_state(struct futex_pstatic struct task_struct *futex_find_get_task (pid_t pid) {struct task_struct *p; -const struct cred *cred =current_cred (), *pcred;rcu_read_lock (); p =find_task_by_vpid (pid); -if (!p) { - p =ERR_PTR (-ESRCH ); - }else { - pcred =__task_cred (p); -if (cred->euid != pcred->euid && - cred->euid != pcred->uid) - p =ERR_PTR (-ESRCH ); -else -get_task_struct (p); - } +if (p) +get_task_struct (p);rcu_read_unlock ();
@@ -564,8 +555,8 @@ lookup_pi_state(u32 uval, struct futex_hif (!pid)return -ESRCH ; p =futex_find_get_task (pid); -if (IS_ERR (p)) -return PTR_ERR (p); +if (!p) +return -ESRCH ;/* * We need to look at the task state flags to figure out,
PATCH 138/165 GFS2: Fix up system xattrs
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Steven Whitehouse <[email protected]>
commit 2646a1f61a3b5525914757f10fa12b5b94713648 upstream.
This code has been shamelessly stolen from XFS at the suggestion of Christoph Hellwig. I've not added support for cached ACLs so far... watch for that in a later patch, although this is designed in such a way that they should be easy to add.
--- fs/gfs2/acl.c | 170 +++++++++++++++++++++++++++++++++++++------------------- fs/gfs2/acl.h | 24 +------ fs/gfs2/xattr.c | 18 ----- 3 files changed, 120 insertions(+), 92 deletions(-)
fs/gfs2/acl.c +115 -55
@@ -12,6 +12,7 @@#include <linux/spinlock.h> #include <linux/completion.h> #include <linux/buffer_head.h> +#include <linux/xattr.h> #include <linux/posix_acl.h> #include <linux/posix_acl_xattr.h> #include <linux/gfs2_ondisk.h>
@@ -26,61 +27,6 @@#include "trans.h" #include "util.h" -#define ACL_ACCESS 1 -#define ACL_DEFAULT 0 - -int gfs2_acl_validate_set (struct gfs2_inode *ip,int access, -struct gfs2_ea_request *er,int *remove,mode_t *mode) -{ -struct posix_acl *acl; -int error; - - error =gfs2_acl_validate_remove (ip, access); -if (error) -return error; - -if (!er->er_data) -return -EINVAL ; - - acl =posix_acl_from_xattr (er->er_data, er->er_data_len); -if (IS_ERR (acl)) -return PTR_ERR (acl); -if (!acl) { - *remove =1 ; -return 0 ; - } - - error =posix_acl_valid (acl); -if (error) - goto out; - -if (access) { - error =posix_acl_equiv_mode (acl, mode); -if (!error) - *remove =1 ; -else if (error >0 ) - error =0 ; - } - -out: -posix_acl_release (acl); -return error; -} - -int gfs2_acl_validate_remove (struct gfs2_inode *ip,int access) -{ -if (!GFS2_SB (&ip->i_inode)->sd_args.ar_posix_acl) -return -EOPNOTSUPP ; -if (!is_owner_or_cap (&ip->i_inode)) -return -EPERM ; -if (S_ISLNK (ip->i_inode.i_mode)) -return -EOPNOTSUPP ; -if (!access && !S_ISDIR (ip->i_inode.i_mode)) -return -EACCES ; - -return 0 ; -} -static int acl_get (struct gfs2_inode *ip,const char *name,struct posix_acl **acl,struct gfs2_ea_location *el,char **datap,unsigned int *lenp)
@@ -277,3 +223,117 @@ out_brelse:return error; } +static int gfs2_acl_type (const char *name) +{ +if (strcmp (name,GFS2_POSIX_ACL_ACCESS ) ==0 ) +return ACL_TYPE_ACCESS ; +if (strcmp (name,GFS2_POSIX_ACL_DEFAULT ) ==0 ) +return ACL_TYPE_DEFAULT ; +return -EINVAL ; +} + +static int gfs2_xattr_system_get (struct inode *inode,const char *name, +void *buffer,size_t size) +{ +int type; + + type =gfs2_acl_type (name); +if (type <0 ) +return type; + +return gfs2_xattr_get (inode,GFS2_EATYPE_SYS , name, buffer, size); +} + +static int gfs2_set_mode (struct inode *inode,mode_t mode) +{ +int error =0 ; + +if (mode != inode->i_mode) { +struct iattr iattr; + + iattr.ia_valid =ATTR_MODE ; + iattr.ia_mode = mode; + + error =gfs2_setattr_simple (GFS2_I (inode), &iattr); + } + +return error; +} + +static int gfs2_xattr_system_set (struct inode *inode,const char *name, +const void *value,size_t size,int flags) +{ +struct gfs2_sbd *sdp =GFS2_SB (inode); +struct posix_acl *acl =NULL ; +int error =0 , type; + +if (!sdp->sd_args.ar_posix_acl) +return -EOPNOTSUPP ; + + type =gfs2_acl_type (name); +if (type <0 ) +return type; +if (flags &XATTR_CREATE ) +return -EINVAL ; +if (type ==ACL_TYPE_DEFAULT && !S_ISDIR (inode->i_mode)) +return value ? -EACCES :0 ; +if ((current_fsuid () != inode->i_uid) && !capable (CAP_FOWNER )) +return -EPERM ; +if (S_ISLNK (inode->i_mode)) +return -EOPNOTSUPP ; + +if (!value) + goto set_acl; + + acl =posix_acl_from_xattr (value, size); +if (!acl) { +/* +* acl_set_file(3) may request that we set default ACLs with +* zero length -- defend (gracefully) against that here. +*/ + goto out; + } +if (IS_ERR (acl)) { + error =PTR_ERR (acl); + goto out; + } + + error =posix_acl_valid (acl); +if (error) + goto out_release; + + error = -EINVAL ; +if (acl->a_count >GFS2_ACL_MAX_ENTRIES ) + goto out_release; + +if (type ==ACL_TYPE_ACCESS ) { +mode_t mode = inode->i_mode; + error =posix_acl_equiv_mode (acl, &mode); + +if (error <=0 ) { +posix_acl_release (acl); + acl =NULL ; + +if (error <0 ) +return error; + } + + error =gfs2_set_mode (inode, mode); +if (error) + goto out_release; + } + +set_acl: + error =gfs2_xattr_set (inode,GFS2_EATYPE_SYS , name, value, size,0 ); +out_release: +posix_acl_release (acl); +out: +return error; +} + +struct xattr_handler gfs2_xattr_system_handler = { + .prefix =XATTR_SYSTEM_PREFIX , + .get = gfs2_xattr_system_get, + .set = gfs2_xattr_system_set, +}; +
fs/gfs2/acl.h +5 -19
@@ -13,26 +13,12 @@#include "incore.h" #define GFS2_POSIX_ACL_ACCESS "posix_acl_access" -#define GFS2_POSIX_ACL_ACCESS_LEN 16#define GFS2_POSIX_ACL_DEFAULT "posix_acl_default" -#define GFS2_POSIX_ACL_DEFAULT_LEN 17 +#define GFS2_ACL_MAX_ENTRIES 25 -#define GFS2_ACL_IS_ACCESS (name, len) \ - ((len) == GFS2_POSIX_ACL_ACCESS_LEN && \ - !memcmp(GFS2_POSIX_ACL_ACCESS, (name), (len))) - -#define GFS2_ACL_IS_DEFAULT (name, len) \ - ((len) == GFS2_POSIX_ACL_DEFAULT_LEN && \ - !memcmp(GFS2_POSIX_ACL_DEFAULT, (name), (len))) - -struct gfs2_ea_request ; - -int gfs2_acl_validate_set (struct gfs2_inode *ip,int access, -struct gfs2_ea_request *er, -int *remove,mode_t *mode); -int gfs2_acl_validate_remove (struct gfs2_inode *ip,int access); -int gfs2_check_acl (struct inode *inode,int mask); -int gfs2_acl_create (struct gfs2_inode *dip,struct gfs2_inode *ip); -int gfs2_acl_chmod (struct gfs2_inode *ip,struct iattr *attr); +extern int gfs2_check_acl (struct inode *inode,int mask); +extern int gfs2_acl_create (struct gfs2_inode *dip,struct gfs2_inode *ip); +extern int gfs2_acl_chmod (struct gfs2_inode *ip,struct iattr *attr); +extern struct xattr_handler gfs2_xattr_system_handler;#endif /* __ACL_DOT_H__ */
fs/gfs2/xattr.c +0 -18
@@ -1507,18 +1507,6 @@ static int gfs2_xattr_user_set(struct inreturn gfs2_xattr_set (inode,GFS2_EATYPE_USR , name, value, size, flags); } -static int gfs2_xattr_system_get (struct inode *inode,const char *name, -void *buffer,size_t size) -{ -return gfs2_xattr_get (inode,GFS2_EATYPE_SYS , name, buffer, size); -} - -static int gfs2_xattr_system_set (struct inode *inode,const char *name, -const void *value,size_t size,int flags) -{ -return gfs2_xattr_set (inode,GFS2_EATYPE_SYS , name, value, size, flags); -} -static int gfs2_xattr_security_get (struct inode *inode,const char *name,void *buffer,size_t size) {
@@ -1543,12 +1531,6 @@ static struct xattr_handler gfs2_xattr_s .set = gfs2_xattr_security_set, }; -static struct xattr_handler gfs2_xattr_system_handler = { - .prefix =XATTR_SYSTEM_PREFIX , - .get = gfs2_xattr_system_get, - .set = gfs2_xattr_system_set, -}; -struct xattr_handler *gfs2_xattr_handlers[] = { &gfs2_xattr_user_handler, &gfs2_xattr_security_handler,
PATCH 139/165 PM / x86: Save/restore MISC_ENABLE register
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ondrej Zary <[email protected]>
commit 85a0e7539781dad4bfcffd98e72fa9f130f4e40d upstream.
Save/restore MISC_ENABLE register on suspend/resume.
This fixes OOPS (invalid opcode) on resume from STR on Asus P4P800-VM, which wakes up with MWAIT disabled.
Fixes https://bugzilla.kernel.org/show_bug.cgi?id=15385
--- arch/x86/include/asm/suspend_32.h | 2 ++ arch/x86/include/asm/suspend_64.h | 2 ++ arch/x86/power/cpu.c | 4 ++++ 3 files changed, 8 insertions(+)
arch/x86/include/asm/suspend_32.h +2 -0
@@ -15,6 +15,8 @@ static inline int arch_prepare_suspend(vstruct saved_context {u16 es, fs, gs, ss;unsigned long cr0, cr2, cr3, cr4; +u64 misc_enable; +bool misc_enable_saved;struct desc_ptr gdt;struct desc_ptr idt;u16 ldt;
arch/x86/include/asm/suspend_64.h +2 -0
@@ -27,6 +27,8 @@ struct saved_context {u16 ds, es, fs, gs, ss;unsigned long gs_base, gs_kernel_base, fs_base;unsigned long cr0, cr2, cr3, cr4, cr8; +u64 misc_enable; +bool misc_enable_saved;unsigned long efer;u16 gdt_pad;u16 gdt_limit;
arch/x86/power/cpu.c +4 -0
@@ -104,6 +104,8 @@ static void __save_processor_state(struc ctxt->cr4 =read_cr4 (); ctxt->cr8 =read_cr8 ();#endif + ctxt->misc_enable_saved = !rdmsrl_safe (MSR_IA32_MISC_ENABLE , + &ctxt->misc_enable); }/* Needed by apm.c */
@@ -176,6 +178,8 @@ static void fix_processor_context(void)*/ static void __restore_processor_state (struct saved_context *ctxt) { +if (ctxt->misc_enable_saved) +wrmsrl (MSR_IA32_MISC_ENABLE , ctxt->misc_enable);/* * control registers */
PATCH 140/165 ACPI: skip checking BM_STS if the BIOS doesnt ask for it
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Len Brown <[email protected]>
commit 718be4aaf3613cf7c2d097f925abc3d3553c0605 upstream.
It turns out that there is a bit in the _CST for Intel FFH C3 that tells the OS if we should be checking BM_STS or not.
Linux has been unconditionally checking BM_STS.
If the chip-set is configured to enable BM_STS,
it can retard or completely prevent entry into
deep C-states -- as illustrated by turbostat:
http://userweb.kernel.org/~lenb/acpi/utils/pmtools/turbostat/
ref: Intel Processor Vendor-Specific ACPI Interface Specification table 4 "_CST FFH GAS Field Encoding"
Bit 1: Set to 1 if OSPM should use Bus Master avoidance for this C-state
https://bugzilla.kernel.org/show_bug.cgi?id=15886
--- arch/x86/kernel/acpi/cstate.c | 9 +++++++++ drivers/acpi/processor_idle.c | 2 +- include/acpi/processor.h | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-)
arch/x86/kernel/acpi/cstate.c +9 -0
@@ -145,6 +145,15 @@ int acpi_processor_ffh_cstate_probe(unsi percpu_entry->states[cx->index].eax = cx->address; percpu_entry->states[cx->index].ecx =MWAIT_ECX_INTERRUPT_BREAK ; } + +/* +* For _CST FFH on Intel, if GAS.access_size bit 1 is cleared, +* then we should skip checking BM_STS for this C-state. +* ref: "Intel Processor Vendor-Specific ACPI Interface Specification" +*/ +if ((c->x86_vendor ==X86_VENDOR_INTEL ) && !(reg->access_size &0x2 )) + cx->bm_sts_skip =1 ; +return retval; }EXPORT_SYMBOL_GPL (acpi_processor_ffh_cstate_probe);
drivers/acpi/processor_idle.c +1 -1
@@ -962,7 +962,7 @@ static int acpi_idle_enter_bm(struct cpuif (acpi_idle_suspend)return (acpi_idle_enter_c1 (dev, state)); -if (acpi_idle_bm_check ()) { +if (!cx->bm_sts_skip &&acpi_idle_bm_check ()) {if (dev->safe_state) { dev->last_state = dev->safe_state;return dev->safe_state->enter (dev, dev->safe_state);
include/acpi/processor.h +2 -1
@@ -48,7 +48,7 @@ struct acpi_power_register {u8 space_id;u8 bit_width;u8 bit_offset; -u8 reserved; +u8 access_size;u64 address; } __attribute__ ((packed));
@@ -74,6 +74,7 @@ struct acpi_processor_cx {u32 power;u32 usage;u64 time; +u8 bm_sts_skip;struct acpi_processor_cx_policy promotion;struct acpi_processor_cx_policy demotion;char desc[ACPI_CX_DESC_LEN ];
PATCH 141/165 ACPI: Unconditionally set SCI_EN on resume
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Matthew Garrett <[email protected]>
commit b6dacf63e9fb2e7a1369843d6cef332f76fca6a3 upstream.
The ACPI spec tells us that the firmware will reenable SCI_EN on resume. Reality disagrees in some cases. The ACPI spec tells us that the only way to set SCI_EN is via an SMM call.
https://bugzilla.kernel.org/show_bug.cgi?id=13745 shows us that doing so may break machines. Tracing the ACPI calls made by Windows shows that it unconditionally sets SCI_EN on resume with a direct register write, and therefore the overwhelming probability is that everything is fine with this behaviour.
--- arch/x86/kernel/acpi/sleep.c | 2 drivers/acpi/sleep.c | 157 ------------------------------------------- include/linux/acpi.h | 1 3 files changed, 2 insertions(+), 158 deletions(-)
arch/x86/kernel/acpi/sleep.c +0 -2
@@ -162,8 +162,6 @@ static int __init acpi_sleep_setup(char#endif if (strncmp (str,"old_ordering" ,12 ) ==0 )acpi_old_suspend_ordering (); -if (strncmp (str,"sci_force_enable" ,16 ) ==0 ) -acpi_set_sci_en_on_resume (); str =strchr (str,',' );if (str !=NULL ) str +=strspn (str,", \t" );
drivers/acpi/sleep.c +2 -155
193 lines not on this page · raw message
include/linux/acpi.h +0 -1
@@ -251,7 +251,6 @@ int acpi_check_mem_region(resource_size_void __init acpi_no_s4_hw_signature (void );void __init acpi_old_suspend_ordering (void );void __init acpi_s4_no_nvs (void ); -void __init acpi_set_sci_en_on_resume (void );#endif /* CONFIG_PM_SLEEP */ struct acpi_osc_context {
PATCH 142/165 libertas/sdio: 8686: set ECSI bit for 1-bit transfers
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Daniel Mack <[email protected]>
commit 8a64c0f6b7ec7f758c4ef445e49f479e27fa2236 upstream.
When operating in 1-bit mode, SDAT1 is used as dedicated interrupt line. However, the 8686 will only drive this line when the ECSI bit is set in the CCCR_IF register.
Thanks to Alagu Sankar for pointing me in the right direction.
--- drivers/net/wireless/libertas/if_sdio.c | 22 ++++++++++++++++++++++ include/linux/mmc/sdio.h | 2 ++ 2 files changed, 24 insertions(+)
drivers/net/wireless/libertas/if_sdio.c +22 -0
@@ -34,6 +34,8 @@#include <linux/mmc/card.h> #include <linux/mmc/sdio_func.h> #include <linux/mmc/sdio_ids.h> +#include <linux/mmc/sdio.h> +#include <linux/mmc/host.h> #include "host.h" #include "decl.h"
@@ -883,6 +885,7 @@ static int if_sdio_probe(struct sdio_funint ret, i;unsigned int model;struct if_sdio_packet *packet; +struct mmc_host *host = func->card->host;lbs_deb_enter (LBS_DEB_SDIO );
@@ -963,6 +966,25 @@ static int if_sdio_probe(struct sdio_funif (ret) goto disable; +/* For 1-bit transfers to the 8686 model, we need to enable the +* interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0 +* bit to allow access to non-vendor registers. */ +if ((card->model ==IF_SDIO_MODEL_8686 ) && + (host->caps &MMC_CAP_SDIO_IRQ ) && + (host->ios.bus_width ==MMC_BUS_WIDTH_1 )) { +u8 reg; + + func->card->quirks |=MMC_QUIRK_LENIENT_FN0 ; + reg =sdio_f0_readb (func,SDIO_CCCR_IF , &ret); +if (ret) + goto release_int; + + reg |=SDIO_BUS_ECSI ; +sdio_f0_writeb (func, reg,SDIO_CCCR_IF , &ret); +if (ret) + goto release_int; + } + card->ioport =sdio_readb (func,IF_SDIO_IOPORT , &ret);if (ret) goto release_int;
include/linux/mmc/sdio.h +2 -0
@@ -94,6 +94,8 @@#define SDIO_BUS_WIDTH_1BIT 0x00#define SDIO_BUS_WIDTH_4BIT 0x02 +#define SDIO_BUS_ECSI 0x20/* Enable continuous SPI interrupt */ +#define SDIO_BUS_SCSI 0x40/* Support continuous SPI interrupt */ #define SDIO_BUS_CD_DISABLE 0x80/* disable pull-up on DAT3 (pin 1) */
PATCH 143/165 dm9000: fix "BUG: spinlock recursion"
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Baruch Siach <[email protected]>
commit 380fefb2ddabd4cd5f14dbe090481f0544e65078 upstream.
dm9000_set_rx_csum and dm9000_hash_table are called from atomic context (in dm9000_init_dm9000), and from non-atomic context (via ethtool_ops and net_device_ops respectively). This causes a spinlock recursion BUG. Fix this by renaming these functions to *_unlocked for the atomic context, and make the original functions locking wrappers for use in the non-atomic context.
--- drivers/net/dm9000.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-)
drivers/net/dm9000.c +27 -11
@@ -471,17 +471,13 @@ static uint32_t dm9000_get_rx_csum(strucreturn dm->rx_csum; } -static int dm9000_set_rx_csum (struct net_device *dev,uint32_t data) +static int dm9000_set_rx_csum_unlocked (struct net_device *dev,uint32_t data) {board_info_t *dm =to_dm9000_board (dev); -unsigned long flags;if (dm->can_csum) { dm->rx_csum = data; - -spin_lock_irqsave (&dm->lock, flags);iow (dm,DM9000_RCSR , dm->rx_csum ?RCSR_CSUM :0 ); -spin_unlock_irqrestore (&dm->lock, flags);return 0 ; }
@@ -489,6 +485,19 @@ static int dm9000_set_rx_csum(struct netreturn -EOPNOTSUPP ; } +static int dm9000_set_rx_csum (struct net_device *dev,uint32_t data) +{ +board_info_t *dm =to_dm9000_board (dev); +unsigned long flags; +int ret; + +spin_lock_irqsave (&dm->lock, flags); + ret =dm9000_set_rx_csum_unlocked (dev, data); +spin_unlock_irqrestore (&dm->lock, flags); + +return ret; +} +static int dm9000_set_tx_csum (struct net_device *dev,uint32_t data) {board_info_t *dm =to_dm9000_board (dev);
@@ -667,7 +676,7 @@ static unsigned char dm9000_type_to_char* Set DM9000 multicast address */ static void -dm9000_hash_table (struct net_device *dev) +dm9000_hash_table_unlocked (struct net_device *dev) {board_info_t *db =netdev_priv (dev);struct dev_mc_list *mcptr = dev->mc_list;
@@ -676,12 +685,9 @@ dm9000_hash_table(struct net_device *devu32 hash_val;u16 hash_table[4 ];u8 rcr =RCR_DIS_LONG |RCR_DIS_CRC |RCR_RXEN ; -unsigned long flags;dm9000_dbg (db,1 ,"entering %s\n" , __func__); -spin_lock_irqsave (&db->lock, flags); -for (i =0 , oft =DM9000_PAR ; i <6 ; i++, oft++)iow (db, oft, dev->dev_addr[i]);
@@ -711,6 +717,16 @@ dm9000_hash_table(struct net_device *dev }iow (db,DM9000_RCR , rcr); +} + +static void +dm9000_hash_table (struct net_device *dev) +{ +board_info_t *db =netdev_priv (dev); +unsigned long flags; + +spin_lock_irqsave (&db->lock, flags); +dm9000_hash_table_unlocked (dev);spin_unlock_irqrestore (&db->lock, flags); }
@@ -729,7 +745,7 @@ dm9000_init_dm9000(struct net_device *de db->io_mode =ior (db,DM9000_ISR ) >>6 ;/* ISR bit7:6 keeps I/O mode */ /* Checksum mode */ -dm9000_set_rx_csum (dev, db->rx_csum); +dm9000_set_rx_csum_unlocked (dev, db->rx_csum);/* GPIO0 on pre-activate PHY */ iow (db,DM9000_GPR ,0 );/* REG_1F bit0 activate phyxcer */
@@ -749,7 +765,7 @@ dm9000_init_dm9000(struct net_device *deiow (db,DM9000_ISR ,ISR_CLR_STATUS );/* Clear interrupt status */ /* Set address filter table */ -dm9000_hash_table (dev); +dm9000_hash_table_unlocked (dev); imr =IMR_PAR |IMR_PTM |IMR_PRM ;if (db->type !=TYPE_DM9000E )
PATCH 144/165 firmware_class: fix memory leak - free allocated pages
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: David Woodhouse <[email protected]>
commit dd336c554d8926c3348a2d5f2a5ef5597f6d1a06 upstream.
fix memory leak introduced by the patch 6e03a201bbe:
firmware: speed up request_firmware()
1. vfree won't release pages there were allocated explicitly and mapped using vmap. The memory has to be vunmap-ed and the pages needs to be freed explicitly
2. page array is moved into the 'struct firmware' so that we can free it from release_firmware() and not only in fw_dev_release()
The fix doesn't break the firmware load speed.
--- drivers/base/firmware_class.c | 26 ++++++++++++++++++++------ include/linux/firmware.h | 1 + 2 files changed, 21 insertions(+), 6 deletions(-)
drivers/base/firmware_class.c +20 -6
@@ -125,6 +125,17 @@ static ssize_t firmware_loading_show(strreturn sprintf (buf,"%d\n" , loading); } +static void firmware_free_data (const struct firmware *fw) +{ +int i; +vunmap (fw->data); +if (fw->pages) { +for (i =0 ; i <PFN_UP (fw->size); i++) +__free_page (fw->pages[i]); +kfree (fw->pages); + } +} +/* Some architectures don't have PAGE_KERNEL_RO */ #ifndef PAGE_KERNEL_RO #define PAGE_KERNEL_RO PAGE_KERNEL
@@ -157,21 +168,21 @@ static ssize_t firmware_loading_store(stmutex_unlock (&fw_lock);break ; } -vfree (fw_priv->fw->data); - fw_priv->fw->data =NULL ; +firmware_free_data (fw_priv->fw); +memset (fw_priv->fw,0 ,sizeof (struct firmware )); +/* If the pages are not owned by 'struct firmware' */ for (i =0 ; i < fw_priv->nr_pages; i++)__free_page (fw_priv->pages[i]);kfree (fw_priv->pages); fw_priv->pages =NULL ; fw_priv->page_array_size =0 ; fw_priv->nr_pages =0 ; - fw_priv->fw->size =0 ;set_bit (FW_STATUS_LOADING , &fw_priv->status);mutex_unlock (&fw_lock);break ;case 0 :if (test_bit (FW_STATUS_LOADING , &fw_priv->status)) { -vfree (fw_priv->fw->data); +vunmap (fw_priv->fw->data); fw_priv->fw->data =vmap (fw_priv->pages, fw_priv->nr_pages,0 ,PAGE_KERNEL_RO );
@@ -179,7 +190,10 @@ static ssize_t firmware_loading_store(stdev_err (dev,"%s: vmap() failed\n" , __func__); goto err; } -/* Pages will be freed by vfree() */ +/* Pages are now owned by 'struct firmware' */ + fw_priv->fw->pages = fw_priv->pages; + fw_priv->pages =NULL ; + fw_priv->page_array_size =0 ; fw_priv->nr_pages =0 ;complete (&fw_priv->completion);
@@ -572,7 +586,7 @@ release_firmware(const struct firmware *if (fw->data == builtin->data) goto free_fw; } -vfree (fw->data); +firmware_free_data (fw); free_fw:kfree (fw); }
include/linux/firmware.h +1 -0
@@ -11,6 +11,7 @@struct firmware {size_t size;const u8 *data; +struct page **pages; };struct device ;
PATCH 145/165 revert "[CPUFREQ] remove rwsem lock from CPUFREQ_GOV_STOP call (second call site)"
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andrej Gelenberg <[email protected]>
commit accd846698439ba18250e8fd5681af280446b853 upstream.
395913d0b1db37092ea3d9d69b832183b1dd84c5 ("[CPUFREQ] remove rwsem lock from CPUFREQ_GOV_STOP call (second call site)") is not needed, because there is no rwsem lock in cpufreq_ondemand and cpufreq_conservative anymore. Lock should not be released until the work done.
Addresses https://bugzilla.kernel.org/show_bug.cgi?id=1594
--- drivers/cpufreq/cpufreq.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-)
drivers/cpufreq/cpufreq.c +1 -10
@@ -1741,17 +1741,8 @@ static int __cpufreq_set_policy(struct cdprintk ("governor switch\n" );/* end old governor */ -if (data->governor) { -/* -* Need to release the rwsem around governor -* stop due to lock dependency between -* cancel_delayed_work_sync and the read lock -* taken in the delayed work handler. -*/ -unlock_policy_rwsem_write (data->cpu); +if (data->governor)__cpufreq_governor (data,CPUFREQ_GOV_STOP ); -lock_policy_rwsem_write (data->cpu); - }/* start new governor */ data->governor = policy->governor;
PATCH 146/165 ALSA: Echoaudio, fix Guru Meditation #00000005.48454C50
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Giuliano Pochini <[email protected]>
commit b721e68bdc5b39c51bf6a1469f8d3663fbe03243 upstream.
This patch fixes a division by zero error in the irq handler.
There is a small window between the hw_params() callback and when runtime->frame_bits is set by ALSA middle layer. When another substream is already running, if an interrupt is delivered during that window the irq handler calls pcm_pointer() which does a division by zero. The patch below makes the irq handler skip substreams that are initialized but not started yet. Cc to Clemens Ladisch because he proposed an alternate fix.
For more information, please read the original thread in the linux-kernel mailing list: http://lkml.org/lkml/2010/2/2/187
--- sound/pci/echoaudio/echoaudio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
sound/pci/echoaudio/echoaudio.c +3 -1
@@ -1821,7 +1821,9 @@ static irqreturn_t snd_echo_interrupt(in/* The hardware doesn't tell us which substream caused the irq, thus we have to check all running substreams. */ for (ss =0 ; ss <DSP_MAXPIPES ; ss++) { -if ((substream = chip->substream[ss])) { + substream = chip->substream[ss]; +if (substream && ((struct audiopipe *)substream->runtime-> + private_data)->state ==PIPE_STATE_STARTED ) { period =pcm_pointer (substream) / substream->runtime->period_size;if (period != chip->last_period[ss]) {
PATCH 147/165 V4L/DVB: dvb-core: Fix ULE decapsulation bug
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ang Way Chuang <[email protected]>
commit 5c331fc8c19e181bffab46e9d18e1637cdc47170 upstream.
Fix ULE decapsulation bug when less than 4 bytes of ULE SNDU is packed into the remaining bytes of a MPEG2-TS frame
ULE (Unidirectional Lightweight Encapsulation RFC 4326) decapsulation code has a bug that incorrectly treats ULE SNDU packed into the remaining 2 or 3 bytes of a MPEG2-TS frame as having invalid pointer field on the subsequent MPEG2-TS frame.
--- drivers/media/dvb/dvb-core/dvb_net.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/media/dvb/dvb-core/dvb_net.c +11 -1
@@ -350,6 +350,7 @@ static void dvb_net_ule( struct net_deviconst u8 *ts, *ts_end, *from_where =NULL ;u8 ts_remain =0 , how_much =0 , new_ts =1 ;struct ethhdr *ethh =NULL ; +bool error = false;#ifdef ULE_DEBUG /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */
@@ -459,10 +460,16 @@ static void dvb_net_ule( struct net_devi/* Drop partly decoded SNDU, reset state, resync on PUSI. */ if (priv->ule_skb) { -dev_kfree_skb ( priv->ule_skb ); + error = true; +dev_kfree_skb (priv->ule_skb); + } + +if (error || priv->ule_sndu_remain) { dev->stats.rx_errors++; dev->stats.rx_frame_errors++; + error = false; } +reset_ule (priv); priv->need_pusi =1 ;continue ;
@@ -534,6 +541,7 @@ static void dvb_net_ule( struct net_devi from_where +=2 ; } + priv->ule_sndu_remain = priv->ule_sndu_len +2 ;/* * State of current TS: * ts_remain (remaining bytes in the current TS cell)
@@ -543,6 +551,7 @@ static void dvb_net_ule( struct net_devi*/ switch (ts_remain) {case 1 : + priv->ule_sndu_remain--; priv->ule_sndu_type = from_where[0 ] <<8 ; priv->ule_sndu_type_1 =1 ;/* first byte of ule_type is set. */ ts_remain -=1 ; from_where +=1 ;
@@ -556,6 +565,7 @@ static void dvb_net_ule( struct net_devidefault :/* complete ULE header is present in current TS. */ /* Extract ULE type field. */ if (priv->ule_sndu_type_1) { + priv->ule_sndu_type_1 =0 ; priv->ule_sndu_type |= from_where[0 ]; from_where +=1 ;/* points to payload start. */ ts_remain -=1 ;
PATCH 148/165 V4L/DVB: FusionHDTV: Use quick reads for I2C IR device probing
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jean Delvare <[email protected]>
commit 806b07c29b711aaf90c81d2a19711607769f8246 upstream.
IR support on FusionHDTV cards is broken since kernel 2.6.31. One side effect of the switch to the standard binding model for IR I2C devices was to let i2c-core do the probing instead of the ir-kbd-i2c driver. There is a slight difference between the two probe methods: i2c-core uses 0-byte writes, while the ir-kbd-i2c was using 0-byte reads. As some IR I2C devices only support reads, the new probe method fails to detect them.
For now, revert to letting the driver do the probe, using 0-byte reads. In the future, i2c-core will be extended to let callers of i2c_new_probed_device() provide a custom probing function.
--- drivers/media/video/cx23885/cx23885-i2c.c | 12 +++++++++++- drivers/media/video/cx88/cx88-i2c.c | 16 +++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-)
drivers/media/video/cx23885/cx23885-i2c.c +11 -1
@@ -365,7 +365,17 @@ int cx23885_i2c_register(struct cx23885_memset (&info,0 ,sizeof (struct i2c_board_info ));strlcpy (info.type,"ir_video" ,I2C_NAME_SIZE ); -i2c_new_probed_device (&bus->i2c_adap, &info, addr_list); +/* +* We can't call i2c_new_probed_device() because it uses +* quick writes for probing and the IR receiver device only +* replies to reads. +*/ +if (i2c_smbus_xfer (&bus->i2c_adap, addr_list[0 ],0 , +I2C_SMBUS_READ ,0 ,I2C_SMBUS_QUICK , +NULL ) >=0 ) { + info.addr = addr_list[0 ]; +i2c_new_device (&bus->i2c_adap, &info); + } }return bus->i2c_rc;
drivers/media/video/cx88/cx88-i2c.c +15 -1
@@ -188,10 +188,24 @@ int cx88_i2c_init(struct cx88_core *core0x18 ,0x6b ,0x71 , I2C_CLIENT_END }; +const unsigned short *addrp;memset (&info,0 ,sizeof (struct i2c_board_info ));strlcpy (info.type,"ir_video" ,I2C_NAME_SIZE ); -i2c_new_probed_device (&core->i2c_adap, &info, addr_list); +/* +* We can't call i2c_new_probed_device() because it uses +* quick writes for probing and at least some R receiver +* devices only reply to reads. +*/ +for (addrp = addr_list; *addrp !=I2C_CLIENT_END ; addrp++) { +if (i2c_smbus_xfer (&core->i2c_adap, *addrp,0 , +I2C_SMBUS_READ ,0 , +I2C_SMBUS_QUICK ,NULL ) >=0 ) { + info.addr = *addrp; +i2c_new_device (&core->i2c_adap, &info); +break ; + } + } }return core->i2c_rc; }
PATCH 149/165 forcedeth: fix tx limit2 flag check
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ayaz Abdulla <[email protected]>
commit 5c659322a904a7cc0265e7b183372b9bdebec6db upstream.
This is a fix for bug 572201 @ bugs.debian.org
This patch fixes the TX_LIMIT feature flag. The previous logic check for TX_LIMIT2 also took into account a device that only had TX_LIMIT set.
--- drivers/net/forcedeth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/forcedeth.c +1 -1
@@ -5900,7 +5900,7 @@ static int __devinit nv_probe(struct pci/* Limit the number of tx's outstanding for hw bug */ if (id->driver_data &DEV_NEED_TX_LIMIT ) { np->tx_limit =1 ; -if ((id->driver_data &DEV_NEED_TX_LIMIT2 ) && +if (((id->driver_data &DEV_NEED_TX_LIMIT2 ) ==DEV_NEED_TX_LIMIT2 ) && pci_dev->revision >=0xA2 ) np->tx_limit =0 ; }
PATCH 150/165 staging: rtl8192su: add Support for Belkin F5D8053 v6
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Richard Airlie <[email protected]>
commit d615da093eb0f691a73a754589e2a4a24a6f1ca7 upstream.
Please find attached a patch which adds the device ID for the Belkin F5D8053 v6 to the rtl8192su driver. I've tested this in 2.6.34-rc3 (Ubuntu 9.10 amd64) and the network adapter is working flawlessly.
--- drivers/staging/rtl8192su/r8192U_core.c | 1 + 1 file changed, 1 insertion(+)
drivers/staging/rtl8192su/r8192U_core.c +1 -0
@@ -119,6 +119,7 @@ static struct usb_device_id rtl8192_usb_ {USB_DEVICE(0x07aa, 0x0043)},/* Belkin */ {USB_DEVICE(0x050d, 0x805E)}, + {USB_DEVICE(0x050d, 0x815F)}, /* Belkin F5D8053 v6 *//* Sitecom */ {USB_DEVICE(0x0df6, 0x0031)}, {USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */
PATCH 151/165 MIPS FPU emulator: allow Cause bits of FCSR to be writeable by ctc1
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Shane McDonald <[email protected]>
commit 95e8f634d7a3ea5af40ec3fa42c8a152fd3a0624 upstream.
In the FPU emulator code of the MIPS, the Cause bits of the FCSR register are not currently writeable by the ctc1 instruction. In odd corner cases, this can cause problems. For example, a case existed where a divide-by-zero exception was generated by the FPU, and the signal handler attempted to restore the FPU registers to their state before the exception occurred. In this particular setup, writing the old value to the FCSR register would cause another divide-by-zero exception to occur immediately. The solution is to change the ctc1 instruction emulator code to allow the Cause bits of the FCSR register to be writeable. This is the behaviour of the hardware that the code is emulating.
This problem was found by Shane McDonald, but the credit for the fix goes to Kevin Kissell. In Kevin's words:
I submit that the bug is indeed in that ctc_op: case of the emulator. The Cause bits (17:12) are supposed to be writable by that instruction, but the CTC1 emulation won't let them be updated by the instruction. I think that actually if you just completely removed lines 387-388 [...] things would work a good deal better. At least, it would be a more accurate emulation of the architecturally defined FPU. If I wanted to be really, really pedantic (which I sometimes do), I'd also protect the reserved bits that aren't necessarily writable.
To: [email protected]
To: [email protected]
To: [email protected]
Patchwork: http://patchwork.linux-mips.org/patch/1205/
---
--- arch/mips/include/asm/mipsregs.h | 9 ++++++++- arch/mips/math-emu/cp1emu.c | 15 +++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-)
arch/mips/include/asm/mipsregs.h +8 -1
@@ -135,6 +135,12 @@#define FPU_CSR_COND7 0x80000000/* $fcc7 */ /* +* Bits 18 - 20 of the FPU Status Register will be read as 0, +* and should be written as zero. +*/ +#define FPU_CSR_RSVD 0x001c0000 + +/* * X the exception cause indicator * E the exception enable * S the sticky/flag bit
@@ -161,7 +167,8 @@#define FPU_CSR_UDF_S 0x00000008#define FPU_CSR_INE_S 0x00000004 -/* rounding mode */ +/* Bits 0 and 1 of FPU Status Register specify the rounding mode */ +#define FPU_CSR_RM 0x00000003#define FPU_CSR_RN 0x0/* nearest */ #define FPU_CSR_RZ 0x1/* towards zero */ #define FPU_CSR_RU 0x2/* towards +Infinity */
arch/mips/math-emu/cp1emu.c +11 -4
@@ -75,6 +75,9 @@ struct mips_fpu_emulator_stats fpuemusta#define FPCREG_RID 0/* $0 = revision id */ #define FPCREG_CSR 31/* $31 = csr */ +/* Determine rounding mode from the RM bits of the FCSR */ +#define modeindex (v) ((v) & FPU_CSR_RM) +/* Convert Mips rounding mode (0..3) to IEEE library modes. */ static const unsigned char ieee_rm[4 ] = { [FPU_CSR_RN ] =IEEE754_RN ,
@@ -381,10 +384,14 @@ static int cop1Emulate(struct pt_regs *x (void *) (xcp->cp0_epc), MIPSInst_RT(ir), value);#endif - value &= (FPU_CSR_FLUSH |FPU_CSR_ALL_E |FPU_CSR_ALL_S |0x03 ); - ctx->fcr31 &= ~(FPU_CSR_FLUSH |FPU_CSR_ALL_E |FPU_CSR_ALL_S |0x03 ); -/* convert to ieee library modes */ - ctx->fcr31 |= (value & ~0x3 ) | ieee_rm[value &0x3 ]; + +/* +* Don't write reserved bits, +* and convert to ieee library modes +*/ + ctx->fcr31 = (value & + ~(FPU_CSR_RSVD |FPU_CSR_RM )) | + ieee_rm[modeindex (value)]; }if ((ctx->fcr31 >>5 ) & ctx->fcr31 &FPU_CSR_ALL_E ) {return SIGFPE ;
PATCH 152/165 V4L/DVB: budget: Select correct frontends
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ben Hutchings <[email protected]>
commit d46b36e7f927772bb72524dc9f1e384e3cb4a975 upstream.
Update the Kconfig selections to match the code.
--- drivers/media/dvb/ttpci/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/media/dvb/ttpci/Kconfig +3 -2
@@ -68,13 +68,14 @@ config DVB_BUDGET select DVB_VES1820 if !DVB_FE_CUSTOMISE select DVB_L64781 if !DVB_FE_CUSTOMISE select DVB_TDA8083 if !DVB_FE_CUSTOMISE - select DVB_TDA10021 if !DVB_FE_CUSTOMISE - select DVB_TDA10023 if !DVB_FE_CUSTOMISE select DVB_S5H1420 if !DVB_FE_CUSTOMISE select DVB_TDA10086 if !DVB_FE_CUSTOMISE select DVB_TDA826X if !DVB_FE_CUSTOMISE select DVB_LNBP21 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE + select DVB_ISL6423 if !DVB_FE_CUSTOMISE + select DVB_STV090x if !DVB_FE_CUSTOMISE + select DVB_STV6110x if !DVB_FE_CUSTOMISE help Support for simple SAA7146 based DVB cards (so called Budget- or Nova-PCI cards) without onboard MPEG2 decoder, and without
PATCH 153/165 cxgb3: fix linkup issue
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Hiroshi Shimamoto <[email protected]>
commit 9441cad99b4b09d6b627351c2d282833868c116c upstream.
I encountered an issue that not to link up on cxgb3 fabric. I bisected and found that this regression was introduced by 0f07c4ee8c800923ae7918c231532a9256233eed.
Correct to pass phy_addr to cphy_init() at t3_xaui_direct_phy_prep().
--- drivers/net/cxgb3/ael1002.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/cxgb3/ael1002.c +1 -1
@@ -934,7 +934,7 @@ static struct cphy_ops xaui_direct_ops =int t3_xaui_direct_phy_prep (struct cphy *phy,struct adapter *adapter,int phy_addr,const struct mdio_ops *mdio_ops) { -cphy_init (phy, adapter,MDIO_PRTAD_NONE , &xaui_direct_ops, mdio_ops, +cphy_init (phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops, SUPPORTED_10000baseT_Full |SUPPORTED_AUI |SUPPORTED_TP ,"10GBASE-CX4" );return 0 ;
PATCH 154/165 mac80211: fix supported rates IE if AP doesnt give us its rates
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Stanislaw Gruszka <[email protected]>
commit 76f273640134f3eb8257179cd5b3bc6ba5fe4a96 upstream.
If AP do not provide us supported rates before assiociation, send all rates we are supporting instead of empty information element.
v1 -> v2: Add comment.
--- net/mac80211/mlme.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
net/mac80211/mlme.c +11 -6
@@ -269,12 +269,6 @@ static void ieee80211_send_assoc(structif (wk->bss->wmm_used) wmm =1 ; -/* get all rates supported by the device and the AP as -* some APs don't like getting a superset of their rates -* in the association request (e.g. D-Link DAP 1353 in -* b-only mode) */ - rates_len =ieee80211_compatible_rates (wk->bss, sband, &rates); -if ((wk->bss->cbss.capability &WLAN_CAPABILITY_SPECTRUM_MGMT ) && (local->hw.flags &IEEE80211_HW_SPECTRUM_MGMT )) capab |=WLAN_CAPABILITY_SPECTRUM_MGMT ;
@@ -309,6 +303,17 @@ static void ieee80211_send_assoc(struct *pos++ = wk->ssid_len;memcpy (pos, wk->ssid, wk->ssid_len); +if (wk->bss->supp_rates_len) { +/* get all rates supported by the device and the AP as +* some APs don't like getting a superset of their rates +* in the association request (e.g. D-Link DAP 1353 in +* b-only mode) */ + rates_len =ieee80211_compatible_rates (wk->bss, sband, &rates); + }else { + rates = ~0 ; + rates_len = sband->n_bitrates; + } +/* add all rates which were marked to be used above */ supp_rates_len = rates_len;if (supp_rates_len >8 )
PATCH 155/165 V4L/DVB: uvcvideo: Add support for unbranded Arkmicro 18ec:3290 webcams
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Laurent Pinchart <[email protected]>
commit 1e4d05bc95a0fe2972c5c91ed45466587d07cd2c upstream.
The camera requires the PROBE_DEF quirk. Add a corresponding entry in the device IDs list.
--- drivers/media/video/uvc/uvc_driver.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/media/video/uvc/uvc_driver.c +9 -0
@@ -2112,6 +2112,15 @@ static struct usb_device_id uvc_ids[] = .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX }, +/* Arkmicro unbranded */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x18ec, + .idProduct = 0x3290, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_DEF }, /* Bodelin ProScopeHR */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |USB_DEVICE_ID_MATCH_DEV_HI
PATCH 156/165 V4L/DVB: uvcvideo: Add support for Packard Bell EasyNote MX52 integrated webcam
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Laurent Pinchart <[email protected]>
commit f129b03ba272c86c42ad476684caa0d6109cb383 upstream.
The camera requires the STREAM_NO_FID quirk. Add a corresponding entry in the device IDs list.
--- drivers/media/video/uvc/uvc_driver.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/media/video/uvc/uvc_driver.c +9 -0
@@ -2048,6 +2048,15 @@ static struct usb_device_id uvc_ids[] = .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_STREAM_NO_FID }, +/* Syntek (Packard Bell EasyNote MX52 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x174f, + .idProduct = 0x8a12, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_STREAM_NO_FID }, /* Syntek (Asus F9SG) */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
PATCH 157/165 V4L/DVB: uvcvideo: Add support for V4L2_PIX_FMT_Y16
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Laurent Pinchart <[email protected]>
commit 61421206833a4085d9bdf35b2b84cd9a67dfdfac upstream.
The Miricle 307K (17dc:0202) camera reports a 16-bit greyscale format, support it in the driver.
--- drivers/media/video/uvc/uvc_driver.c | 7 ++++++- drivers/media/video/uvc/uvcvideo.h | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-)
drivers/media/video/uvc/uvc_driver.c +6 -1
@@ -83,11 +83,16 @@ static struct uvc_format_desc uvc_fmts[] .fcc = V4L2_PIX_FMT_UYVY, }, { - .name = "Greyscale", + .name = "Greyscale (8-bit)", .guid = UVC_GUID_FORMAT_Y800, .fcc = V4L2_PIX_FMT_GREY, }, { + .name = "Greyscale (16-bit)", + .guid = UVC_GUID_FORMAT_Y16, + .fcc = V4L2_PIX_FMT_Y16, + }, + { .name = "RGB Bayer", .guid = UVC_GUID_FORMAT_BY8, .fcc = V4L2_PIX_FMT_SBGGR8,
drivers/media/video/uvc/uvcvideo.h +3 -1
@@ -127,11 +127,13 @@ struct uvc_xu_control {#define UVC_GUID_FORMAT_Y800 \ { 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_Y16 \ + { 'Y', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}#define UVC_GUID_FORMAT_BY8 \ { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -/* ------------------------------------------------------------------------ * Driver specific constants. */
PATCH 158/165 iwlagn: verify flow id in compressed BA packet
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Shanyu Zhao <[email protected]>
commit b561e8274f75831ee87e4ea378cbb1f9f050a51a upstream.
The flow id (scd_flow) in a compressed BA packet should match the txq_id of the queue from which the aggregated packets were sent. However, in some hardware like the 1000 series, sometimes the flow id is 0 for the txq_id (10 to 19). This can cause the annoying message:
[ 2213.306191] iwlagn 0000:01:00.0: Received BA when not expected [ 2213.310178] iwlagn 0000:01:00.0: Read index for DMA queue txq id (0),
index 5, is out of range [0-256] 7 7.
And even worse, if agg->wait_for_ba is true when the bad BA is arriving, this can cause system hang due to NULL pointer dereference because the code is operating in a wrong tx queue!
--- drivers/net/wireless/iwlwifi/iwl-tx.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/wireless/iwlwifi/iwl-tx.c +5 -0
@@ -1479,6 +1479,11 @@ void iwl_rx_reply_compressed_ba(struct i sta_id = ba_resp->sta_id; tid = ba_resp->tid; agg = &priv->stations[sta_id].tid[tid].agg; +if (unlikely (agg->txq_id != scd_flow)) { +IWL_ERR (priv,"BA scd_flow %d does not match txq_id %d\n" , + scd_flow, agg->txq_id); +return ; + }/* Find index just before block-ack window */ index =iwl_queue_dec_wrap (ba_resp_scd_ssn &0xff , txq->q.n_bd);
PATCH 159/165 kbuild: Fix modpost segfault
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Krzysztof Halasa <[email protected]>
commit 1c938663d58b5b2965976a6f54cc51b5d6f691aa upstream.
Quoted 4 lines · Alan
program:
/home/alan/GitTrees/linux-2.6-mid-ref/scripts/mod/modpost-o Module.symvers -S vmlinux.oProgram received signal SIGSEGV, Segmentation fault.
It just hit me.
It's the offset calculation in reloc_location() which overflows:
return (void *)elf->hdr + sechdrs[section].sh_offset +
(r->r_offset - sechdrs[section].sh_addr);E.g. for the first rodata r entry:r->r_offset < sechdrs[section].sh_addr
and the expression in the parenthesis produces 0xFFFFFFE0 or something equally wise.
--- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/mod/modpost.c +1 -1
@@ -1311,7 +1311,7 @@ static unsigned int *reloc_location(struint section = sechdr->sh_info;return (void *)elf->hdr + sechdrs[section].sh_offset + - (r->r_offset - sechdrs[section].sh_addr); + r->r_offset - sechdrs[section].sh_addr; }static int addend_386_rel (struct elf_info *elf,Elf_Shdr *sechdr,Elf_Rela *r)
PATCH 160/165 eeepc-laptop: check wireless hotplug events
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alan Jenkins <[email protected]>
commit bc9d24a3aeb1532fc3e234907a8b6d671f7ed68f upstream.
Before we mark the wireless device as unplugged, check PCI config space to see whether the wireless device is really disabled (and vice versa). This works around newer models which don't want the hotplug code, where we end up disabling the wired network device.
My old 701 still works correctly with this. I can also simulate an afflicted model by changing the hardcoded PCI bus/slot number in the driver, and it seems to work nicely (although it is a bit noisy).
In future this type of hotplug support will be implemented by the PCI core. The existing blacklist and the new warning message will be removed at that point.
--- drivers/platform/x86/eeepc-laptop.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
drivers/platform/x86/eeepc-laptop.c +18 -0
@@ -752,6 +752,8 @@ static void eeepc_rfkill_hotplug(void)struct pci_dev *dev;struct pci_bus *bus;bool blocked =eeepc_wlan_rfkill_blocked (); +bool absent; +u32 l;if (ehotk->wlan_rfkill)rfkill_set_sw_state (ehotk->wlan_rfkill, blocked);
@@ -765,6 +767,22 @@ static void eeepc_rfkill_hotplug(void) goto out_unlock; } +if (pci_bus_read_config_dword (bus,0 ,PCI_VENDOR_ID , &l)) { +pr_err ("Unable to read PCI config space?\n" ); + goto out_unlock; + } + absent = (l ==0xffffffff ); + +if (blocked != absent) { +pr_warning ("BIOS says wireless lan is %s, " +"but the pci device is %s\n" , + blocked ?"blocked" :"unblocked" , + absent ?"absent" :"present" ); +pr_warning ("skipped wireless hotplug as probably " +"inappropriate for this model\n" ); + goto out_unlock; + } +if (!blocked) { dev =pci_get_slot (bus,0 );if (dev) {
PATCH 161/165 Fix spinaphore down_spin()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Tony Luck <[email protected]>
commit b70f4e85bfc4d7000036355b714a92d5c574f1be upstream.
Typo in down_spin() meant it only read the low 32 bits of the "serve" value, instead of the full 64 bits. This results in the system hanging when the values in ticket/serve get larger than 32-bits. A big enough system running the right test can hit this in a just a few hours.
Broken since 883a3acf5b0d4782ac35981227a0d094e8b44850
[IA64] Re-implement spinaphores using ticket lock concepts
Reported via IRC by Bjorn Helgaas
--- arch/ia64/mm/tlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/ia64/mm/tlb.c +1 -1
@@ -120,7 +120,7 @@ static inline void down_spin(struct spinia64_invala ();for (;;) { - asmvolatile ("ld4.c.nc %0=[%1]" :"=r" (serve) :"r" (&ss->serve) :"memory" ); + asmvolatile ("ld8.c.nc %0=[%1]" :"=r" (serve) :"r" (&ss->serve) :"memory" );if (time_before (t, serve))return ;cpu_relax ();