[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20121105101031.GB24501@kroah.com>
Date: Mon, 5 Nov 2012 11:10:31 +0100
From: Greg KH <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org,
Andrew Morton <akpm@...ux-foundation.org>,
torvalds@...ux-foundation.org, stable@...r.kernel.org
Cc: lwn@....net, Jiri Slaby <jslaby@...e.cz>
Subject: Re: Linux 3.6.6
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 majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists