--- /dev/null
+From 9fe678fa2feb4aaac0b4220de63e1b7f8ccebae6 Mon Sep 17 00:00:00 2001
+From: Clifton Barnes <cabarnes@indesign-llc.com>
+Date: Wed, 2 Nov 2011 13:39:52 -0700
+Subject: drivers/power/ds2780_battery.c: add a nolock function to w1 interface
+
+From: Clifton Barnes <cabarnes@indesign-llc.com>
+
+commit 9fe678fa2feb4aaac0b4220de63e1b7f8ccebae6 upstream.
+
+Adds a nolock function to the w1 interface to avoid locking the
+mutex if needed.
+
+Signed-off-by: Clifton Barnes <cabarnes@indesign-llc.com>
+Cc: Evgeniy Polyakov <zbr@ioremap.net>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/w1/slaves/w1_ds2780.c | 48 ++++++++++++++++++++++++++++++------------
+ drivers/w1/slaves/w1_ds2780.h | 2 +
+ 2 files changed, 37 insertions(+), 13 deletions(-)
+
+--- a/drivers/w1/slaves/w1_ds2780.c
++++ b/drivers/w1/slaves/w1_ds2780.c
+@@ -26,20 +26,14 @@
+ #include "../w1_family.h"
+ #include "w1_ds2780.h"
+
+-int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count,
+- int io)
++static int w1_ds2780_do_io(struct device *dev, char *buf, int addr,
++ size_t count, int io)
+ {
+ struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+
+- if (!dev)
+- return -ENODEV;
+-
+- mutex_lock(&sl->master->mutex);
++ if (addr > DS2780_DATA_SIZE || addr < 0)
++ return 0;
+
+- if (addr > DS2780_DATA_SIZE || addr < 0) {
+- count = 0;
+- goto out;
+- }
+ count = min_t(int, count, DS2780_DATA_SIZE - addr);
+
+ if (w1_reset_select_slave(sl) == 0) {
+@@ -47,7 +41,6 @@ int w1_ds2780_io(struct device *dev, cha
+ w1_write_8(sl->master, W1_DS2780_WRITE_DATA);
+ w1_write_8(sl->master, addr);
+ w1_write_block(sl->master, buf, count);
+- /* XXX w1_write_block returns void, not n_written */
+ } else {
+ w1_write_8(sl->master, W1_DS2780_READ_DATA);
+ w1_write_8(sl->master, addr);
+@@ -55,13 +48,42 @@ int w1_ds2780_io(struct device *dev, cha
+ }
+ }
+
+-out:
++ return count;
++}
++
++int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count,
++ int io)
++{
++ struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
++ int ret;
++
++ if (!dev)
++ return -ENODEV;
++
++ mutex_lock(&sl->master->mutex);
++
++ ret = w1_ds2780_do_io(dev, buf, addr, count, io);
++
+ mutex_unlock(&sl->master->mutex);
+
+- return count;
++ return ret;
+ }
+ EXPORT_SYMBOL(w1_ds2780_io);
+
++int w1_ds2780_io_nolock(struct device *dev, char *buf, int addr, size_t count,
++ int io)
++{
++ int ret;
++
++ if (!dev)
++ return -ENODEV;
++
++ ret = w1_ds2780_do_io(dev, buf, addr, count, io);
++
++ return ret;
++}
++EXPORT_SYMBOL(w1_ds2780_io_nolock);
++
+ int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd)
+ {
+ struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+--- a/drivers/w1/slaves/w1_ds2780.h
++++ b/drivers/w1/slaves/w1_ds2780.h
+@@ -124,6 +124,8 @@
+
+ extern int w1_ds2780_io(struct device *dev, char *buf, int addr, size_t count,
+ int io);
++extern int w1_ds2780_io_nolock(struct device *dev, char *buf, int addr,
++ size_t count, int io);
+ extern int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd);
+
+ #endif /* !_W1_DS2780_H */
--- /dev/null
+From 853eee72f74f449797f0500ea19fc1bf497428d8 Mon Sep 17 00:00:00 2001
+From: Clifton Barnes <cabarnes@indesign-llc.com>
+Date: Wed, 2 Nov 2011 13:39:50 -0700
+Subject: drivers/power/ds2780_battery.c: create central point for calling w1 interface
+
+From: Clifton Barnes <cabarnes@indesign-llc.com>
+
+commit 853eee72f74f449797f0500ea19fc1bf497428d8 upstream.
+
+Simply creates one point to call the w1 interface.
+
+Signed-off-by: Clifton Barnes <cabarnes@indesign-llc.com>
+Cc: Evgeniy Polyakov <zbr@ioremap.net>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/power/ds2780_battery.c | 77 ++++++++++++++++++++++-------------------
+ 1 file changed, 42 insertions(+), 35 deletions(-)
+
+--- a/drivers/power/ds2780_battery.c
++++ b/drivers/power/ds2780_battery.c
+@@ -49,8 +49,8 @@ enum current_types {
+ static const char model[] = "DS2780";
+ static const char manufacturer[] = "Maxim/Dallas";
+
+-static inline struct ds2780_device_info *to_ds2780_device_info(
+- struct power_supply *psy)
++static inline struct ds2780_device_info *
++to_ds2780_device_info(struct power_supply *psy)
+ {
+ return container_of(psy, struct ds2780_device_info, bat);
+ }
+@@ -60,17 +60,25 @@ static inline struct power_supply *to_po
+ return dev_get_drvdata(dev);
+ }
+
+-static inline int ds2780_read8(struct device *dev, u8 *val, int addr)
++static inline int ds2780_battery_io(struct ds2780_device_info *dev_info,
++ char *buf, int addr, size_t count, int io)
+ {
+- return w1_ds2780_io(dev, val, addr, sizeof(u8), 0);
++ return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io);
+ }
+
+-static int ds2780_read16(struct device *dev, s16 *val, int addr)
++static inline int ds2780_read8(struct ds2780_device_info *dev_info, u8 *val,
++ int addr)
++{
++ return ds2780_battery_io(dev_info, val, addr, sizeof(u8), 0);
++}
++
++static int ds2780_read16(struct ds2780_device_info *dev_info, s16 *val,
++ int addr)
+ {
+ int ret;
+ u8 raw[2];
+
+- ret = w1_ds2780_io(dev, raw, addr, sizeof(u8) * 2, 0);
++ ret = ds2780_battery_io(dev_info, raw, addr, sizeof(raw), 0);
+ if (ret < 0)
+ return ret;
+
+@@ -79,16 +87,16 @@ static int ds2780_read16(struct device *
+ return 0;
+ }
+
+-static inline int ds2780_read_block(struct device *dev, u8 *val, int addr,
+- size_t count)
++static inline int ds2780_read_block(struct ds2780_device_info *dev_info,
++ u8 *val, int addr, size_t count)
+ {
+- return w1_ds2780_io(dev, val, addr, count, 0);
++ return ds2780_battery_io(dev_info, val, addr, count, 0);
+ }
+
+-static inline int ds2780_write(struct device *dev, u8 *val, int addr,
+- size_t count)
++static inline int ds2780_write(struct ds2780_device_info *dev_info, u8 *val,
++ int addr, size_t count)
+ {
+- return w1_ds2780_io(dev, val, addr, count, 1);
++ return ds2780_battery_io(dev_info, val, addr, count, 1);
+ }
+
+ static inline int ds2780_store_eeprom(struct device *dev, int addr)
+@@ -122,7 +130,7 @@ static int ds2780_set_sense_register(str
+ {
+ int ret;
+
+- ret = ds2780_write(dev_info->w1_dev, &conductance,
++ ret = ds2780_write(dev_info, &conductance,
+ DS2780_RSNSP_REG, sizeof(u8));
+ if (ret < 0)
+ return ret;
+@@ -134,7 +142,7 @@ static int ds2780_set_sense_register(str
+ static int ds2780_get_rsgain_register(struct ds2780_device_info *dev_info,
+ u16 *rsgain)
+ {
+- return ds2780_read16(dev_info->w1_dev, rsgain, DS2780_RSGAIN_MSB_REG);
++ return ds2780_read16(dev_info, rsgain, DS2780_RSGAIN_MSB_REG);
+ }
+
+ /* Set RSGAIN value from 0 to 1.999 in steps of 0.001 */
+@@ -144,8 +152,8 @@ static int ds2780_set_rsgain_register(st
+ int ret;
+ u8 raw[] = {rsgain >> 8, rsgain & 0xFF};
+
+- ret = ds2780_write(dev_info->w1_dev, raw,
+- DS2780_RSGAIN_MSB_REG, sizeof(u8) * 2);
++ ret = ds2780_write(dev_info, raw,
++ DS2780_RSGAIN_MSB_REG, sizeof(raw));
+ if (ret < 0)
+ return ret;
+
+@@ -167,7 +175,7 @@ static int ds2780_get_voltage(struct ds2
+ * Bits 2 - 0 of the voltage value are in bits 7 - 5 of the
+ * voltage LSB register
+ */
+- ret = ds2780_read16(dev_info->w1_dev, &voltage_raw,
++ ret = ds2780_read16(dev_info, &voltage_raw,
+ DS2780_VOLT_MSB_REG);
+ if (ret < 0)
+ return ret;
+@@ -196,7 +204,7 @@ static int ds2780_get_temperature(struct
+ * Bits 2 - 0 of the temperature value are in bits 7 - 5 of the
+ * temperature LSB register
+ */
+- ret = ds2780_read16(dev_info->w1_dev, &temperature_raw,
++ ret = ds2780_read16(dev_info, &temperature_raw,
+ DS2780_TEMP_MSB_REG);
+ if (ret < 0)
+ return ret;
+@@ -222,13 +230,13 @@ static int ds2780_get_current(struct ds2
+ * The units of measurement for current are dependent on the value of
+ * the sense resistor.
+ */
+- ret = ds2780_read8(dev_info->w1_dev, &sense_res_raw, DS2780_RSNSP_REG);
++ ret = ds2780_read8(dev_info, &sense_res_raw, DS2780_RSNSP_REG);
+ if (ret < 0)
+ return ret;
+
+ if (sense_res_raw == 0) {
+ dev_err(dev_info->dev, "sense resistor value is 0\n");
+- return -ENXIO;
++ return -EINVAL;
+ }
+ sense_res = 1000 / sense_res_raw;
+
+@@ -248,7 +256,7 @@ static int ds2780_get_current(struct ds2
+ * Bits 7 - 0 of the current value are in bits 7 - 0 of the current
+ * LSB register
+ */
+- ret = ds2780_read16(dev_info->w1_dev, ¤t_raw, reg_msb);
++ ret = ds2780_read16(dev_info, ¤t_raw, reg_msb);
+ if (ret < 0)
+ return ret;
+
+@@ -267,7 +275,7 @@ static int ds2780_get_accumulated_curren
+ * The units of measurement for accumulated current are dependent on
+ * the value of the sense resistor.
+ */
+- ret = ds2780_read8(dev_info->w1_dev, &sense_res_raw, DS2780_RSNSP_REG);
++ ret = ds2780_read8(dev_info, &sense_res_raw, DS2780_RSNSP_REG);
+ if (ret < 0)
+ return ret;
+
+@@ -285,7 +293,7 @@ static int ds2780_get_accumulated_curren
+ * Bits 7 - 0 of the ACR value are in bits 7 - 0 of the ACR
+ * LSB register
+ */
+- ret = ds2780_read16(dev_info->w1_dev, ¤t_raw, DS2780_ACR_MSB_REG);
++ ret = ds2780_read16(dev_info, ¤t_raw, DS2780_ACR_MSB_REG);
+ if (ret < 0)
+ return ret;
+
+@@ -299,7 +307,7 @@ static int ds2780_get_capacity(struct ds
+ int ret;
+ u8 raw;
+
+- ret = ds2780_read8(dev_info->w1_dev, &raw, DS2780_RARC_REG);
++ ret = ds2780_read8(dev_info, &raw, DS2780_RARC_REG);
+ if (ret < 0)
+ return ret;
+
+@@ -345,7 +353,7 @@ static int ds2780_get_charge_now(struct
+ * Bits 7 - 0 of the RAAC value are in bits 7 - 0 of the RAAC
+ * LSB register
+ */
+- ret = ds2780_read16(dev_info->w1_dev, &charge_raw, DS2780_RAAC_MSB_REG);
++ ret = ds2780_read16(dev_info, &charge_raw, DS2780_RAAC_MSB_REG);
+ if (ret < 0)
+ return ret;
+
+@@ -356,7 +364,7 @@ static int ds2780_get_charge_now(struct
+ static int ds2780_get_control_register(struct ds2780_device_info *dev_info,
+ u8 *control_reg)
+ {
+- return ds2780_read8(dev_info->w1_dev, control_reg, DS2780_CONTROL_REG);
++ return ds2780_read8(dev_info, control_reg, DS2780_CONTROL_REG);
+ }
+
+ static int ds2780_set_control_register(struct ds2780_device_info *dev_info,
+@@ -364,7 +372,7 @@ static int ds2780_set_control_register(s
+ {
+ int ret;
+
+- ret = ds2780_write(dev_info->w1_dev, &control_reg,
++ ret = ds2780_write(dev_info, &control_reg,
+ DS2780_CONTROL_REG, sizeof(u8));
+ if (ret < 0)
+ return ret;
+@@ -503,7 +511,7 @@ static ssize_t ds2780_get_sense_resistor
+ struct power_supply *psy = to_power_supply(dev);
+ struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+
+- ret = ds2780_read8(dev_info->w1_dev, &sense_resistor, DS2780_RSNSP_REG);
++ ret = ds2780_read8(dev_info, &sense_resistor, DS2780_RSNSP_REG);
+ if (ret < 0)
+ return ret;
+
+@@ -584,7 +592,7 @@ static ssize_t ds2780_get_pio_pin(struct
+ struct power_supply *psy = to_power_supply(dev);
+ struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+
+- ret = ds2780_read8(dev_info->w1_dev, &sfr, DS2780_SFR_REG);
++ ret = ds2780_read8(dev_info, &sfr, DS2780_SFR_REG);
+ if (ret < 0)
+ return ret;
+
+@@ -611,7 +619,7 @@ static ssize_t ds2780_set_pio_pin(struct
+ return -EINVAL;
+ }
+
+- ret = ds2780_write(dev_info->w1_dev, &new_setting,
++ ret = ds2780_write(dev_info, &new_setting,
+ DS2780_SFR_REG, sizeof(u8));
+ if (ret < 0)
+ return ret;
+@@ -632,7 +640,7 @@ static ssize_t ds2780_read_param_eeprom_
+ DS2780_EEPROM_BLOCK1_END -
+ DS2780_EEPROM_BLOCK1_START + 1 - off);
+
+- return ds2780_read_block(dev_info->w1_dev, buf,
++ return ds2780_read_block(dev_info, buf,
+ DS2780_EEPROM_BLOCK1_START + off, count);
+ }
+
+@@ -650,7 +658,7 @@ static ssize_t ds2780_write_param_eeprom
+ DS2780_EEPROM_BLOCK1_END -
+ DS2780_EEPROM_BLOCK1_START + 1 - off);
+
+- ret = ds2780_write(dev_info->w1_dev, buf,
++ ret = ds2780_write(dev_info, buf,
+ DS2780_EEPROM_BLOCK1_START + off, count);
+ if (ret < 0)
+ return ret;
+@@ -685,9 +693,8 @@ static ssize_t ds2780_read_user_eeprom_b
+ DS2780_EEPROM_BLOCK0_END -
+ DS2780_EEPROM_BLOCK0_START + 1 - off);
+
+- return ds2780_read_block(dev_info->w1_dev, buf,
++ return ds2780_read_block(dev_info, buf,
+ DS2780_EEPROM_BLOCK0_START + off, count);
+-
+ }
+
+ static ssize_t ds2780_write_user_eeprom_bin(struct file *filp,
+@@ -704,7 +711,7 @@ static ssize_t ds2780_write_user_eeprom_
+ DS2780_EEPROM_BLOCK0_END -
+ DS2780_EEPROM_BLOCK0_START + 1 - off);
+
+- ret = ds2780_write(dev_info->w1_dev, buf,
++ ret = ds2780_write(dev_info, buf,
+ DS2780_EEPROM_BLOCK0_START + off, count);
+ if (ret < 0)
+ return ret;
--- /dev/null
+From 0e053fcbbbc4d945247cb32cad2767b483cb65f8 Mon Sep 17 00:00:00 2001
+From: Clifton Barnes <cabarnes@indesign-llc.com>
+Date: Wed, 2 Nov 2011 13:39:55 -0700
+Subject: drivers/power/ds2780_battery.c: fix deadlock upon insertion and removal
+
+From: Clifton Barnes <cabarnes@indesign-llc.com>
+
+commit 0e053fcbbbc4d945247cb32cad2767b483cb65f8 upstream.
+
+Fixes the deadlock when inserting and removing the ds2780.
+
+Signed-off-by: Clifton Barnes <cabarnes@indesign-llc.com>
+Cc: Evgeniy Polyakov <zbr@ioremap.net>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/power/ds2780_battery.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/power/ds2780_battery.c
++++ b/drivers/power/ds2780_battery.c
+@@ -39,6 +39,7 @@ struct ds2780_device_info {
+ struct device *dev;
+ struct power_supply bat;
+ struct device *w1_dev;
++ struct task_struct *mutex_holder;
+ };
+
+ enum current_types {
+@@ -63,6 +64,9 @@ static inline struct power_supply *to_po
+ static inline int ds2780_battery_io(struct ds2780_device_info *dev_info,
+ char *buf, int addr, size_t count, int io)
+ {
++ if (dev_info->mutex_holder == current)
++ return w1_ds2780_io_nolock(dev_info->w1_dev, buf, addr, count, io);
++ else
+ return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io);
+ }
+
+@@ -775,6 +779,7 @@ static int __devinit ds2780_battery_prob
+ dev_info->bat.properties = ds2780_battery_props;
+ dev_info->bat.num_properties = ARRAY_SIZE(ds2780_battery_props);
+ dev_info->bat.get_property = ds2780_battery_get_property;
++ dev_info->mutex_holder = current;
+
+ ret = power_supply_register(&pdev->dev, &dev_info->bat);
+ if (ret) {
+@@ -804,6 +809,8 @@ static int __devinit ds2780_battery_prob
+ goto fail_remove_bin_file;
+ }
+
++ dev_info->mutex_holder = NULL;
++
+ return 0;
+
+ fail_remove_bin_file:
+@@ -823,6 +830,8 @@ static int __devexit ds2780_battery_remo
+ {
+ struct ds2780_device_info *dev_info = platform_get_drvdata(pdev);
+
++ dev_info->mutex_holder = current;
++
+ /* remove attributes */
+ sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group);
+
--- /dev/null
+From 1cd9f0976aa4606db8d6e3dc3edd0aca8019372a Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 31 Aug 2011 11:54:51 -0400
+Subject: ext2,ext3,ext4: don't inherit APPEND_FL or IMMUTABLE_FL for new inodes
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 1cd9f0976aa4606db8d6e3dc3edd0aca8019372a upstream.
+
+This doesn't make much sense, and it exposes a bug in the kernel where
+attempts to create a new file in an append-only directory using
+O_CREAT will fail (but still leave a zero-length file). This was
+discovered when xfstests #79 was generalized so it could run on all
+file systems.
+
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/ext4.h | 3 +--
+ include/linux/ext2_fs.h | 4 ++--
+ include/linux/ext3_fs.h | 4 ++--
+ 3 files changed, 5 insertions(+), 6 deletions(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -358,8 +358,7 @@ struct flex_groups {
+
+ /* Flags that should be inherited by new inodes from their parent. */
+ #define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\
+- EXT4_SYNC_FL | EXT4_IMMUTABLE_FL | EXT4_APPEND_FL |\
+- EXT4_NODUMP_FL | EXT4_NOATIME_FL |\
++ EXT4_SYNC_FL | EXT4_NODUMP_FL | EXT4_NOATIME_FL |\
+ EXT4_NOCOMPR_FL | EXT4_JOURNAL_DATA_FL |\
+ EXT4_NOTAIL_FL | EXT4_DIRSYNC_FL)
+
+--- a/include/linux/ext2_fs.h
++++ b/include/linux/ext2_fs.h
+@@ -197,8 +197,8 @@ struct ext2_group_desc
+
+ /* Flags that should be inherited by new inodes from their parent. */
+ #define EXT2_FL_INHERITED (EXT2_SECRM_FL | EXT2_UNRM_FL | EXT2_COMPR_FL |\
+- EXT2_SYNC_FL | EXT2_IMMUTABLE_FL | EXT2_APPEND_FL |\
+- EXT2_NODUMP_FL | EXT2_NOATIME_FL | EXT2_COMPRBLK_FL|\
++ EXT2_SYNC_FL | EXT2_NODUMP_FL |\
++ EXT2_NOATIME_FL | EXT2_COMPRBLK_FL |\
+ EXT2_NOCOMP_FL | EXT2_JOURNAL_DATA_FL |\
+ EXT2_NOTAIL_FL | EXT2_DIRSYNC_FL)
+
+--- a/include/linux/ext3_fs.h
++++ b/include/linux/ext3_fs.h
+@@ -180,8 +180,8 @@ struct ext3_group_desc
+
+ /* Flags that should be inherited by new inodes from their parent. */
+ #define EXT3_FL_INHERITED (EXT3_SECRM_FL | EXT3_UNRM_FL | EXT3_COMPR_FL |\
+- EXT3_SYNC_FL | EXT3_IMMUTABLE_FL | EXT3_APPEND_FL |\
+- EXT3_NODUMP_FL | EXT3_NOATIME_FL | EXT3_COMPRBLK_FL|\
++ EXT3_SYNC_FL | EXT3_NODUMP_FL |\
++ EXT3_NOATIME_FL | EXT3_COMPRBLK_FL |\
+ EXT3_NOCOMPR_FL | EXT3_JOURNAL_DATA_FL |\
+ EXT3_NOTAIL_FL | EXT3_DIRSYNC_FL)
+
--- /dev/null
+From 5930ea643805feb50a2f8383ae12eb6f10935e49 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 31 Aug 2011 12:02:51 -0400
+Subject: ext4: call ext4_handle_dirty_metadata with correct inode in ext4_dx_add_entry
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 5930ea643805feb50a2f8383ae12eb6f10935e49 upstream.
+
+ext4_dx_add_entry manipulates bh2 and frames[0].bh, which are two buffer_heads
+that point to directory blocks assigned to the directory inode. However, the
+function calls ext4_handle_dirty_metadata with the inode of the file that's
+being added to the directory, not the directory inode itself. Therefore,
+correct the code to dirty the directory buffers with the directory inode, not
+the file inode.
+
+Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/namei.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -1586,7 +1586,7 @@ static int ext4_dx_add_entry(handle_t *h
+ dxtrace(dx_show_index("node", frames[1].entries));
+ dxtrace(dx_show_index("node",
+ ((struct dx_node *) bh2->b_data)->entries));
+- err = ext4_handle_dirty_metadata(handle, inode, bh2);
++ err = ext4_handle_dirty_metadata(handle, dir, bh2);
+ if (err)
+ goto journal_error;
+ brelse (bh2);
+@@ -1612,7 +1612,7 @@ static int ext4_dx_add_entry(handle_t *h
+ if (err)
+ goto journal_error;
+ }
+- err = ext4_handle_dirty_metadata(handle, inode, frames[0].bh);
++ err = ext4_handle_dirty_metadata(handle, dir, frames[0].bh);
+ if (err) {
+ ext4_std_error(inode->i_sb, err);
+ goto cleanup;
--- /dev/null
+From f9287c1f2d329f4d78a3bbc9cf0db0ebae6f146a Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@us.ibm.com>
+Date: Wed, 31 Aug 2011 12:00:51 -0400
+Subject: ext4: ext4_mkdir should dirty dir_block with newly created directory inode
+
+From: "Darrick J. Wong" <djwong@us.ibm.com>
+
+commit f9287c1f2d329f4d78a3bbc9cf0db0ebae6f146a upstream.
+
+ext4_mkdir calls ext4_handle_dirty_metadata with dir_block and the inode "dir".
+Unfortunately, dir_block belongs to the newly created directory (which is
+"inode"), not the parent directory (which is "dir"). Fix the incorrect
+association.
+
+Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/namei.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -1863,7 +1863,7 @@ retry:
+ ext4_set_de_type(dir->i_sb, de, S_IFDIR);
+ inode->i_nlink = 2;
+ BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
+- err = ext4_handle_dirty_metadata(handle, dir, dir_block);
++ err = ext4_handle_dirty_metadata(handle, inode, dir_block);
+ if (err)
+ goto out_clear_inode;
+ err = ext4_mark_inode_dirty(handle, inode);
--- /dev/null
+From bcaa992975041e40449be8c010c26192b8c8b409 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@us.ibm.com>
+Date: Wed, 31 Aug 2011 11:58:51 -0400
+Subject: ext4: ext4_rename should dirty dir_bh with the correct directory
+
+From: "Darrick J. Wong" <djwong@us.ibm.com>
+
+commit bcaa992975041e40449be8c010c26192b8c8b409 upstream.
+
+When ext4_rename performs a directory rename (move), dir_bh is a
+buffer that is modified to update the '..' link in the directory being
+moved (old_inode). However, ext4_handle_dirty_metadata is called with
+the old parent directory inode (old_dir) and dir_bh, which is
+incorrect because dir_bh does not belong to the parent inode. Fix
+this error.
+
+Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/namei.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2530,7 +2530,7 @@ static int ext4_rename(struct inode *old
+ PARENT_INO(dir_bh->b_data, new_dir->i_sb->s_blocksize) =
+ cpu_to_le32(new_dir->i_ino);
+ BUFFER_TRACE(dir_bh, "call ext4_handle_dirty_metadata");
+- retval = ext4_handle_dirty_metadata(handle, old_dir, dir_bh);
++ retval = ext4_handle_dirty_metadata(handle, old_inode, dir_bh);
+ if (retval) {
+ ext4_std_error(old_dir->i_sb, retval);
+ goto end_rename;
--- /dev/null
+From 6d6a435190bdf2e04c9465cde5bdc3ac68cf11a4 Mon Sep 17 00:00:00 2001
+From: Eric Sandeen <sandeen@redhat.com>
+Date: Sat, 29 Oct 2011 10:15:35 -0400
+Subject: ext4: fix race in xattr block allocation path
+
+From: Eric Sandeen <sandeen@redhat.com>
+
+commit 6d6a435190bdf2e04c9465cde5bdc3ac68cf11a4 upstream.
+
+Ceph users reported that when using Ceph on ext4, the filesystem
+would often become corrupted, containing inodes with incorrect
+i_blocks counters.
+
+I managed to reproduce this with a very hacked-up "streamtest"
+binary from the Ceph tree.
+
+Ceph is doing a lot of xattr writes, to out-of-inode blocks.
+There is also another thread which does sync_file_range and close,
+of the same files. The problem appears to happen due to this race:
+
+sync/flush thread xattr-set thread
+----------------- ----------------
+
+do_writepages ext4_xattr_set
+ext4_da_writepages ext4_xattr_set_handle
+mpage_da_map_blocks ext4_xattr_block_set
+ set DELALLOC_RESERVE
+ ext4_new_meta_blocks
+ ext4_mb_new_blocks
+ if (!i_delalloc_reserved_flag)
+ vfs_dq_alloc_block
+ext4_get_blocks
+ down_write(i_data_sem)
+ set i_delalloc_reserved_flag
+ ...
+ up_write(i_data_sem)
+ if (i_delalloc_reserved_flag)
+ vfs_dq_alloc_block_nofail
+
+
+In other words, the sync/flush thread pops in and sets
+i_delalloc_reserved_flag on the inode, which makes the xattr thread
+think that it's in a delalloc path in ext4_new_meta_blocks(),
+and add the block for a second time, after already having added
+it once in the !i_delalloc_reserved_flag case in ext4_mb_new_blocks
+
+The real problem is that we shouldn't be using the DELALLOC_RESERVED
+state flag, and instead we should be passing
+EXT4_GET_BLOCKS_DELALLOC_RESERVE down to ext4_map_blocks() instead of
+using an inode state flag. We'll fix this for now with using
+i_data_sem to prevent this race, but this is really not the right way
+to fix things.
+
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/xattr.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -820,8 +820,14 @@ inserted:
+ if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
+ goal = goal & EXT4_MAX_BLOCK_FILE_PHYS;
+
++ /*
++ * take i_data_sem because we will test
++ * i_delalloc_reserved_flag in ext4_mb_new_blocks
++ */
++ down_read((&EXT4_I(inode)->i_data_sem));
+ block = ext4_new_meta_blocks(handle, inode, goal, 0,
+ NULL, &error);
++ up_read((&EXT4_I(inode)->i_data_sem));
+ if (error)
+ goto cleanup;
+
--- /dev/null
+From fcbb5515825f1bb20b7a6f75ec48bee61416f879 Mon Sep 17 00:00:00 2001
+From: Yongqiang Yang <xiaoqiangnk@gmail.com>
+Date: Wed, 26 Oct 2011 05:00:19 -0400
+Subject: ext4: let ext4_page_mkwrite stop started handle in failure
+
+From: Yongqiang Yang <xiaoqiangnk@gmail.com>
+
+commit fcbb5515825f1bb20b7a6f75ec48bee61416f879 upstream.
+
+The started journal handle should be stopped in failure case.
+
+Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Acked-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/inode.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4416,6 +4416,7 @@ retry_alloc:
+ PAGE_CACHE_SIZE, NULL, do_journal_get_write_access)) {
+ unlock_page(page);
+ ret = VM_FAULT_SIGBUS;
++ ext4_journal_stop(handle);
+ goto out;
+ }
+ ext4_set_inode_state(inode, EXT4_STATE_JDATA);
--- /dev/null
+From 93b465c2e186d96fb90012ba0f9372eb9952e732 Mon Sep 17 00:00:00 2001
+From: Juan Gutierrez <jgutierrez@ti.com>
+Date: Tue, 6 Sep 2011 09:30:16 +0300
+Subject: hwspinlock/core: use a mutex to protect the radix tree
+
+From: Juan Gutierrez <jgutierrez@ti.com>
+
+commit 93b465c2e186d96fb90012ba0f9372eb9952e732 upstream.
+
+Since we're using non-atomic radix tree allocations, we
+should be protecting the tree using a mutex and not a
+spinlock.
+
+Non-atomic allocations and process context locking is good enough,
+as the tree is manipulated only when locks are registered/
+unregistered/requested/freed.
+
+The locks themselves are still protected by spinlocks of course,
+and mutexes are not involved in the locking/unlocking paths.
+
+Signed-off-by: Juan Gutierrez <jgutierrez@ti.com>
+[ohad@wizery.com: rewrite the commit log, #include mutex.h, add minor
+commentary]
+[ohad@wizery.com: update register/unregister parts in hwspinlock.txt]
+Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/hwspinlock.txt | 18 +++++---------
+ drivers/hwspinlock/hwspinlock_core.c | 45 +++++++++++++++--------------------
+ 2 files changed, 27 insertions(+), 36 deletions(-)
+
+--- a/Documentation/hwspinlock.txt
++++ b/Documentation/hwspinlock.txt
+@@ -39,23 +39,20 @@ independent, drivers.
+ in case an unused hwspinlock isn't available. Users of this
+ API will usually want to communicate the lock's id to the remote core
+ before it can be used to achieve synchronization.
+- Can be called from an atomic context (this function will not sleep) but
+- not from within interrupt context.
++ Should be called from a process context (might sleep).
+
+ struct hwspinlock *hwspin_lock_request_specific(unsigned int id);
+ - assign a specific hwspinlock id and return its address, or NULL
+ if that hwspinlock is already in use. Usually board code will
+ be calling this function in order to reserve specific hwspinlock
+ ids for predefined purposes.
+- Can be called from an atomic context (this function will not sleep) but
+- not from within interrupt context.
++ Should be called from a process context (might sleep).
+
+ int hwspin_lock_free(struct hwspinlock *hwlock);
+ - free a previously-assigned hwspinlock; returns 0 on success, or an
+ appropriate error code on failure (e.g. -EINVAL if the hwspinlock
+ is already free).
+- Can be called from an atomic context (this function will not sleep) but
+- not from within interrupt context.
++ Should be called from a process context (might sleep).
+
+ int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout);
+ - lock a previously-assigned hwspinlock with a timeout limit (specified in
+@@ -232,15 +229,14 @@ int hwspinlock_example2(void)
+
+ int hwspin_lock_register(struct hwspinlock *hwlock);
+ - to be called from the underlying platform-specific implementation, in
+- order to register a new hwspinlock instance. Can be called from an atomic
+- context (this function will not sleep) but not from within interrupt
+- context. Returns 0 on success, or appropriate error code on failure.
++ order to register a new hwspinlock instance. Should be called from
++ a process context (this function might sleep).
++ Returns 0 on success, or appropriate error code on failure.
+
+ struct hwspinlock *hwspin_lock_unregister(unsigned int id);
+ - to be called from the underlying vendor-specific implementation, in order
+ to unregister an existing (and unused) hwspinlock instance.
+- Can be called from an atomic context (will not sleep) but not from
+- within interrupt context.
++ Should be called from a process context (this function might sleep).
+ Returns the address of hwspinlock on success, or NULL on error (e.g.
+ if the hwspinlock is sill in use).
+
+--- a/drivers/hwspinlock/hwspinlock_core.c
++++ b/drivers/hwspinlock/hwspinlock_core.c
+@@ -26,6 +26,7 @@
+ #include <linux/radix-tree.h>
+ #include <linux/hwspinlock.h>
+ #include <linux/pm_runtime.h>
++#include <linux/mutex.h>
+
+ #include "hwspinlock_internal.h"
+
+@@ -52,10 +53,12 @@
+ static RADIX_TREE(hwspinlock_tree, GFP_KERNEL);
+
+ /*
+- * Synchronization of access to the tree is achieved using this spinlock,
++ * Synchronization of access to the tree is achieved using this mutex,
+ * as the radix-tree API requires that users provide all synchronisation.
++ * A mutex is needed because we're using non-atomic radix tree allocations.
+ */
+-static DEFINE_SPINLOCK(hwspinlock_tree_lock);
++static DEFINE_MUTEX(hwspinlock_tree_lock);
++
+
+ /**
+ * __hwspin_trylock() - attempt to lock a specific hwspinlock
+@@ -261,8 +264,7 @@ EXPORT_SYMBOL_GPL(__hwspin_unlock);
+ * This function should be called from the underlying platform-specific
+ * implementation, to register a new hwspinlock instance.
+ *
+- * Can be called from an atomic context (will not sleep) but not from
+- * within interrupt context.
++ * Should be called from a process context (might sleep)
+ *
+ * Returns 0 on success, or an appropriate error code on failure
+ */
+@@ -279,7 +281,7 @@ int hwspin_lock_register(struct hwspinlo
+
+ spin_lock_init(&hwlock->lock);
+
+- spin_lock(&hwspinlock_tree_lock);
++ mutex_lock(&hwspinlock_tree_lock);
+
+ ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock);
+ if (ret)
+@@ -293,7 +295,7 @@ int hwspin_lock_register(struct hwspinlo
+ WARN_ON(tmp != hwlock);
+
+ out:
+- spin_unlock(&hwspinlock_tree_lock);
++ mutex_unlock(&hwspinlock_tree_lock);
+ return ret;
+ }
+ EXPORT_SYMBOL_GPL(hwspin_lock_register);
+@@ -305,8 +307,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_register);
+ * This function should be called from the underlying platform-specific
+ * implementation, to unregister an existing (and unused) hwspinlock.
+ *
+- * Can be called from an atomic context (will not sleep) but not from
+- * within interrupt context.
++ * Should be called from a process context (might sleep)
+ *
+ * Returns the address of hwspinlock @id on success, or NULL on failure
+ */
+@@ -315,7 +316,7 @@ struct hwspinlock *hwspin_lock_unregiste
+ struct hwspinlock *hwlock = NULL;
+ int ret;
+
+- spin_lock(&hwspinlock_tree_lock);
++ mutex_lock(&hwspinlock_tree_lock);
+
+ /* make sure the hwspinlock is not in use (tag is set) */
+ ret = radix_tree_tag_get(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
+@@ -331,7 +332,7 @@ struct hwspinlock *hwspin_lock_unregiste
+ }
+
+ out:
+- spin_unlock(&hwspinlock_tree_lock);
++ mutex_unlock(&hwspinlock_tree_lock);
+ return hwlock;
+ }
+ EXPORT_SYMBOL_GPL(hwspin_lock_unregister);
+@@ -400,9 +401,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_get_id);
+ * to the remote core before it can be used for synchronization (to get the
+ * id of a given hwlock, use hwspin_lock_get_id()).
+ *
+- * Can be called from an atomic context (will not sleep) but not from
+- * within interrupt context (simply because there is no use case for
+- * that yet).
++ * Should be called from a process context (might sleep)
+ *
+ * Returns the address of the assigned hwspinlock, or NULL on error
+ */
+@@ -411,7 +410,7 @@ struct hwspinlock *hwspin_lock_request(v
+ struct hwspinlock *hwlock;
+ int ret;
+
+- spin_lock(&hwspinlock_tree_lock);
++ mutex_lock(&hwspinlock_tree_lock);
+
+ /* look for an unused lock */
+ ret = radix_tree_gang_lookup_tag(&hwspinlock_tree, (void **)&hwlock,
+@@ -431,7 +430,7 @@ struct hwspinlock *hwspin_lock_request(v
+ hwlock = NULL;
+
+ out:
+- spin_unlock(&hwspinlock_tree_lock);
++ mutex_unlock(&hwspinlock_tree_lock);
+ return hwlock;
+ }
+ EXPORT_SYMBOL_GPL(hwspin_lock_request);
+@@ -445,9 +444,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request);
+ * Usually early board code will be calling this function in order to
+ * reserve specific hwspinlock ids for predefined purposes.
+ *
+- * Can be called from an atomic context (will not sleep) but not from
+- * within interrupt context (simply because there is no use case for
+- * that yet).
++ * Should be called from a process context (might sleep)
+ *
+ * Returns the address of the assigned hwspinlock, or NULL on error
+ */
+@@ -456,7 +453,7 @@ struct hwspinlock *hwspin_lock_request_s
+ struct hwspinlock *hwlock;
+ int ret;
+
+- spin_lock(&hwspinlock_tree_lock);
++ mutex_lock(&hwspinlock_tree_lock);
+
+ /* make sure this hwspinlock exists */
+ hwlock = radix_tree_lookup(&hwspinlock_tree, id);
+@@ -482,7 +479,7 @@ struct hwspinlock *hwspin_lock_request_s
+ hwlock = NULL;
+
+ out:
+- spin_unlock(&hwspinlock_tree_lock);
++ mutex_unlock(&hwspinlock_tree_lock);
+ return hwlock;
+ }
+ EXPORT_SYMBOL_GPL(hwspin_lock_request_specific);
+@@ -495,9 +492,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request_sp
+ * Should only be called with an @hwlock that was retrieved from
+ * an earlier call to omap_hwspin_lock_request{_specific}.
+ *
+- * Can be called from an atomic context (will not sleep) but not from
+- * within interrupt context (simply because there is no use case for
+- * that yet).
++ * Should be called from a process context (might sleep)
+ *
+ * Returns 0 on success, or an appropriate error code on failure
+ */
+@@ -511,7 +506,7 @@ int hwspin_lock_free(struct hwspinlock *
+ return -EINVAL;
+ }
+
+- spin_lock(&hwspinlock_tree_lock);
++ mutex_lock(&hwspinlock_tree_lock);
+
+ /* make sure the hwspinlock is used */
+ ret = radix_tree_tag_get(&hwspinlock_tree, hwlock->id,
+@@ -538,7 +533,7 @@ int hwspin_lock_free(struct hwspinlock *
+ module_put(hwlock->owner);
+
+ out:
+- spin_unlock(&hwspinlock_tree_lock);
++ mutex_unlock(&hwspinlock_tree_lock);
+ return ret;
+ }
+ EXPORT_SYMBOL_GPL(hwspin_lock_free);
proc-fix-races-against-execve-of-proc-pid-fd.patch
alsa-hda-add-missing-static-adc-tables-for-alc269-quirks.patch
drivers-net-rionet.c-fix-ethernet-address-macros-for-le-platforms.patch
+hwspinlock-core-use-a-mutex-to-protect-the-radix-tree.patch
+drivers-power-ds2780_battery.c-create-central-point-for-calling-w1-interface.patch
+drivers-power-ds2780_battery.c-add-a-nolock-function-to-w1-interface.patch
+drivers-power-ds2780_battery.c-fix-deadlock-upon-insertion-and-removal.patch
+ext2-ext3-ext4-don-t-inherit-append_fl-or-immutable_fl-for-new-inodes.patch
+ext4-ext4_rename-should-dirty-dir_bh-with-the-correct-directory.patch
+ext4-ext4_mkdir-should-dirty-dir_block-with-newly-created-directory-inode.patch
+ext4-call-ext4_handle_dirty_metadata-with-correct-inode-in-ext4_dx_add_entry.patch
+ext4-let-ext4_page_mkwrite-stop-started-handle-in-failure.patch
+ext4-fix-race-in-xattr-block-allocation-path.patch