From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id B5DB1139694 for ; Mon, 8 May 2017 10:40:42 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 501C7E0DC3; Mon, 8 May 2017 10:40:39 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 202EAE0DC3 for ; Mon, 8 May 2017 10:40:39 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id D5FA0341686 for ; Mon, 8 May 2017 10:40:37 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 010102494 for ; Mon, 8 May 2017 10:40:36 +0000 (UTC) From: "Mike Pagano" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Mike Pagano" Message-ID: <1494240025.76c5fbb16e325e55281e54aa20ceca47629ecada.mpagano@gentoo> Subject: [gentoo-commits] proj/linux-patches:4.4 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1066_linux-4.4.67.patch X-VCS-Directories: / X-VCS-Committer: mpagano X-VCS-Committer-Name: Mike Pagano X-VCS-Revision: 76c5fbb16e325e55281e54aa20ceca47629ecada X-VCS-Branch: 4.4 Date: Mon, 8 May 2017 10:40:36 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 9b1d42d5-6ecd-44c4-a860-c1af2518bb9b X-Archives-Hash: 836c06a06fc56e4dd7a43e5b47b85e96 commit: 76c5fbb16e325e55281e54aa20ceca47629ecada Author: Mike Pagano gentoo org> AuthorDate: Mon May 8 10:40:25 2017 +0000 Commit: Mike Pagano gentoo org> CommitDate: Mon May 8 10:40:25 2017 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=76c5fbb1 Linux patch 4.4.67 0000_README | 4 + 1066_linux-4.4.67.patch | 948 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 952 insertions(+) diff --git a/0000_README b/0000_README index d08d290..dd02f06 100644 --- a/0000_README +++ b/0000_README @@ -307,6 +307,10 @@ Patch: 1065_linux-4.4.66.patch From: http://www.kernel.org Desc: Linux 4.4.66 +Patch: 1066_linux-4.4.67.patch +From: http://www.kernel.org +Desc: Linux 4.4.67 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1066_linux-4.4.67.patch b/1066_linux-4.4.67.patch new file mode 100644 index 0000000..aafd894 --- /dev/null +++ b/1066_linux-4.4.67.patch @@ -0,0 +1,948 @@ +diff --git a/Makefile b/Makefile +index 1cd052823c03..c987902ae1ee 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 66 ++SUBLEVEL = 67 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c +index 9462d2752850..8bdc34dbaedf 100644 +--- a/drivers/block/drbd/drbd_bitmap.c ++++ b/drivers/block/drbd/drbd_bitmap.c +@@ -479,8 +479,14 @@ void drbd_bm_cleanup(struct drbd_device *device) + * this masks out the remaining bits. + * Returns the number of bits cleared. + */ ++#ifndef BITS_PER_PAGE + #define BITS_PER_PAGE (1UL << (PAGE_SHIFT + 3)) + #define BITS_PER_PAGE_MASK (BITS_PER_PAGE - 1) ++#else ++# if BITS_PER_PAGE != (1UL << (PAGE_SHIFT + 3)) ++# error "ambiguous BITS_PER_PAGE" ++# endif ++#endif + #define BITS_PER_LONG_MASK (BITS_PER_LONG - 1) + static int bm_clear_surplus(struct drbd_bitmap *b) + { +diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c +index 3eff35c2d453..2684605fe67f 100644 +--- a/drivers/infiniband/hw/qib/qib_qp.c ++++ b/drivers/infiniband/hw/qib/qib_qp.c +@@ -41,13 +41,13 @@ + + #include "qib.h" + +-#define BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE) +-#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1) ++#define RVT_BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE) ++#define RVT_BITS_PER_PAGE_MASK (RVT_BITS_PER_PAGE-1) + + static inline unsigned mk_qpn(struct qib_qpn_table *qpt, + struct qpn_map *map, unsigned off) + { +- return (map - qpt->map) * BITS_PER_PAGE + off; ++ return (map - qpt->map) * RVT_BITS_PER_PAGE + off; + } + + static inline unsigned find_next_offset(struct qib_qpn_table *qpt, +@@ -59,7 +59,7 @@ static inline unsigned find_next_offset(struct qib_qpn_table *qpt, + if (((off & qpt->mask) >> 1) >= n) + off = (off | qpt->mask) + 2; + } else +- off = find_next_zero_bit(map->page, BITS_PER_PAGE, off); ++ off = find_next_zero_bit(map->page, RVT_BITS_PER_PAGE, off); + return off; + } + +@@ -147,8 +147,8 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt, + qpn = 2; + if (qpt->mask && ((qpn & qpt->mask) >> 1) >= dd->n_krcv_queues) + qpn = (qpn | qpt->mask) + 2; +- offset = qpn & BITS_PER_PAGE_MASK; +- map = &qpt->map[qpn / BITS_PER_PAGE]; ++ offset = qpn & RVT_BITS_PER_PAGE_MASK; ++ map = &qpt->map[qpn / RVT_BITS_PER_PAGE]; + max_scan = qpt->nmaps - !offset; + for (i = 0;;) { + if (unlikely(!map->page)) { +@@ -173,7 +173,7 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt, + * We just need to be sure we don't loop + * forever. + */ +- } while (offset < BITS_PER_PAGE && qpn < QPN_MAX); ++ } while (offset < RVT_BITS_PER_PAGE && qpn < QPN_MAX); + /* + * In order to keep the number of pages allocated to a + * minimum, we scan the all existing pages before increasing +@@ -204,9 +204,9 @@ static void free_qpn(struct qib_qpn_table *qpt, u32 qpn) + { + struct qpn_map *map; + +- map = qpt->map + qpn / BITS_PER_PAGE; ++ map = qpt->map + qpn / RVT_BITS_PER_PAGE; + if (map->page) +- clear_bit(qpn & BITS_PER_PAGE_MASK, map->page); ++ clear_bit(qpn & RVT_BITS_PER_PAGE_MASK, map->page); + } + + static inline unsigned qpn_hash(struct qib_ibdev *dev, u32 qpn) +diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c +index 80a439543259..e503279c34fc 100644 +--- a/drivers/md/dm-ioctl.c ++++ b/drivers/md/dm-ioctl.c +@@ -1843,7 +1843,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user) + if (r) + goto out; + +- param->data_size = sizeof(*param); ++ param->data_size = offsetof(struct dm_ioctl, data); + r = fn(param, input_param_size); + + if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) && +diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig +index 54479c481a7a..8a25adced79f 100644 +--- a/drivers/mtd/chips/Kconfig ++++ b/drivers/mtd/chips/Kconfig +@@ -111,6 +111,7 @@ config MTD_MAP_BANK_WIDTH_16 + + config MTD_MAP_BANK_WIDTH_32 + bool "Support 256-bit buswidth" if MTD_CFI_GEOMETRY ++ select MTD_COMPLEX_MAPPINGS if HAS_IOMEM + default n + help + If you wish to support CFI devices on a physical bus which is +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index 49056c33be74..21e5b9ed1ead 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -12031,7 +12031,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, + int ret; + u32 offset, len, b_offset, odd_len; + u8 *buf; +- __be32 start, end; ++ __be32 start = 0, end; + + if (tg3_flag(tp, NO_NVRAM) || + eeprom->magic != TG3_EEPROM_MAGIC) +diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c +index 2882bcac918a..0b096730c72a 100644 +--- a/drivers/scsi/cxlflash/main.c ++++ b/drivers/scsi/cxlflash/main.c +@@ -996,6 +996,8 @@ static int wait_port_online(__be64 __iomem *fc_regs, u32 delay_us, u32 nretry) + do { + msleep(delay_us / 1000); + status = readq_be(&fc_regs[FC_MTIP_STATUS / 8]); ++ if (status == U64_MAX) ++ nretry /= 2; + } while ((status & FC_MTIP_STATUS_MASK) != FC_MTIP_STATUS_ONLINE && + nretry--); + +@@ -1027,6 +1029,8 @@ static int wait_port_offline(__be64 __iomem *fc_regs, u32 delay_us, u32 nretry) + do { + msleep(delay_us / 1000); + status = readq_be(&fc_regs[FC_MTIP_STATUS / 8]); ++ if (status == U64_MAX) ++ nretry /= 2; + } while ((status & FC_MTIP_STATUS_MASK) != FC_MTIP_STATUS_OFFLINE && + nretry--); + +@@ -1137,7 +1141,7 @@ static const struct asyc_intr_info ainfo[] = { + {SISL_ASTATUS_FC0_LOGI_F, "login failed", 0, CLR_FC_ERROR}, + {SISL_ASTATUS_FC0_LOGI_S, "login succeeded", 0, SCAN_HOST}, + {SISL_ASTATUS_FC0_LINK_DN, "link down", 0, 0}, +- {SISL_ASTATUS_FC0_LINK_UP, "link up", 0, SCAN_HOST}, ++ {SISL_ASTATUS_FC0_LINK_UP, "link up", 0, 0}, + {SISL_ASTATUS_FC1_OTHER, "other error", 1, CLR_FC_ERROR | LINK_RESET}, + {SISL_ASTATUS_FC1_LOGO, "target initiated LOGO", 1, 0}, + {SISL_ASTATUS_FC1_CRC_T, "CRC threshold exceeded", 1, LINK_RESET}, +@@ -1145,7 +1149,7 @@ static const struct asyc_intr_info ainfo[] = { + {SISL_ASTATUS_FC1_LOGI_F, "login failed", 1, CLR_FC_ERROR}, + {SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, SCAN_HOST}, + {SISL_ASTATUS_FC1_LINK_DN, "link down", 1, 0}, +- {SISL_ASTATUS_FC1_LINK_UP, "link up", 1, SCAN_HOST}, ++ {SISL_ASTATUS_FC1_LINK_UP, "link up", 1, 0}, + {0x0, "", 0, 0} /* terminator */ + }; + +@@ -1962,6 +1966,11 @@ retry: + * cxlflash_eh_host_reset_handler() - reset the host adapter + * @scp: SCSI command from stack identifying host. + * ++ * Following a reset, the state is evaluated again in case an EEH occurred ++ * during the reset. In such a scenario, the host reset will either yield ++ * until the EEH recovery is complete or return success or failure based ++ * upon the current device state. ++ * + * Return: + * SUCCESS as defined in scsi/scsi.h + * FAILED as defined in scsi/scsi.h +@@ -1993,7 +2002,8 @@ static int cxlflash_eh_host_reset_handler(struct scsi_cmnd *scp) + } else + cfg->state = STATE_NORMAL; + wake_up_all(&cfg->reset_waitq); +- break; ++ ssleep(1); ++ /* fall through */ + case STATE_RESET: + wait_event(cfg->reset_waitq, cfg->state != STATE_RESET); + if (cfg->state == STATE_NORMAL) +@@ -2534,6 +2544,9 @@ static void drain_ioctls(struct cxlflash_cfg *cfg) + * @pdev: PCI device struct. + * @state: PCI channel state. + * ++ * When an EEH occurs during an active reset, wait until the reset is ++ * complete and then take action based upon the device state. ++ * + * Return: PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT + */ + static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev, +@@ -2547,6 +2560,10 @@ static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev, + + switch (state) { + case pci_channel_io_frozen: ++ wait_event(cfg->reset_waitq, cfg->state != STATE_RESET); ++ if (cfg->state == STATE_FAILTERM) ++ return PCI_ERS_RESULT_DISCONNECT; ++ + cfg->state = STATE_RESET; + scsi_block_requests(cfg->host); + drain_ioctls(cfg); +diff --git a/drivers/staging/rdma/ehca/ehca_mrmw.c b/drivers/staging/rdma/ehca/ehca_mrmw.c +index f914b30999f8..4d52ca42644a 100644 +--- a/drivers/staging/rdma/ehca/ehca_mrmw.c ++++ b/drivers/staging/rdma/ehca/ehca_mrmw.c +@@ -1921,7 +1921,7 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo, + u64 *kpage) + { + int ret = 0; +- u64 pgaddr, prev_pgaddr; ++ u64 pgaddr, prev_pgaddr = 0; + u32 j = 0; + int kpages_per_hwpage = pginfo->hwpage_size / PAGE_SIZE; + int nr_kpages = kpages_per_hwpage; +@@ -2417,6 +2417,7 @@ static int ehca_reg_bmap_mr_rpages(struct ehca_shca *shca, + ehca_err(&shca->ib_device, "kpage alloc failed"); + return -ENOMEM; + } ++ hret = H_SUCCESS; + for (top = 0; top < EHCA_MAP_ENTRIES; top++) { + if (!ehca_bmap_valid(ehca_bmap->top[top])) + continue; +diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +index 83ff1724ec79..cf3da51a3536 100644 +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -5850,17 +5850,15 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev) + static void serial8250_io_resume(struct pci_dev *dev) + { + struct serial_private *priv = pci_get_drvdata(dev); +- const struct pciserial_board *board; ++ struct serial_private *new; + + if (!priv) + return; + +- board = priv->board; +- kfree(priv); +- priv = pciserial_init_ports(dev, board); +- +- if (!IS_ERR(priv)) { +- pci_set_drvdata(dev, priv); ++ new = pciserial_init_ports(dev, priv->board); ++ if (!IS_ERR(new)) { ++ pci_set_drvdata(dev, new); ++ kfree(priv); + } + } + +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index 94906aaa9b7c..e2f6a79e9b01 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -227,6 +227,7 @@ struct smb_version_operations { + /* verify the message */ + int (*check_message)(char *, unsigned int); + bool (*is_oplock_break)(char *, struct TCP_Server_Info *); ++ int (*handle_cancelled_mid)(char *, struct TCP_Server_Info *); + void (*downgrade_oplock)(struct TCP_Server_Info *, + struct cifsInodeInfo *, bool); + /* process transaction2 response */ +@@ -1289,12 +1290,19 @@ struct mid_q_entry { + void *callback_data; /* general purpose pointer for callback */ + void *resp_buf; /* pointer to received SMB header */ + int mid_state; /* wish this were enum but can not pass to wait_event */ ++ unsigned int mid_flags; + __le16 command; /* smb command code */ + bool large_buf:1; /* if valid response, is pointer to large buf */ + bool multiRsp:1; /* multiple trans2 responses for one request */ + bool multiEnd:1; /* both received */ + }; + ++struct close_cancelled_open { ++ struct cifs_fid fid; ++ struct cifs_tcon *tcon; ++ struct work_struct work; ++}; ++ + /* Make code in transport.c a little cleaner by moving + update of optional stats into function below */ + #ifdef CONFIG_CIFS_STATS2 +@@ -1426,6 +1434,9 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, + #define MID_RESPONSE_MALFORMED 0x10 + #define MID_SHUTDOWN 0x20 + ++/* Flags */ ++#define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ ++ + /* Types of response buffer returned from SendReceive2 */ + #define CIFS_NO_BUFFER 0 /* Response buffer not returned */ + #define CIFS_SMALL_BUFFER 1 +diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c +index b1104ed8f54c..5e2f8b8ca08a 100644 +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -1424,6 +1424,8 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) + + length = discard_remaining_data(server); + dequeue_mid(mid, rdata->result); ++ mid->resp_buf = server->smallbuf; ++ server->smallbuf = NULL; + return length; + } + +@@ -1538,6 +1540,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) + return cifs_readv_discard(server, mid); + + dequeue_mid(mid, false); ++ mid->resp_buf = server->smallbuf; ++ server->smallbuf = NULL; + return length; + } + +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index 5d59f25521ce..156bc18eac69 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -924,10 +924,19 @@ cifs_demultiplex_thread(void *p) + + server->lstrp = jiffies; + if (mid_entry != NULL) { ++ if ((mid_entry->mid_flags & MID_WAIT_CANCELLED) && ++ mid_entry->mid_state == MID_RESPONSE_RECEIVED && ++ server->ops->handle_cancelled_mid) ++ server->ops->handle_cancelled_mid( ++ mid_entry->resp_buf, ++ server); ++ + if (!mid_entry->multiRsp || mid_entry->multiEnd) + mid_entry->callback(mid_entry); +- } else if (!server->ops->is_oplock_break || +- !server->ops->is_oplock_break(buf, server)) { ++ } else if (server->ops->is_oplock_break && ++ server->ops->is_oplock_break(buf, server)) { ++ cifs_dbg(FYI, "Received oplock break\n"); ++ } else { + cifs_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n", + atomic_read(&midCount)); + cifs_dump_mem("Received Data is: ", buf, +diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c +index e5bc85e49be7..76ccf20fbfb7 100644 +--- a/fs/cifs/smb2misc.c ++++ b/fs/cifs/smb2misc.c +@@ -630,3 +630,47 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) + cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n"); + return false; + } ++ ++void ++smb2_cancelled_close_fid(struct work_struct *work) ++{ ++ struct close_cancelled_open *cancelled = container_of(work, ++ struct close_cancelled_open, work); ++ ++ cifs_dbg(VFS, "Close unmatched open\n"); ++ ++ SMB2_close(0, cancelled->tcon, cancelled->fid.persistent_fid, ++ cancelled->fid.volatile_fid); ++ cifs_put_tcon(cancelled->tcon); ++ kfree(cancelled); ++} ++ ++int ++smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server) ++{ ++ struct smb2_hdr *hdr = (struct smb2_hdr *)buffer; ++ struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer; ++ struct cifs_tcon *tcon; ++ struct close_cancelled_open *cancelled; ++ ++ if (hdr->Command != SMB2_CREATE || hdr->Status != STATUS_SUCCESS) ++ return 0; ++ ++ cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL); ++ if (!cancelled) ++ return -ENOMEM; ++ ++ tcon = smb2_find_smb_tcon(server, hdr->SessionId, hdr->TreeId); ++ if (!tcon) { ++ kfree(cancelled); ++ return -ENOENT; ++ } ++ ++ cancelled->fid.persistent_fid = rsp->PersistentFileId; ++ cancelled->fid.volatile_fid = rsp->VolatileFileId; ++ cancelled->tcon = tcon; ++ INIT_WORK(&cancelled->work, smb2_cancelled_close_fid); ++ queue_work(cifsiod_wq, &cancelled->work); ++ ++ return 0; ++} +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index be34b4860675..087918c4612a 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -1511,6 +1511,7 @@ struct smb_version_operations smb20_operations = { + .clear_stats = smb2_clear_stats, + .print_stats = smb2_print_stats, + .is_oplock_break = smb2_is_valid_oplock_break, ++ .handle_cancelled_mid = smb2_handle_cancelled_mid, + .downgrade_oplock = smb2_downgrade_oplock, + .need_neg = smb2_need_neg, + .negotiate = smb2_negotiate, +@@ -1589,6 +1590,7 @@ struct smb_version_operations smb21_operations = { + .clear_stats = smb2_clear_stats, + .print_stats = smb2_print_stats, + .is_oplock_break = smb2_is_valid_oplock_break, ++ .handle_cancelled_mid = smb2_handle_cancelled_mid, + .downgrade_oplock = smb2_downgrade_oplock, + .need_neg = smb2_need_neg, + .negotiate = smb2_negotiate, +@@ -1670,6 +1672,7 @@ struct smb_version_operations smb30_operations = { + .print_stats = smb2_print_stats, + .dump_share_caps = smb2_dump_share_caps, + .is_oplock_break = smb2_is_valid_oplock_break, ++ .handle_cancelled_mid = smb2_handle_cancelled_mid, + .downgrade_oplock = smb2_downgrade_oplock, + .need_neg = smb2_need_neg, + .negotiate = smb2_negotiate, +@@ -1757,6 +1760,7 @@ struct smb_version_operations smb311_operations = { + .print_stats = smb2_print_stats, + .dump_share_caps = smb2_dump_share_caps, + .is_oplock_break = smb2_is_valid_oplock_break, ++ .handle_cancelled_mid = smb2_handle_cancelled_mid, + .downgrade_oplock = smb2_downgrade_oplock, + .need_neg = smb2_need_neg, + .negotiate = smb2_negotiate, +diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h +index 0a406ae78129..adc5234486c3 100644 +--- a/fs/cifs/smb2proto.h ++++ b/fs/cifs/smb2proto.h +@@ -47,6 +47,10 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses, + struct smb_rqst *rqst); + extern struct mid_q_entry *smb2_setup_async_request( + struct TCP_Server_Info *server, struct smb_rqst *rqst); ++extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server, ++ __u64 ses_id); ++extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server, ++ __u64 ses_id, __u32 tid); + extern int smb2_calc_signature(struct smb_rqst *rqst, + struct TCP_Server_Info *server); + extern int smb3_calc_signature(struct smb_rqst *rqst, +@@ -157,6 +161,9 @@ extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, + extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, + const u64 persistent_fid, const u64 volatile_fid, + const __u8 oplock_level); ++extern int smb2_handle_cancelled_mid(char *buffer, ++ struct TCP_Server_Info *server); ++void smb2_cancelled_close_fid(struct work_struct *work); + extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_file_id, u64 volatile_file_id, + struct kstatfs *FSData); +diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c +index d4c5b6f109a7..69e3b322bbfe 100644 +--- a/fs/cifs/smb2transport.c ++++ b/fs/cifs/smb2transport.c +@@ -115,22 +115,68 @@ smb3_crypto_shash_allocate(struct TCP_Server_Info *server) + } + + static struct cifs_ses * +-smb2_find_smb_ses(struct smb2_hdr *smb2hdr, struct TCP_Server_Info *server) ++smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id) + { + struct cifs_ses *ses; + +- spin_lock(&cifs_tcp_ses_lock); + list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { +- if (ses->Suid != smb2hdr->SessionId) ++ if (ses->Suid != ses_id) + continue; +- spin_unlock(&cifs_tcp_ses_lock); + return ses; + } ++ ++ return NULL; ++} ++ ++struct cifs_ses * ++smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id) ++{ ++ struct cifs_ses *ses; ++ ++ spin_lock(&cifs_tcp_ses_lock); ++ ses = smb2_find_smb_ses_unlocked(server, ses_id); + spin_unlock(&cifs_tcp_ses_lock); + ++ return ses; ++} ++ ++static struct cifs_tcon * ++smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32 tid) ++{ ++ struct cifs_tcon *tcon; ++ ++ list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { ++ if (tcon->tid != tid) ++ continue; ++ ++tcon->tc_count; ++ return tcon; ++ } ++ + return NULL; + } + ++/* ++ * Obtain tcon corresponding to the tid in the given ++ * cifs_ses ++ */ ++ ++struct cifs_tcon * ++smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid) ++{ ++ struct cifs_ses *ses; ++ struct cifs_tcon *tcon; ++ ++ spin_lock(&cifs_tcp_ses_lock); ++ ses = smb2_find_smb_ses_unlocked(server, ses_id); ++ if (!ses) { ++ spin_unlock(&cifs_tcp_ses_lock); ++ return NULL; ++ } ++ tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid); ++ spin_unlock(&cifs_tcp_ses_lock); ++ ++ return tcon; ++} + + int + smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) +@@ -143,7 +189,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) + struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base; + struct cifs_ses *ses; + +- ses = smb2_find_smb_ses(smb2_pdu, server); ++ ses = smb2_find_smb_ses(server, smb2_pdu->SessionId); + if (!ses) { + cifs_dbg(VFS, "%s: Could not find session\n", __func__); + return 0; +@@ -314,7 +360,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) + struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base; + struct cifs_ses *ses; + +- ses = smb2_find_smb_ses(smb2_pdu, server); ++ ses = smb2_find_smb_ses(server, smb2_pdu->SessionId); + if (!ses) { + cifs_dbg(VFS, "%s: Could not find session\n", __func__); + return 0; +diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c +index 87abe8ed074c..54af10204e83 100644 +--- a/fs/cifs/transport.c ++++ b/fs/cifs/transport.c +@@ -786,9 +786,11 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, + + rc = wait_for_response(ses->server, midQ); + if (rc != 0) { ++ cifs_dbg(FYI, "Cancelling wait for mid %llu\n", midQ->mid); + send_cancel(ses->server, buf, midQ); + spin_lock(&GlobalMid_Lock); + if (midQ->mid_state == MID_REQUEST_SUBMITTED) { ++ midQ->mid_flags |= MID_WAIT_CANCELLED; + midQ->callback = DeleteMidQEntry; + spin_unlock(&GlobalMid_Lock); + cifs_small_buf_release(buf); +diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c +index 1a0835073663..9d6c2dcf1bd0 100644 +--- a/fs/ext4/crypto.c ++++ b/fs/ext4/crypto.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + #include "ext4_extents.h" + #include "xattr.h" +@@ -469,3 +470,61 @@ uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size) + return size; + return 0; + } ++ ++/* ++ * Validate dentries for encrypted directories to make sure we aren't ++ * potentially caching stale data after a key has been added or ++ * removed. ++ */ ++static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags) ++{ ++ struct dentry *dir; ++ struct ext4_crypt_info *ci; ++ int dir_has_key, cached_with_key; ++ ++ if (flags & LOOKUP_RCU) ++ return -ECHILD; ++ ++ dir = dget_parent(dentry); ++ if (!ext4_encrypted_inode(d_inode(dir))) { ++ dput(dir); ++ return 0; ++ } ++ ci = EXT4_I(d_inode(dir))->i_crypt_info; ++ ++ /* this should eventually be an flag in d_flags */ ++ cached_with_key = dentry->d_fsdata != NULL; ++ dir_has_key = (ci != NULL); ++ dput(dir); ++ ++ /* ++ * If the dentry was cached without the key, and it is a ++ * negative dentry, it might be a valid name. We can't check ++ * if the key has since been made available due to locking ++ * reasons, so we fail the validation so ext4_lookup() can do ++ * this check. ++ * ++ * We also fail the validation if the dentry was created with ++ * the key present, but we no longer have the key, or vice versa. ++ */ ++ if ((!cached_with_key && d_is_negative(dentry)) || ++ (!cached_with_key && dir_has_key) || ++ (cached_with_key && !dir_has_key)) { ++#if 0 /* Revalidation debug */ ++ char buf[80]; ++ char *cp = simple_dname(dentry, buf, sizeof(buf)); ++ ++ if (IS_ERR(cp)) ++ cp = (char *) "???"; ++ pr_err("revalidate: %s %p %d %d %d\n", cp, dentry->d_fsdata, ++ cached_with_key, d_is_negative(dentry), ++ dir_has_key); ++#endif ++ return 0; ++ } ++ return 1; ++} ++ ++const struct dentry_operations ext4_encrypted_d_ops = { ++ .d_revalidate = ext4_d_revalidate, ++}; +diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c +index 1d1bca74f844..6d17f31a31d7 100644 +--- a/fs/ext4/dir.c ++++ b/fs/ext4/dir.c +@@ -111,6 +111,12 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx) + int dir_has_error = 0; + struct ext4_str fname_crypto_str = {.name = NULL, .len = 0}; + ++ if (ext4_encrypted_inode(inode)) { ++ err = ext4_get_encryption_info(inode); ++ if (err && err != -ENOKEY) ++ return err; ++ } ++ + if (is_dx_dir(inode)) { + err = ext4_dx_readdir(file, ctx); + if (err != ERR_BAD_DX_DIR) { +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index 362d59b24f1d..3de9bb357b4f 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -2268,6 +2268,7 @@ struct page *ext4_encrypt(struct inode *inode, + struct page *plaintext_page); + int ext4_decrypt(struct page *page); + int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex); ++extern const struct dentry_operations ext4_encrypted_d_ops; + + #ifdef CONFIG_EXT4_FS_ENCRYPTION + int ext4_init_crypto(void); +diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c +index 789e2d6724a9..bcd7c4788903 100644 +--- a/fs/ext4/ioctl.c ++++ b/fs/ext4/ioctl.c +@@ -622,6 +622,9 @@ resizefs_out: + struct ext4_encryption_policy policy; + int err = 0; + ++ if (!ext4_has_feature_encrypt(sb)) ++ return -EOPNOTSUPP; ++ + if (copy_from_user(&policy, + (struct ext4_encryption_policy __user *)arg, + sizeof(policy))) { +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index 573b4cbb0cb9..fafa903ab3c0 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -1557,6 +1557,24 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi + struct ext4_dir_entry_2 *de; + struct buffer_head *bh; + ++ if (ext4_encrypted_inode(dir)) { ++ int res = ext4_get_encryption_info(dir); ++ ++ /* ++ * This should be a properly defined flag for ++ * dentry->d_flags when we uplift this to the VFS. ++ * d_fsdata is set to (void *) 1 if if the dentry is ++ * created while the directory was encrypted and we ++ * don't have access to the key. ++ */ ++ dentry->d_fsdata = NULL; ++ if (ext4_encryption_info(dir)) ++ dentry->d_fsdata = (void *) 1; ++ d_set_d_op(dentry, &ext4_encrypted_d_ops); ++ if (res && res != -ENOKEY) ++ return ERR_PTR(res); ++ } ++ + if (dentry->d_name.len > EXT4_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + +diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c +index 00575d776d91..7162ab7bc093 100644 +--- a/fs/nfsd/nfs3xdr.c ++++ b/fs/nfsd/nfs3xdr.c +@@ -358,6 +358,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + { + unsigned int len, v, hdr, dlen; + u32 max_blocksize = svc_max_payload(rqstp); ++ struct kvec *head = rqstp->rq_arg.head; + + p = decode_fh(p, &args->fh); + if (!p) +@@ -367,6 +368,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + args->count = ntohl(*p++); + args->stable = ntohl(*p++); + len = args->len = ntohl(*p++); ++ if ((void *)p > head->iov_base + head->iov_len) ++ return 0; + /* + * The count must equal the amount of data passed. + */ +@@ -377,9 +380,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + * Check to make sure that we got the right number of + * bytes. + */ +- hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; +- dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len +- - hdr; ++ hdr = (void*)p - head->iov_base; ++ dlen = head->iov_len + rqstp->rq_arg.page_len - hdr; + /* + * Round the length of the data which was specified up to + * the next multiple of XDR units and then compare that +@@ -396,7 +398,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + len = args->len = max_blocksize; + } + rqstp->rq_vec[0].iov_base = (void*)p; +- rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr; ++ rqstp->rq_vec[0].iov_len = head->iov_len - hdr; + v = 0; + while (len > rqstp->rq_vec[v].iov_len) { + len -= rqstp->rq_vec[v].iov_len; +@@ -471,6 +473,8 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, + /* first copy and check from the first page */ + old = (char*)p; + vec = &rqstp->rq_arg.head[0]; ++ if ((void *)old > vec->iov_base + vec->iov_len) ++ return 0; + avail = vec->iov_len - (old - (char*)vec->iov_base); + while (len && avail && *old) { + *new++ = *old++; +diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c +index 79d964aa8079..bf913201a6ad 100644 +--- a/fs/nfsd/nfsxdr.c ++++ b/fs/nfsd/nfsxdr.c +@@ -280,6 +280,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + struct nfsd_writeargs *args) + { + unsigned int len, hdr, dlen; ++ struct kvec *head = rqstp->rq_arg.head; + int v; + + p = decode_fh(p, &args->fh); +@@ -300,9 +301,10 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + * Check to make sure that we got the right number of + * bytes. + */ +- hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; +- dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len +- - hdr; ++ hdr = (void*)p - head->iov_base; ++ if (hdr > head->iov_len) ++ return 0; ++ dlen = head->iov_len + rqstp->rq_arg.page_len - hdr; + + /* + * Round the length of the data which was specified up to +@@ -316,7 +318,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + return 0; + + rqstp->rq_vec[0].iov_base = (void*)p; +- rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr; ++ rqstp->rq_vec[0].iov_len = head->iov_len - hdr; + v = 0; + while (len > rqstp->rq_vec[v].iov_len) { + len -= rqstp->rq_vec[v].iov_len; +diff --git a/fs/timerfd.c b/fs/timerfd.c +index 053818dd6c18..1327a02ec778 100644 +--- a/fs/timerfd.c ++++ b/fs/timerfd.c +@@ -40,6 +40,7 @@ struct timerfd_ctx { + short unsigned settime_flags; /* to show in fdinfo */ + struct rcu_head rcu; + struct list_head clist; ++ spinlock_t cancel_lock; + bool might_cancel; + }; + +@@ -112,7 +113,7 @@ void timerfd_clock_was_set(void) + rcu_read_unlock(); + } + +-static void timerfd_remove_cancel(struct timerfd_ctx *ctx) ++static void __timerfd_remove_cancel(struct timerfd_ctx *ctx) + { + if (ctx->might_cancel) { + ctx->might_cancel = false; +@@ -122,6 +123,13 @@ static void timerfd_remove_cancel(struct timerfd_ctx *ctx) + } + } + ++static void timerfd_remove_cancel(struct timerfd_ctx *ctx) ++{ ++ spin_lock(&ctx->cancel_lock); ++ __timerfd_remove_cancel(ctx); ++ spin_unlock(&ctx->cancel_lock); ++} ++ + static bool timerfd_canceled(struct timerfd_ctx *ctx) + { + if (!ctx->might_cancel || ctx->moffs.tv64 != KTIME_MAX) +@@ -132,6 +140,7 @@ static bool timerfd_canceled(struct timerfd_ctx *ctx) + + static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) + { ++ spin_lock(&ctx->cancel_lock); + if ((ctx->clockid == CLOCK_REALTIME || + ctx->clockid == CLOCK_REALTIME_ALARM) && + (flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) { +@@ -141,9 +150,10 @@ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) + list_add_rcu(&ctx->clist, &cancel_list); + spin_unlock(&cancel_lock); + } +- } else if (ctx->might_cancel) { +- timerfd_remove_cancel(ctx); ++ } else { ++ __timerfd_remove_cancel(ctx); + } ++ spin_unlock(&ctx->cancel_lock); + } + + static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx) +@@ -395,6 +405,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) + return -ENOMEM; + + init_waitqueue_head(&ctx->wqh); ++ spin_lock_init(&ctx->cancel_lock); + ctx->clockid = clockid; + + if (isalarm(ctx)) +diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h +index 366cf77953b5..806d0ab845e0 100644 +--- a/include/linux/mtd/map.h ++++ b/include/linux/mtd/map.h +@@ -122,18 +122,13 @@ + #endif + + #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32 +-# ifdef map_bankwidth +-# undef map_bankwidth +-# define map_bankwidth(map) ((map)->bankwidth) +-# undef map_bankwidth_is_large +-# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) +-# undef map_words +-# define map_words(map) map_calc_words(map) +-# else +-# define map_bankwidth(map) 32 +-# define map_bankwidth_is_large(map) (1) +-# define map_words(map) map_calc_words(map) +-# endif ++/* always use indirect access for 256-bit to preserve kernel stack */ ++# undef map_bankwidth ++# define map_bankwidth(map) ((map)->bankwidth) ++# undef map_bankwidth_is_large ++# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) ++# undef map_words ++# define map_words(map) map_calc_words(map) + #define map_bankwidth_is_32(map) (map_bankwidth(map) == 32) + #undef MAX_MAP_BANKWIDTH + #define MAX_MAP_BANKWIDTH 32 +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 8e33019d8e7b..acfb16fdcd55 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -2107,7 +2107,7 @@ static int netlink_dump(struct sock *sk) + if (!skb) { + alloc_size = alloc_min_size; + skb = netlink_alloc_skb(sk, alloc_size, nlk->portid, +- (GFP_KERNEL & ~__GFP_DIRECT_RECLAIM)); ++ GFP_KERNEL); + } + if (!skb) + goto errout_skb; +diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c +index 09da7b52bc2e..1468e4b7bf93 100644 +--- a/sound/ppc/awacs.c ++++ b/sound/ppc/awacs.c +@@ -991,6 +991,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip) + if (err < 0) + return err; + } ++ master_vol = NULL; + if (pm7500) + err = build_mixers(chip, + ARRAY_SIZE(snd_pmac_awacs_mixers_pmac7500), +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index 7a5c9a36c1db..daba8c56b43b 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -139,7 +139,7 @@ static struct snd_soc_dai_link byt_dailink[] = { + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", +- .ignore_suspend = 1, ++ .nonatomic = true, + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, +@@ -166,6 +166,7 @@ static struct snd_soc_dai_link byt_dailink[] = { + | SND_SOC_DAIFMT_CBS_CFS, + .be_hw_params_fixup = byt_codec_fixup, + .ignore_suspend = 1, ++ .nonatomic = true, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ops = &byt_be_ssp2_ops,