aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2010-09-14 14:40:41 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2010-10-14 12:38:49 -0400
commit22cc37a943832c948808884604ec6f5ff2594c1d (patch)
tree5c0784f0010421c45c4fd847dac8692d03f399e6
parentaf85e8e83d160f72a10e4467852646ac08614260 (diff)
drbd: fix unlikely access after free and list corruption
Various cleanup paths have been incomplete, for the very unlikely case that we cannot allocate enough bios from process context when submitting on behalf of the peer or resync process. Never observed. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r--drivers/block/drbd/drbd_receiver.c25
-rw-r--r--drivers/block/drbd/drbd_worker.c7
-rw-r--r--include/linux/drbd.h4
3 files changed, 34 insertions, 2 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 990fe01afa50..71775a9de21d 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1573,6 +1573,13 @@ static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_si
1573 if (drbd_submit_ee(mdev, e, WRITE, DRBD_FAULT_RS_WR) == 0) 1573 if (drbd_submit_ee(mdev, e, WRITE, DRBD_FAULT_RS_WR) == 0)
1574 return TRUE; 1574 return TRUE;
1575 1575
1576 /* drbd_submit_ee currently fails for one reason only:
1577 * not being able to allocate enough bios.
1578 * Is dropping the connection going to help? */
1579 spin_lock_irq(&mdev->req_lock);
1580 list_del(&e->w.list);
1581 spin_unlock_irq(&mdev->req_lock);
1582
1576 drbd_free_ee(mdev, e); 1583 drbd_free_ee(mdev, e);
1577fail: 1584fail:
1578 put_ldev(mdev); 1585 put_ldev(mdev);
@@ -1998,6 +2005,16 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
1998 if (drbd_submit_ee(mdev, e, rw, DRBD_FAULT_DT_WR) == 0) 2005 if (drbd_submit_ee(mdev, e, rw, DRBD_FAULT_DT_WR) == 0)
1999 return TRUE; 2006 return TRUE;
2000 2007
2008 /* drbd_submit_ee currently fails for one reason only:
2009 * not being able to allocate enough bios.
2010 * Is dropping the connection going to help? */
2011 spin_lock_irq(&mdev->req_lock);
2012 list_del(&e->w.list);
2013 hlist_del_init(&e->colision);
2014 spin_unlock_irq(&mdev->req_lock);
2015 if (e->flags & EE_CALL_AL_COMPLETE_IO)
2016 drbd_al_complete_io(mdev, e->sector);
2017
2001out_interrupted: 2018out_interrupted:
2002 /* yes, the epoch_size now is imbalanced. 2019 /* yes, the epoch_size now is imbalanced.
2003 * but we drop the connection anyways, so we don't have a chance to 2020 * but we drop the connection anyways, so we don't have a chance to
@@ -2202,6 +2219,14 @@ submit:
2202 if (drbd_submit_ee(mdev, e, READ, fault_type) == 0) 2219 if (drbd_submit_ee(mdev, e, READ, fault_type) == 0)
2203 return TRUE; 2220 return TRUE;
2204 2221
2222 /* drbd_submit_ee currently fails for one reason only:
2223 * not being able to allocate enough bios.
2224 * Is dropping the connection going to help? */
2225 spin_lock_irq(&mdev->req_lock);
2226 list_del(&e->w.list);
2227 spin_unlock_irq(&mdev->req_lock);
2228 /* no drbd_rs_complete_io(), we are dropping the connection anyways */
2229
2205out_free_e: 2230out_free_e:
2206 put_ldev(mdev); 2231 put_ldev(mdev);
2207 drbd_free_ee(mdev, e); 2232 drbd_free_ee(mdev, e);
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 88be45ad84ed..f12822d53867 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -387,6 +387,13 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size)
387 if (drbd_submit_ee(mdev, e, READ, DRBD_FAULT_RS_RD) == 0) 387 if (drbd_submit_ee(mdev, e, READ, DRBD_FAULT_RS_RD) == 0)
388 return 0; 388 return 0;
389 389
390 /* drbd_submit_ee currently fails for one reason only:
391 * not being able to allocate enough bios.
392 * Is dropping the connection going to help? */
393 spin_lock_irq(&mdev->req_lock);
394 list_del(&e->w.list);
395 spin_unlock_irq(&mdev->req_lock);
396
390 drbd_free_ee(mdev, e); 397 drbd_free_ee(mdev, e);
391defer: 398defer:
392 put_ldev(mdev); 399 put_ldev(mdev);
diff --git a/include/linux/drbd.h b/include/linux/drbd.h
index 5e72a5d3d48f..da7d9bd4f3f0 100644
--- a/include/linux/drbd.h
+++ b/include/linux/drbd.h
@@ -53,10 +53,10 @@
53 53
54 54
55extern const char *drbd_buildtag(void); 55extern const char *drbd_buildtag(void);
56#define REL_VERSION "8.3.8.1" 56#define REL_VERSION "8.3.9rc1"
57#define API_VERSION 88 57#define API_VERSION 88
58#define PRO_VERSION_MIN 86 58#define PRO_VERSION_MIN 86
59#define PRO_VERSION_MAX 94 59#define PRO_VERSION_MAX 95
60 60
61 61
62enum drbd_io_error_p { 62enum drbd_io_error_p {