diff --git a/Makefile b/Makefile
index 9cf513828341..e55476c4aef0 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 10
-SUBLEVEL = 43
+SUBLEVEL = 44
 EXTRAVERSION =
 NAME = TOSSUG Baby Fish
 
diff --git a/arch/arm/boot/dts/armada-xp-gp.dts 
b/arch/arm/boot/dts/armada-xp-gp.dts
index 76db557adbe7..f97550420fcc 100644
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -124,7 +124,7 @@
                                /* Device Bus parameters are required */
 
                                /* Read parameters */
-                               devbus,bus-width    = <8>;
+                               devbus,bus-width    = <16>;
                                devbus,turn-off-ps  = <60000>;
                                devbus,badr-skew-ps = <0>;
                                devbus,acc-first-ps = <124000>;
diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts 
b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
index fdea75c73411..9746d0e7fcb4 100644
--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -152,7 +152,7 @@
                                /* Device Bus parameters are required */
 
                                /* Read parameters */
-                               devbus,bus-width    = <8>;
+                               devbus,bus-width    = <16>;
                                devbus,turn-off-ps  = <60000>;
                                devbus,badr-skew-ps = <0>;
                                devbus,acc-first-ps = <124000>;
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 4942058402a4..b0d33d9533aa 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -444,10 +444,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
          .driver_data = board_ahci_yes_fbs },                  /* 88se9172 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192),
          .driver_data = board_ahci_yes_fbs },                  /* 88se9172 on 
some Gigabyte */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0),
+         .driver_data = board_ahci_yes_fbs },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3),
          .driver_data = board_ahci_yes_fbs },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230),
          .driver_data = board_ahci_yes_fbs },
+       { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642),
+         .driver_data = board_ahci_yes_fbs },
 
        /* Promise */
        { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci },   /* PDC42819 */
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c 
b/drivers/infiniband/ulp/isert/ib_isert.c
index bae20f8bb034..144999918022 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -382,6 +382,14 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct 
rdma_cm_event *event)
        struct ib_device *ib_dev = cma_id->device;
        int ret = 0;
 
+       spin_lock_bh(&np->np_thread_lock);
+       if (!np->enabled) {
+               spin_unlock_bh(&np->np_thread_lock);
+               pr_debug("iscsi_np is not enabled, reject connect request\n");
+               return rdma_reject(cma_id, NULL, 0);
+       }
+       spin_unlock_bh(&np->np_thread_lock);
+
        pr_debug("Entering isert_connect_request cma_id: %p, context: %p\n",
                 cma_id, cma_id->context);
 
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 1bf3f8b5ce3a..06311c5ada36 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -183,6 +183,7 @@ static void mei_me_hw_reset(struct mei_device *dev, bool 
intr_enable)
        else
                hcsr &= ~H_IE;
 
+       dev->recvd_hw_ready = false;
        mei_me_reg_write(hw, H_CSR, hcsr);
 
        if (dev->dev_state == MEI_DEV_POWER_DOWN)
@@ -233,10 +234,7 @@ static bool mei_me_hw_is_ready(struct mei_device *dev)
 static int mei_me_hw_ready_wait(struct mei_device *dev)
 {
        int err;
-       if (mei_me_hw_is_ready(dev))
-               return 0;
 
-       dev->recvd_hw_ready = false;
        mutex_unlock(&dev->device_lock);
        err = wait_event_interruptible_timeout(dev->wait_hw_ready,
                        dev->recvd_hw_ready,
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c 
b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
index 1e6c594d6d04..58c18d3a4880 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
@@ -55,7 +55,6 @@ int mlx4_en_create_cq(struct mlx4_en_priv *priv,
 
        cq->ring = ring;
        cq->is_tx = mode;
-       spin_lock_init(&cq->lock);
 
        err = mlx4_alloc_hwq_res(mdev->dev, &cq->wqres,
                                cq->buf_size, 2 * PAGE_SIZE);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c 
b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 89c47ea84b50..063f3f4d4867 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1190,15 +1190,11 @@ static void mlx4_en_netpoll(struct net_device *dev)
 {
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_en_cq *cq;
-       unsigned long flags;
        int i;
 
        for (i = 0; i < priv->rx_ring_num; i++) {
                cq = &priv->rx_cq[i];
-               spin_lock_irqsave(&cq->lock, flags);
-               napi_synchronize(&cq->napi);
-               mlx4_en_process_rx_cq(dev, cq, 0);
-               spin_unlock_irqrestore(&cq->lock, flags);
+               napi_schedule(&cq->napi);
        }
 }
 #endif
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h 
b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index b1d7657b2bf5..628e1f9355a8 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -299,7 +299,6 @@ struct mlx4_en_cq {
        struct mlx4_cq          mcq;
        struct mlx4_hwq_resources wqres;
        int                     ring;
-       spinlock_t              lock;
        struct net_device      *dev;
        struct napi_struct      napi;
        int size;
diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 684cc343cf09..b52121358385 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1295,7 +1295,6 @@ struct megasas_instance {
        u32 *reply_queue;
        dma_addr_t reply_queue_h;
 
-       unsigned long base_addr;
        struct megasas_register_set __iomem *reg_set;
 
        struct megasas_pd_list          pd_list[MEGASAS_MAX_PD];
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index b3e5c1787876..4956c99ed90e 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -3461,6 +3461,7 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
        u32 max_sectors_1;
        u32 max_sectors_2;
        u32 tmp_sectors, msix_enable;
+       resource_size_t base_addr;
        struct megasas_register_set __iomem *reg_set;
        struct megasas_ctrl_info *ctrl_info;
        unsigned long bar_list;
@@ -3469,14 +3470,14 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
        /* Find first memory bar */
        bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
        instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
-       instance->base_addr = pci_resource_start(instance->pdev, instance->bar);
        if (pci_request_selected_regions(instance->pdev, instance->bar,
                                         "megasas: LSI")) {
                printk(KERN_DEBUG "megasas: IO memory region busy!\n");
                return -EBUSY;
        }
 
-       instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
+       base_addr = pci_resource_start(instance->pdev, instance->bar);
+       instance->reg_set = ioremap_nocache(base_addr, 8192);
 
        if (!instance->reg_set) {
                printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 58c479d13b57..68dbd88babbd 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -460,6 +460,7 @@ int iscsit_del_np(struct iscsi_np *np)
        spin_lock_bh(&np->np_thread_lock);
        np->np_exports--;
        if (np->np_exports) {
+               np->enabled = true;
                spin_unlock_bh(&np->np_thread_lock);
                return 0;
        }
diff --git a/drivers/target/iscsi/iscsi_target_core.h 
b/drivers/target/iscsi/iscsi_target_core.h
index 8907dcdc0db9..e117870eb445 100644
--- a/drivers/target/iscsi/iscsi_target_core.h
+++ b/drivers/target/iscsi/iscsi_target_core.h
@@ -760,6 +760,7 @@ struct iscsi_np {
        int                     np_ip_proto;
        int                     np_sock_type;
        enum np_thread_state_table np_thread_state;
+       bool                    enabled;
        enum iscsi_timer_flags_table np_login_timer_flags;
        u32                     np_exports;
        enum np_flags_table     np_flags;
diff --git a/drivers/target/iscsi/iscsi_target_login.c 
b/drivers/target/iscsi/iscsi_target_login.c
index bc788c52b6cc..0d6c3dd25679 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -250,6 +250,28 @@ static void iscsi_login_set_conn_values(
        mutex_unlock(&auth_id_lock);
 }
 
+static __printf(2, 3) int iscsi_change_param_sprintf(
+       struct iscsi_conn *conn,
+       const char *fmt, ...)
+{
+       va_list args;
+       unsigned char buf[64];
+
+       memset(buf, 0, sizeof buf);
+
+       va_start(args, fmt);
+       vsnprintf(buf, sizeof buf, fmt, args);
+       va_end(args);
+
+       if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
+               iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+                               ISCSI_LOGIN_STATUS_NO_RESOURCES);
+               return -1;
+       }
+
+       return 0;
+}
+
 /*
  *     This is the leading connection of a new session,
  *     or session reinstatement.
@@ -339,7 +361,6 @@ static int iscsi_login_zero_tsih_s2(
 {
        struct iscsi_node_attrib *na;
        struct iscsi_session *sess = conn->sess;
-       unsigned char buf[32];
        bool iser = false;
 
        sess->tpg = conn->tpg;
@@ -380,26 +401,16 @@ static int iscsi_login_zero_tsih_s2(
         *
         * In our case, we have already located the struct iscsi_tiqn at this 
point.
         */
-       memset(buf, 0, 32);
-       sprintf(buf, "TargetPortalGroupTag=%hu", ISCSI_TPG_S(sess)->tpgt);
-       if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
-               iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
-                               ISCSI_LOGIN_STATUS_NO_RESOURCES);
+       if (iscsi_change_param_sprintf(conn, "TargetPortalGroupTag=%hu", 
sess->tpg->tpgt))
                return -1;
-       }
 
        /*
         * Workaround for Initiators that have broken connection recovery logic.
         *
         * "We would really like to get rid of this." Linux-iSCSI.org team
         */
-       memset(buf, 0, 32);
-       sprintf(buf, "ErrorRecoveryLevel=%d", na->default_erl);
-       if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
-               iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
-                               ISCSI_LOGIN_STATUS_NO_RESOURCES);
+       if (iscsi_change_param_sprintf(conn, "ErrorRecoveryLevel=%d", 
na->default_erl))
                return -1;
-       }
 
        if (iscsi_login_disable_FIM_keys(conn->param_list, conn) < 0)
                return -1;
@@ -411,12 +422,9 @@ static int iscsi_login_zero_tsih_s2(
                unsigned long mrdsl, off;
                int rc;
 
-               sprintf(buf, "RDMAExtensions=Yes");
-               if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
-                       iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
-                               ISCSI_LOGIN_STATUS_NO_RESOURCES);
+               if (iscsi_change_param_sprintf(conn, "RDMAExtensions=Yes"))
                        return -1;
-               }
+
                /*
                 * Make MaxRecvDataSegmentLength PAGE_SIZE aligned for
                 * Immediate Data + Unsolicitied Data-OUT if necessary..
@@ -446,12 +454,8 @@ static int iscsi_login_zero_tsih_s2(
                pr_warn("Aligning ISER MaxRecvDataSegmentLength: %lu down"
                        " to PAGE_SIZE\n", mrdsl);
 
-               sprintf(buf, "MaxRecvDataSegmentLength=%lu\n", mrdsl);
-               if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
-                       iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
-                               ISCSI_LOGIN_STATUS_NO_RESOURCES);
+               if (iscsi_change_param_sprintf(conn, 
"MaxRecvDataSegmentLength=%lu\n", mrdsl))
                        return -1;
-               }
        }
 
        return 0;
@@ -984,6 +988,7 @@ int iscsi_target_setup_login_socket(
        }
 
        np->np_transport = t;
+       np->enabled = true;
        return 0;
 }
 
diff --git a/drivers/target/iscsi/iscsi_target_tpg.c 
b/drivers/target/iscsi/iscsi_target_tpg.c
index f31b4c5cdf3f..75a4e83842c2 100644
--- a/drivers/target/iscsi/iscsi_target_tpg.c
+++ b/drivers/target/iscsi/iscsi_target_tpg.c
@@ -175,13 +175,16 @@ void iscsit_put_tpg(struct iscsi_portal_group *tpg)
 
 static void iscsit_clear_tpg_np_login_thread(
        struct iscsi_tpg_np *tpg_np,
-       struct iscsi_portal_group *tpg)
+       struct iscsi_portal_group *tpg,
+       bool shutdown)
 {
        if (!tpg_np->tpg_np) {
                pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
                return;
        }
 
+       if (shutdown)
+               tpg_np->tpg_np->enabled = false;
        iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg);
 }
 
@@ -197,7 +200,7 @@ void iscsit_clear_tpg_np_login_threads(
                        continue;
                }
                spin_unlock(&tpg->tpg_np_lock);
-               iscsit_clear_tpg_np_login_thread(tpg_np, tpg);
+               iscsit_clear_tpg_np_login_thread(tpg_np, tpg, false);
                spin_lock(&tpg->tpg_np_lock);
        }
        spin_unlock(&tpg->tpg_np_lock);
@@ -520,7 +523,7 @@ static int iscsit_tpg_release_np(
        struct iscsi_portal_group *tpg,
        struct iscsi_np *np)
 {
-       iscsit_clear_tpg_np_login_thread(tpg_np, tpg);
+       iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true);
 
        pr_debug("CORE[%s] - Removed Network Portal: %s:%hu,%hu on %s\n",
                tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt,
diff --git a/drivers/target/target_core_alua.c 
b/drivers/target/target_core_alua.c
index f608fbc14a27..df58a67f81e0 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -409,7 +409,16 @@ static inline int core_alua_state_standby(
        case REPORT_LUNS:
        case RECEIVE_DIAGNOSTIC:
        case SEND_DIAGNOSTIC:
+       case READ_CAPACITY:
                return 0;
+       case SERVICE_ACTION_IN:
+               switch (cdb[1] & 0x1f) {
+               case SAI_READ_CAPACITY_16:
+                       return 0;
+               default:
+                       *alua_ascq = ASCQ_04H_ALUA_TG_PT_STANDBY;
+                       return 1;
+               }
        case MAINTENANCE_IN:
                switch (cdb[1] & 0x1f) {
                case MI_REPORT_TARGET_PGS:
diff --git a/drivers/target/target_core_configfs.c 
b/drivers/target/target_core_configfs.c
index 4a8bd36d3958..8cda4080b597 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -2034,6 +2034,11 @@ static ssize_t 
target_core_alua_tg_pt_gp_store_attr_alua_access_state(
                        " tg_pt_gp ID: %hu\n", tg_pt_gp->tg_pt_gp_valid_id);
                return -EINVAL;
        }
+       if (!(dev->dev_flags & DF_CONFIGURED)) {
+               pr_err("Unable to set alua_access_state while device is"
+                      " not configured\n");
+               return -ENODEV;
+       }
 
        ret = strict_strtoul(page, 0, &tmp);
        if (ret < 0) {
diff --git a/fs/attr.c b/fs/attr.c
index 8dd5825ec708..66fa6251c398 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -50,14 +50,14 @@ int inode_change_ok(const struct inode *inode, struct iattr 
*attr)
        if ((ia_valid & ATTR_UID) &&
            (!uid_eq(current_fsuid(), inode->i_uid) ||
             !uid_eq(attr->ia_uid, inode->i_uid)) &&
-           !inode_capable(inode, CAP_CHOWN))
+           !capable_wrt_inode_uidgid(inode, CAP_CHOWN))
                return -EPERM;
 
        /* Make sure caller can chgrp. */
        if ((ia_valid & ATTR_GID) &&
            (!uid_eq(current_fsuid(), inode->i_uid) ||
            (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) 
&&
-           !inode_capable(inode, CAP_CHOWN))
+           !capable_wrt_inode_uidgid(inode, CAP_CHOWN))
                return -EPERM;
 
        /* Make sure a caller can chmod. */
@@ -67,7 +67,7 @@ int inode_change_ok(const struct inode *inode, struct iattr 
*attr)
                /* Also check the setgid bit! */
                if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
                                inode->i_gid) &&
-                   !inode_capable(inode, CAP_FSETID))
+                   !capable_wrt_inode_uidgid(inode, CAP_FSETID))
                        attr->ia_mode &= ~S_ISGID;
        }
 
@@ -160,7 +160,7 @@ void setattr_copy(struct inode *inode, const struct iattr 
*attr)
                umode_t mode = attr->ia_mode;
 
                if (!in_group_p(inode->i_gid) &&
-                   !inode_capable(inode, CAP_FSETID))
+                   !capable_wrt_inode_uidgid(inode, CAP_FSETID))
                        mode &= ~S_ISGID;
                inode->i_mode = mode;
        }
diff --git a/fs/inode.c b/fs/inode.c
index 00d5fc3b86e1..1b300a06b8be 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1837,14 +1837,18 @@ EXPORT_SYMBOL(inode_init_owner);
  * inode_owner_or_capable - check current task permissions to inode
  * @inode: inode being checked
  *
- * Return true if current either has CAP_FOWNER to the inode, or
- * owns the file.
+ * Return true if current either has CAP_FOWNER in a namespace with the
+ * inode owner uid mapped, or owns the file.
  */
 bool inode_owner_or_capable(const struct inode *inode)
 {
+       struct user_namespace *ns;
+
        if (uid_eq(current_fsuid(), inode->i_uid))
                return true;
-       if (inode_capable(inode, CAP_FOWNER))
+
+       ns = current_user_ns();
+       if (ns_capable(ns, CAP_FOWNER) && kuid_has_mapping(ns, inode->i_uid))
                return true;
        return false;
 }
diff --git a/fs/namei.c b/fs/namei.c
index 1211ee5a1cb3..6ac16a37ded2 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -321,10 +321,11 @@ int generic_permission(struct inode *inode, int mask)
 
        if (S_ISDIR(inode->i_mode)) {
                /* DACs are overridable for directories */
-               if (inode_capable(inode, CAP_DAC_OVERRIDE))
+               if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
                        return 0;
                if (!(mask & MAY_WRITE))
-                       if (inode_capable(inode, CAP_DAC_READ_SEARCH))
+                       if (capable_wrt_inode_uidgid(inode,
+                                                    CAP_DAC_READ_SEARCH))
                                return 0;
                return -EACCES;
        }
@@ -334,7 +335,7 @@ int generic_permission(struct inode *inode, int mask)
         * at least one exec bit set.
         */
        if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO))
-               if (inode_capable(inode, CAP_DAC_OVERRIDE))
+               if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
                        return 0;
 
        /*
@@ -342,7 +343,7 @@ int generic_permission(struct inode *inode, int mask)
         */
        mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
        if (mask == MAY_READ)
-               if (inode_capable(inode, CAP_DAC_READ_SEARCH))
+               if (capable_wrt_inode_uidgid(inode, CAP_DAC_READ_SEARCH))
                        return 0;
 
        return -EACCES;
@@ -2199,7 +2200,7 @@ static inline int check_sticky(struct inode *dir, struct 
inode *inode)
                return 0;
        if (uid_eq(dir->i_uid, fsuid))
                return 0;
-       return !inode_capable(inode, CAP_FOWNER);
+       return !capable_wrt_inode_uidgid(inode, CAP_FOWNER);
 }
 
 /*
diff --git a/include/linux/capability.h b/include/linux/capability.h
index d9a4f7f40f32..15f90929fb51 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -211,7 +211,7 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
 extern bool capable(int cap);
 extern bool ns_capable(struct user_namespace *ns, int cap);
 extern bool nsown_capable(int cap);
-extern bool inode_capable(const struct inode *inode, int cap);
+extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
 extern bool file_ns_capable(const struct file *file, struct user_namespace 
*ns, int cap);
 
 /* audit system wants to get cap info from files as well */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 9845cb32b60a..03a3af8538bd 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -733,6 +733,22 @@ static enum audit_state audit_filter_task(struct 
task_struct *tsk, char **key)
        return AUDIT_BUILD_CONTEXT;
 }
 
+static int audit_in_mask(const struct audit_krule *rule, unsigned long val)
+{
+       int word, bit;
+
+       if (val > 0xffffffff)
+               return false;
+
+       word = AUDIT_WORD(val);
+       if (word >= AUDIT_BITMASK_SIZE)
+               return false;
+
+       bit = AUDIT_BIT(val);
+
+       return rule->mask[word] & bit;
+}
+
 /* At syscall entry and exit time, this filter is called if the
  * audit_state is not low enough that auditing cannot take place, but is
  * also not high enough that we already know we have to write an audit
@@ -750,11 +766,8 @@ static enum audit_state audit_filter_syscall(struct 
task_struct *tsk,
 
        rcu_read_lock();
        if (!list_empty(list)) {
-               int word = AUDIT_WORD(ctx->major);
-               int bit  = AUDIT_BIT(ctx->major);
-
                list_for_each_entry_rcu(e, list, list) {
-                       if ((e->rule.mask[word] & bit) == bit &&
+                       if (audit_in_mask(&e->rule, ctx->major) &&
                            audit_filter_rules(tsk, &e->rule, ctx, NULL,
                                               &state, false)) {
                                rcu_read_unlock();
@@ -774,20 +787,16 @@ static enum audit_state audit_filter_syscall(struct 
task_struct *tsk,
 static int audit_filter_inode_name(struct task_struct *tsk,
                                   struct audit_names *n,
                                   struct audit_context *ctx) {
-       int word, bit;
        int h = audit_hash_ino((u32)n->ino);
        struct list_head *list = &audit_inode_hash[h];
        struct audit_entry *e;
        enum audit_state state;
 
-       word = AUDIT_WORD(ctx->major);
-       bit  = AUDIT_BIT(ctx->major);
-
        if (list_empty(list))
                return 0;
 
        list_for_each_entry_rcu(e, list, list) {
-               if ((e->rule.mask[word] & bit) == bit &&
+               if (audit_in_mask(&e->rule, ctx->major) &&
                    audit_filter_rules(tsk, &e->rule, ctx, n, &state, false)) {
                        ctx->current_state = state;
                        return 1;
diff --git a/kernel/capability.c b/kernel/capability.c
index f6c2ce5701e1..d52eecc0942b 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -445,22 +445,18 @@ bool nsown_capable(int cap)
 }
 
 /**
- * inode_capable - Check superior capability over inode
+ * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped
  * @inode: The inode in question
  * @cap: The capability in question
  *
- * Return true if the current task has the given superior capability
- * targeted at it's own user namespace and that the given inode is owned
- * by the current user namespace or a child namespace.
- *
- * Currently we check to see if an inode is owned by the current
- * user namespace by seeing if the inode's owner maps into the
- * current user namespace.
- *
+ * Return true if the current task has the given capability targeted at
+ * its own user namespace and that the given inode's uid and gid are
+ * mapped into the current user namespace.
  */
-bool inode_capable(const struct inode *inode, int cap)
+bool capable_wrt_inode_uidgid(const struct inode *inode, int cap)
 {
        struct user_namespace *ns = current_user_ns();
 
-       return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid);
+       return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid) &&
+               kgid_has_mapping(ns, inode->i_gid);
 }
diff --git a/mm/compaction.c b/mm/compaction.c
index 18a90b4d0bfc..fb797a32362f 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -657,17 +657,21 @@ static void isolate_freepages(struct zone *zone,
                                struct compact_control *cc)
 {
        struct page *page;
-       unsigned long high_pfn, low_pfn, pfn, z_end_pfn, end_pfn;
+       unsigned long high_pfn, low_pfn, pfn, z_end_pfn;
        int nr_freepages = cc->nr_freepages;
        struct list_head *freelist = &cc->freepages;
 
        /*
         * Initialise the free scanner. The starting point is where we last
-        * scanned from (or the end of the zone if starting). The low point
-        * is the end of the pageblock the migration scanner is using.
+        * successfully isolated from, zone-cached value, or the end of the
+        * zone when isolating for the first time. We need this aligned to
+        * the pageblock boundary, because we do pfn -= pageblock_nr_pages
+        * in the for loop.
+        * The low boundary is the end of the pageblock the migration scanner
+        * is using.
         */
-       pfn = cc->free_pfn;
-       low_pfn = cc->migrate_pfn + pageblock_nr_pages;
+       pfn = cc->free_pfn & ~(pageblock_nr_pages-1);
+       low_pfn = ALIGN(cc->migrate_pfn + 1, pageblock_nr_pages);
 
        /*
         * Take care that if the migration scanner is at the end of the zone
@@ -683,9 +687,10 @@ static void isolate_freepages(struct zone *zone,
         * pages on cc->migratepages. We stop searching if the migrate
         * and free page scanners meet or enough free pages are isolated.
         */
-       for (; pfn > low_pfn && cc->nr_migratepages > nr_freepages;
+       for (; pfn >= low_pfn && cc->nr_migratepages > nr_freepages;
                                        pfn -= pageblock_nr_pages) {
                unsigned long isolated;
+               unsigned long end_pfn;
 
                if (!pfn_valid(pfn))
                        continue;
@@ -713,13 +718,10 @@ static void isolate_freepages(struct zone *zone,
                isolated = 0;
 
                /*
-                * As pfn may not start aligned, pfn+pageblock_nr_page
-                * may cross a MAX_ORDER_NR_PAGES boundary and miss
-                * a pfn_valid check. Ensure isolate_freepages_block()
-                * only scans within a pageblock
+                * Take care when isolating in last pageblock of a zone which
+                * ends in the middle of a pageblock.
                 */
-               end_pfn = ALIGN(pfn + 1, pageblock_nr_pages);
-               end_pfn = min(end_pfn, z_end_pfn);
+               end_pfn = min(pfn + pageblock_nr_pages, z_end_pfn);
                isolated = isolate_freepages_block(cc, pfn, end_pfn,
                                                   freelist, false);
                nr_freepages += isolated;
@@ -738,7 +740,14 @@ static void isolate_freepages(struct zone *zone,
        /* split_free_page does not map the pages */
        map_pages(freelist);
 
-       cc->free_pfn = high_pfn;
+       /*
+        * If we crossed the migrate scanner, we want to keep it that way
+        * so that compact_finished() may detect this
+        */
+       if (pfn < low_pfn)
+               cc->free_pfn = max(pfn, zone->zone_start_pfn);
+       else
+               cc->free_pfn = high_pfn;
        cc->nr_freepages = nr_freepages;
 }
 
@@ -947,6 +956,14 @@ static int compact_zone(struct zone *zone, struct 
compact_control *cc)
        }
 
        /*
+        * Clear pageblock skip if there were failures recently and compaction
+        * is about to be retried after being deferred. kswapd does not do
+        * this reset as it'll reset the cached information when going to sleep.
+        */
+       if (compaction_restarting(zone, cc->order) && !current_is_kswapd())
+               __reset_isolation_suitable(zone);
+
+       /*
         * Setup to move all movable pages to the end of the zone. Used cached
         * information on where the scanners should start but check that it
         * is initialised by ensuring the values are within zone boundaries.
@@ -962,14 +979,6 @@ static int compact_zone(struct zone *zone, struct 
compact_control *cc)
                zone->compact_cached_migrate_pfn = cc->migrate_pfn;
        }
 
-       /*
-        * Clear pageblock skip if there were failures recently and compaction
-        * is about to be retried after being deferred. kswapd does not do
-        * this reset as it'll reset the cached information when going to sleep.
-        */
-       if (compaction_restarting(zone, cc->order) && !current_is_kswapd())
-               __reset_isolation_suitable(zone);
-
        migrate_prep_local();
 
        while ((ret = compact_finished(zone, cc)) == COMPACT_CONTINUE) {
@@ -1003,7 +1012,11 @@ static int compact_zone(struct zone *zone, struct 
compact_control *cc)
                if (err) {
                        putback_movable_pages(&cc->migratepages);
                        cc->nr_migratepages = 0;
-                       if (err == -ENOMEM) {
+                       /*
+                        * migrate_pages() may return -ENOMEM when scanners meet
+                        * and we want compact_finished() to detect it
+                        */
+                       if (err == -ENOMEM && cc->free_pfn > cc->migrate_pfn) {
                                ret = COMPACT_PARTIAL;
                                goto out;
                        }
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c 
b/net/ipv4/netfilter/nf_defrag_ipv4.c
index 742815518b0f..4cfb3bd1677c 100644
--- a/net/ipv4/netfilter/nf_defrag_ipv4.c
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -22,7 +22,6 @@
 #endif
 #include <net/netfilter/nf_conntrack_zones.h>
 
-/* Returns new sk_buff, or NULL */
 static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
 {
        int err;
@@ -33,8 +32,10 @@ static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, 
u_int32_t user)
        err = ip_defrag(skb, user);
        local_bh_enable();
 
-       if (!err)
+       if (!err) {
                ip_send_check(ip_hdr(skb));
+               skb->local_df = 1;
+       }
 
        return err;
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to