提交 22cc37a9 编写于 作者: L Lars Ellenberg 提交者: Philipp Reisner

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: NPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: NLars Ellenberg <lars.ellenberg@linbit.com>
上级 af85e8e8
...@@ -1573,6 +1573,13 @@ static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_si ...@@ -1573,6 +1573,13 @@ static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_si
if (drbd_submit_ee(mdev, e, WRITE, DRBD_FAULT_RS_WR) == 0) if (drbd_submit_ee(mdev, e, WRITE, DRBD_FAULT_RS_WR) == 0)
return TRUE; return TRUE;
/* drbd_submit_ee currently fails for one reason only:
* not being able to allocate enough bios.
* Is dropping the connection going to help? */
spin_lock_irq(&mdev->req_lock);
list_del(&e->w.list);
spin_unlock_irq(&mdev->req_lock);
drbd_free_ee(mdev, e); drbd_free_ee(mdev, e);
fail: fail:
put_ldev(mdev); put_ldev(mdev);
...@@ -1998,6 +2005,16 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned ...@@ -1998,6 +2005,16 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
if (drbd_submit_ee(mdev, e, rw, DRBD_FAULT_DT_WR) == 0) if (drbd_submit_ee(mdev, e, rw, DRBD_FAULT_DT_WR) == 0)
return TRUE; return TRUE;
/* drbd_submit_ee currently fails for one reason only:
* not being able to allocate enough bios.
* Is dropping the connection going to help? */
spin_lock_irq(&mdev->req_lock);
list_del(&e->w.list);
hlist_del_init(&e->colision);
spin_unlock_irq(&mdev->req_lock);
if (e->flags & EE_CALL_AL_COMPLETE_IO)
drbd_al_complete_io(mdev, e->sector);
out_interrupted: out_interrupted:
/* yes, the epoch_size now is imbalanced. /* yes, the epoch_size now is imbalanced.
* but we drop the connection anyways, so we don't have a chance to * but we drop the connection anyways, so we don't have a chance to
...@@ -2202,6 +2219,14 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, un ...@@ -2202,6 +2219,14 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packets cmd, un
if (drbd_submit_ee(mdev, e, READ, fault_type) == 0) if (drbd_submit_ee(mdev, e, READ, fault_type) == 0)
return TRUE; return TRUE;
/* drbd_submit_ee currently fails for one reason only:
* not being able to allocate enough bios.
* Is dropping the connection going to help? */
spin_lock_irq(&mdev->req_lock);
list_del(&e->w.list);
spin_unlock_irq(&mdev->req_lock);
/* no drbd_rs_complete_io(), we are dropping the connection anyways */
out_free_e: out_free_e:
put_ldev(mdev); put_ldev(mdev);
drbd_free_ee(mdev, e); drbd_free_ee(mdev, e);
......
...@@ -387,6 +387,13 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size) ...@@ -387,6 +387,13 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size)
if (drbd_submit_ee(mdev, e, READ, DRBD_FAULT_RS_RD) == 0) if (drbd_submit_ee(mdev, e, READ, DRBD_FAULT_RS_RD) == 0)
return 0; return 0;
/* drbd_submit_ee currently fails for one reason only:
* not being able to allocate enough bios.
* Is dropping the connection going to help? */
spin_lock_irq(&mdev->req_lock);
list_del(&e->w.list);
spin_unlock_irq(&mdev->req_lock);
drbd_free_ee(mdev, e); drbd_free_ee(mdev, e);
defer: defer:
put_ldev(mdev); put_ldev(mdev);
......
...@@ -53,10 +53,10 @@ ...@@ -53,10 +53,10 @@
extern const char *drbd_buildtag(void); extern const char *drbd_buildtag(void);
#define REL_VERSION "8.3.8.1" #define REL_VERSION "8.3.9rc1"
#define API_VERSION 88 #define API_VERSION 88
#define PRO_VERSION_MIN 86 #define PRO_VERSION_MIN 86
#define PRO_VERSION_MAX 94 #define PRO_VERSION_MAX 95
enum drbd_io_error_p { enum drbd_io_error_p {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册