diff --git a/Makefile b/Makefile
index 6e4a00d..471b83c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 6
-SUBLEVEL = 5
+SUBLEVEL = 6
 EXTRAVERSION =
 NAME = Terrified Chipmunk
 
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index f3b44a6..54f35d1c0 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -285,6 +285,13 @@ static void blkg_destroy_all(struct request_queue *q)
                blkg_destroy(blkg);
                spin_unlock(&blkcg->lock);
        }
+
+       /*
+        * root blkg is destroyed.  Just clear the pointer since
+        * root_rl does not take reference on root blkg.
+        */
+       q->root_blkg = NULL;
+       q->root_rl.blkg = NULL;
 }
 
 static void blkg_rcu_free(struct rcu_head *rcu_head)
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index a7d6347..fe0de7e 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4138,6 +4138,10 @@ static int __init do_floppy_init(void)
 
        raw_cmd = NULL;
 
+       floppy_wq = alloc_ordered_workqueue("floppy", 0);
+       if (!floppy_wq)
+               return -ENOMEM;
+
        for (dr = 0; dr < N_DRIVE; dr++) {
                disks[dr] = alloc_disk(1);
                if (!disks[dr]) {
@@ -4145,16 +4149,11 @@ static int __init do_floppy_init(void)
                        goto out_put_disk;
                }
 
-               floppy_wq = alloc_ordered_workqueue("floppy", 0);
-               if (!floppy_wq) {
-                       err = -ENOMEM;
-                       goto out_put_disk;
-               }
-
                disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock);
                if (!disks[dr]->queue) {
+                       put_disk(disks[dr]);
                        err = -ENOMEM;
-                       goto out_destroy_workq;
+                       goto out_put_disk;
                }
 
                blk_queue_max_hw_sectors(disks[dr]->queue, 64);
@@ -4294,7 +4293,7 @@ static int __init do_floppy_init(void)
 
                err = platform_device_register(&floppy_device[drive]);
                if (err)
-                       goto out_release_dma;
+                       goto out_remove_drives;
 
                err = device_create_file(&floppy_device[drive].dev,
                                         &dev_attr_cmos);
@@ -4312,14 +4311,21 @@ static int __init do_floppy_init(void)
 
 out_unreg_platform_dev:
        platform_device_unregister(&floppy_device[drive]);
+out_remove_drives:
+       while (drive--) {
+               if ((allowed_drive_mask & (1 << drive)) &&
+                   fdc_state[FDC(drive)].version != FDC_NONE) {
+                       del_gendisk(disks[drive]);
+                       device_remove_file(&floppy_device[drive].dev, 
&dev_attr_cmos);
+                       platform_device_unregister(&floppy_device[drive]);
+               }
+       }
 out_release_dma:
        if (atomic_read(&usage_count))
                floppy_release_irq_and_dma();
 out_unreg_region:
        blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
        platform_driver_unregister(&floppy_driver);
-out_destroy_workq:
-       destroy_workqueue(floppy_wq);
 out_unreg_blkdev:
        unregister_blkdev(FLOPPY_MAJOR, "fd");
 out_put_disk:
@@ -4335,6 +4341,7 @@ out_put_disk:
                }
                put_disk(disks[dr]);
        }
+       destroy_workqueue(floppy_wq);
        return err;
 }
 
diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c
index 031c6ad..1a3e2b9 100644
--- a/drivers/gpio/gpio-timberdale.c
+++ b/drivers/gpio/gpio-timberdale.c
@@ -116,7 +116,7 @@ static void timbgpio_irq_disable(struct irq_data *d)
        unsigned long flags;
 
        spin_lock_irqsave(&tgpio->lock, flags);
-       tgpio->last_ier &= ~(1 << offset);
+       tgpio->last_ier &= ~(1UL << offset);
        iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
        spin_unlock_irqrestore(&tgpio->lock, flags);
 }
@@ -128,7 +128,7 @@ static void timbgpio_irq_enable(struct irq_data *d)
        unsigned long flags;
 
        spin_lock_irqsave(&tgpio->lock, flags);
-       tgpio->last_ier |= 1 << offset;
+       tgpio->last_ier |= 1UL << offset;
        iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
        spin_unlock_irqrestore(&tgpio->lock, flags);
 }
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index de0213c..f03ae68 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -623,9 +623,11 @@ static ssize_t export_store(struct class *class,
         */
 
        status = gpio_request(gpio, "sysfs");
-       if (status < 0)
+       if (status < 0) {
+               if (status == -EPROBE_DEFER)
+                       status = -ENODEV;
                goto done;
-
+       }
        status = gpio_export(gpio, true);
        if (status < 0)
                gpio_free(gpio);
@@ -1191,8 +1193,10 @@ int gpio_request(unsigned gpio, const char *label)
 
        spin_lock_irqsave(&gpio_lock, flags);
 
-       if (!gpio_is_valid(gpio))
+       if (!gpio_is_valid(gpio)) {
+               status = -EINVAL;
                goto done;
+       }
        desc = &gpio_desc[gpio];
        chip = desc->chip;
        if (chip == NULL)
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c 
b/drivers/gpu/drm/nouveau/nouveau_drv.c
index 9a36f5f..a06eb3d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -188,11 +188,13 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t 
pm_state)
        if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
                return 0;
 
-       NV_INFO(dev, "Disabling display...\n");
-       nouveau_display_fini(dev);
+       if (dev->mode_config.num_crtc) {
+               NV_INFO(dev, "Disabling display...\n");
+               nouveau_display_fini(dev);
 
-       NV_INFO(dev, "Disabling fbcon...\n");
-       nouveau_fbcon_set_suspend(dev, 1);
+               NV_INFO(dev, "Disabling fbcon...\n");
+               nouveau_fbcon_set_suspend(dev, 1);
+       }
 
        NV_INFO(dev, "Unpinning framebuffer(s)...\n");
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
@@ -359,10 +361,12 @@ nouveau_pci_resume(struct pci_dev *pdev)
                        NV_ERROR(dev, "Could not pin/map cursor.\n");
        }
 
-       nouveau_fbcon_set_suspend(dev, 0);
-       nouveau_fbcon_zfill_all(dev);
+       if (dev->mode_config.num_crtc) {
+               nouveau_fbcon_set_suspend(dev, 0);
+               nouveau_fbcon_zfill_all(dev);
 
-       nouveau_display_init(dev);
+               nouveau_display_init(dev);
+       }
 
        /* Force CLUT to get re-loaded during modeset */
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
@@ -484,9 +488,7 @@ static int __init nouveau_init(void)
 #ifdef CONFIG_VGA_CONSOLE
                if (vgacon_text_force())
                        nouveau_modeset = 0;
-               else
 #endif
-                       nouveau_modeset = 1;
        }
 
        if (!nouveau_modeset)
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c 
b/drivers/gpu/drm/nouveau/nouveau_state.c
index c610144..f5e9584 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -50,6 +50,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_engine *engine = &dev_priv->engine;
+       u32 pclass = dev->pdev->class >> 8;
 
        switch (dev_priv->chipset & 0xf0) {
        case 0x00:
@@ -428,7 +429,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
        }
 
        /* headless mode */
-       if (nouveau_modeset == 2) {
+       if (nouveau_modeset == 2 ||
+           (nouveau_modeset < 0 && pclass != PCI_CLASS_DISPLAY_VGA)) {
                engine->display.early_init = nouveau_stub_init;
                engine->display.late_takedown = nouveau_stub_takedown;
                engine->display.create = nouveau_stub_init;
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c 
b/drivers/gpu/drm/nouveau/nv04_dac.c
index 38f1947..09ac275 100644
--- a/drivers/gpu/drm/nouveau/nv04_dac.c
+++ b/drivers/gpu/drm/nouveau/nv04_dac.c
@@ -210,7 +210,7 @@ out:
        NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode);
 
        if (blue == 0x18) {
-               NV_INFO(dev, "Load detected on head A\n");
+               NV_DEBUG(dev, "Load detected on head A\n");
                return connector_status_connected;
        }
 
@@ -323,7 +323,7 @@ nv17_dac_detect(struct drm_encoder *encoder, struct 
drm_connector *connector)
 
        if (nv17_dac_sample_load(encoder) &
            NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) {
-               NV_INFO(dev, "Load detected on output %c\n",
+               NV_DEBUG(dev, "Load detected on output %c\n",
                        '@' + ffs(dcb->or));
                return connector_status_connected;
        } else {
@@ -398,7 +398,7 @@ static void nv04_dac_commit(struct drm_encoder *encoder)
 
        helper->dpms(encoder, DRM_MODE_DPMS_ON);
 
-       NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+       NV_DEBUG(dev, "Output %s is running on CRTC %d using output %c\n",
                
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
                nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
 }
@@ -447,7 +447,7 @@ static void nv04_dac_dpms(struct drm_encoder *encoder, int 
mode)
                return;
        nv_encoder->last_dpms = mode;
 
-       NV_INFO(dev, "Setting dpms mode %d on vga encoder (output %d)\n",
+       NV_DEBUG(dev, "Setting dpms mode %d on vga encoder (output %d)\n",
                     mode, nv_encoder->dcb->index);
 
        nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON);
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c 
b/drivers/gpu/drm/nouveau/nv04_dfp.c
index c267562..89640f2 100644
--- a/drivers/gpu/drm/nouveau/nv04_dfp.c
+++ b/drivers/gpu/drm/nouveau/nv04_dfp.c
@@ -476,7 +476,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder)
 
        helper->dpms(encoder, DRM_MODE_DPMS_ON);
 
-       NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+       NV_DEBUG(dev, "Output %s is running on CRTC %d using output %c\n",
                
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
                nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
 }
@@ -519,7 +519,7 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int 
mode)
                return;
        nv_encoder->last_dpms = mode;
 
-       NV_INFO(dev, "Setting dpms mode %d on lvds encoder (output %d)\n",
+       NV_DEBUG(dev, "Setting dpms mode %d on lvds encoder (output %d)\n",
                     mode, nv_encoder->dcb->index);
 
        if (was_powersaving && is_powersaving_dpms(mode))
@@ -564,7 +564,7 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int 
mode)
                return;
        nv_encoder->last_dpms = mode;
 
-       NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n",
+       NV_DEBUG(dev, "Setting dpms mode %d on tmds encoder (output %d)\n",
                     mode, nv_encoder->dcb->index);
 
        nv04_dfp_update_backlight(encoder, mode);
diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c 
b/drivers/gpu/drm/nouveau/nv04_tv.c
index 3eb605d..4de1fbe 100644
--- a/drivers/gpu/drm/nouveau/nv04_tv.c
+++ b/drivers/gpu/drm/nouveau/nv04_tv.c
@@ -69,7 +69,7 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int 
mode)
        struct nv04_mode_state *state = &dev_priv->mode_reg;
        uint8_t crtc1A;
 
-       NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n",
+       NV_DEBUG(dev, "Setting dpms mode %d on TV encoder (output %d)\n",
                mode, nv_encoder->dcb->index);
 
        state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK);
@@ -162,7 +162,7 @@ static void nv04_tv_commit(struct drm_encoder *encoder)
 
        helper->dpms(encoder, DRM_MODE_DPMS_ON);
 
-       NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+       NV_DEBUG(dev, "Output %s is running on CRTC %d using output %c\n",
                      
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), 
nv_crtc->index,
                      '@' + ffs(nv_encoder->dcb->or));
 }
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index e5c699b..3899989 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -29,22 +29,30 @@
 #define MS_RDESC               0x08
 #define MS_NOGET               0x10
 #define MS_DUPLICATE_USAGES    0x20
+#define MS_RDESC_3K            0x40
 
-/*
- * Microsoft Wireless Desktop Receiver (Model 1028) has
- * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
- */
 static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
                unsigned int *rsize)
 {
        unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
 
+       /*
+        * Microsoft Wireless Desktop Receiver (Model 1028) has
+        * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
+        */
        if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 &&
                        rdesc[559] == 0x29) {
                hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 
1028 report descriptor\n");
                rdesc[557] = 0x35;
                rdesc[559] = 0x45;
        }
+       /* the same as above (s/usage/physical/) */
+       if ((quirks & MS_RDESC_3K) && *rsize == 106 &&
+                       !memcmp((char []){ 0x19, 0x00, 0x29, 0xff },
+                               &rdesc[94], 4)) {
+               rdesc[94] = 0x35;
+               rdesc[96] = 0x45;
+       }
        return rdesc;
 }
 
@@ -193,7 +201,7 @@ static const struct hid_device_id ms_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, 
USB_DEVICE_ID_MS_PRESENTER_8K_USB),
                .driver_data = MS_PRESENTER },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, 
USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K),
-               .driver_data = MS_ERGONOMY },
+               .driver_data = MS_ERGONOMY | MS_RDESC_3K },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, 
USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0),
                .driver_data = MS_NOGET },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, 
USB_DEVICE_ID_MS_COMFORT_MOUSE_4500),
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 611b5f7..05bb49e 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2699,7 +2699,7 @@ static struct r1conf *setup_conf(struct mddev *mddev)
                    || disk_idx < 0)
                        continue;
                if (test_bit(Replacement, &rdev->flags))
-                       disk = conf->mirrors + conf->raid_disks + disk_idx;
+                       disk = conf->mirrors + mddev->raid_disks + disk_idx;
                else
                        disk = conf->mirrors + disk_idx;
 
diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 41b74ba..515c250 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -557,6 +557,7 @@ static bool qlt_check_fcport_exist(struct scsi_qla_host 
*vha,
        int pmap_len;
        fc_port_t *fcport;
        int global_resets;
+       unsigned long flags;
 
 retry:
        global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count);
@@ -625,10 +626,10 @@ retry:
            sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain,
            fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id);
 
-       sess->s_id = fcport->d_id;
-       sess->loop_id = fcport->loop_id;
-       sess->conf_compl_supported = !!(fcport->flags &
-           FCF_CONF_COMP_SUPPORTED);
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id,
+                               (fcport->flags & FCF_CONF_COMP_SUPPORTED));
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        res = true;
 
@@ -740,10 +741,9 @@ static struct qla_tgt_sess *qlt_create_sess(
                                qlt_undelete_sess(sess);
 
                        kref_get(&sess->se_sess->sess_kref);
-                       sess->s_id = fcport->d_id;
-                       sess->loop_id = fcport->loop_id;
-                       sess->conf_compl_supported = !!(fcport->flags &
-                           FCF_CONF_COMP_SUPPORTED);
+                       ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, 
fcport->loop_id,
+                                               (fcport->flags & 
FCF_CONF_COMP_SUPPORTED));
+
                        if (sess->local && !local)
                                sess->local = 0;
                        spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -796,8 +796,7 @@ static struct qla_tgt_sess *qlt_create_sess(
         */
        kref_get(&sess->se_sess->sess_kref);
 
-       sess->conf_compl_supported = !!(fcport->flags &
-           FCF_CONF_COMP_SUPPORTED);
+       sess->conf_compl_supported = (fcport->flags & FCF_CONF_COMP_SUPPORTED);
        BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name));
        memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name));
 
@@ -869,10 +868,8 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, 
fc_port_t *fcport)
                        ql_dbg(ql_dbg_tgt_mgt, vha, 0xf007,
                            "Reappeared sess %p\n", sess);
                }
-               sess->s_id = fcport->d_id;
-               sess->loop_id = fcport->loop_id;
-               sess->conf_compl_supported = !!(fcport->flags &
-                   FCF_CONF_COMP_SUPPORTED);
+               ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, 
fcport->loop_id,
+                                       (fcport->flags & 
FCF_CONF_COMP_SUPPORTED));
        }
 
        if (sess && sess->local) {
diff --git a/drivers/scsi/qla2xxx/qla_target.h 
b/drivers/scsi/qla2xxx/qla_target.h
index 170af15..bad7495 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -648,6 +648,7 @@ struct qla_tgt_func_tmpl {
 
        int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *,
                                        void *, uint8_t *, uint16_t);
+       void (*update_sess)(struct qla_tgt_sess *, port_id_t, uint16_t, bool);
        struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *,
                                                const uint16_t);
        struct qla_tgt_sess *(*find_sess_by_s_id)(struct scsi_qla_host *,
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c 
b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 4752f65..7fa0672 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -1468,6 +1468,78 @@ static int tcm_qla2xxx_check_initiator_node_acl(
        return 0;
 }
 
+static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id,
+                                   uint16_t loop_id, bool conf_compl_supported)
+{
+       struct qla_tgt *tgt = sess->tgt;
+       struct qla_hw_data *ha = tgt->ha;
+       struct tcm_qla2xxx_lport *lport = ha->tgt.target_lport_ptr;
+       struct se_node_acl *se_nacl = sess->se_sess->se_node_acl;
+       struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl,
+                       struct tcm_qla2xxx_nacl, se_node_acl);
+       u32 key;
+
+
+       if (sess->loop_id != loop_id || sess->s_id.b24 != s_id.b24)
+               pr_info("Updating session %p from port 
%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x loop_id %d -> %d s_id %x:%x:%x -> 
%x:%x:%x\n",
+                       sess,
+                       sess->port_name[0], sess->port_name[1],
+                       sess->port_name[2], sess->port_name[3],
+                       sess->port_name[4], sess->port_name[5],
+                       sess->port_name[6], sess->port_name[7],
+                       sess->loop_id, loop_id,
+                       sess->s_id.b.domain, sess->s_id.b.area, 
sess->s_id.b.al_pa,
+                       s_id.b.domain, s_id.b.area, s_id.b.al_pa);
+
+       if (sess->loop_id != loop_id) {
+               /*
+                * Because we can shuffle loop IDs around and we
+                * update different sessions non-atomically, we might
+                * have overwritten this session's old loop ID
+                * already, and we might end up overwriting some other
+                * session that will be updated later.  So we have to
+                * be extra careful and we can't warn about those things...
+                */
+               if (lport->lport_loopid_map[sess->loop_id].se_nacl == se_nacl)
+                       lport->lport_loopid_map[sess->loop_id].se_nacl = NULL;
+
+               lport->lport_loopid_map[loop_id].se_nacl = se_nacl;
+
+               sess->loop_id = loop_id;
+       }
+
+       if (sess->s_id.b24 != s_id.b24) {
+               key = (((u32) sess->s_id.b.domain << 16) |
+                      ((u32) sess->s_id.b.area   <<  8) |
+                      ((u32) sess->s_id.b.al_pa));
+
+               if (btree_lookup32(&lport->lport_fcport_map, key))
+                       WARN(btree_remove32(&lport->lport_fcport_map, key) != 
se_nacl,
+                            "Found wrong se_nacl when updating s_id 
%x:%x:%x\n",
+                            sess->s_id.b.domain, sess->s_id.b.area, 
sess->s_id.b.al_pa);
+               else
+                       WARN(1, "No lport_fcport_map entry for s_id %x:%x:%x\n",
+                            sess->s_id.b.domain, sess->s_id.b.area, 
sess->s_id.b.al_pa);
+
+               key = (((u32) s_id.b.domain << 16) |
+                      ((u32) s_id.b.area   <<  8) |
+                      ((u32) s_id.b.al_pa));
+
+               if (btree_lookup32(&lport->lport_fcport_map, key)) {
+                       WARN(1, "Already have lport_fcport_map entry for s_id 
%x:%x:%x\n",
+                            s_id.b.domain, s_id.b.area, s_id.b.al_pa);
+                       btree_update32(&lport->lport_fcport_map, key, se_nacl);
+               } else {
+                       btree_insert32(&lport->lport_fcport_map, key, se_nacl, 
GFP_ATOMIC);
+               }
+
+               sess->s_id = s_id;
+               nacl->nport_id = key;
+       }
+
+       sess->conf_compl_supported = conf_compl_supported;
+}
+
 /*
  * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path.
  */
@@ -1478,6 +1550,7 @@ static struct qla_tgt_func_tmpl tcm_qla2xxx_template = {
        .free_cmd               = tcm_qla2xxx_free_cmd,
        .free_mcmd              = tcm_qla2xxx_free_mcmd,
        .free_session           = tcm_qla2xxx_free_session,
+       .update_sess            = tcm_qla2xxx_update_sess,
        .check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl,
        .find_sess_by_s_id      = tcm_qla2xxx_find_sess_by_s_id,
        .find_sess_by_loop_id   = tcm_qla2xxx_find_sess_by_loop_id,
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index a9dd946..323e192 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -128,6 +128,12 @@ static int sbc_emulate_verify(struct se_cmd *cmd)
        return 0;
 }
 
+static int sbc_emulate_noop(struct se_cmd *cmd)
+{
+       target_complete_cmd(cmd, GOOD);
+       return 0;
+}
+
 static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors)
 {
        return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors;
@@ -524,6 +530,18 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops)
                size = 0;
                cmd->execute_cmd = sbc_emulate_verify;
                break;
+       case REZERO_UNIT:
+       case SEEK_6:
+       case SEEK_10:
+               /*
+                * There are still clients out there which use these old SCSI-2
+                * commands. This mainly happens when running VMs with legacy
+                * guest systems, connected via SCSI command pass-through to
+                * iSCSI targets. Make them happy and return status GOOD.
+                */
+               size = 0;
+               cmd->execute_cmd = sbc_emulate_noop;
+               break;
        default:
                ret = spc_parse_cdb(cmd, &size);
                if (ret)
diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index 269f544..7502660 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1553,7 +1553,6 @@ static void target_complete_tmr_failure(struct 
work_struct *work)
 
        se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST;
        se_cmd->se_tfo->queue_tm_rsp(se_cmd);
-       transport_generic_free_cmd(se_cmd, 0);
 }
 
 /**
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index dca27a5..6c22679 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -3152,7 +3152,6 @@ static void edge_disconnect(struct usb_serial *serial)
 static void edge_release(struct usb_serial *serial)
 {
        struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
-       int i;
 
        dbg("%s", __func__);
 
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index cdf0f99..8d3692b 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -105,7 +105,7 @@ static int iuu_port_probe(struct usb_serial_port *port)
        }
 
        priv->dbgbuf = kzalloc(256, GFP_KERNEL);
-       if (!priv->writebuf) {
+       if (!priv->dbgbuf) {
                kfree(priv->writebuf);
                kfree(priv->buf);
                kfree(priv);
@@ -120,6 +120,7 @@ static int iuu_port_probe(struct usb_serial_port *port)
 
        ret = iuu_create_sysfs_attrs(port);
        if (ret) {
+               kfree(priv->dbgbuf);
                kfree(priv->writebuf);
                kfree(priv->buf);
                kfree(priv);
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 52e5ca7..5311819 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -2405,52 +2405,43 @@ static int mos7840_calc_num_ports(struct usb_serial 
*serial)
        return mos7840_num_ports;
 }
 
-/****************************************************************************
- * mos7840_startup
- ****************************************************************************/
-
-static int mos7840_startup(struct usb_serial *serial)
+static int mos7840_port_probe(struct usb_serial_port *port)
 {
+       struct usb_serial *serial = port->serial;
        struct moschip_port *mos7840_port;
-       struct usb_device *dev;
-       int i, status;
+       int status;
+       int pnum;
        __u16 Data;
 
-       if (!serial) {
-               dbg("%s", "Invalid Handler");
-               return -1;
-       }
-
-       dev = serial->dev;
-
        /* we set up the pointers to the endpoints in the mos7840_open *
         * function, as the structures aren't created yet.             */
 
-       /* set up port private structures */
-       for (i = 0; i < serial->num_ports; ++i) {
-               dbg ("mos7840_startup: configuring port %d............", i);
+       pnum = port->number - serial->minor;
+
+       /* FIXME: remove do-while(0) loop used to keep stable patch minimal.
+        */
+       do {
+               dbg("mos7840_startup: configuring port %d............", pnum);
                mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
                if (mos7840_port == NULL) {
-                       dev_err(&dev->dev, "%s - Out of memory\n", __func__);
-                       status = -ENOMEM;
-                       i--; /* don't follow NULL pointer cleaning up */
-                       goto error;
+                       dev_err(&port->dev, "%s - Out of memory\n", __func__);
+                       return -ENOMEM;
                }
 
                /* Initialize all port interrupt end point to port 0 int
                 * endpoint. Our device has only one interrupt end point
                 * common to all port */
 
-               mos7840_port->port = serial->port[i];
-               mos7840_set_port_private(serial->port[i], mos7840_port);
+               mos7840_port->port = port;
+               mos7840_set_port_private(port, mos7840_port);
                spin_lock_init(&mos7840_port->pool_lock);
 
                /* minor is not initialised until later by
                 * usb-serial.c:get_free_serial() and cannot therefore be used
                 * to index device instances */
-               mos7840_port->port_num = i + 1;
-               dbg ("serial->port[i]->number = %d", serial->port[i]->number);
-               dbg ("serial->port[i]->serial->minor = %d", 
serial->port[i]->serial->minor);
+               mos7840_port->port_num = pnum + 1;
+               dbg("port->number = %d", port->number);
+               dbg("port->serial->minor = %d", port->serial->minor);
                dbg ("mos7840_port->port_num = %d", mos7840_port->port_num);
                dbg ("serial->minor = %d", serial->minor);
 
@@ -2480,10 +2471,10 @@ static int mos7840_startup(struct usb_serial *serial)
                        mos7840_port->DcrRegOffset = 0x1c;
                }
                mos7840_dump_serial_port(mos7840_port);
-               mos7840_set_port_private(serial->port[i], mos7840_port);
+               mos7840_set_port_private(port, mos7840_port);
 
                /* enable rx_disable bit in control register */
-               status = mos7840_get_reg_sync(serial->port[i],
+               status = mos7840_get_reg_sync(port,
                                 mos7840_port->ControlRegOffset, &Data);
                if (status < 0) {
                        dbg("Reading ControlReg failed status-0x%x", status);
@@ -2491,12 +2482,13 @@ static int mos7840_startup(struct usb_serial *serial)
                } else
                        dbg("ControlReg Reading success val is %x, status%d",
                            Data, status);
+
                Data |= 0x08;   /* setting driver done bit */
                Data |= 0x04;   /* sp1_bit to have cts change reflect in
                                   modem status reg */
 
                /* Data |= 0x20; //rx_disable bit */
-               status = mos7840_set_reg_sync(serial->port[i],
+               status = mos7840_set_reg_sync(port,
                                         mos7840_port->ControlRegOffset, Data);
                if (status < 0) {
                        dbg("Writing ControlReg failed(rx_disable) 
status-0x%x", status);
@@ -2508,7 +2500,7 @@ static int mos7840_startup(struct usb_serial *serial)
                /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
                   and 0x24 in DCR3 */
                Data = 0x01;
-               status = mos7840_set_reg_sync(serial->port[i],
+               status = mos7840_set_reg_sync(port,
                         (__u16) (mos7840_port->DcrRegOffset + 0), Data);
                if (status < 0) {
                        dbg("Writing DCR0 failed status-0x%x", status);
@@ -2517,7 +2509,7 @@ static int mos7840_startup(struct usb_serial *serial)
                        dbg("DCR0 Writing success status%d", status);
 
                Data = 0x05;
-               status = mos7840_set_reg_sync(serial->port[i],
+               status = mos7840_set_reg_sync(port,
                         (__u16) (mos7840_port->DcrRegOffset + 1), Data);
                if (status < 0) {
                        dbg("Writing DCR1 failed status-0x%x", status);
@@ -2526,7 +2518,7 @@ static int mos7840_startup(struct usb_serial *serial)
                        dbg("DCR1 Writing success status%d", status);
 
                Data = 0x24;
-               status = mos7840_set_reg_sync(serial->port[i],
+               status = mos7840_set_reg_sync(port,
                         (__u16) (mos7840_port->DcrRegOffset + 2), Data);
                if (status < 0) {
                        dbg("Writing DCR2 failed status-0x%x", status);
@@ -2536,7 +2528,7 @@ static int mos7840_startup(struct usb_serial *serial)
 
                /* write values in clkstart0x0 and clkmulti 0x20 */
                Data = 0x0;
-               status = mos7840_set_reg_sync(serial->port[i],
+               status = mos7840_set_reg_sync(port,
                                         CLK_START_VALUE_REGISTER, Data);
                if (status < 0) {
                        dbg("Writing CLK_START_VALUE_REGISTER failed 
status-0x%x", status);
@@ -2545,7 +2537,7 @@ static int mos7840_startup(struct usb_serial *serial)
                        dbg("CLK_START_VALUE_REGISTER Writing success 
status%d", status);
 
                Data = 0x20;
-               status = mos7840_set_reg_sync(serial->port[i],
+               status = mos7840_set_reg_sync(port,
                                        CLK_MULTI_REGISTER, Data);
                if (status < 0) {
                        dbg("Writing CLK_MULTI_REGISTER failed status-0x%x",
@@ -2557,7 +2549,7 @@ static int mos7840_startup(struct usb_serial *serial)
 
                /* write value 0x0 to scratchpad register */
                Data = 0x00;
-               status = mos7840_set_uart_reg(serial->port[i],
+               status = mos7840_set_uart_reg(port,
                                                SCRATCH_PAD_REGISTER, Data);
                if (status < 0) {
                        dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x",
@@ -2572,7 +2564,7 @@ static int mos7840_startup(struct usb_serial *serial)
                    && (serial->num_ports == 2)) {
 
                        Data = 0xff;
-                       status = mos7840_set_reg_sync(serial->port[i],
+                       status = mos7840_set_reg_sync(port,
                                      (__u16) (ZLP_REG1 +
                                      ((__u16)mos7840_port->port_num)), Data);
                        dbg("ZLIP offset %x",
@@ -2580,14 +2572,14 @@ static int mos7840_startup(struct usb_serial *serial)
                                        ((__u16) mos7840_port->port_num)));
                        if (status < 0) {
                                dbg("Writing ZLP_REG%d failed status-0x%x",
-                                   i + 2, status);
+                                   pnum + 2, status);
                                break;
                        } else
                                dbg("ZLP_REG%d Writing success status%d",
-                                   i + 2, status);
+                                   pnum + 2, status);
                } else {
                        Data = 0xff;
-                       status = mos7840_set_reg_sync(serial->port[i],
+                       status = mos7840_set_reg_sync(port,
                              (__u16) (ZLP_REG1 +
                              ((__u16)mos7840_port->port_num) - 0x1), Data);
                        dbg("ZLIP offset %x",
@@ -2595,11 +2587,11 @@ static int mos7840_startup(struct usb_serial *serial)
                                     ((__u16) mos7840_port->port_num) - 0x1));
                        if (status < 0) {
                                dbg("Writing ZLP_REG%d failed status-0x%x",
-                                   i + 1, status);
+                                   pnum + 1, status);
                                break;
                        } else
                                dbg("ZLP_REG%d Writing success status%d",
-                                   i + 1, status);
+                                   pnum + 1, status);
 
                }
                mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -2636,105 +2628,58 @@ static int mos7840_startup(struct usb_serial *serial)
                        mos7840_port->led_flag = false;
 
                        /* Turn off LED */
-                       mos7840_set_led_sync(serial->port[i],
+                       mos7840_set_led_sync(port,
                                                MODEM_CONTROL_REGISTER, 0x0300);
                }
-       }
-       dbg ("mos7840_startup: all ports configured...........");
+       } while (0);
 
-       /* Zero Length flag enable */
-       Data = 0x0f;
-       status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
-       if (status < 0) {
-               dbg("Writing ZLP_REG5 failed status-0x%x", status);
-               goto error;
-       } else
-               dbg("ZLP_REG5 Writing success status%d", status);
-
-       /* setting configuration feature to one */
-       usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                       (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 
MOS_WDR_TIMEOUT);
+       if (pnum == serial->num_ports - 1) {
+               dbg("mos7840_startup: all ports configured...........");
+
+               /* Zero Length flag enable */
+               Data = 0x0f;
+               status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
+               if (status < 0) {
+                       dbg("Writing ZLP_REG5 failed status-0x%x", status);
+                       goto error;
+               } else
+                       dbg("ZLP_REG5 Writing success status%d", status);
+
+               /* setting configuration feature to one */
+               usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+                               0x03, 0x00, 0x01, 0x00, NULL, 0x00,
+                               MOS_WDR_TIMEOUT);
+       }
        return 0;
 error:
-       for (/* nothing */; i >= 0; i--) {
-               mos7840_port = mos7840_get_port_private(serial->port[i]);
+       kfree(mos7840_port->dr);
+       kfree(mos7840_port->ctrl_buf);
+       usb_free_urb(mos7840_port->control_urb);
+       kfree(mos7840_port);
 
-               kfree(mos7840_port->dr);
-               kfree(mos7840_port->ctrl_buf);
-               usb_free_urb(mos7840_port->control_urb);
-               kfree(mos7840_port);
-       }
        return status;
 }
 
-/****************************************************************************
- * mos7840_disconnect
- *     This function is called whenever the device is removed from the usb bus.
- ****************************************************************************/
-
-static void mos7840_disconnect(struct usb_serial *serial)
+static int mos7840_port_remove(struct usb_serial_port *port)
 {
-       int i;
-       unsigned long flags;
        struct moschip_port *mos7840_port;
 
-       if (!serial) {
-               dbg("%s", "Invalid Handler");
-               return;
-       }
-
-       /* check for the ports to be closed,close the ports and disconnect */
+       mos7840_port = mos7840_get_port_private(port);
 
-       /* free private structure allocated for serial port  *
-        * stop reads and writes on all ports                */
+       if (mos7840_port->has_led) {
+               /* Turn off LED */
+               mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300);
 
-       for (i = 0; i < serial->num_ports; ++i) {
-               mos7840_port = mos7840_get_port_private(serial->port[i]);
-               dbg ("mos7840_port %d = %p", i, mos7840_port);
-               if (mos7840_port) {
-                       usb_kill_urb(mos7840_port->control_urb);
-               }
+               del_timer_sync(&mos7840_port->led_timer1);
+               del_timer_sync(&mos7840_port->led_timer2);
        }
-}
+       usb_kill_urb(mos7840_port->control_urb);
+       usb_free_urb(mos7840_port->control_urb);
+       kfree(mos7840_port->ctrl_buf);
+       kfree(mos7840_port->dr);
+       kfree(mos7840_port);
 
-/****************************************************************************
- * mos7840_release
- *     This function is called when the usb_serial structure is freed.
- ****************************************************************************/
-
-static void mos7840_release(struct usb_serial *serial)
-{
-       int i;
-       struct moschip_port *mos7840_port;
-
-       if (!serial) {
-               dbg("%s", "Invalid Handler");
-               return;
-       }
-
-       /* check for the ports to be closed,close the ports and disconnect */
-
-       /* free private structure allocated for serial port  *
-        * stop reads and writes on all ports                */
-
-       for (i = 0; i < serial->num_ports; ++i) {
-               mos7840_port = mos7840_get_port_private(serial->port[i]);
-               dbg("mos7840_port %d = %p", i, mos7840_port);
-               if (mos7840_port) {
-                       if (mos7840_port->has_led) {
-                               /* Turn off LED */
-                               mos7840_set_led_sync(mos7840_port->port,
-                                               MODEM_CONTROL_REGISTER, 0x0300);
-
-                               del_timer_sync(&mos7840_port->led_timer1);
-                               del_timer_sync(&mos7840_port->led_timer2);
-                       }
-                       usb_free_urb(mos7840_port->control_urb);
-                       kfree(mos7840_port->ctrl_buf);
-                       kfree(mos7840_port->dr);
-                       kfree(mos7840_port);
-               }
-       }
+       return 0;
 }
 
 static struct usb_serial_driver moschip7840_4port_device = {
@@ -2762,9 +2707,8 @@ static struct usb_serial_driver moschip7840_4port_device 
= {
        .tiocmget = mos7840_tiocmget,
        .tiocmset = mos7840_tiocmset,
        .get_icount = mos7840_get_icount,
-       .attach = mos7840_startup,
-       .disconnect = mos7840_disconnect,
-       .release = mos7840_release,
+       .port_probe = mos7840_port_probe,
+       .port_remove = mos7840_port_remove,
        .read_bulk_callback = mos7840_bulk_in_callback,
        .read_int_callback = mos7840_interrupt_callback,
 };
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 452e71a..1ced2d8 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -205,7 +205,7 @@ static int readpage_nounlock(struct file *filp, struct page 
*page)
        dout("readpage inode %p file %p page %p index %lu\n",
             inode, filp, page, page->index);
        err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
-                                 page->index << PAGE_CACHE_SHIFT, &len,
+                                 (u64) page_offset(page), &len,
                                  ci->i_truncate_seq, ci->i_truncate_size,
                                  &page, 1, 0);
        if (err == -ENOENT)
@@ -286,7 +286,7 @@ static int start_read(struct inode *inode, struct list_head 
*page_list, int max)
        int nr_pages = 0;
        int ret;
 
-       off = page->index << PAGE_CACHE_SHIFT;
+       off = (u64) page_offset(page);
 
        /* count pages */
        next_index = page->index;
@@ -426,7 +426,7 @@ static int writepage_nounlock(struct page *page, struct 
writeback_control *wbc)
        struct ceph_inode_info *ci;
        struct ceph_fs_client *fsc;
        struct ceph_osd_client *osdc;
-       loff_t page_off = page->index << PAGE_CACHE_SHIFT;
+       loff_t page_off = page_offset(page);
        int len = PAGE_CACHE_SIZE;
        loff_t i_size;
        int err = 0;
@@ -817,8 +817,7 @@ get_more_pages:
                        /* ok */
                        if (locked_pages == 0) {
                                /* prepare async write request */
-                               offset = (unsigned long long)page->index
-                                       << PAGE_CACHE_SHIFT;
+                               offset = (u64) page_offset(page);
                                len = wsize;
                                req = ceph_osdc_new_request(&fsc->client->osdc,
                                            &ci->i_layout,
@@ -1180,7 +1179,7 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, 
struct vm_fault *vmf)
        struct inode *inode = vma->vm_file->f_dentry->d_inode;
        struct page *page = vmf->page;
        struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
-       loff_t off = page->index << PAGE_CACHE_SHIFT;
+       loff_t off = page_offset(page);
        loff_t size, len;
        int ret;
 
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
index 02ce909..9349bb3 100644
--- a/fs/ceph/export.c
+++ b/fs/ceph/export.c
@@ -90,6 +90,8 @@ static int ceph_encode_fh(struct inode *inode, u32 *rawfh, 
int *max_len,
                *max_len = handle_length;
                type = 255;
        }
+       if (dentry)
+               dput(dentry);
        return type;
 }
 
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index a5a7354..1bcf712 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2625,7 +2625,8 @@ static void check_new_map(struct ceph_mds_client *mdsc,
                     ceph_mdsmap_is_laggy(newmap, i) ? " (laggy)" : "",
                     session_state_name(s->s_state));
 
-               if (memcmp(ceph_mdsmap_get_addr(oldmap, i),
+               if (i >= newmap->m_max_mds ||
+                   memcmp(ceph_mdsmap_get_addr(oldmap, i),
                           ceph_mdsmap_get_addr(newmap, i),
                           sizeof(struct ceph_entity_addr))) {
                        if (s->s_state == CEPH_MDS_SESSION_OPENING) {
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 8ce0076..cc2d77c 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -716,6 +716,10 @@ repeat_in_this_group:
                                   "inode=%lu", ino + 1);
                        continue;
                }
+               BUFFER_TRACE(inode_bitmap_bh, "get_write_access");
+               err = ext4_journal_get_write_access(handle, inode_bitmap_bh);
+               if (err)
+                       goto fail;
                ext4_lock_group(sb, group);
                ret2 = ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data);
                ext4_unlock_group(sb, group);
@@ -729,6 +733,11 @@ repeat_in_this_group:
        goto out;
 
 got:
+       BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata");
+       err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh);
+       if (err)
+               goto fail;
+
        /* We may have to initialize the block bitmap if it isn't already */
        if (ext4_has_group_desc_csum(sb) &&
            gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
@@ -762,11 +771,6 @@ got:
                        goto fail;
        }
 
-       BUFFER_TRACE(inode_bitmap_bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, inode_bitmap_bh);
-       if (err)
-               goto fail;
-
        BUFFER_TRACE(group_desc_bh, "get_write_access");
        err = ext4_journal_get_write_access(handle, group_desc_bh);
        if (err)
@@ -814,11 +818,6 @@ got:
        }
        ext4_unlock_group(sb, group);
 
-       BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata");
-       err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh);
-       if (err)
-               goto fail;
-
        BUFFER_TRACE(group_desc_bh, "call ext4_handle_dirty_metadata");
        err = ext4_handle_dirty_metadata(handle, NULL, group_desc_bh);
        if (err)
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index cedfb1a..d9b880e 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -207,7 +207,7 @@ extern void ceph_osdc_handle_reply(struct ceph_osd_client 
*osdc,
 extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc,
                                 struct ceph_msg *msg);
 
-extern void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
+extern int ceph_calc_raw_layout(struct ceph_osd_client *osdc,
                        struct ceph_file_layout *layout,
                        u64 snapid,
                        u64 off, u64 *plen, u64 *bno,
diff --git a/include/linux/ceph/osdmap.h b/include/linux/ceph/osdmap.h
index 311ef8d..e88a620 100644
--- a/include/linux/ceph/osdmap.h
+++ b/include/linux/ceph/osdmap.h
@@ -109,9 +109,9 @@ extern struct ceph_osdmap *osdmap_apply_incremental(void 
**p, void *end,
 extern void ceph_osdmap_destroy(struct ceph_osdmap *map);
 
 /* calculate mapping of a file extent to an object */
-extern void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
-                                         u64 off, u64 *plen,
-                                         u64 *bno, u64 *oxoff, u64 *oxlen);
+extern int ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
+                                        u64 off, u64 *plen,
+                                        u64 *bno, u64 *oxoff, u64 *oxlen);
 
 /* calculate mapping of object to a placement group */
 extern int ceph_calc_object_layout(struct ceph_object_layout *ol,
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 159aa8b..3ef1759 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -2300,10 +2300,11 @@ restart:
                        mutex_unlock(&con->mutex);
                        return;
                } else {
-                       con->ops->put(con);
                        dout("con_work %p FAILED to back off %lu\n", con,
                             con->delay);
+                       set_bit(CON_FLAG_BACKOFF, &con->flags);
                }
+               goto done;
        }
 
        if (con->state == CON_STATE_STANDBY) {
@@ -2749,7 +2750,8 @@ static int ceph_con_in_msg_alloc(struct ceph_connection 
*con, int *skip)
                msg = con->ops->alloc_msg(con, hdr, skip);
                mutex_lock(&con->mutex);
                if (con->state != CON_STATE_OPEN) {
-                       ceph_msg_put(msg);
+                       if (msg)
+                               ceph_msg_put(msg);
                        return -EAGAIN;
                }
                con->in_msg = msg;
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 42119c0..f7b56e2 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -52,7 +52,7 @@ static int op_has_extent(int op)
                op == CEPH_OSD_OP_WRITE);
 }
 
-void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
+int ceph_calc_raw_layout(struct ceph_osd_client *osdc,
                        struct ceph_file_layout *layout,
                        u64 snapid,
                        u64 off, u64 *plen, u64 *bno,
@@ -62,12 +62,15 @@ void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
        struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
        u64 orig_len = *plen;
        u64 objoff, objlen;    /* extent in object */
+       int r;
 
        reqhead->snapid = cpu_to_le64(snapid);
 
        /* object extent? */
-       ceph_calc_file_object_mapping(layout, off, plen, bno,
-                                     &objoff, &objlen);
+       r = ceph_calc_file_object_mapping(layout, off, plen, bno,
+                                         &objoff, &objlen);
+       if (r < 0)
+               return r;
        if (*plen < orig_len)
                dout(" skipping last %llu, final file extent %llu~%llu\n",
                     orig_len - *plen, off, *plen);
@@ -83,7 +86,7 @@ void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
 
        dout("calc_layout bno=%llx %llu~%llu (%d pages)\n",
             *bno, objoff, objlen, req->r_num_pages);
-
+       return 0;
 }
 EXPORT_SYMBOL(ceph_calc_raw_layout);
 
@@ -112,20 +115,25 @@ EXPORT_SYMBOL(ceph_calc_raw_layout);
  *
  * fill osd op in request message.
  */
-static void calc_layout(struct ceph_osd_client *osdc,
-                       struct ceph_vino vino,
-                       struct ceph_file_layout *layout,
-                       u64 off, u64 *plen,
-                       struct ceph_osd_request *req,
-                       struct ceph_osd_req_op *op)
+static int calc_layout(struct ceph_osd_client *osdc,
+                      struct ceph_vino vino,
+                      struct ceph_file_layout *layout,
+                      u64 off, u64 *plen,
+                      struct ceph_osd_request *req,
+                      struct ceph_osd_req_op *op)
 {
        u64 bno;
+       int r;
 
-       ceph_calc_raw_layout(osdc, layout, vino.snap, off,
-                            plen, &bno, req, op);
+       r = ceph_calc_raw_layout(osdc, layout, vino.snap, off,
+                                plen, &bno, req, op);
+       if (r < 0)
+               return r;
 
        snprintf(req->r_oid, sizeof(req->r_oid), "%llx.%08llx", vino.ino, bno);
        req->r_oid_len = strlen(req->r_oid);
+
+       return r;
 }
 
 /*
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index 3124b71..5433fb0 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -984,7 +984,7 @@ bad:
  * for now, we write only a single su, until we can
  * pass a stride back to the caller.
  */
-void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
+int ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
                                   u64 off, u64 *plen,
                                   u64 *ono,
                                   u64 *oxoff, u64 *oxlen)
@@ -998,11 +998,17 @@ void ceph_calc_file_object_mapping(struct 
ceph_file_layout *layout,
 
        dout("mapping %llu~%llu  osize %u fl_su %u\n", off, *plen,
             osize, su);
+       if (su == 0 || sc == 0)
+               goto invalid;
        su_per_object = osize / su;
+       if (su_per_object == 0)
+               goto invalid;
        dout("osize %u / su %u = su_per_object %u\n", osize, su,
             su_per_object);
 
-       BUG_ON((su & ~PAGE_MASK) != 0);
+       if ((su & ~PAGE_MASK) != 0)
+               goto invalid;
+
        /* bl = *off / su; */
        t = off;
        do_div(t, su);
@@ -1030,6 +1036,14 @@ void ceph_calc_file_object_mapping(struct 
ceph_file_layout *layout,
        *plen = *oxlen;
 
        dout(" obj extent %llu~%llu\n", *oxoff, *oxlen);
+       return 0;
+
+invalid:
+       dout(" invalid layout\n");
+       *ono = 0;
+       *oxoff = 0;
+       *oxlen = 0;
+       return -EINVAL;
 }
 EXPORT_SYMBOL(ceph_calc_file_object_mapping);
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
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