+++ /dev/null
-From 9ea578528656e191c1097798a771ff08bab6f323 Mon Sep 17 00:00:00 2001
-From: Noa Osherovich <noaos@mellanox.com>
-Date: Sat, 4 Jun 2016 15:15:34 +0300
-Subject: IB/mlx5: Fix entries checks in mlx5_ib_create_cq
-
-From: Noa Osherovich <noaos@mellanox.com>
-
-commit 9ea578528656e191c1097798a771ff08bab6f323 upstream.
-
-Number of entries shouldn't be greater than the device's max
-capability. This should be checked before rounding the entries number
-to power of two.
-
-Fixes: 51ee86a4af639 ('IB/mlx5: Fix check of number of entries...')
-Signed-off-by: Majd Dibbiny <majd@mellanox.com>
-Signed-off-by: Noa Osherovich <noaos@mellanox.com>
-Signed-off-by: Leon Romanovsky <leon@kernel.org>
-Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
-Signed-off-by: Doug Ledford <dledford@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- drivers/infiniband/hw/mlx5/cq.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/infiniband/hw/mlx5/cq.c
-+++ b/drivers/infiniband/hw/mlx5/cq.c
-@@ -686,7 +686,8 @@ struct ib_cq *mlx5_ib_create_cq(struct i
- int eqn;
- int err;
-
-- if (entries < 0)
-+ if (entries < 0 ||
-+ (entries > (1 << MLX5_CAP_GEN(dev->mdev, log_max_cq_sz))))
- return ERR_PTR(-EINVAL);
-
- entries = roundup_pow_of_two(entries + 1);
--- /dev/null
+From 4097461897df91041382ff6fcd2bfa7ee6b2448c Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Mon, 25 Jul 2016 11:36:54 -0700
+Subject: Input: i8042 - break load dependency between atkbd/psmouse and i8042
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit 4097461897df91041382ff6fcd2bfa7ee6b2448c upstream.
+
+As explained in 1407814240-4275-1-git-send-email-decui@microsoft.com we
+have a hard load dependency between i8042 and atkbd which prevents
+keyboard from working on Gen2 Hyper-V VMs.
+
+> hyperv_keyboard invokes serio_interrupt(), which needs a valid serio
+> driver like atkbd.c. atkbd.c depends on libps2.c because it invokes
+> ps2_command(). libps2.c depends on i8042.c because it invokes
+> i8042_check_port_owner(). As a result, hyperv_keyboard actually
+> depends on i8042.c.
+>
+> For a Generation 2 Hyper-V VM (meaning no i8042 device emulated), if a
+> Linux VM (like Arch Linux) happens to configure CONFIG_SERIO_I8042=m
+> rather than =y, atkbd.ko can't load because i8042.ko can't load(due to
+> no i8042 device emulated) and finally hyperv_keyboard can't work and
+> the user can't input: https://bugs.archlinux.org/task/39820
+> (Ubuntu/RHEL/SUSE aren't affected since they use CONFIG_SERIO_I8042=y)
+
+To break the dependency we move away from using i8042_check_port_owner()
+and instead allow serio port owner specify a mutex that clients should use
+to serialize PS/2 command stream.
+
+Reported-by: Mark Laws <mdl@60hz.org>
+Tested-by: Mark Laws <mdl@60hz.org>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/serio/i8042.c | 16 +---------------
+ drivers/input/serio/libps2.c | 10 ++++------
+ include/linux/i8042.h | 6 ------
+ include/linux/serio.h | 24 +++++++++++++++++++-----
+ 4 files changed, 24 insertions(+), 32 deletions(-)
+
+--- a/drivers/input/serio/i8042.c
++++ b/drivers/input/serio/i8042.c
+@@ -1230,6 +1230,7 @@ static int __init i8042_create_kbd_port(
+ serio->start = i8042_start;
+ serio->stop = i8042_stop;
+ serio->close = i8042_port_close;
++ serio->ps2_cmd_mutex = &i8042_mutex;
+ serio->port_data = port;
+ serio->dev.parent = &i8042_platform_device->dev;
+ strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name));
+@@ -1321,21 +1322,6 @@ static void i8042_unregister_ports(void)
+ }
+ }
+
+-/*
+- * Checks whether port belongs to i8042 controller.
+- */
+-bool i8042_check_port_owner(const struct serio *port)
+-{
+- int i;
+-
+- for (i = 0; i < I8042_NUM_PORTS; i++)
+- if (i8042_ports[i].serio == port)
+- return true;
+-
+- return false;
+-}
+-EXPORT_SYMBOL(i8042_check_port_owner);
+-
+ static void i8042_free_irqs(void)
+ {
+ if (i8042_aux_irq_registered)
+--- a/drivers/input/serio/libps2.c
++++ b/drivers/input/serio/libps2.c
+@@ -56,19 +56,17 @@ EXPORT_SYMBOL(ps2_sendbyte);
+
+ void ps2_begin_command(struct ps2dev *ps2dev)
+ {
+- mutex_lock(&ps2dev->cmd_mutex);
++ struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
+
+- if (i8042_check_port_owner(ps2dev->serio))
+- i8042_lock_chip();
++ mutex_lock(m);
+ }
+ EXPORT_SYMBOL(ps2_begin_command);
+
+ void ps2_end_command(struct ps2dev *ps2dev)
+ {
+- if (i8042_check_port_owner(ps2dev->serio))
+- i8042_unlock_chip();
++ struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
+
+- mutex_unlock(&ps2dev->cmd_mutex);
++ mutex_unlock(m);
+ }
+ EXPORT_SYMBOL(ps2_end_command);
+
+--- a/include/linux/i8042.h
++++ b/include/linux/i8042.h
+@@ -62,7 +62,6 @@ struct serio;
+ void i8042_lock_chip(void);
+ void i8042_unlock_chip(void);
+ int i8042_command(unsigned char *param, int command);
+-bool i8042_check_port_owner(const struct serio *);
+ int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
+ struct serio *serio));
+ int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str,
+@@ -83,11 +82,6 @@ static inline int i8042_command(unsigned
+ return -ENODEV;
+ }
+
+-static inline bool i8042_check_port_owner(const struct serio *serio)
+-{
+- return false;
+-}
+-
+ static inline int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
+ struct serio *serio))
+ {
+--- a/include/linux/serio.h
++++ b/include/linux/serio.h
+@@ -29,7 +29,8 @@ struct serio {
+
+ struct serio_device_id id;
+
+- spinlock_t lock; /* protects critical sections from port's interrupt handler */
++ /* Protects critical sections from port's interrupt handler */
++ spinlock_t lock;
+
+ int (*write)(struct serio *, unsigned char);
+ int (*open)(struct serio *);
+@@ -38,16 +39,29 @@ struct serio {
+ void (*stop)(struct serio *);
+
+ struct serio *parent;
+- struct list_head child_node; /* Entry in parent->children list */
++ /* Entry in parent->children list */
++ struct list_head child_node;
+ struct list_head children;
+- unsigned int depth; /* level of nesting in serio hierarchy */
++ /* Level of nesting in serio hierarchy */
++ unsigned int depth;
+
+- struct serio_driver *drv; /* accessed from interrupt, must be protected by serio->lock and serio->sem */
+- struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */
++ /*
++ * serio->drv is accessed from interrupt handlers; when modifying
++ * caller should acquire serio->drv_mutex and serio->lock.
++ */
++ struct serio_driver *drv;
++ /* Protects serio->drv so attributes can pin current driver */
++ struct mutex drv_mutex;
+
+ struct device dev;
+
+ struct list_head node;
++
++ /*
++ * For use by PS/2 layer when several ports share hardware and
++ * may get indigestion when exposed to concurrent access (i8042).
++ */
++ struct mutex *ps2_cmd_mutex;
+ };
+ #define to_serio_port(d) container_of(d, struct serio, dev)
+
--- /dev/null
+From 9ac0108c2bac3f1d0255f64fb89fc27e71131b24 Mon Sep 17 00:00:00 2001
+From: Chris Blake <chrisrblake93@gmail.com>
+Date: Mon, 30 May 2016 07:26:37 -0500
+Subject: PCI: Mark Atheros AR9485 and QCA9882 to avoid bus reset
+
+From: Chris Blake <chrisrblake93@gmail.com>
+
+commit 9ac0108c2bac3f1d0255f64fb89fc27e71131b24 upstream.
+
+Similar to the AR93xx series, the AR94xx and the Qualcomm QCA988x also have
+the same quirk for the Bus Reset.
+
+Fixes: c3e59ee4e766 ("PCI: Mark Atheros AR93xx to avoid bus reset")
+Signed-off-by: Chris Blake <chrisrblake93@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/quirks.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -3017,13 +3017,15 @@ static void quirk_no_bus_reset(struct pc
+ }
+
+ /*
+- * Atheros AR93xx chips do not behave after a bus reset. The device will
+- * throw a Link Down error on AER-capable systems and regardless of AER,
+- * config space of the device is never accessible again and typically
+- * causes the system to hang or reset when access is attempted.
++ * Some Atheros AR9xxx and QCA988x chips do not behave after a bus reset.
++ * The device will throw a Link Down error on AER-capable systems and
++ * regardless of AER, config space of the device is never accessible again
++ * and typically causes the system to hang or reset when access is attempted.
+ * http://www.spinics.net/lists/linux-pci/msg34797.html
+ */
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0032, quirk_no_bus_reset);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset);
+
+ static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
+ struct pci_fixup *end)
ftrace-recordmcount-work-around-for-addition-of-metag-magic-but-not-relocations.patch
metag-fix-__cmpxchg_u32-asm-constraint-for-cmp.patch
ib-mlx5-fix-modify_qp-command-input-structure.patch
-ib-mlx5-fix-entries-checks-in-mlx5_ib_create_cq.patch
ib-mlx5-fix-returned-values-of-query-qp.patch
ib-mlx5-fix-post-send-fence-logic.patch
ib-ipoib-don-t-update-neigh-validity-for-unresolved-entries.patch
ib-mlx4-fix-the-sq-size-of-an-rc-qp.patch
+ubi-make-volume-resize-power-cut-aware.patch
+ubi-fix-race-condition-between-ubi-device-creation-and-udev.patch
+target-fix-race-between-iscsi-target-connection-shutdown-abort_task.patch
+target-fix-max_unmap_lba_count-calc-overflow.patch
+input-i8042-break-load-dependency-between-atkbd-psmouse-and-i8042.patch
+pci-mark-atheros-ar9485-and-qca9882-to-avoid-bus-reset.patch
--- /dev/null
+From ea263c7fada4af8ec7fe5fcfd6e7d7705a89351b Mon Sep 17 00:00:00 2001
+From: Mike Christie <mchristi@redhat.com>
+Date: Thu, 2 Jun 2016 20:12:37 -0500
+Subject: target: Fix max_unmap_lba_count calc overflow
+
+From: Mike Christie <mchristi@redhat.com>
+
+commit ea263c7fada4af8ec7fe5fcfd6e7d7705a89351b upstream.
+
+max_discard_sectors only 32bits, and some non scsi backend
+devices will set this to the max 0xffffffff, so we can end up
+overflowing during the max_unmap_lba_count calculation.
+
+This fixes a regression caused by my patch:
+
+commit 8a9ebe717a133ba7bc90b06047f43cc6b8bcb8b3
+Author: Mike Christie <mchristi@redhat.com>
+Date: Mon Jan 18 14:09:27 2016 -0600
+
+ target: Fix WRITE_SAME/DISCARD conversion to linux 512b sectors
+
+which can result in extra discards being sent to due the overflow
+causing max_unmap_lba_count to be smaller than what the backing
+device can actually support.
+
+Signed-off-by: Mike Christie <mchristi@redhat.com>
+Reviewed-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_device.c | 8 +++++---
+ drivers/target/target_core_file.c | 3 +--
+ drivers/target/target_core_iblock.c | 3 +--
+ include/target/target_core_backend.h | 2 +-
+ 4 files changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/target/target_core_device.c
++++ b/drivers/target/target_core_device.c
+@@ -1583,13 +1583,15 @@ struct se_device *target_alloc_device(st
+ * in ATA and we need to set TPE=1
+ */
+ bool target_configure_unmap_from_queue(struct se_dev_attrib *attrib,
+- struct request_queue *q, int block_size)
++ struct request_queue *q)
+ {
++ int block_size = queue_logical_block_size(q);
++
+ if (!blk_queue_discard(q))
+ return false;
+
+- attrib->max_unmap_lba_count = (q->limits.max_discard_sectors << 9) /
+- block_size;
++ attrib->max_unmap_lba_count =
++ q->limits.max_discard_sectors >> (ilog2(block_size) - 9);
+ /*
+ * Currently hardcoded to 1 in Linux/SCSI code..
+ */
+--- a/drivers/target/target_core_file.c
++++ b/drivers/target/target_core_file.c
+@@ -165,8 +165,7 @@ static int fd_configure_device(struct se
+ dev_size, div_u64(dev_size, fd_dev->fd_block_size),
+ fd_dev->fd_block_size);
+
+- if (target_configure_unmap_from_queue(&dev->dev_attrib, q,
+- fd_dev->fd_block_size))
++ if (target_configure_unmap_from_queue(&dev->dev_attrib, q))
+ pr_debug("IFILE: BLOCK Discard support available,"
+ " disabled by default\n");
+ /*
+--- a/drivers/target/target_core_iblock.c
++++ b/drivers/target/target_core_iblock.c
+@@ -126,8 +126,7 @@ static int iblock_configure_device(struc
+ dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q);
+ dev->dev_attrib.hw_queue_depth = q->nr_requests;
+
+- if (target_configure_unmap_from_queue(&dev->dev_attrib, q,
+- dev->dev_attrib.hw_block_size))
++ if (target_configure_unmap_from_queue(&dev->dev_attrib, q))
+ pr_debug("IBLOCK: BLOCK Discard support available,"
+ " disabled by default\n");
+
+--- a/include/target/target_core_backend.h
++++ b/include/target/target_core_backend.h
+@@ -96,6 +96,6 @@ void array_free(void *array, int n);
+
+ sector_t target_to_linux_sector(struct se_device *dev, sector_t lb);
+ bool target_configure_unmap_from_queue(struct se_dev_attrib *attrib,
+- struct request_queue *q, int block_size);
++ struct request_queue *q);
+
+ #endif /* TARGET_CORE_BACKEND_H */
--- /dev/null
+From 064cdd2d91c2805d788876082f31cc63506f22c3 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Thu, 2 Jun 2016 14:56:45 -0700
+Subject: target: Fix race between iscsi-target connection shutdown + ABORT_TASK
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit 064cdd2d91c2805d788876082f31cc63506f22c3 upstream.
+
+This patch fixes a race in iscsit_release_commands_from_conn() ->
+iscsit_free_cmd() -> transport_generic_free_cmd() + wait_for_tasks=1,
+where CMD_T_FABRIC_STOP could end up being set after the final
+kref_put() is called from core_tmr_abort_task() context.
+
+This results in transport_generic_free_cmd() blocking indefinately
+on se_cmd->cmd_wait_comp, because the target_release_cmd_kref()
+check for CMD_T_FABRIC_STOP returns false.
+
+To address this bug, make iscsit_release_commands_from_conn()
+do list_splice and set CMD_T_FABRIC_STOP early while holding
+iscsi_conn->cmd_lock. Also make iscsit_aborted_task() only
+remove iscsi_cmd_t if CMD_T_FABRIC_STOP has not already been
+set.
+
+Finally in target_release_cmd_kref(), only honor fabric_stop
+if CMD_T_ABORTED has been set.
+
+Cc: Mike Christie <mchristi@redhat.com>
+Cc: Quinn Tran <quinn.tran@qlogic.com>
+Cc: Himanshu Madhani <himanshu.madhani@qlogic.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Hannes Reinecke <hare@suse.de>
+Tested-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/iscsi/iscsi_target.c | 22 ++++++++++++++++------
+ drivers/target/target_core_transport.c | 3 ++-
+ 2 files changed, 18 insertions(+), 7 deletions(-)
+
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -505,7 +505,8 @@ static void iscsit_aborted_task(struct i
+ bool scsi_cmd = (cmd->iscsi_opcode == ISCSI_OP_SCSI_CMD);
+
+ spin_lock_bh(&conn->cmd_lock);
+- if (!list_empty(&cmd->i_conn_node))
++ if (!list_empty(&cmd->i_conn_node) &&
++ !(cmd->se_cmd.transport_state & CMD_T_FABRIC_STOP))
+ list_del_init(&cmd->i_conn_node);
+ spin_unlock_bh(&conn->cmd_lock);
+
+@@ -4160,6 +4161,7 @@ transport_err:
+
+ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn)
+ {
++ LIST_HEAD(tmp_list);
+ struct iscsi_cmd *cmd = NULL, *cmd_tmp = NULL;
+ struct iscsi_session *sess = conn->sess;
+ /*
+@@ -4168,18 +4170,26 @@ static void iscsit_release_commands_from
+ * has been reset -> returned sleeping pre-handler state.
+ */
+ spin_lock_bh(&conn->cmd_lock);
+- list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) {
++ list_splice_init(&conn->conn_cmd_list, &tmp_list);
+
++ list_for_each_entry(cmd, &tmp_list, i_conn_node) {
++ struct se_cmd *se_cmd = &cmd->se_cmd;
++
++ if (se_cmd->se_tfo != NULL) {
++ spin_lock(&se_cmd->t_state_lock);
++ se_cmd->transport_state |= CMD_T_FABRIC_STOP;
++ spin_unlock(&se_cmd->t_state_lock);
++ }
++ }
++ spin_unlock_bh(&conn->cmd_lock);
++
++ list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) {
+ list_del_init(&cmd->i_conn_node);
+- spin_unlock_bh(&conn->cmd_lock);
+
+ iscsit_increment_maxcmdsn(cmd, sess);
+-
+ iscsit_free_cmd(cmd, true);
+
+- spin_lock_bh(&conn->cmd_lock);
+ }
+- spin_unlock_bh(&conn->cmd_lock);
+ }
+
+ static void iscsit_stop_timers_for_cmds(
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -2407,7 +2407,8 @@ static void target_release_cmd_kref(stru
+ }
+
+ spin_lock(&se_cmd->t_state_lock);
+- fabric_stop = (se_cmd->transport_state & CMD_T_FABRIC_STOP);
++ fabric_stop = (se_cmd->transport_state & CMD_T_FABRIC_STOP) &&
++ (se_cmd->transport_state & CMD_T_ABORTED);
+ spin_unlock(&se_cmd->t_state_lock);
+
+ if (se_cmd->cmd_wait_set || fabric_stop) {
--- /dev/null
+From 714fb87e8bc05ff78255afc0dca981e8c5242785 Mon Sep 17 00:00:00 2001
+From: Iosif Harutyunov <iharutyunov@SonicWALL.com>
+Date: Fri, 22 Jul 2016 23:22:42 +0000
+Subject: ubi: Fix race condition between ubi device creation and udev
+
+From: Iosif Harutyunov <iharutyunov@SonicWALL.com>
+
+commit 714fb87e8bc05ff78255afc0dca981e8c5242785 upstream.
+
+Install the UBI device object before we arm sysfs.
+Otherwise udev tries to read sysfs attributes before UBI is ready and
+udev rules will not match.
+
+Signed-off-by: Iosif Harutyunov <iharutyunov@sonicwall.com>
+[rw: massaged commit message]
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/ubi/build.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/ubi/build.c
++++ b/drivers/mtd/ubi/build.c
+@@ -999,6 +999,9 @@ int ubi_attach_mtd_dev(struct mtd_info *
+ goto out_detach;
+ }
+
++ /* Make device "available" before it becomes accessible via sysfs */
++ ubi_devices[ubi_num] = ubi;
++
+ err = uif_init(ubi, &ref);
+ if (err)
+ goto out_detach;
+@@ -1043,7 +1046,6 @@ int ubi_attach_mtd_dev(struct mtd_info *
+ wake_up_process(ubi->bgt_thread);
+ spin_unlock(&ubi->wl_lock);
+
+- ubi_devices[ubi_num] = ubi;
+ ubi_notify_all(ubi, UBI_VOLUME_ADDED, NULL);
+ return ubi_num;
+
+@@ -1054,6 +1056,7 @@ out_uif:
+ ubi_assert(ref);
+ uif_close(ubi);
+ out_detach:
++ ubi_devices[ubi_num] = NULL;
+ ubi_wl_close(ubi);
+ ubi_free_internal_volumes(ubi);
+ vfree(ubi->vtbl);
--- /dev/null
+From 4946784bd3924b1374f05eebff2fd68660bae866 Mon Sep 17 00:00:00 2001
+From: Richard Weinberger <richard@nod.at>
+Date: Thu, 23 Jun 2016 19:30:38 +0200
+Subject: ubi: Make volume resize power cut aware
+
+From: Richard Weinberger <richard@nod.at>
+
+commit 4946784bd3924b1374f05eebff2fd68660bae866 upstream.
+
+When the volume resize operation shrinks a volume,
+LEBs will be unmapped. Since unmapping will not erase these
+LEBs immediately we have to wait for that operation to finish.
+Otherwise in case of a power cut right after writing the new
+volume table the UBI attach process can find more LEBs than the
+volume table knows. This will render the UBI image unattachable.
+
+Fix this issue by waiting for erase to complete and write the new
+volume table afterward.
+
+Reported-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/ubi/vmt.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+--- a/drivers/mtd/ubi/vmt.c
++++ b/drivers/mtd/ubi/vmt.c
+@@ -534,13 +534,6 @@ int ubi_resize_volume(struct ubi_volume_
+ spin_unlock(&ubi->volumes_lock);
+ }
+
+- /* Change volume table record */
+- vtbl_rec = ubi->vtbl[vol_id];
+- vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs);
+- err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
+- if (err)
+- goto out_acc;
+-
+ if (pebs < 0) {
+ for (i = 0; i < -pebs; i++) {
+ err = ubi_eba_unmap_leb(ubi, vol, reserved_pebs + i);
+@@ -558,6 +551,24 @@ int ubi_resize_volume(struct ubi_volume_
+ spin_unlock(&ubi->volumes_lock);
+ }
+
++ /*
++ * When we shrink a volume we have to flush all pending (erase) work.
++ * Otherwise it can happen that upon next attach UBI finds a LEB with
++ * lnum > highest_lnum and refuses to attach.
++ */
++ if (pebs < 0) {
++ err = ubi_wl_flush(ubi, vol_id, UBI_ALL);
++ if (err)
++ goto out_acc;
++ }
++
++ /* Change volume table record */
++ vtbl_rec = ubi->vtbl[vol_id];
++ vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs);
++ err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
++ if (err)
++ goto out_acc;
++
+ vol->reserved_pebs = reserved_pebs;
+ if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
+ vol->used_ebs = reserved_pebs;