diff -druNp --no-dereference linux-libre-4.1.36-gnu/arch/arm/include/asm/dma-mapping.h linux-libre-4.1.37-gnu/arch/arm/include/asm/dma-mapping.h
--- linux-libre-4.1.36-gnu/arch/arm/include/asm/dma-mapping.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/arch/arm/include/asm/dma-mapping.h	2016-12-24 11:09:53.000000000 -0500
@@ -117,7 +117,7 @@ static inline dma_addr_t virt_to_dma(str
 /* The ARM override for dma_max_pfn() */
 static inline unsigned long dma_max_pfn(struct device *dev)
 {
-	return PHYS_PFN_OFFSET + dma_to_pfn(dev, *dev->dma_mask);
+	return dma_to_pfn(dev, *dev->dma_mask);
 }
 #define dma_max_pfn(dev) dma_max_pfn(dev)
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/arch/x86/include/asm/tlbflush.h linux-libre-4.1.37-gnu/arch/x86/include/asm/tlbflush.h
--- linux-libre-4.1.36-gnu/arch/x86/include/asm/tlbflush.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/arch/x86/include/asm/tlbflush.h	2016-12-24 11:09:53.000000000 -0500
@@ -32,7 +32,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct tl
 /* Initialize cr4 shadow for this CPU. */
 static inline void cr4_init_shadow(void)
 {
-	this_cpu_write(cpu_tlbstate.cr4, __read_cr4());
+	this_cpu_write(cpu_tlbstate.cr4, __read_cr4_safe());
 }
 
 /* Set in this cpu's CR4. */
diff -druNp --no-dereference linux-libre-4.1.36-gnu/arch/x86/purgatory/Makefile linux-libre-4.1.37-gnu/arch/x86/purgatory/Makefile
--- linux-libre-4.1.36-gnu/arch/x86/purgatory/Makefile	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/arch/x86/purgatory/Makefile	2016-12-24 11:09:53.000000000 -0500
@@ -12,6 +12,7 @@ targets += purgatory.ro
 
 KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -fno-builtin -ffreestanding -c -MD -Os -mcmodel=large
 KBUILD_CFLAGS += -m$(BITS)
+KBUILD_CFLAGS += $(call cc-option,-fno-PIE)
 
 $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
 		$(call if_changed,ld)
diff -druNp --no-dereference linux-libre-4.1.36-gnu/Documentation/arm/CCN.txt linux-libre-4.1.37-gnu/Documentation/arm/CCN.txt
--- linux-libre-4.1.36-gnu/Documentation/arm/CCN.txt	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/Documentation/arm/CCN.txt	2016-12-24 11:09:53.000000000 -0500
@@ -38,7 +38,7 @@ Example of perf tool use:
 / # perf list | grep ccn
   ccn/cycles/                                        [Kernel PMU event]
 <...>
-  ccn/xp_valid_flit/                                 [Kernel PMU event]
+  ccn/xp_valid_flit,xp=?,port=?,vc=?,dir=?/          [Kernel PMU event]
 <...>
 
 / # perf stat -C 0 -e ccn/cycles/,ccn/xp_valid_flit,xp=1,port=0,vc=1,dir=1/ \
diff -druNp --no-dereference linux-libre-4.1.36-gnu/Documentation/filesystems/porting linux-libre-4.1.37-gnu/Documentation/filesystems/porting
--- linux-libre-4.1.36-gnu/Documentation/filesystems/porting	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/Documentation/filesystems/porting	2016-12-24 11:09:53.000000000 -0500
@@ -287,8 +287,8 @@ implementing on-disk size changes.  Star
 and vmtruncate, and the reorder the vmtruncate + foofs_vmtruncate sequence to
 be in order of zeroing blocks using block_truncate_page or similar helpers,
 size update and on finally on-disk truncation which should not fail.
-inode_change_ok now includes the size checks for ATTR_SIZE and must be called
-in the beginning of ->setattr unconditionally.
+setattr_prepare (which used to be inode_change_ok) now includes the size checks
+for ATTR_SIZE and must be called in the beginning of ->setattr unconditionally.
 
 [mandatory]
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/Documentation/sysctl/fs.txt linux-libre-4.1.37-gnu/Documentation/sysctl/fs.txt
--- linux-libre-4.1.36-gnu/Documentation/sysctl/fs.txt	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/Documentation/sysctl/fs.txt	2016-12-24 11:09:53.000000000 -0500
@@ -265,6 +265,13 @@ aio-nr can grow to.
 
 ==============================================================
 
+mount-max:
+
+This denotes the maximum number of mounts that may exist
+in a mount namespace.
+
+==============================================================
+
 
 2. /proc/sys/fs/binfmt_misc
 ----------------------------------------------------------
diff -druNp --no-dereference linux-libre-4.1.36-gnu/drivers/bus/arm-ccn.c linux-libre-4.1.37-gnu/drivers/bus/arm-ccn.c
--- linux-libre-4.1.36-gnu/drivers/bus/arm-ccn.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/drivers/bus/arm-ccn.c	2016-12-24 11:09:53.000000000 -0500
@@ -183,6 +183,7 @@ struct arm_ccn {
 	struct arm_ccn_component *xp;
 
 	struct arm_ccn_dt dt;
+	int mn_id;
 };
 
 
@@ -322,6 +323,7 @@ struct arm_ccn_pmu_event {
 static ssize_t arm_ccn_pmu_event_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
+	struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev));
 	struct arm_ccn_pmu_event *event = container_of(attr,
 			struct arm_ccn_pmu_event, attr);
 	ssize_t res;
@@ -336,6 +338,26 @@ static ssize_t arm_ccn_pmu_event_show(st
 	if (event->mask)
 		res += snprintf(buf + res, PAGE_SIZE - res, ",mask=0x%x",
 				event->mask);
+
+	/* Arguments required by an event */
+	switch (event->type) {
+	case CCN_TYPE_CYCLES:
+		break;
+	case CCN_TYPE_XP:
+		res += snprintf(buf + res, PAGE_SIZE - res,
+				",xp=?,port=?,vc=?,dir=?");
+		if (event->event == CCN_EVENT_WATCHPOINT)
+			res += snprintf(buf + res, PAGE_SIZE - res,
+					",cmp_l=?,cmp_h=?,mask=?");
+		break;
+	case CCN_TYPE_MN:
+		res += snprintf(buf + res, PAGE_SIZE - res, ",node=%d", ccn->mn_id);
+		break;
+	default:
+		res += snprintf(buf + res, PAGE_SIZE - res, ",node=?");
+		break;
+	}
+
 	res += snprintf(buf + res, PAGE_SIZE - res, "\n");
 
 	return res;
@@ -360,9 +382,9 @@ static umode_t arm_ccn_pmu_events_is_vis
 }
 
 static struct arm_ccn_pmu_event arm_ccn_pmu_events[] = {
-	CCN_EVENT_MN(eobarrier, "dir=0,vc=0,cmp_h=0x1c00", CCN_IDX_MASK_OPCODE),
-	CCN_EVENT_MN(ecbarrier, "dir=0,vc=0,cmp_h=0x1e00", CCN_IDX_MASK_OPCODE),
-	CCN_EVENT_MN(dvmop, "dir=0,vc=0,cmp_h=0x2800", CCN_IDX_MASK_OPCODE),
+	CCN_EVENT_MN(eobarrier, "dir=1,vc=0,cmp_h=0x1c00", CCN_IDX_MASK_OPCODE),
+	CCN_EVENT_MN(ecbarrier, "dir=1,vc=0,cmp_h=0x1e00", CCN_IDX_MASK_OPCODE),
+	CCN_EVENT_MN(dvmop, "dir=1,vc=0,cmp_h=0x2800", CCN_IDX_MASK_OPCODE),
 	CCN_EVENT_HNI(txdatflits, "dir=1,vc=3", CCN_IDX_MASK_ANY),
 	CCN_EVENT_HNI(rxdatflits, "dir=0,vc=3", CCN_IDX_MASK_ANY),
 	CCN_EVENT_HNI(txreqflits, "dir=1,vc=0", CCN_IDX_MASK_ANY),
@@ -649,6 +671,12 @@ static int arm_ccn_pmu_event_init(struct
 
 	/* Validate node/xp vs topology */
 	switch (type) {
+	case CCN_TYPE_MN:
+		if (node_xp != ccn->mn_id) {
+			dev_warn(ccn->dev, "Invalid MN ID %d!\n", node_xp);
+			return -EINVAL;
+		}
+		break;
 	case CCN_TYPE_XP:
 		if (node_xp >= ccn->num_xps) {
 			dev_warn(ccn->dev, "Invalid XP ID %d!\n", node_xp);
@@ -1214,6 +1242,8 @@ static int arm_ccn_init_nodes(struct arm
 
 	switch (type) {
 	case CCN_TYPE_MN:
+		ccn->mn_id = id;
+		return 0;
 	case CCN_TYPE_DT:
 		return 0;
 	case CCN_TYPE_XP:
diff -druNp --no-dereference linux-libre-4.1.36-gnu/drivers/gpu/drm/msm/msm_gem_submit.c linux-libre-4.1.37-gnu/drivers/gpu/drm/msm/msm_gem_submit.c
--- linux-libre-4.1.36-gnu/drivers/gpu/drm/msm/msm_gem_submit.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/drivers/gpu/drm/msm/msm_gem_submit.c	2016-12-24 11:09:53.000000000 -0500
@@ -55,6 +55,14 @@ static struct msm_gem_submit *submit_cre
 	return submit;
 }
 
+static inline unsigned long __must_check
+copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
+{
+	if (access_ok(VERIFY_READ, from, n))
+		return __copy_from_user_inatomic(to, from, n);
+	return -EFAULT;
+}
+
 static int submit_lookup_objects(struct msm_gem_submit *submit,
 		struct drm_msm_gem_submit *args, struct drm_file *file)
 {
@@ -62,6 +70,7 @@ static int submit_lookup_objects(struct
 	int ret = 0;
 
 	spin_lock(&file->table_lock);
+	pagefault_disable();
 
 	for (i = 0; i < args->nr_bos; i++) {
 		struct drm_msm_gem_submit_bo submit_bo;
@@ -70,10 +79,15 @@ static int submit_lookup_objects(struct
 		void __user *userptr =
 			to_user_ptr(args->bos + (i * sizeof(submit_bo)));
 
-		ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
-		if (ret) {
-			ret = -EFAULT;
-			goto out_unlock;
+		ret = copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo));
+		if (unlikely(ret)) {
+			pagefault_enable();
+			spin_unlock(&file->table_lock);
+			ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
+			if (ret)
+				goto out;
+			spin_lock(&file->table_lock);
+			pagefault_disable();
 		}
 
 		if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) {
@@ -113,9 +127,12 @@ static int submit_lookup_objects(struct
 	}
 
 out_unlock:
-	submit->nr_bos = i;
+	pagefault_enable();
 	spin_unlock(&file->table_lock);
 
+out:
+	submit->nr_bos = i;
+
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/drivers/mtd/nand/davinci_nand.c linux-libre-4.1.37-gnu/drivers/mtd/nand/davinci_nand.c
--- linux-libre-4.1.36-gnu/drivers/mtd/nand/davinci_nand.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/drivers/mtd/nand/davinci_nand.c	2016-12-24 11:09:53.000000000 -0500
@@ -241,6 +241,9 @@ static void nand_davinci_hwctl_4bit(stru
 	unsigned long flags;
 	u32 val;
 
+	/* Reset ECC hardware */
+	davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET);
+
 	spin_lock_irqsave(&davinci_nand_lock, flags);
 
 	/* Start 4-bit ECC calculation for read/write */
diff -druNp --no-dereference linux-libre-4.1.36-gnu/drivers/net/can/dev.c linux-libre-4.1.37-gnu/drivers/net/can/dev.c
--- linux-libre-4.1.36-gnu/drivers/net/can/dev.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/drivers/net/can/dev.c	2016-12-24 11:09:53.000000000 -0500
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
+#include <linux/workqueue.h>
 #include <linux/can.h>
 #include <linux/can/dev.h>
 #include <linux/can/skb.h>
@@ -471,9 +472,8 @@ EXPORT_SYMBOL_GPL(can_free_echo_skb);
 /*
  * CAN device restart for bus-off recovery
  */
-static void can_restart(unsigned long data)
+static void can_restart(struct net_device *dev)
 {
-	struct net_device *dev = (struct net_device *)data;
 	struct can_priv *priv = netdev_priv(dev);
 	struct net_device_stats *stats = &dev->stats;
 	struct sk_buff *skb;
@@ -513,6 +513,14 @@ restart:
 		netdev_err(dev, "Error %d during restart", err);
 }
 
+static void can_restart_work(struct work_struct *work)
+{
+	struct delayed_work *dwork = to_delayed_work(work);
+	struct can_priv *priv = container_of(dwork, struct can_priv, restart_work);
+
+	can_restart(priv->dev);
+}
+
 int can_restart_now(struct net_device *dev)
 {
 	struct can_priv *priv = netdev_priv(dev);
@@ -526,8 +534,8 @@ int can_restart_now(struct net_device *d
 	if (priv->state != CAN_STATE_BUS_OFF)
 		return -EBUSY;
 
-	/* Runs as soon as possible in the timer context */
-	mod_timer(&priv->restart_timer, jiffies);
+	cancel_delayed_work_sync(&priv->restart_work);
+	can_restart(dev);
 
 	return 0;
 }
@@ -548,8 +556,8 @@ void can_bus_off(struct net_device *dev)
 	netif_carrier_off(dev);
 
 	if (priv->restart_ms)
-		mod_timer(&priv->restart_timer,
-			  jiffies + (priv->restart_ms * HZ) / 1000);
+		schedule_delayed_work(&priv->restart_work,
+				      msecs_to_jiffies(priv->restart_ms));
 }
 EXPORT_SYMBOL_GPL(can_bus_off);
 
@@ -658,6 +666,7 @@ struct net_device *alloc_candev(int size
 		return NULL;
 
 	priv = netdev_priv(dev);
+	priv->dev = dev;
 
 	if (echo_skb_max) {
 		priv->echo_skb_max = echo_skb_max;
@@ -667,7 +676,7 @@ struct net_device *alloc_candev(int size
 
 	priv->state = CAN_STATE_STOPPED;
 
-	init_timer(&priv->restart_timer);
+	INIT_DELAYED_WORK(&priv->restart_work, can_restart_work);
 
 	return dev;
 }
@@ -748,8 +757,6 @@ int open_candev(struct net_device *dev)
 	if (!netif_carrier_ok(dev))
 		netif_carrier_on(dev);
 
-	setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev);
-
 	return 0;
 }
 EXPORT_SYMBOL_GPL(open_candev);
@@ -764,7 +771,7 @@ void close_candev(struct net_device *dev
 {
 	struct can_priv *priv = netdev_priv(dev);
 
-	del_timer_sync(&priv->restart_timer);
+	cancel_delayed_work_sync(&priv->restart_work);
 	can_flush_echo_skb(dev);
 }
 EXPORT_SYMBOL_GPL(close_candev);
diff -druNp --no-dereference linux-libre-4.1.36-gnu/drivers/net/vxlan.c linux-libre-4.1.37-gnu/drivers/net/vxlan.c
--- linux-libre-4.1.36-gnu/drivers/net/vxlan.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/drivers/net/vxlan.c	2016-12-24 11:09:53.000000000 -0500
@@ -635,7 +635,7 @@ static struct sk_buff **vxlan_gro_receiv
 		}
 	}
 
-	pp = eth_gro_receive(head, skb);
+	pp = call_gro_receive(eth_gro_receive, head, skb);
 
 out:
 	skb_gro_remcsum_cleanup(skb, &grc);
diff -druNp --no-dereference linux-libre-4.1.36-gnu/drivers/scsi/arcmsr/arcmsr_hba.c linux-libre-4.1.37-gnu/drivers/scsi/arcmsr/arcmsr_hba.c
--- linux-libre-4.1.36-gnu/drivers/scsi/arcmsr/arcmsr_hba.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/drivers/scsi/arcmsr/arcmsr_hba.c	2016-12-24 11:09:53.000000000 -0500
@@ -2300,7 +2300,8 @@ static int arcmsr_iop_message_xfer(struc
 	}
 	case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
 		unsigned char *ver_addr;
-		int32_t user_len, cnt2end;
+		uint32_t user_len;
+		int32_t cnt2end;
 		uint8_t *pQbuffer, *ptmpuserbuffer;
 		ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC);
 		if (!ver_addr) {
@@ -2309,6 +2310,11 @@ static int arcmsr_iop_message_xfer(struc
 		}
 		ptmpuserbuffer = ver_addr;
 		user_len = pcmdmessagefld->cmdmessage.Length;
+		if (user_len > ARCMSR_API_DATA_BUFLEN) {
+			retvalue = ARCMSR_MESSAGE_FAIL;
+			kfree(ver_addr);
+			goto message_out;
+		}
 		memcpy(ptmpuserbuffer,
 			pcmdmessagefld->messagedatabuffer, user_len);
 		spin_lock_irqsave(&acb->wqbuffer_lock, flags);
diff -druNp --no-dereference linux-libre-4.1.36-gnu/drivers/scsi/megaraid/megaraid_sas.h linux-libre-4.1.37-gnu/drivers/scsi/megaraid/megaraid_sas.h
--- linux-libre-4.1.36-gnu/drivers/scsi/megaraid/megaraid_sas.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/drivers/scsi/megaraid/megaraid_sas.h	2016-12-24 11:09:53.000000000 -0500
@@ -1862,7 +1862,7 @@ struct megasas_instance_template {
 };
 
 #define MEGASAS_IS_LOGICAL(scp)						\
-	(scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1
+	((scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1)
 
 #define MEGASAS_DEV_INDEX(inst, scp)					\
 	((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + 	\
diff -druNp --no-dereference linux-libre-4.1.36-gnu/drivers/staging/lustre/lustre/llite/llite_lib.c linux-libre-4.1.37-gnu/drivers/staging/lustre/lustre/llite/llite_lib.c
--- linux-libre-4.1.36-gnu/drivers/staging/lustre/lustre/llite/llite_lib.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/drivers/staging/lustre/lustre/llite/llite_lib.c	2016-12-24 11:09:53.000000000 -0500
@@ -1323,7 +1323,7 @@ int ll_setattr_raw(struct dentry *dentry
 		attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
 	}
 
-	/* POSIX: check before ATTR_*TIME_SET set (from inode_change_ok) */
+	/* POSIX: check before ATTR_*TIME_SET set (from setattr_prepare) */
 	if (attr->ia_valid & TIMES_SET_FLAGS) {
 		if ((!uid_eq(current_fsuid(), inode->i_uid)) &&
 		    !capable(CFS_CAP_FOWNER))
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/9p/acl.c linux-libre-4.1.37-gnu/fs/9p/acl.c
--- linux-libre-4.1.36-gnu/fs/9p/acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/9p/acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -320,32 +320,26 @@ static int v9fs_xattr_set_acl(struct den
 	case ACL_TYPE_ACCESS:
 		name = POSIX_ACL_XATTR_ACCESS;
 		if (acl) {
-			umode_t mode = inode->i_mode;
-			retval = posix_acl_equiv_mode(acl, &mode);
-			if (retval < 0)
+			struct iattr iattr;
+
+			retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
+			if (retval)
 				goto err_out;
-			else {
-				struct iattr iattr;
-				if (retval == 0) {
-					/*
-					 * ACL can be represented
-					 * by the mode bits. So don't
-					 * update ACL.
-					 */
-					acl = NULL;
-					value = NULL;
-					size = 0;
-				}
-				/* Updte the mode bits */
-				iattr.ia_mode = ((mode & S_IALLUGO) |
-						 (inode->i_mode & ~S_IALLUGO));
-				iattr.ia_valid = ATTR_MODE;
-				/* FIXME should we update ctime ?
-				 * What is the following setxattr update the
-				 * mode ?
+			if (!acl) {
+				/*
+				 * ACL can be represented
+				 * by the mode bits. So don't
+				 * update ACL.
 				 */
-				v9fs_vfs_setattr_dotl(dentry, &iattr);
+				value = NULL;
+				size = 0;
 			}
+			iattr.ia_valid = ATTR_MODE;
+			/* FIXME should we update ctime ?
+			 * What is the following setxattr update the
+			 * mode ?
+			 */
+			v9fs_vfs_setattr_dotl(dentry, &iattr);
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/9p/vfs_inode.c linux-libre-4.1.37-gnu/fs/9p/vfs_inode.c
--- linux-libre-4.1.36-gnu/fs/9p/vfs_inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/9p/vfs_inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -1094,7 +1094,7 @@ static int v9fs_vfs_setattr(struct dentr
 	struct p9_wstat wstat;
 
 	p9_debug(P9_DEBUG_VFS, "\n");
-	retval = inode_change_ok(d_inode(dentry), iattr);
+	retval = setattr_prepare(dentry, iattr);
 	if (retval)
 		return retval;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/9p/vfs_inode_dotl.c linux-libre-4.1.37-gnu/fs/9p/vfs_inode_dotl.c
--- linux-libre-4.1.36-gnu/fs/9p/vfs_inode_dotl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/9p/vfs_inode_dotl.c	2016-12-24 11:09:53.000000000 -0500
@@ -560,7 +560,7 @@ int v9fs_vfs_setattr_dotl(struct dentry
 
 	p9_debug(P9_DEBUG_VFS, "\n");
 
-	retval = inode_change_ok(inode, iattr);
+	retval = setattr_prepare(dentry, iattr);
 	if (retval)
 		return retval;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/adfs/inode.c linux-libre-4.1.37-gnu/fs/adfs/inode.c
--- linux-libre-4.1.36-gnu/fs/adfs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/adfs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -303,7 +303,7 @@ adfs_notify_change(struct dentry *dentry
 	unsigned int ia_valid = attr->ia_valid;
 	int error;
 	
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 
 	/*
 	 * we can't change the UID or GID of any file -
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/affs/inode.c linux-libre-4.1.37-gnu/fs/affs/inode.c
--- linux-libre-4.1.36-gnu/fs/affs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/affs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -218,7 +218,7 @@ affs_notify_change(struct dentry *dentry
 
 	pr_debug("notify_change(%lu,0x%x)\n", inode->i_ino, attr->ia_valid);
 
-	error = inode_change_ok(inode,attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		goto out;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/attr.c linux-libre-4.1.37-gnu/fs/attr.c
--- linux-libre-4.1.36-gnu/fs/attr.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/attr.c	2016-12-24 11:09:53.000000000 -0500
@@ -17,19 +17,22 @@
 #include <linux/ima.h>
 
 /**
- * inode_change_ok - check if attribute changes to an inode are allowed
- * @inode:	inode to check
+ * setattr_prepare - check if attribute changes to a dentry are allowed
+ * @dentry:	dentry to check
  * @attr:	attributes to change
  *
  * Check if we are allowed to change the attributes contained in @attr
- * in the given inode.  This includes the normal unix access permission
- * checks, as well as checks for rlimits and others.
+ * in the given dentry.  This includes the normal unix access permission
+ * checks, as well as checks for rlimits and others. The function also clears
+ * SGID bit from mode if user is not allowed to set it. Also file capabilities
+ * and IMA extended attributes are cleared if ATTR_KILL_PRIV is set.
  *
  * Should be called as the first thing in ->setattr implementations,
  * possibly after taking additional locks.
  */
-int inode_change_ok(const struct inode *inode, struct iattr *attr)
+int setattr_prepare(struct dentry *dentry, struct iattr *attr)
 {
+	struct inode *inode = d_inode(dentry);
 	unsigned int ia_valid = attr->ia_valid;
 
 	/*
@@ -44,7 +47,7 @@ int inode_change_ok(const struct inode *
 
 	/* If force is set do it anyway. */
 	if (ia_valid & ATTR_FORCE)
-		return 0;
+		goto kill_priv;
 
 	/* Make sure a caller can chown. */
 	if ((ia_valid & ATTR_UID) &&
@@ -77,9 +80,19 @@ int inode_change_ok(const struct inode *
 			return -EPERM;
 	}
 
+kill_priv:
+	/* User has permission for the change */
+	if (ia_valid & ATTR_KILL_PRIV) {
+		int error;
+
+		error = security_inode_killpriv(dentry);
+		if (error)
+			return error;
+	}
+
 	return 0;
 }
-EXPORT_SYMBOL(inode_change_ok);
+EXPORT_SYMBOL(setattr_prepare);
 
 /**
  * inode_newsize_ok - may this inode be truncated to a given size
@@ -217,13 +230,11 @@ int notify_change(struct dentry * dentry
 	if (!(ia_valid & ATTR_MTIME_SET))
 		attr->ia_mtime = now;
 	if (ia_valid & ATTR_KILL_PRIV) {
-		attr->ia_valid &= ~ATTR_KILL_PRIV;
-		ia_valid &= ~ATTR_KILL_PRIV;
 		error = security_inode_need_killpriv(dentry);
-		if (error > 0)
-			error = security_inode_killpriv(dentry);
-		if (error)
+		if (error < 0)
 			return error;
+		if (error == 0)
+			ia_valid = attr->ia_valid &= ~ATTR_KILL_PRIV;
 	}
 
 	/*
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/btrfs/acl.c linux-libre-4.1.37-gnu/fs/btrfs/acl.c
--- linux-libre-4.1.36-gnu/fs/btrfs/acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/btrfs/acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -83,11 +83,9 @@ static int __btrfs_set_acl(struct btrfs_
 	case ACL_TYPE_ACCESS:
 		name = POSIX_ACL_XATTR_ACCESS;
 		if (acl) {
-			ret = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (ret < 0)
+			ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (ret)
 				return ret;
-			if (ret == 0)
-				acl = NULL;
 		}
 		ret = 0;
 		break;
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/btrfs/inode.c linux-libre-4.1.37-gnu/fs/btrfs/inode.c
--- linux-libre-4.1.36-gnu/fs/btrfs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/btrfs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -4975,7 +4975,7 @@ static int btrfs_setattr(struct dentry *
 	if (btrfs_root_readonly(root))
 		return -EROFS;
 
-	err = inode_change_ok(inode, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err)
 		return err;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ceph/acl.c linux-libre-4.1.37-gnu/fs/ceph/acl.c
--- linux-libre-4.1.36-gnu/fs/ceph/acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ceph/acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -94,11 +94,9 @@ int ceph_set_acl(struct inode *inode, st
 	case ACL_TYPE_ACCESS:
 		name = POSIX_ACL_XATTR_ACCESS;
 		if (acl) {
-			ret = posix_acl_equiv_mode(acl, &new_mode);
-			if (ret < 0)
+			ret = posix_acl_update_mode(inode, &new_mode, &acl);
+			if (ret)
 				goto out;
-			if (ret == 0)
-				acl = NULL;
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ceph/inode.c linux-libre-4.1.37-gnu/fs/ceph/inode.c
--- linux-libre-4.1.36-gnu/fs/ceph/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ceph/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -1728,7 +1728,7 @@ int ceph_setattr(struct dentry *dentry,
 	if (ceph_snap(inode) != CEPH_NOSNAP)
 		return -EROFS;
 
-	err = inode_change_ok(inode, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err != 0)
 		return err;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/cifs/inode.c linux-libre-4.1.37-gnu/fs/cifs/inode.c
--- linux-libre-4.1.36-gnu/fs/cifs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/cifs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -2134,7 +2134,7 @@ cifs_setattr_unix(struct dentry *direntr
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
 		attrs->ia_valid |= ATTR_FORCE;
 
-	rc = inode_change_ok(inode, attrs);
+	rc = setattr_prepare(direntry, attrs);
 	if (rc < 0)
 		goto out;
 
@@ -2274,7 +2274,7 @@ cifs_setattr_nounix(struct dentry *diren
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
 		attrs->ia_valid |= ATTR_FORCE;
 
-	rc = inode_change_ok(inode, attrs);
+	rc = setattr_prepare(direntry, attrs);
 	if (rc < 0) {
 		free_xid(xid);
 		return rc;
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ecryptfs/inode.c linux-libre-4.1.37-gnu/fs/ecryptfs/inode.c
--- linux-libre-4.1.36-gnu/fs/ecryptfs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ecryptfs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -942,7 +942,7 @@ static int ecryptfs_setattr(struct dentr
 	}
 	mutex_unlock(&crypt_stat->cs_mutex);
 
-	rc = inode_change_ok(inode, ia);
+	rc = setattr_prepare(dentry, ia);
 	if (rc)
 		goto out;
 	if (ia->ia_valid & ATTR_SIZE) {
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/exofs/inode.c linux-libre-4.1.37-gnu/fs/exofs/inode.c
--- linux-libre-4.1.36-gnu/fs/exofs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/exofs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -1038,7 +1038,7 @@ int exofs_setattr(struct dentry *dentry,
 	if (unlikely(error))
 		return error;
 
-	error = inode_change_ok(inode, iattr);
+	error = setattr_prepare(dentry, iattr);
 	if (unlikely(error))
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ext2/acl.c linux-libre-4.1.37-gnu/fs/ext2/acl.c
--- linux-libre-4.1.36-gnu/fs/ext2/acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ext2/acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -193,15 +193,11 @@ ext2_set_acl(struct inode *inode, struct
 		case ACL_TYPE_ACCESS:
 			name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
 			if (acl) {
-				error = posix_acl_equiv_mode(acl, &inode->i_mode);
-				if (error < 0)
+				error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+				if (error)
 					return error;
-				else {
-					inode->i_ctime = CURRENT_TIME_SEC;
-					mark_inode_dirty(inode);
-					if (error == 0)
-						acl = NULL;
-				}
+				inode->i_ctime = CURRENT_TIME_SEC;
+				mark_inode_dirty(inode);
 			}
 			break;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ext2/inode.c linux-libre-4.1.37-gnu/fs/ext2/inode.c
--- linux-libre-4.1.36-gnu/fs/ext2/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ext2/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -1547,7 +1547,7 @@ int ext2_setattr(struct dentry *dentry,
 	struct inode *inode = d_inode(dentry);
 	int error;
 
-	error = inode_change_ok(inode, iattr);
+	error = setattr_prepare(dentry, iattr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ext3/inode.c linux-libre-4.1.37-gnu/fs/ext3/inode.c
--- linux-libre-4.1.36-gnu/fs/ext3/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ext3/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -3244,7 +3244,7 @@ int ext3_setattr(struct dentry *dentry,
 	int error, rc = 0;
 	const unsigned int ia_valid = attr->ia_valid;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ext4/acl.c linux-libre-4.1.37-gnu/fs/ext4/acl.c
--- linux-libre-4.1.36-gnu/fs/ext4/acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ext4/acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -196,15 +196,11 @@ __ext4_set_acl(handle_t *handle, struct
 	case ACL_TYPE_ACCESS:
 		name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
 		if (acl) {
-			error = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (error < 0)
+			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (error)
 				return error;
-			else {
-				inode->i_ctime = ext4_current_time(inode);
-				ext4_mark_inode_dirty(handle, inode);
-				if (error == 0)
-					acl = NULL;
-			}
+			inode->i_ctime = ext4_current_time(inode);
+			ext4_mark_inode_dirty(handle, inode);
 		}
 		break;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ext4/ext4.h linux-libre-4.1.37-gnu/fs/ext4/ext4.h
--- linux-libre-4.1.36-gnu/fs/ext4/ext4.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ext4/ext4.h	2016-12-24 11:09:53.000000000 -0500
@@ -1008,6 +1008,7 @@ struct ext4_inode_info {
 /*
  * Mount flags set via mount options or defaults
  */
+#define EXT4_MOUNT_NO_MBCACHE		0x00001 /* Disable mbcache */
 #define EXT4_MOUNT_GRPID		0x00004	/* Create files with directory's group */
 #define EXT4_MOUNT_DEBUG		0x00008	/* Some debugging messages */
 #define EXT4_MOUNT_ERRORS_CONT		0x00010	/* Continue on errors */
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ext4/inode.c linux-libre-4.1.37-gnu/fs/ext4/inode.c
--- linux-libre-4.1.36-gnu/fs/ext4/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ext4/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -4751,7 +4751,7 @@ int ext4_setattr(struct dentry *dentry,
 	int orphan = 0;
 	const unsigned int ia_valid = attr->ia_valid;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ext4/super.c linux-libre-4.1.37-gnu/fs/ext4/super.c
--- linux-libre-4.1.36-gnu/fs/ext4/super.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ext4/super.c	2016-12-24 11:09:53.000000000 -0500
@@ -1144,6 +1144,7 @@ enum {
 	Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
 	Opt_inode_readahead_blks, Opt_journal_ioprio,
 	Opt_dioread_nolock, Opt_dioread_lock,
+	Opt_no_mbcache,
 	Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
 	Opt_max_dir_size_kb, Opt_nojournal_checksum,
 };
@@ -1222,6 +1223,7 @@ static const match_table_t tokens = {
 	{Opt_discard, "discard"},
 	{Opt_nodiscard, "nodiscard"},
 	{Opt_init_itable, "init_itable=%u"},
+	{Opt_no_mbcache, "no_mbcache"},
 	{Opt_init_itable, "init_itable"},
 	{Opt_noinit_itable, "noinit_itable"},
 	{Opt_max_dir_size_kb, "max_dir_size_kb=%u"},
@@ -1385,6 +1387,7 @@ static const struct mount_opts {
 	{Opt_noauto_da_alloc, EXT4_MOUNT_NO_AUTO_DA_ALLOC, MOPT_SET},
 	{Opt_auto_da_alloc, EXT4_MOUNT_NO_AUTO_DA_ALLOC, MOPT_CLEAR},
 	{Opt_noinit_itable, EXT4_MOUNT_INIT_INODE_TABLE, MOPT_CLEAR},
+	{Opt_no_mbcache, EXT4_MOUNT_NO_MBCACHE, MOPT_SET},
 	{Opt_commit, 0, MOPT_GTE0},
 	{Opt_max_batch_time, 0, MOPT_GTE0},
 	{Opt_min_batch_time, 0, MOPT_GTE0},
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ext4/xattr.c linux-libre-4.1.37-gnu/fs/ext4/xattr.c
--- linux-libre-4.1.36-gnu/fs/ext4/xattr.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ext4/xattr.c	2016-12-24 11:09:53.000000000 -0500
@@ -80,7 +80,7 @@
 # define ea_bdebug(bh, fmt, ...)	no_printk(fmt, ##__VA_ARGS__)
 #endif
 
-static void ext4_xattr_cache_insert(struct mb_cache *, struct buffer_head *);
+static void ext4_xattr_cache_insert(struct inode *, struct buffer_head *);
 static struct buffer_head *ext4_xattr_cache_find(struct inode *,
 						 struct ext4_xattr_header *,
 						 struct mb_cache_entry **);
@@ -278,7 +278,6 @@ ext4_xattr_block_get(struct inode *inode
 	struct ext4_xattr_entry *entry;
 	size_t size;
 	int error;
-	struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
 
 	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
 		  name_index, name, buffer, (long)buffer_size);
@@ -300,7 +299,7 @@ bad_block:
 		error = -EIO;
 		goto cleanup;
 	}
-	ext4_xattr_cache_insert(ext4_mb_cache, bh);
+	ext4_xattr_cache_insert(inode, bh);
 	entry = BFIRST(bh);
 	error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1);
 	if (error == -EIO)
@@ -426,7 +425,6 @@ ext4_xattr_block_list(struct dentry *den
 	struct inode *inode = d_inode(dentry);
 	struct buffer_head *bh = NULL;
 	int error;
-	struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
 
 	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
 		  buffer, (long)buffer_size);
@@ -448,7 +446,7 @@ ext4_xattr_block_list(struct dentry *den
 		error = -EIO;
 		goto cleanup;
 	}
-	ext4_xattr_cache_insert(ext4_mb_cache, bh);
+	ext4_xattr_cache_insert(inode, bh);
 	error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size);
 
 cleanup:
@@ -547,7 +545,8 @@ ext4_xattr_release_block(handle_t *handl
 	int error = 0;
 	struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
 
-	ce = mb_cache_entry_get(ext4_mb_cache, bh->b_bdev, bh->b_blocknr);
+	if (!test_opt(inode->i_sb, NO_MBCACHE))
+		ce = mb_cache_entry_get(ext4_mb_cache, bh->b_bdev, bh->b_blocknr);
 	BUFFER_TRACE(bh, "get_write_access");
 	error = ext4_journal_get_write_access(handle, bh);
 	if (error)
@@ -788,8 +787,9 @@ ext4_xattr_block_set(handle_t *handle, s
 	if (i->value && i->value_len > sb->s_blocksize)
 		return -ENOSPC;
 	if (s->base) {
-		ce = mb_cache_entry_get(ext4_mb_cache, bs->bh->b_bdev,
-					bs->bh->b_blocknr);
+		if (!test_opt(inode->i_sb, NO_MBCACHE))
+			ce = mb_cache_entry_get(ext4_mb_cache, bs->bh->b_bdev,
+						bs->bh->b_blocknr);
 		BUFFER_TRACE(bs->bh, "get_write_access");
 		error = ext4_journal_get_write_access(handle, bs->bh);
 		if (error)
@@ -807,7 +807,7 @@ ext4_xattr_block_set(handle_t *handle, s
 				if (!IS_LAST_ENTRY(s->first))
 					ext4_xattr_rehash(header(s->base),
 							  s->here);
-				ext4_xattr_cache_insert(ext4_mb_cache,
+				ext4_xattr_cache_insert(inode,
 					bs->bh);
 			}
 			unlock_buffer(bs->bh);
@@ -892,7 +892,8 @@ inserted:
 				if (error)
 					goto cleanup_dquot;
 			}
-			mb_cache_entry_release(ce);
+			if (ce)
+				mb_cache_entry_release(ce);
 			ce = NULL;
 		} else if (bs->bh && s->base == bs->bh->b_data) {
 			/* We were modifying this block in-place. */
@@ -939,7 +940,7 @@ getblk_failed:
 			memcpy(new_bh->b_data, s->base, new_bh->b_size);
 			set_buffer_uptodate(new_bh);
 			unlock_buffer(new_bh);
-			ext4_xattr_cache_insert(ext4_mb_cache, new_bh);
+			ext4_xattr_cache_insert(inode, new_bh);
 			error = ext4_handle_dirty_xattr_block(handle,
 							      inode, new_bh);
 			if (error)
@@ -1529,12 +1530,17 @@ ext4_xattr_put_super(struct super_block
  * Returns 0, or a negative error number on failure.
  */
 static void
-ext4_xattr_cache_insert(struct mb_cache *ext4_mb_cache, struct buffer_head *bh)
+ext4_xattr_cache_insert(struct inode *inode, struct buffer_head *bh)
 {
+	struct super_block *sb = inode->i_sb;
+	struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
 	__u32 hash = le32_to_cpu(BHDR(bh)->h_hash);
 	struct mb_cache_entry *ce;
 	int error;
 
+	if (test_opt(sb, NO_MBCACHE))
+		return;
+
 	ce = mb_cache_entry_alloc(ext4_mb_cache, GFP_NOFS);
 	if (!ce) {
 		ea_bdebug(bh, "out of memory");
@@ -1609,6 +1615,8 @@ ext4_xattr_cache_find(struct inode *inod
 	struct mb_cache_entry *ce;
 	struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
 
+	if (test_opt(inode->i_sb, NO_MBCACHE))
+		return NULL;
 	if (!header->h_hash)
 		return NULL;  /* never share */
 	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/f2fs/acl.c linux-libre-4.1.37-gnu/fs/f2fs/acl.c
--- linux-libre-4.1.36-gnu/fs/f2fs/acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/f2fs/acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -214,12 +214,10 @@ static int __f2fs_set_acl(struct inode *
 	case ACL_TYPE_ACCESS:
 		name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
 		if (acl) {
-			error = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (error < 0)
+			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (error)
 				return error;
 			set_acl_inode(fi, inode->i_mode);
-			if (error == 0)
-				acl = NULL;
 		}
 		break;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/f2fs/file.c linux-libre-4.1.37-gnu/fs/f2fs/file.c
--- linux-libre-4.1.36-gnu/fs/f2fs/file.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/f2fs/file.c	2016-12-24 11:09:53.000000000 -0500
@@ -617,7 +617,7 @@ int f2fs_setattr(struct dentry *dentry,
 	struct f2fs_inode_info *fi = F2FS_I(inode);
 	int err;
 
-	err = inode_change_ok(inode, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err)
 		return err;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/fat/file.c linux-libre-4.1.37-gnu/fs/fat/file.c
--- linux-libre-4.1.36-gnu/fs/fat/file.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/fat/file.c	2016-12-24 11:09:53.000000000 -0500
@@ -388,7 +388,7 @@ int fat_setattr(struct dentry *dentry, s
 			attr->ia_valid &= ~TIMES_SET_FLAGS;
 	}
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	attr->ia_valid = ia_valid;
 	if (error) {
 		if (sbi->options.quiet)
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/fuse/dir.c linux-libre-4.1.37-gnu/fs/fuse/dir.c
--- linux-libre-4.1.36-gnu/fs/fuse/dir.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/fuse/dir.c	2016-12-24 11:09:53.000000000 -0500
@@ -1602,9 +1602,10 @@ int fuse_flush_times(struct inode *inode
  * vmtruncate() doesn't allow for this case, so do the rlimit checking
  * and the actual truncation by hand.
  */
-int fuse_do_setattr(struct inode *inode, struct iattr *attr,
+int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
 		    struct file *file)
 {
+	struct inode *inode = d_inode(dentry);
 	struct fuse_conn *fc = get_fuse_conn(inode);
 	struct fuse_inode *fi = get_fuse_inode(inode);
 	FUSE_ARGS(args);
@@ -1619,7 +1620,7 @@ int fuse_do_setattr(struct inode *inode,
 	if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
 		attr->ia_valid |= ATTR_FORCE;
 
-	err = inode_change_ok(inode, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err)
 		return err;
 
@@ -1718,9 +1719,9 @@ static int fuse_setattr(struct dentry *e
 		return -EACCES;
 
 	if (attr->ia_valid & ATTR_FILE)
-		return fuse_do_setattr(inode, attr, attr->ia_file);
+		return fuse_do_setattr(entry, attr, attr->ia_file);
 	else
-		return fuse_do_setattr(inode, attr, NULL);
+		return fuse_do_setattr(entry, attr, NULL);
 }
 
 static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/fuse/file.c linux-libre-4.1.37-gnu/fs/fuse/file.c
--- linux-libre-4.1.36-gnu/fs/fuse/file.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/fuse/file.c	2016-12-24 11:09:53.000000000 -0500
@@ -2797,7 +2797,7 @@ static void fuse_do_truncate(struct file
 	attr.ia_file = file;
 	attr.ia_valid |= ATTR_FILE;
 
-	fuse_do_setattr(inode, &attr, file);
+	fuse_do_setattr(file->f_path.dentry, &attr, file);
 }
 
 static inline loff_t fuse_round_up(loff_t off)
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/fuse/fuse_i.h linux-libre-4.1.37-gnu/fs/fuse/fuse_i.h
--- linux-libre-4.1.36-gnu/fs/fuse/fuse_i.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/fuse/fuse_i.h	2016-12-24 11:09:53.000000000 -0500
@@ -913,7 +913,7 @@ bool fuse_write_update_size(struct inode
 int fuse_flush_times(struct inode *inode, struct fuse_file *ff);
 int fuse_write_inode(struct inode *inode, struct writeback_control *wbc);
 
-int fuse_do_setattr(struct inode *inode, struct iattr *attr,
+int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
 		    struct file *file);
 
 void fuse_set_initialized(struct fuse_conn *fc);
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/gfs2/acl.c linux-libre-4.1.37-gnu/fs/gfs2/acl.c
--- linux-libre-4.1.36-gnu/fs/gfs2/acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/gfs2/acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -79,17 +79,11 @@ int gfs2_set_acl(struct inode *inode, st
 	if (type == ACL_TYPE_ACCESS) {
 		umode_t mode = inode->i_mode;
 
-		error = posix_acl_equiv_mode(acl, &mode);
-		if (error < 0)
+		error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+		if (error)
 			return error;
-
-		if (error == 0)
-			acl = NULL;
-
-		if (mode != inode->i_mode) {
-			inode->i_mode = mode;
+		if (mode != inode->i_mode)
 			mark_inode_dirty(inode);
-		}
 	}
 
 	if (acl) {
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/gfs2/inode.c linux-libre-4.1.37-gnu/fs/gfs2/inode.c
--- linux-libre-4.1.36-gnu/fs/gfs2/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/gfs2/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -1759,7 +1759,7 @@ static int gfs2_setattr(struct dentry *d
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		goto out;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		goto out;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/hfs/inode.c linux-libre-4.1.37-gnu/fs/hfs/inode.c
--- linux-libre-4.1.36-gnu/fs/hfs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/hfs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -604,7 +604,7 @@ int hfs_inode_setattr(struct dentry *den
 	struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
 	int error;
 
-	error = inode_change_ok(inode, attr); /* basic permission checks */
+	error = setattr_prepare(dentry, attr); /* basic permission checks */
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/hfsplus/inode.c linux-libre-4.1.37-gnu/fs/hfsplus/inode.c
--- linux-libre-4.1.36-gnu/fs/hfsplus/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/hfsplus/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -246,7 +246,7 @@ static int hfsplus_setattr(struct dentry
 	struct inode *inode = d_inode(dentry);
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/hfsplus/posix_acl.c linux-libre-4.1.37-gnu/fs/hfsplus/posix_acl.c
--- linux-libre-4.1.36-gnu/fs/hfsplus/posix_acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/hfsplus/posix_acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -68,8 +68,8 @@ int hfsplus_set_posix_acl(struct inode *
 	case ACL_TYPE_ACCESS:
 		xattr_name = POSIX_ACL_XATTR_ACCESS;
 		if (acl) {
-			err = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (err < 0)
+			err = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (err)
 				return err;
 		}
 		err = 0;
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/hostfs/hostfs_kern.c linux-libre-4.1.37-gnu/fs/hostfs/hostfs_kern.c
--- linux-libre-4.1.36-gnu/fs/hostfs/hostfs_kern.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/hostfs/hostfs_kern.c	2016-12-24 11:09:53.000000000 -0500
@@ -812,7 +812,7 @@ static int hostfs_setattr(struct dentry
 
 	int fd = HOSTFS_I(inode)->fd;
 
-	err = inode_change_ok(inode, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err)
 		return err;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/hpfs/inode.c linux-libre-4.1.37-gnu/fs/hpfs/inode.c
--- linux-libre-4.1.36-gnu/fs/hpfs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/hpfs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -272,7 +272,7 @@ int hpfs_setattr(struct dentry *dentry,
 	if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size)
 		goto out_unlock;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		goto out_unlock;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/hugetlbfs/inode.c linux-libre-4.1.37-gnu/fs/hugetlbfs/inode.c
--- linux-libre-4.1.36-gnu/fs/hugetlbfs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/hugetlbfs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -400,7 +400,7 @@ static int hugetlbfs_setattr(struct dent
 
 	BUG_ON(!inode);
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/jffs2/acl.c linux-libre-4.1.37-gnu/fs/jffs2/acl.c
--- linux-libre-4.1.36-gnu/fs/jffs2/acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/jffs2/acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -235,9 +235,10 @@ int jffs2_set_acl(struct inode *inode, s
 	case ACL_TYPE_ACCESS:
 		xprefix = JFFS2_XPREFIX_ACL_ACCESS;
 		if (acl) {
-			umode_t mode = inode->i_mode;
-			rc = posix_acl_equiv_mode(acl, &mode);
-			if (rc < 0)
+			umode_t mode;
+
+			rc = posix_acl_update_mode(inode, &mode, &acl);
+			if (rc)
 				return rc;
 			if (inode->i_mode != mode) {
 				struct iattr attr;
@@ -249,8 +250,6 @@ int jffs2_set_acl(struct inode *inode, s
 				if (rc < 0)
 					return rc;
 			}
-			if (rc == 0)
-				acl = NULL;
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/jffs2/fs.c linux-libre-4.1.37-gnu/fs/jffs2/fs.c
--- linux-libre-4.1.36-gnu/fs/jffs2/fs.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/jffs2/fs.c	2016-12-24 11:09:53.000000000 -0500
@@ -193,7 +193,7 @@ int jffs2_setattr(struct dentry *dentry,
 	struct inode *inode = d_inode(dentry);
 	int rc;
 
-	rc = inode_change_ok(inode, iattr);
+	rc = setattr_prepare(dentry, iattr);
 	if (rc)
 		return rc;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/jfs/acl.c linux-libre-4.1.37-gnu/fs/jfs/acl.c
--- linux-libre-4.1.36-gnu/fs/jfs/acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/jfs/acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -84,13 +84,11 @@ static int __jfs_set_acl(tid_t tid, stru
 	case ACL_TYPE_ACCESS:
 		ea_name = POSIX_ACL_XATTR_ACCESS;
 		if (acl) {
-			rc = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (rc < 0)
+			rc = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (rc)
 				return rc;
 			inode->i_ctime = CURRENT_TIME;
 			mark_inode_dirty(inode);
-			if (rc == 0)
-				acl = NULL;
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/jfs/file.c linux-libre-4.1.37-gnu/fs/jfs/file.c
--- linux-libre-4.1.36-gnu/fs/jfs/file.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/jfs/file.c	2016-12-24 11:09:53.000000000 -0500
@@ -103,7 +103,7 @@ int jfs_setattr(struct dentry *dentry, s
 	struct inode *inode = d_inode(dentry);
 	int rc;
 
-	rc = inode_change_ok(inode, iattr);
+	rc = setattr_prepare(dentry, iattr);
 	if (rc)
 		return rc;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/kernfs/inode.c linux-libre-4.1.37-gnu/fs/kernfs/inode.c
--- linux-libre-4.1.36-gnu/fs/kernfs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/kernfs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -119,7 +119,7 @@ int kernfs_iop_setattr(struct dentry *de
 		return -EINVAL;
 
 	mutex_lock(&kernfs_mutex);
-	error = inode_change_ok(inode, iattr);
+	error = setattr_prepare(dentry, iattr);
 	if (error)
 		goto out;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/libfs.c linux-libre-4.1.37-gnu/fs/libfs.c
--- linux-libre-4.1.36-gnu/fs/libfs.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/libfs.c	2016-12-24 11:09:53.000000000 -0500
@@ -371,7 +371,7 @@ int simple_setattr(struct dentry *dentry
 	struct inode *inode = d_inode(dentry);
 	int error;
 
-	error = inode_change_ok(inode, iattr);
+	error = setattr_prepare(dentry, iattr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/logfs/file.c linux-libre-4.1.37-gnu/fs/logfs/file.c
--- linux-libre-4.1.36-gnu/fs/logfs/file.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/logfs/file.c	2016-12-24 11:09:53.000000000 -0500
@@ -244,7 +244,7 @@ static int logfs_setattr(struct dentry *
 	struct inode *inode = d_inode(dentry);
 	int err = 0;
 
-	err = inode_change_ok(inode, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err)
 		return err;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/minix/file.c linux-libre-4.1.37-gnu/fs/minix/file.c
--- linux-libre-4.1.36-gnu/fs/minix/file.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/minix/file.c	2016-12-24 11:09:53.000000000 -0500
@@ -26,7 +26,7 @@ static int minix_setattr(struct dentry *
 	struct inode *inode = d_inode(dentry);
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/mount.h linux-libre-4.1.37-gnu/fs/mount.h
--- linux-libre-4.1.36-gnu/fs/mount.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/mount.h	2016-12-24 11:09:53.000000000 -0500
@@ -13,6 +13,8 @@ struct mnt_namespace {
 	u64			seq;	/* Sequence number to prevent loops */
 	wait_queue_head_t poll;
 	u64 event;
+	unsigned int		mounts; /* # of mounts in the namespace */
+	unsigned int		pending_mounts;
 };
 
 struct mnt_pcp {
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/namespace.c linux-libre-4.1.37-gnu/fs/namespace.c
--- linux-libre-4.1.36-gnu/fs/namespace.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/namespace.c	2016-12-24 11:09:53.000000000 -0500
@@ -27,6 +27,9 @@
 #include "pnode.h"
 #include "internal.h"
 
+/* Maximum number of mounts in a mount namespace */
+unsigned int sysctl_mount_max __read_mostly = 100000;
+
 static unsigned int m_hash_mask __read_mostly;
 static unsigned int m_hash_shift __read_mostly;
 static unsigned int mp_hash_mask __read_mostly;
@@ -888,6 +891,9 @@ static void commit_tree(struct mount *mn
 
 	list_splice(&head, n->list.prev);
 
+	n->mounts += n->pending_mounts;
+	n->pending_mounts = 0;
+
 	attach_shadowed(mnt, parent, shadows);
 	touch_mnt_namespace(n);
 }
@@ -1408,11 +1414,16 @@ static void umount_tree(struct mount *mn
 		propagate_umount(&tmp_list);
 
 	while (!list_empty(&tmp_list)) {
+		struct mnt_namespace *ns;
 		bool disconnect;
 		p = list_first_entry(&tmp_list, struct mount, mnt_list);
 		list_del_init(&p->mnt_expire);
 		list_del_init(&p->mnt_list);
-		__touch_mnt_namespace(p->mnt_ns);
+		ns = p->mnt_ns;
+		if (ns) {
+			ns->mounts--;
+			__touch_mnt_namespace(ns);
+		}
 		p->mnt_ns = NULL;
 		if (how & UMOUNT_SYNC)
 			p->mnt.mnt_flags |= MNT_SYNC_UMOUNT;
@@ -1821,6 +1832,28 @@ static int invent_group_ids(struct mount
 	return 0;
 }
 
+int count_mounts(struct mnt_namespace *ns, struct mount *mnt)
+{
+	unsigned int max = READ_ONCE(sysctl_mount_max);
+	unsigned int mounts = 0, old, pending, sum;
+	struct mount *p;
+
+	for (p = mnt; p; p = next_mnt(p, mnt))
+		mounts++;
+
+	old = ns->mounts;
+	pending = ns->pending_mounts;
+	sum = old + pending;
+	if ((old > sum) ||
+	    (pending > sum) ||
+	    (max < sum) ||
+	    (mounts > (max - sum)))
+		return -ENOSPC;
+
+	ns->pending_mounts = pending + mounts;
+	return 0;
+}
+
 /*
  *  @source_mnt : mount tree to be attached
  *  @nd         : place the mount tree @source_mnt is attached
@@ -1890,10 +1923,18 @@ static int attach_recursive_mnt(struct m
 			struct path *parent_path)
 {
 	HLIST_HEAD(tree_list);
+	struct mnt_namespace *ns = dest_mnt->mnt_ns;
 	struct mount *child, *p;
 	struct hlist_node *n;
 	int err;
 
+	/* Is there space to add these mounts to the mount namespace? */
+	if (!parent_path) {
+		err = count_mounts(ns, source_mnt);
+		if (err)
+			goto out;
+	}
+
 	if (IS_MNT_SHARED(dest_mnt)) {
 		err = invent_group_ids(source_mnt, true);
 		if (err)
@@ -1930,11 +1971,13 @@ static int attach_recursive_mnt(struct m
  out_cleanup_ids:
 	while (!hlist_empty(&tree_list)) {
 		child = hlist_entry(tree_list.first, struct mount, mnt_hash);
+		child->mnt_parent->mnt_ns->pending_mounts = 0;
 		umount_tree(child, UMOUNT_SYNC);
 	}
 	unlock_mount_hash();
 	cleanup_group_ids(source_mnt, NULL);
  out:
+	ns->pending_mounts = 0;
 	return err;
 }
 
@@ -2758,6 +2801,8 @@ static struct mnt_namespace *alloc_mnt_n
 	init_waitqueue_head(&new_ns->poll);
 	new_ns->event = 0;
 	new_ns->user_ns = get_user_ns(user_ns);
+	new_ns->mounts = 0;
+	new_ns->pending_mounts = 0;
 	return new_ns;
 }
 
@@ -2807,6 +2852,7 @@ struct mnt_namespace *copy_mnt_ns(unsign
 	q = new;
 	while (p) {
 		q->mnt_ns = new_ns;
+		new_ns->mounts++;
 		if (new_fs) {
 			if (&p->mnt == new_fs->root.mnt) {
 				new_fs->root.mnt = mntget(&q->mnt);
@@ -2845,6 +2891,7 @@ static struct mnt_namespace *create_mnt_
 		struct mount *mnt = real_mount(m);
 		mnt->mnt_ns = new_ns;
 		new_ns->root = mnt;
+		new_ns->mounts++;
 		list_add(&mnt->mnt_list, &new_ns->list);
 	} else {
 		mntput(m);
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ncpfs/inode.c linux-libre-4.1.37-gnu/fs/ncpfs/inode.c
--- linux-libre-4.1.36-gnu/fs/ncpfs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ncpfs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -884,7 +884,7 @@ int ncp_notify_change(struct dentry *den
 	/* ageing the dentry to force validation */
 	ncp_age_dentry(server, dentry);
 
-	result = inode_change_ok(inode, attr);
+	result = setattr_prepare(dentry, attr);
 	if (result < 0)
 		goto out;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/nfsd/nfsproc.c linux-libre-4.1.37-gnu/fs/nfsd/nfsproc.c
--- linux-libre-4.1.36-gnu/fs/nfsd/nfsproc.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/nfsd/nfsproc.c	2016-12-24 11:09:53.000000000 -0500
@@ -59,13 +59,59 @@ static __be32
 nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp,
 					  struct nfsd_attrstat  *resp)
 {
+	struct iattr *iap = &argp->attrs;
+	struct svc_fh *fhp;
 	__be32 nfserr;
+
 	dprintk("nfsd: SETATTR  %s, valid=%x, size=%ld\n",
 		SVCFH_fmt(&argp->fh),
 		argp->attrs.ia_valid, (long) argp->attrs.ia_size);
 
-	fh_copy(&resp->fh, &argp->fh);
-	nfserr = nfsd_setattr(rqstp, &resp->fh, &argp->attrs,0, (time_t)0);
+	fhp = fh_copy(&resp->fh, &argp->fh);
+
+	/*
+	 * NFSv2 does not differentiate between "set-[ac]time-to-now"
+	 * which only requires access, and "set-[ac]time-to-X" which
+	 * requires ownership.
+	 * So if it looks like it might be "set both to the same time which
+	 * is close to now", and if setattr_prepare fails, then we
+	 * convert to "set to now" instead of "set to explicit time"
+	 *
+	 * We only call setattr_prepare as the last test as technically
+	 * it is not an interface that we should be using.
+	 */
+#define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
+#define	MAX_TOUCH_TIME_ERROR (30*60)
+	if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET &&
+	    iap->ia_mtime.tv_sec == iap->ia_atime.tv_sec) {
+		/*
+		 * Looks probable.
+		 *
+		 * Now just make sure time is in the right ballpark.
+		 * Solaris, at least, doesn't seem to care what the time
+		 * request is.  We require it be within 30 minutes of now.
+		 */
+		time_t delta = iap->ia_atime.tv_sec - get_seconds();
+
+		nfserr = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP);
+		if (nfserr)
+			goto done;
+
+		if (delta < 0)
+			delta = -delta;
+		if (delta < MAX_TOUCH_TIME_ERROR &&
+		    setattr_prepare(fhp->fh_dentry, iap) != 0) {
+			/*
+			 * Turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME.
+			 * This will cause notify_change to set these times
+			 * to "now"
+			 */
+			iap->ia_valid &= ~BOTH_TIME_SET;
+		}
+	}
+
+	nfserr = nfsd_setattr(rqstp, fhp, iap, 0, (time_t)0);
+done:
 	return nfsd_return_attrs(nfserr, resp);
 }
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/nfsd/vfs.c linux-libre-4.1.37-gnu/fs/nfsd/vfs.c
--- linux-libre-4.1.36-gnu/fs/nfsd/vfs.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/nfsd/vfs.c	2016-12-24 11:09:53.000000000 -0500
@@ -302,42 +302,6 @@ commit_metadata(struct svc_fh *fhp)
 static void
 nfsd_sanitize_attrs(struct inode *inode, struct iattr *iap)
 {
-	/*
-	 * NFSv2 does not differentiate between "set-[ac]time-to-now"
-	 * which only requires access, and "set-[ac]time-to-X" which
-	 * requires ownership.
-	 * So if it looks like it might be "set both to the same time which
-	 * is close to now", and if inode_change_ok fails, then we
-	 * convert to "set to now" instead of "set to explicit time"
-	 *
-	 * We only call inode_change_ok as the last test as technically
-	 * it is not an interface that we should be using.
-	 */
-#define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
-#define	MAX_TOUCH_TIME_ERROR (30*60)
-	if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET &&
-	    iap->ia_mtime.tv_sec == iap->ia_atime.tv_sec) {
-		/*
-		 * Looks probable.
-		 *
-		 * Now just make sure time is in the right ballpark.
-		 * Solaris, at least, doesn't seem to care what the time
-		 * request is.  We require it be within 30 minutes of now.
-		 */
-		time_t delta = iap->ia_atime.tv_sec - get_seconds();
-		if (delta < 0)
-			delta = -delta;
-		if (delta < MAX_TOUCH_TIME_ERROR &&
-		    inode_change_ok(inode, iap) != 0) {
-			/*
-			 * Turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME.
-			 * This will cause notify_change to set these times
-			 * to "now"
-			 */
-			iap->ia_valid &= ~BOTH_TIME_SET;
-		}
-	}
-
 	/* sanitize the mode change */
 	if (iap->ia_valid & ATTR_MODE) {
 		iap->ia_mode &= S_IALLUGO;
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/nilfs2/inode.c linux-libre-4.1.37-gnu/fs/nilfs2/inode.c
--- linux-libre-4.1.36-gnu/fs/nilfs2/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/nilfs2/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -839,7 +839,7 @@ int nilfs_setattr(struct dentry *dentry,
 	struct super_block *sb = inode->i_sb;
 	int err;
 
-	err = inode_change_ok(inode, iattr);
+	err = setattr_prepare(dentry, iattr);
 	if (err)
 		return err;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ntfs/inode.c linux-libre-4.1.37-gnu/fs/ntfs/inode.c
--- linux-libre-4.1.36-gnu/fs/ntfs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ntfs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -2893,7 +2893,7 @@ int ntfs_setattr(struct dentry *dentry,
 	int err;
 	unsigned int ia_valid = attr->ia_valid;
 
-	err = inode_change_ok(vi, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err)
 		goto out;
 	/* We do not support NTFS ACLs yet. */
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ocfs2/acl.c linux-libre-4.1.37-gnu/fs/ocfs2/acl.c
--- linux-libre-4.1.36-gnu/fs/ocfs2/acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ocfs2/acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -241,13 +241,11 @@ int ocfs2_set_acl(handle_t *handle,
 	case ACL_TYPE_ACCESS:
 		name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
 		if (acl) {
-			umode_t mode = inode->i_mode;
-			ret = posix_acl_equiv_mode(acl, &mode);
-			if (ret < 0)
-				return ret;
+			umode_t mode;
 
-			if (ret == 0)
-				acl = NULL;
+			ret = posix_acl_update_mode(inode, &mode, &acl);
+			if (ret)
+				return ret;
 
 			ret = ocfs2_acl_set_mode(inode, di_bh,
 						 handle, mode);
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ocfs2/dlmfs/dlmfs.c linux-libre-4.1.37-gnu/fs/ocfs2/dlmfs/dlmfs.c
--- linux-libre-4.1.36-gnu/fs/ocfs2/dlmfs/dlmfs.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ocfs2/dlmfs/dlmfs.c	2016-12-24 11:09:53.000000000 -0500
@@ -211,7 +211,7 @@ static int dlmfs_file_setattr(struct den
 	struct inode *inode = d_inode(dentry);
 
 	attr->ia_valid &= ~ATTR_SIZE;
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ocfs2/file.c linux-libre-4.1.37-gnu/fs/ocfs2/file.c
--- linux-libre-4.1.36-gnu/fs/ocfs2/file.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ocfs2/file.c	2016-12-24 11:09:53.000000000 -0500
@@ -1150,7 +1150,7 @@ int ocfs2_setattr(struct dentry *dentry,
 	if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
 		return 0;
 
-	status = inode_change_ok(inode, attr);
+	status = setattr_prepare(dentry, attr);
 	if (status)
 		return status;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/omfs/file.c linux-libre-4.1.37-gnu/fs/omfs/file.c
--- linux-libre-4.1.36-gnu/fs/omfs/file.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/omfs/file.c	2016-12-24 11:09:53.000000000 -0500
@@ -349,7 +349,7 @@ static int omfs_setattr(struct dentry *d
 	struct inode *inode = d_inode(dentry);
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/overlayfs/inode.c linux-libre-4.1.37-gnu/fs/overlayfs/inode.c
--- linux-libre-4.1.36-gnu/fs/overlayfs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/overlayfs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -54,7 +54,7 @@ int ovl_setattr(struct dentry *dentry, s
 	 * inode_newsize_ok() will always check against MAX_LFS_FILESIZE and not
 	 * check for a swapfile (which this won't be anyway).
 	 */
-	err = inode_change_ok(dentry->d_inode, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err)
 		return err;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/pnode.c linux-libre-4.1.37-gnu/fs/pnode.c
--- linux-libre-4.1.36-gnu/fs/pnode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/pnode.c	2016-12-24 11:09:53.000000000 -0500
@@ -259,7 +259,7 @@ static int propagate_one(struct mount *m
 		read_sequnlock_excl(&mount_lock);
 	}
 	hlist_add_head(&child->mnt_hash, list);
-	return 0;
+	return count_mounts(m->mnt_ns, child);
 }
 
 /*
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/pnode.h linux-libre-4.1.37-gnu/fs/pnode.h
--- linux-libre-4.1.36-gnu/fs/pnode.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/pnode.h	2016-12-24 11:09:53.000000000 -0500
@@ -52,4 +52,5 @@ void mnt_set_mountpoint(struct mount *,
 struct mount *copy_tree(struct mount *, struct dentry *, int);
 bool is_path_reachable(struct mount *, struct dentry *,
 			 const struct path *root);
+int count_mounts(struct mnt_namespace *ns, struct mount *mnt);
 #endif /* _LINUX_PNODE_H */
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/posix_acl.c linux-libre-4.1.37-gnu/fs/posix_acl.c
--- linux-libre-4.1.36-gnu/fs/posix_acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/posix_acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -598,6 +598,37 @@ no_mem:
 }
 EXPORT_SYMBOL_GPL(posix_acl_create);
 
+/**
+ * posix_acl_update_mode  -  update mode in set_acl
+ *
+ * Update the file mode when setting an ACL: compute the new file permission
+ * bits based on the ACL.  In addition, if the ACL is equivalent to the new
+ * file mode, set *acl to NULL to indicate that no ACL should be set.
+ *
+ * As with chmod, clear the setgit bit if the caller is not in the owning group
+ * or capable of CAP_FSETID (see inode_change_ok).
+ *
+ * Called from set_acl inode operations.
+ */
+int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,
+			  struct posix_acl **acl)
+{
+	umode_t mode = inode->i_mode;
+	int error;
+
+	error = posix_acl_equiv_mode(*acl, &mode);
+	if (error < 0)
+		return error;
+	if (error == 0)
+		*acl = NULL;
+	if (!in_group_p(inode->i_gid) &&
+	    !capable_wrt_inode_uidgid(inode, CAP_FSETID))
+		mode &= ~S_ISGID;
+	*mode_p = mode;
+	return 0;
+}
+EXPORT_SYMBOL(posix_acl_update_mode);
+
 /*
  * Fix up the uids and gids in posix acl extended attributes in place.
  */
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/proc/base.c linux-libre-4.1.37-gnu/fs/proc/base.c
--- linux-libre-4.1.36-gnu/fs/proc/base.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/proc/base.c	2016-12-24 11:09:53.000000000 -0500
@@ -517,7 +517,7 @@ int proc_setattr(struct dentry *dentry,
 	if (attr->ia_valid & ATTR_MODE)
 		return -EPERM;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/proc/generic.c linux-libre-4.1.37-gnu/fs/proc/generic.c
--- linux-libre-4.1.36-gnu/fs/proc/generic.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/proc/generic.c	2016-12-24 11:09:53.000000000 -0500
@@ -105,7 +105,7 @@ static int proc_notify_change(struct den
 	struct proc_dir_entry *de = PDE(inode);
 	int error;
 
-	error = inode_change_ok(inode, iattr);
+	error = setattr_prepare(dentry, iattr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/proc/proc_sysctl.c linux-libre-4.1.37-gnu/fs/proc/proc_sysctl.c
--- linux-libre-4.1.36-gnu/fs/proc/proc_sysctl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/proc/proc_sysctl.c	2016-12-24 11:09:53.000000000 -0500
@@ -753,7 +753,7 @@ static int proc_sys_setattr(struct dentr
 	if (attr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
 		return -EPERM;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ramfs/file-nommu.c linux-libre-4.1.37-gnu/fs/ramfs/file-nommu.c
--- linux-libre-4.1.36-gnu/fs/ramfs/file-nommu.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ramfs/file-nommu.c	2016-12-24 11:09:53.000000000 -0500
@@ -168,7 +168,7 @@ static int ramfs_nommu_setattr(struct de
 	int ret = 0;
 
 	/* POSIX UID/GID verification for setting inode attributes */
-	ret = inode_change_ok(inode, ia);
+	ret = setattr_prepare(dentry, ia);
 	if (ret)
 		return ret;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/reiserfs/inode.c linux-libre-4.1.37-gnu/fs/reiserfs/inode.c
--- linux-libre-4.1.36-gnu/fs/reiserfs/inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/reiserfs/inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -3312,7 +3312,7 @@ int reiserfs_setattr(struct dentry *dent
 	unsigned int ia_valid;
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/reiserfs/xattr_acl.c linux-libre-4.1.37-gnu/fs/reiserfs/xattr_acl.c
--- linux-libre-4.1.36-gnu/fs/reiserfs/xattr_acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/reiserfs/xattr_acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -246,13 +246,9 @@ __reiserfs_set_acl(struct reiserfs_trans
 	case ACL_TYPE_ACCESS:
 		name = POSIX_ACL_XATTR_ACCESS;
 		if (acl) {
-			error = posix_acl_equiv_mode(acl, &inode->i_mode);
-			if (error < 0)
+			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+			if (error)
 				return error;
-			else {
-				if (error == 0)
-					acl = NULL;
-			}
 		}
 		break;
 	case ACL_TYPE_DEFAULT:
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/sysv/file.c linux-libre-4.1.37-gnu/fs/sysv/file.c
--- linux-libre-4.1.36-gnu/fs/sysv/file.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/sysv/file.c	2016-12-24 11:09:53.000000000 -0500
@@ -33,7 +33,7 @@ static int sysv_setattr(struct dentry *d
 	struct inode *inode = d_inode(dentry);
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ubifs/file.c linux-libre-4.1.37-gnu/fs/ubifs/file.c
--- linux-libre-4.1.36-gnu/fs/ubifs/file.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ubifs/file.c	2016-12-24 11:09:53.000000000 -0500
@@ -1263,7 +1263,7 @@ int ubifs_setattr(struct dentry *dentry,
 
 	dbg_gen("ino %lu, mode %#x, ia_valid %#x",
 		inode->i_ino, inode->i_mode, attr->ia_valid);
-	err = inode_change_ok(inode, attr);
+	err = setattr_prepare(dentry, attr);
 	if (err)
 		return err;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/udf/file.c linux-libre-4.1.37-gnu/fs/udf/file.c
--- linux-libre-4.1.36-gnu/fs/udf/file.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/udf/file.c	2016-12-24 11:09:53.000000000 -0500
@@ -252,7 +252,7 @@ static int udf_setattr(struct dentry *de
 	struct inode *inode = d_inode(dentry);
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/ufs/truncate.c linux-libre-4.1.37-gnu/fs/ufs/truncate.c
--- linux-libre-4.1.36-gnu/fs/ufs/truncate.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/ufs/truncate.c	2016-12-24 11:09:53.000000000 -0500
@@ -496,7 +496,7 @@ int ufs_setattr(struct dentry *dentry, s
 	unsigned int ia_valid = attr->ia_valid;
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/utimes.c linux-libre-4.1.37-gnu/fs/utimes.c
--- linux-libre-4.1.36-gnu/fs/utimes.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/utimes.c	2016-12-24 11:09:53.000000000 -0500
@@ -81,7 +81,7 @@ static int utimes_common(struct path *pa
 			newattrs.ia_valid |= ATTR_MTIME_SET;
 		}
 		/*
-		 * Tell inode_change_ok(), that this is an explicit time
+		 * Tell setattr_prepare(), that this is an explicit time
 		 * update, even if neither ATTR_ATIME_SET nor ATTR_MTIME_SET
 		 * were used.
 		 */
@@ -90,7 +90,7 @@ static int utimes_common(struct path *pa
 		/*
 		 * If times is NULL (or both times are UTIME_NOW),
 		 * then we need to check permissions, because
-		 * inode_change_ok() won't do it.
+		 * setattr_prepare() won't do it.
 		 */
 		error = -EACCES;
                 if (IS_IMMUTABLE(inode))
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/xfs/xfs_acl.c linux-libre-4.1.37-gnu/fs/xfs/xfs_acl.c
--- linux-libre-4.1.36-gnu/fs/xfs/xfs_acl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/xfs/xfs_acl.c	2016-12-24 11:09:53.000000000 -0500
@@ -284,16 +284,11 @@ xfs_set_acl(struct inode *inode, struct
 		return error;
 
 	if (type == ACL_TYPE_ACCESS) {
-		umode_t mode = inode->i_mode;
-		error = posix_acl_equiv_mode(acl, &mode);
-
-		if (error <= 0) {
-			acl = NULL;
-
-			if (error < 0)
-				return error;
-		}
+		umode_t mode;
 
+		error = posix_acl_update_mode(inode, &mode, &acl);
+		if (error)
+			return error;
 		error = xfs_set_mode(inode, mode);
 		if (error)
 			return error;
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/xfs/xfs_file.c linux-libre-4.1.37-gnu/fs/xfs/xfs_file.c
--- linux-libre-4.1.36-gnu/fs/xfs/xfs_file.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/xfs/xfs_file.c	2016-12-24 11:09:53.000000000 -0500
@@ -973,7 +973,7 @@ xfs_file_fallocate(
 
 		iattr.ia_valid = ATTR_SIZE;
 		iattr.ia_size = new_size;
-		error = xfs_setattr_size(ip, &iattr);
+		error = xfs_vn_setattr_size(file->f_path.dentry, &iattr);
 		if (error)
 			goto out_unlock;
 	}
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/xfs/xfs_inode.c linux-libre-4.1.37-gnu/fs/xfs/xfs_inode.c
--- linux-libre-4.1.36-gnu/fs/xfs/xfs_inode.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/xfs/xfs_inode.c	2016-12-24 11:09:53.000000000 -0500
@@ -1766,7 +1766,7 @@ xfs_inactive_truncate(
 	/*
 	 * Log the inode size first to prevent stale data exposure in the event
 	 * of a system crash before the truncate completes. See the related
-	 * comment in xfs_setattr_size() for details.
+	 * comment in xfs_vn_setattr_size() for details.
 	 */
 	ip->i_d.di_size = 0;
 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/xfs/xfs_ioctl.c linux-libre-4.1.37-gnu/fs/xfs/xfs_ioctl.c
--- linux-libre-4.1.36-gnu/fs/xfs/xfs_ioctl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/xfs/xfs_ioctl.c	2016-12-24 11:09:53.000000000 -0500
@@ -720,7 +720,7 @@ xfs_ioc_space(
 		iattr.ia_valid = ATTR_SIZE;
 		iattr.ia_size = bf->l_start;
 
-		error = xfs_setattr_size(ip, &iattr);
+		error = xfs_vn_setattr_size(filp->f_path.dentry, &iattr);
 		break;
 	default:
 		ASSERT(0);
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/xfs/xfs_iops.c linux-libre-4.1.37-gnu/fs/xfs/xfs_iops.c
--- linux-libre-4.1.36-gnu/fs/xfs/xfs_iops.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/xfs/xfs_iops.c	2016-12-24 11:09:53.000000000 -0500
@@ -537,6 +537,30 @@ xfs_setattr_time(
 	}
 }
 
+static int
+xfs_vn_change_ok(
+	struct dentry	*dentry,
+	struct iattr	*iattr)
+{
+	struct inode		*inode = d_inode(dentry);
+	struct xfs_inode	*ip = XFS_I(inode);
+	struct xfs_mount	*mp = ip->i_mount;
+
+	if (mp->m_flags & XFS_MOUNT_RDONLY)
+		return -EROFS;
+
+	if (XFS_FORCED_SHUTDOWN(mp))
+		return -EIO;
+
+	return setattr_prepare(dentry, iattr);
+}
+
+/*
+ * Set non-size attributes of an inode.
+ *
+ * Caution: The caller of this function is responsible for calling
+ * setattr_prepare() or otherwise verifying the change is fine.
+ */
 int
 xfs_setattr_nonsize(
 	struct xfs_inode	*ip,
@@ -553,21 +577,6 @@ xfs_setattr_nonsize(
 	struct xfs_dquot	*udqp = NULL, *gdqp = NULL;
 	struct xfs_dquot	*olddquot1 = NULL, *olddquot2 = NULL;
 
-	trace_xfs_setattr(ip);
-
-	/* If acls are being inherited, we already have this checked */
-	if (!(flags & XFS_ATTR_NOACL)) {
-		if (mp->m_flags & XFS_MOUNT_RDONLY)
-			return -EROFS;
-
-		if (XFS_FORCED_SHUTDOWN(mp))
-			return -EIO;
-
-		error = inode_change_ok(inode, iattr);
-		if (error)
-			return error;
-	}
-
 	ASSERT((mask & ATTR_SIZE) == 0);
 
 	/*
@@ -741,8 +750,27 @@ out_dqrele:
 	return error;
 }
 
+int
+xfs_vn_setattr_nonsize(
+	struct dentry		*dentry,
+	struct iattr		*iattr)
+{
+	struct xfs_inode	*ip = XFS_I(d_inode(dentry));
+	int error;
+
+	trace_xfs_setattr(ip);
+
+	error = xfs_vn_change_ok(dentry, iattr);
+	if (error)
+		return error;
+	return xfs_setattr_nonsize(ip, iattr, 0);
+}
+
 /*
  * Truncate file.  Must have write permission and not be a directory.
+ *
+ * Caution: The caller of this function is responsible for calling
+ * setattr_prepare() or otherwise verifying the change is fine.
  */
 int
 xfs_setattr_size(
@@ -758,18 +786,6 @@ xfs_setattr_size(
 	uint			commit_flags = 0;
 	bool			did_zeroing = false;
 
-	trace_xfs_setattr(ip);
-
-	if (mp->m_flags & XFS_MOUNT_RDONLY)
-		return -EROFS;
-
-	if (XFS_FORCED_SHUTDOWN(mp))
-		return -EIO;
-
-	error = inode_change_ok(inode, iattr);
-	if (error)
-		return error;
-
 	ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
 	ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL));
 	ASSERT(S_ISREG(ip->i_d.di_mode));
@@ -941,16 +957,32 @@ out_trans_cancel:
 	goto out_unlock;
 }
 
+int
+xfs_vn_setattr_size(
+	struct dentry		*dentry,
+	struct iattr		*iattr)
+{
+	struct xfs_inode	*ip = XFS_I(d_inode(dentry));
+	int error;
+
+	trace_xfs_setattr(ip);
+
+	error = xfs_vn_change_ok(dentry, iattr);
+	if (error)
+		return error;
+	return xfs_setattr_size(ip, iattr);
+}
+
 STATIC int
 xfs_vn_setattr(
 	struct dentry		*dentry,
 	struct iattr		*iattr)
 {
-	struct xfs_inode	*ip = XFS_I(d_inode(dentry));
 	int			error;
 
 	if (iattr->ia_valid & ATTR_SIZE) {
-		uint		iolock = XFS_IOLOCK_EXCL;
+		struct xfs_inode	*ip = XFS_I(d_inode(dentry));
+		uint			iolock = XFS_IOLOCK_EXCL;
 
 		xfs_ilock(ip, iolock);
 		error = xfs_break_layouts(d_inode(dentry), &iolock, true);
@@ -958,11 +990,11 @@ xfs_vn_setattr(
 			xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
 			iolock |= XFS_MMAPLOCK_EXCL;
 
-			error = xfs_setattr_size(ip, iattr);
+			error = xfs_vn_setattr_size(dentry, iattr);
 		}
 		xfs_iunlock(ip, iolock);
 	} else {
-		error = xfs_setattr_nonsize(ip, iattr, 0);
+		error = xfs_vn_setattr_nonsize(dentry, iattr);
 	}
 
 	return error;
diff -druNp --no-dereference linux-libre-4.1.36-gnu/fs/xfs/xfs_iops.h linux-libre-4.1.37-gnu/fs/xfs/xfs_iops.h
--- linux-libre-4.1.36-gnu/fs/xfs/xfs_iops.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/fs/xfs/xfs_iops.h	2016-12-24 11:09:53.000000000 -0500
@@ -33,6 +33,7 @@ extern ssize_t xfs_vn_listxattr(struct d
 extern void xfs_setattr_time(struct xfs_inode *ip, struct iattr *iattr);
 extern int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap,
 			       int flags);
-extern int xfs_setattr_size(struct xfs_inode *ip, struct iattr *vap);
+extern int xfs_vn_setattr_nonsize(struct dentry *dentry, struct iattr *vap);
+extern int xfs_vn_setattr_size(struct dentry *dentry, struct iattr *vap);
 
 #endif /* __XFS_IOPS_H__ */
diff -druNp --no-dereference linux-libre-4.1.36-gnu/include/linux/can/dev.h linux-libre-4.1.37-gnu/include/linux/can/dev.h
--- linux-libre-4.1.36-gnu/include/linux/can/dev.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/include/linux/can/dev.h	2016-12-24 11:09:53.000000000 -0500
@@ -31,6 +31,7 @@ enum can_mode {
  * CAN common private data
  */
 struct can_priv {
+	struct net_device *dev;
 	struct can_device_stats can_stats;
 
 	struct can_bittiming bittiming, data_bittiming;
@@ -46,7 +47,7 @@ struct can_priv {
 	u32 ctrlmode_static;	/* static enabled options for driver/hardware */
 
 	int restart_ms;
-	struct timer_list restart_timer;
+	struct delayed_work restart_work;
 
 	int (*do_set_bittiming)(struct net_device *dev);
 	int (*do_set_data_bittiming)(struct net_device *dev);
diff -druNp --no-dereference linux-libre-4.1.36-gnu/include/linux/fs.h linux-libre-4.1.37-gnu/include/linux/fs.h
--- linux-libre-4.1.36-gnu/include/linux/fs.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/include/linux/fs.h	2016-12-24 11:09:53.000000000 -0500
@@ -2816,7 +2816,7 @@ extern int buffer_migrate_page(struct ad
 #define buffer_migrate_page NULL
 #endif
 
-extern int inode_change_ok(const struct inode *, struct iattr *);
+extern int setattr_prepare(struct dentry *, struct iattr *);
 extern int inode_newsize_ok(const struct inode *, loff_t offset);
 extern void setattr_copy(struct inode *inode, const struct iattr *attr);
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/include/linux/mount.h linux-libre-4.1.37-gnu/include/linux/mount.h
--- linux-libre-4.1.36-gnu/include/linux/mount.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/include/linux/mount.h	2016-12-24 11:09:53.000000000 -0500
@@ -95,4 +95,6 @@ extern void mark_mounts_for_expiry(struc
 
 extern dev_t name_to_dev_t(const char *name);
 
+extern unsigned int sysctl_mount_max;
+
 #endif /* _LINUX_MOUNT_H */
diff -druNp --no-dereference linux-libre-4.1.36-gnu/include/linux/netdevice.h linux-libre-4.1.37-gnu/include/linux/netdevice.h
--- linux-libre-4.1.36-gnu/include/linux/netdevice.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/include/linux/netdevice.h	2016-12-24 11:09:53.000000000 -0500
@@ -1957,7 +1957,10 @@ struct napi_gro_cb {
 	/* Used in foo-over-udp, set in udp[46]_gro_receive */
 	u8	is_ipv6:1;
 
-	/* 7 bit hole */
+	/* Number of gro_receive callbacks this packet already went through */
+	u8 recursion_counter:4;
+
+	/* 3 bit hole */
 
 	/* used to support CHECKSUM_COMPLETE for tunneling protocols */
 	__wsum	csum;
@@ -1968,6 +1971,25 @@ struct napi_gro_cb {
 
 #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb)
 
+#define GRO_RECURSION_LIMIT 15
+static inline int gro_recursion_inc_test(struct sk_buff *skb)
+{
+	return ++NAPI_GRO_CB(skb)->recursion_counter == GRO_RECURSION_LIMIT;
+}
+
+typedef struct sk_buff **(*gro_receive_t)(struct sk_buff **, struct sk_buff *);
+static inline struct sk_buff **call_gro_receive(gro_receive_t cb,
+						struct sk_buff **head,
+						struct sk_buff *skb)
+{
+	if (gro_recursion_inc_test(skb)) {
+		NAPI_GRO_CB(skb)->flush |= 1;
+		return NULL;
+	}
+
+	return cb(head, skb);
+}
+
 struct packet_type {
 	__be16			type;	/* This is really htons(ether_type). */
 	struct net_device	*dev;	/* NULL is wildcarded here	     */
diff -druNp --no-dereference linux-libre-4.1.36-gnu/include/linux/posix_acl.h linux-libre-4.1.37-gnu/include/linux/posix_acl.h
--- linux-libre-4.1.36-gnu/include/linux/posix_acl.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/include/linux/posix_acl.h	2016-12-24 11:09:53.000000000 -0500
@@ -95,6 +95,7 @@ extern int set_posix_acl(struct inode *,
 extern int posix_acl_chmod(struct inode *, umode_t);
 extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **,
 		struct posix_acl **);
+extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **);
 
 extern int simple_set_acl(struct inode *, struct posix_acl *, int);
 extern int simple_acl_create(struct inode *, struct inode *);
diff -druNp --no-dereference linux-libre-4.1.36-gnu/include/net/tcp.h linux-libre-4.1.37-gnu/include/net/tcp.h
--- linux-libre-4.1.36-gnu/include/net/tcp.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/include/net/tcp.h	2016-12-24 11:09:53.000000000 -0500
@@ -1434,6 +1434,8 @@ static inline void tcp_check_send_head(s
 {
 	if (sk->sk_send_head == skb_unlinked)
 		sk->sk_send_head = NULL;
+	if (tcp_sk(sk)->highest_sack == skb_unlinked)
+		tcp_sk(sk)->highest_sack = NULL;
 }
 
 static inline void tcp_init_send_head(struct sock *sk)
diff -druNp --no-dereference linux-libre-4.1.36-gnu/kernel/cpuset.c linux-libre-4.1.37-gnu/kernel/cpuset.c
--- linux-libre-4.1.36-gnu/kernel/cpuset.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/kernel/cpuset.c	2016-12-24 11:09:53.000000000 -0500
@@ -323,8 +323,7 @@ static struct file_system_type cpuset_fs
 /*
  * Return in pmask the portion of a cpusets's cpus_allowed that
  * are online.  If none are online, walk up the cpuset hierarchy
- * until we find one that does have some online cpus.  The top
- * cpuset always has some cpus online.
+ * until we find one that does have some online cpus.
  *
  * One way or another, we guarantee to return some non-empty subset
  * of cpu_online_mask.
@@ -333,8 +332,20 @@ static struct file_system_type cpuset_fs
  */
 static void guarantee_online_cpus(struct cpuset *cs, struct cpumask *pmask)
 {
-	while (!cpumask_intersects(cs->effective_cpus, cpu_online_mask))
+	while (!cpumask_intersects(cs->effective_cpus, cpu_online_mask)) {
 		cs = parent_cs(cs);
+		if (unlikely(!cs)) {
+			/*
+			 * The top cpuset doesn't have any online cpu as a
+			 * consequence of a race between cpuset_hotplug_work
+			 * and cpu hotplug notifier.  But we know the top
+			 * cpuset's effective_cpus is on its way to to be
+			 * identical to cpu_online_mask.
+			 */
+			cpumask_copy(pmask, cpu_online_mask);
+			return;
+		}
+	}
 	cpumask_and(pmask, cs->effective_cpus, cpu_online_mask);
 }
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/kernel/ptrace.c linux-libre-4.1.37-gnu/kernel/ptrace.c
--- linux-libre-4.1.36-gnu/kernel/ptrace.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/kernel/ptrace.c	2016-12-24 11:09:53.000000000 -0500
@@ -20,6 +20,7 @@
 #include <linux/uio.h>
 #include <linux/audit.h>
 #include <linux/pid_namespace.h>
+#include <linux/user_namespace.h>
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
 #include <linux/regset.h>
@@ -207,12 +208,34 @@ static int ptrace_check_attach(struct ta
 	return ret;
 }
 
-static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
+static bool ptrace_has_cap(const struct cred *tcred, unsigned int mode)
 {
+	struct user_namespace *tns = tcred->user_ns;
+
+	/* When a root-owned process enters a user namespace created by a
+	 * malicious user, the user shouldn't be able to execute code under
+	 * uid 0 by attaching to the root-owned process via ptrace.
+	 * Therefore, similar to the capable_wrt_inode_uidgid() check,
+	 * verify that all the uids and gids of the target process are
+	 * mapped into a namespace below the current one in which the caller
+	 * is capable.
+	 * No fsuid/fsgid check because __ptrace_may_access doesn't do it
+	 * either.
+	 */
+	while (
+	    !kuid_has_mapping(tns, tcred->euid) ||
+	    !kuid_has_mapping(tns, tcred->suid) ||
+	    !kuid_has_mapping(tns, tcred->uid)  ||
+	    !kgid_has_mapping(tns, tcred->egid) ||
+	    !kgid_has_mapping(tns, tcred->sgid) ||
+	    !kgid_has_mapping(tns, tcred->gid)) {
+		tns = tns->parent;
+	}
+
 	if (mode & PTRACE_MODE_NOAUDIT)
-		return has_ns_capability_noaudit(current, ns, CAP_SYS_PTRACE);
+		return has_ns_capability_noaudit(current, tns, CAP_SYS_PTRACE);
 	else
-		return has_ns_capability(current, ns, CAP_SYS_PTRACE);
+		return has_ns_capability(current, tns, CAP_SYS_PTRACE);
 }
 
 /* Returns 0 on success, -errno on denial. */
@@ -264,7 +287,7 @@ static int __ptrace_may_access(struct ta
 	    gid_eq(caller_gid, tcred->sgid) &&
 	    gid_eq(caller_gid, tcred->gid))
 		goto ok;
-	if (ptrace_has_cap(tcred->user_ns, mode))
+	if (ptrace_has_cap(tcred, mode))
 		goto ok;
 	rcu_read_unlock();
 	return -EPERM;
@@ -275,7 +298,7 @@ ok:
 		dumpable = get_dumpable(task->mm);
 	rcu_read_lock();
 	if (dumpable != SUID_DUMP_USER &&
-	    !ptrace_has_cap(__task_cred(task)->user_ns, mode)) {
+	    !ptrace_has_cap(__task_cred(task), mode)) {
 		rcu_read_unlock();
 		return -EPERM;
 	}
diff -druNp --no-dereference linux-libre-4.1.36-gnu/kernel/sysctl.c linux-libre-4.1.37-gnu/kernel/sysctl.c
--- linux-libre-4.1.36-gnu/kernel/sysctl.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/kernel/sysctl.c	2016-12-24 11:09:53.000000000 -0500
@@ -64,6 +64,7 @@
 #include <linux/binfmts.h>
 #include <linux/sched/sysctl.h>
 #include <linux/kexec.h>
+#include <linux/mount.h>
 
 #include <asm/uaccess.h>
 #include <asm/processor.h>
@@ -1709,6 +1710,14 @@ static struct ctl_table fs_table[] = {
 		.mode		= 0644,
 		.proc_handler	= proc_doulongvec_minmax,
 	},
+	{
+		.procname	= "mount-max",
+		.data		= &sysctl_mount_max,
+		.maxlen		= sizeof(unsigned int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &one,
+	},
 	{ }
 };
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/Makefile linux-libre-4.1.37-gnu/Makefile
--- linux-libre-4.1.36-gnu/Makefile	2016-11-30 10:10:45.000000000 -0500
+++ linux-libre-4.1.37-gnu/Makefile	2016-12-27 13:55:15.000000000 -0500
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 1
-SUBLEVEL = 36
+SUBLEVEL = 37
 EXTRAVERSION = -gnu
 NAME = Series 4800
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/mm/ksm.c linux-libre-4.1.37-gnu/mm/ksm.c
--- linux-libre-4.1.36-gnu/mm/ksm.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/mm/ksm.c	2016-12-24 11:09:53.000000000 -0500
@@ -283,7 +283,8 @@ static inline struct rmap_item *alloc_rm
 {
 	struct rmap_item *rmap_item;
 
-	rmap_item = kmem_cache_zalloc(rmap_item_cache, GFP_KERNEL);
+	rmap_item = kmem_cache_zalloc(rmap_item_cache, GFP_KERNEL |
+						__GFP_NORETRY | __GFP_NOWARN);
 	if (rmap_item)
 		ksm_rmap_items++;
 	return rmap_item;
diff -druNp --no-dereference linux-libre-4.1.36-gnu/mm/shmem.c linux-libre-4.1.37-gnu/mm/shmem.c
--- linux-libre-4.1.36-gnu/mm/shmem.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/mm/shmem.c	2016-12-24 11:09:53.000000000 -0500
@@ -548,7 +548,7 @@ static int shmem_setattr(struct dentry *
 	struct shmem_inode_info *info = SHMEM_I(inode);
 	int error;
 
-	error = inode_change_ok(inode, attr);
+	error = setattr_prepare(dentry, attr);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/net/bluetooth/rfcomm/sock.c linux-libre-4.1.37-gnu/net/bluetooth/rfcomm/sock.c
--- linux-libre-4.1.36-gnu/net/bluetooth/rfcomm/sock.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/net/bluetooth/rfcomm/sock.c	2016-12-24 11:09:53.000000000 -0500
@@ -334,16 +334,19 @@ static int rfcomm_sock_create(struct net
 
 static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
 {
-	struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
+	struct sockaddr_rc sa;
 	struct sock *sk = sock->sk;
-	int chan = sa->rc_channel;
-	int err = 0;
-
-	BT_DBG("sk %p %pMR", sk, &sa->rc_bdaddr);
+	int len, err = 0;
 
 	if (!addr || addr->sa_family != AF_BLUETOOTH)
 		return -EINVAL;
 
+	memset(&sa, 0, sizeof(sa));
+	len = min_t(unsigned int, sizeof(sa), addr_len);
+	memcpy(&sa, addr, len);
+
+	BT_DBG("sk %p %pMR", sk, &sa.rc_bdaddr);
+
 	lock_sock(sk);
 
 	if (sk->sk_state != BT_OPEN) {
@@ -358,12 +361,13 @@ static int rfcomm_sock_bind(struct socke
 
 	write_lock(&rfcomm_sk_list.lock);
 
-	if (chan && __rfcomm_get_listen_sock_by_addr(chan, &sa->rc_bdaddr)) {
+	if (sa.rc_channel &&
+	    __rfcomm_get_listen_sock_by_addr(sa.rc_channel, &sa.rc_bdaddr)) {
 		err = -EADDRINUSE;
 	} else {
 		/* Save source address */
-		bacpy(&rfcomm_pi(sk)->src, &sa->rc_bdaddr);
-		rfcomm_pi(sk)->channel = chan;
+		bacpy(&rfcomm_pi(sk)->src, &sa.rc_bdaddr);
+		rfcomm_pi(sk)->channel = sa.rc_channel;
 		sk->sk_state = BT_BOUND;
 	}
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/net/core/dev.c linux-libre-4.1.37-gnu/net/core/dev.c
--- linux-libre-4.1.36-gnu/net/core/dev.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/net/core/dev.c	2016-12-24 11:09:53.000000000 -0500
@@ -4060,6 +4060,7 @@ static enum gro_result dev_gro_receive(s
 		NAPI_GRO_CB(skb)->flush = 0;
 		NAPI_GRO_CB(skb)->free = 0;
 		NAPI_GRO_CB(skb)->udp_mark = 0;
+		NAPI_GRO_CB(skb)->recursion_counter = 0;
 		NAPI_GRO_CB(skb)->gro_remcsum_start = 0;
 
 		/* Setup for GRO checksum validation */
diff -druNp --no-dereference linux-libre-4.1.36-gnu/net/ethernet/eth.c linux-libre-4.1.37-gnu/net/ethernet/eth.c
--- linux-libre-4.1.36-gnu/net/ethernet/eth.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/net/ethernet/eth.c	2016-12-24 11:09:53.000000000 -0500
@@ -434,7 +434,7 @@ struct sk_buff **eth_gro_receive(struct
 
 	skb_gro_pull(skb, sizeof(*eh));
 	skb_gro_postpull_rcsum(skb, eh, sizeof(*eh));
-	pp = ptype->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
diff -druNp --no-dereference linux-libre-4.1.36-gnu/net/ipv4/af_inet.c linux-libre-4.1.37-gnu/net/ipv4/af_inet.c
--- linux-libre-4.1.36-gnu/net/ipv4/af_inet.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/net/ipv4/af_inet.c	2016-12-24 11:09:53.000000000 -0500
@@ -1377,7 +1377,7 @@ static struct sk_buff **inet_gro_receive
 	skb_gro_pull(skb, sizeof(*iph));
 	skb_set_transport_header(skb, skb_gro_offset(skb));
 
-	pp = ops->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
diff -druNp --no-dereference linux-libre-4.1.36-gnu/net/ipv4/fou.c linux-libre-4.1.37-gnu/net/ipv4/fou.c
--- linux-libre-4.1.36-gnu/net/ipv4/fou.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/net/ipv4/fou.c	2016-12-24 11:09:53.000000000 -0500
@@ -188,7 +188,7 @@ static struct sk_buff **fou_gro_receive(
 	if (!ops || !ops->callbacks.gro_receive)
 		goto out_unlock;
 
-	pp = ops->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
@@ -355,7 +355,7 @@ static struct sk_buff **gue_gro_receive(
 	if (WARN_ON(!ops || !ops->callbacks.gro_receive))
 		goto out_unlock;
 
-	pp = ops->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
diff -druNp --no-dereference linux-libre-4.1.36-gnu/net/ipv4/gre_offload.c linux-libre-4.1.37-gnu/net/ipv4/gre_offload.c
--- linux-libre-4.1.36-gnu/net/ipv4/gre_offload.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/net/ipv4/gre_offload.c	2016-12-24 11:09:53.000000000 -0500
@@ -214,7 +214,7 @@ static struct sk_buff **gre_gro_receive(
 	/* Adjusted NAPI_GRO_CB(skb)->csum after skb_gro_pull()*/
 	skb_gro_postpull_rcsum(skb, greh, grehlen);
 
-	pp = ptype->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
diff -druNp --no-dereference linux-libre-4.1.36-gnu/net/ipv4/ping.c linux-libre-4.1.37-gnu/net/ipv4/ping.c
--- linux-libre-4.1.36-gnu/net/ipv4/ping.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/net/ipv4/ping.c	2016-12-24 11:09:53.000000000 -0500
@@ -659,6 +659,10 @@ int ping_common_sendmsg(int family, stru
 	if (len > 0xFFFF)
 		return -EMSGSIZE;
 
+	/* Must have at least a full ICMP header. */
+	if (len < icmph_len)
+		return -EINVAL;
+
 	/*
 	 *	Check the flags.
 	 */
diff -druNp --no-dereference linux-libre-4.1.36-gnu/net/ipv4/udp_offload.c linux-libre-4.1.37-gnu/net/ipv4/udp_offload.c
--- linux-libre-4.1.36-gnu/net/ipv4/udp_offload.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/net/ipv4/udp_offload.c	2016-12-24 11:09:53.000000000 -0500
@@ -339,8 +339,13 @@ unflush:
 	skb_gro_pull(skb, sizeof(struct udphdr)); /* pull encapsulating udp header */
 	skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr));
 	NAPI_GRO_CB(skb)->proto = uo_priv->offload->ipproto;
-	pp = uo_priv->offload->callbacks.gro_receive(head, skb,
-						     uo_priv->offload);
+
+	if (gro_recursion_inc_test(skb)) {
+		pp = NULL;
+	} else {
+		pp = uo_priv->offload->callbacks.gro_receive(head, skb,
+							     uo_priv->offload);
+	}
 
 out_unlock:
 	rcu_read_unlock();
diff -druNp --no-dereference linux-libre-4.1.36-gnu/net/ipv6/ip6_offload.c linux-libre-4.1.37-gnu/net/ipv6/ip6_offload.c
--- linux-libre-4.1.36-gnu/net/ipv6/ip6_offload.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/net/ipv6/ip6_offload.c	2016-12-24 11:09:53.000000000 -0500
@@ -247,7 +247,7 @@ static struct sk_buff **ipv6_gro_receive
 
 	skb_gro_postpull_rcsum(skb, iph, nlen);
 
-	pp = ops->callbacks.gro_receive(head, skb);
+	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
 
 out_unlock:
 	rcu_read_unlock();
diff -druNp --no-dereference linux-libre-4.1.36-gnu/net/packet/af_packet.c linux-libre-4.1.37-gnu/net/packet/af_packet.c
--- linux-libre-4.1.36-gnu/net/packet/af_packet.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/net/packet/af_packet.c	2016-12-24 11:09:53.000000000 -0500
@@ -3344,19 +3344,25 @@ packet_setsockopt(struct socket *sock, i
 
 		if (optlen != sizeof(val))
 			return -EINVAL;
-		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
-			return -EBUSY;
 		if (copy_from_user(&val, optval, sizeof(val)))
 			return -EFAULT;
 		switch (val) {
 		case TPACKET_V1:
 		case TPACKET_V2:
 		case TPACKET_V3:
-			po->tp_version = val;
-			return 0;
+			break;
 		default:
 			return -EINVAL;
 		}
+		lock_sock(sk);
+		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
+			ret = -EBUSY;
+		} else {
+			po->tp_version = val;
+			ret = 0;
+		}
+		release_sock(sk);
+		return ret;
 	}
 	case PACKET_RESERVE:
 	{
@@ -3819,6 +3825,7 @@ static int packet_set_ring(struct sock *
 	/* Added to avoid minimal code churn */
 	struct tpacket_req *req = &req_u->req;
 
+	lock_sock(sk);
 	/* Opening a Tx-ring is NOT supported in TPACKET_V3 */
 	if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
 		WARN(1, "Tx-ring is not supported.\n");
@@ -3900,7 +3907,6 @@ static int packet_set_ring(struct sock *
 			goto out;
 	}
 
-	lock_sock(sk);
 
 	/* Detach socket from network */
 	spin_lock(&po->bind_lock);
@@ -3949,11 +3955,11 @@ static int packet_set_ring(struct sock *
 		if (!tx_ring)
 			prb_shutdown_retire_blk_timer(po, tx_ring, rb_queue);
 	}
-	release_sock(sk);
 
 	if (pg_vec)
 		free_pg_vec(pg_vec, order, req->tp_block_nr);
 out:
+	release_sock(sk);
 	return err;
 }
 
diff -druNp --no-dereference linux-libre-4.1.36-gnu/net/tipc/bearer.c linux-libre-4.1.37-gnu/net/tipc/bearer.c
--- linux-libre-4.1.36-gnu/net/tipc/bearer.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/net/tipc/bearer.c	2016-12-24 11:09:53.000000000 -0500
@@ -386,6 +386,10 @@ int tipc_enable_l2_media(struct net *net
 	dev = dev_get_by_name(net, driver_name);
 	if (!dev)
 		return -ENODEV;
+	if (tipc_mtu_bad(dev, 0)) {
+		dev_put(dev);
+		return -EINVAL;
+	}
 
 	/* Associate TIPC bearer with L2 bearer */
 	rcu_assign_pointer(b->media_ptr, dev);
@@ -524,14 +528,17 @@ static int tipc_l2_device_event(struct n
 	if (!b_ptr)
 		return NOTIFY_DONE;
 
-	b_ptr->mtu = dev->mtu;
-
 	switch (evt) {
 	case NETDEV_CHANGE:
 		if (netif_carrier_ok(dev))
 			break;
 	case NETDEV_DOWN:
 	case NETDEV_CHANGEMTU:
+		if (tipc_mtu_bad(dev, 0)) {
+			bearer_disable(net, b_ptr, false);
+			break;
+		}
+		b_ptr->mtu = dev->mtu;
 		tipc_reset_bearer(net, b_ptr);
 		break;
 	case NETDEV_CHANGEADDR:
diff -druNp --no-dereference linux-libre-4.1.36-gnu/net/tipc/bearer.h linux-libre-4.1.37-gnu/net/tipc/bearer.h
--- linux-libre-4.1.36-gnu/net/tipc/bearer.h	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/net/tipc/bearer.h	2016-12-24 11:09:53.000000000 -0500
@@ -38,6 +38,7 @@
 #define _TIPC_BEARER_H
 
 #include "netlink.h"
+#include "msg.h"
 #include <net/genetlink.h>
 
 #define MAX_BEARERS	2
@@ -61,6 +62,9 @@
 #define TIPC_MEDIA_TYPE_IB	2
 #define TIPC_MEDIA_TYPE_UDP	3
 
+/* minimum bearer MTU */
+#define TIPC_MIN_BEARER_MTU	(MAX_H_SIZE + INT_H_SIZE)
+
 /**
  * struct tipc_node_map - set of node identifiers
  * @count: # of nodes in set
@@ -218,4 +222,13 @@ void tipc_bearer_stop(struct net *net);
 void tipc_bearer_send(struct net *net, u32 bearer_id, struct sk_buff *buf,
 		      struct tipc_media_addr *dest);
 
+/* check if device MTU is too low for tipc headers */
+static inline bool tipc_mtu_bad(struct net_device *dev, unsigned int reserve)
+{
+	if (dev->mtu >= TIPC_MIN_BEARER_MTU + reserve)
+		return false;
+	netdev_warn(dev, "MTU too low for tipc bearer\n");
+	return true;
+}
+
 #endif	/* _TIPC_BEARER_H */
diff -druNp --no-dereference linux-libre-4.1.36-gnu/net/tipc/udp_media.c linux-libre-4.1.37-gnu/net/tipc/udp_media.c
--- linux-libre-4.1.36-gnu/net/tipc/udp_media.c	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/net/tipc/udp_media.c	2016-12-24 11:09:53.000000000 -0500
@@ -374,6 +374,11 @@ static int tipc_udp_enable(struct net *n
 		udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
 		udp_conf.use_udp_checksums = false;
 		ub->ifindex = dev->ifindex;
+		if (tipc_mtu_bad(dev, sizeof(struct iphdr) +
+				      sizeof(struct udphdr))) {
+			err = -EINVAL;
+			goto err;
+		}
 		b->mtu = dev->mtu - sizeof(struct iphdr)
 			- sizeof(struct udphdr);
 #if IS_ENABLED(CONFIG_IPV6)
diff -druNp --no-dereference linux-libre-4.1.36-gnu/scripts/gcc-x86_64-has-stack-protector.sh linux-libre-4.1.37-gnu/scripts/gcc-x86_64-has-stack-protector.sh
--- linux-libre-4.1.36-gnu/scripts/gcc-x86_64-has-stack-protector.sh	2016-11-29 11:34:50.000000000 -0500
+++ linux-libre-4.1.37-gnu/scripts/gcc-x86_64-has-stack-protector.sh	2016-12-24 11:09:53.000000000 -0500
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
+echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fno-PIE -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
 if [ "$?" -eq "0" ] ; then
 	echo y
 else
