diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-01-28 04:31:04 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2011-09-28 04:26:31 -0400 |
commit | 53840641bb1feff8c08acdba9de4c0f8b8674df5 (patch) | |
tree | 4a0eb7966272182b417a9a94f1c5423bcb1fd663 /drivers/block/drbd/drbd_receiver.c | |
parent | 3e05146f0a9f28ef5959403eabf3239869476315 (diff) |
drbd: Allow to wait for the completion of an epoch entry as well
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_receiver.c')
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index d9f3f7fd9bb2..b84a9c9fd3f8 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -334,13 +334,15 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, | |||
334 | goto fail; | 334 | goto fail; |
335 | 335 | ||
336 | drbd_clear_interval(&e->i); | 336 | drbd_clear_interval(&e->i); |
337 | e->i.size = data_size; | ||
338 | e->i.sector = sector; | ||
339 | e->i.waiting = false; | ||
340 | |||
337 | e->epoch = NULL; | 341 | e->epoch = NULL; |
338 | e->mdev = mdev; | 342 | e->mdev = mdev; |
339 | e->pages = page; | 343 | e->pages = page; |
340 | atomic_set(&e->pending_bios, 0); | 344 | atomic_set(&e->pending_bios, 0); |
341 | e->i.size = data_size; | ||
342 | e->flags = 0; | 345 | e->flags = 0; |
343 | e->i.sector = sector; | ||
344 | /* | 346 | /* |
345 | * The block_id is opaque to the receiver. It is not endianness | 347 | * The block_id is opaque to the receiver. It is not endianness |
346 | * converted, and sent back to the sender unchanged. | 348 | * converted, and sent back to the sender unchanged. |
@@ -1172,6 +1174,19 @@ fail: | |||
1172 | return err; | 1174 | return err; |
1173 | } | 1175 | } |
1174 | 1176 | ||
1177 | static void drbd_remove_epoch_entry_interval(struct drbd_conf *mdev, | ||
1178 | struct drbd_epoch_entry *e) | ||
1179 | { | ||
1180 | struct drbd_interval *i = &e->i; | ||
1181 | |||
1182 | drbd_remove_interval(&mdev->write_requests, i); | ||
1183 | drbd_clear_interval(i); | ||
1184 | |||
1185 | /* Wake up any processes waiting for this epoch entry to complete. */ | ||
1186 | if (i->waiting) | ||
1187 | wake_up(&mdev->misc_wait); | ||
1188 | } | ||
1189 | |||
1175 | static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd, | 1190 | static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd, |
1176 | unsigned int data_size) | 1191 | unsigned int data_size) |
1177 | { | 1192 | { |
@@ -1591,8 +1606,7 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel) | |||
1591 | if (mdev->tconn->net_conf->two_primaries) { | 1606 | if (mdev->tconn->net_conf->two_primaries) { |
1592 | spin_lock_irq(&mdev->tconn->req_lock); | 1607 | spin_lock_irq(&mdev->tconn->req_lock); |
1593 | D_ASSERT(!drbd_interval_empty(&e->i)); | 1608 | D_ASSERT(!drbd_interval_empty(&e->i)); |
1594 | drbd_remove_interval(&mdev->epoch_entries, &e->i); | 1609 | drbd_remove_epoch_entry_interval(mdev, e); |
1595 | drbd_clear_interval(&e->i); | ||
1596 | spin_unlock_irq(&mdev->tconn->req_lock); | 1610 | spin_unlock_irq(&mdev->tconn->req_lock); |
1597 | } else | 1611 | } else |
1598 | D_ASSERT(drbd_interval_empty(&e->i)); | 1612 | D_ASSERT(drbd_interval_empty(&e->i)); |
@@ -1612,8 +1626,7 @@ static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int u | |||
1612 | 1626 | ||
1613 | spin_lock_irq(&mdev->tconn->req_lock); | 1627 | spin_lock_irq(&mdev->tconn->req_lock); |
1614 | D_ASSERT(!drbd_interval_empty(&e->i)); | 1628 | D_ASSERT(!drbd_interval_empty(&e->i)); |
1615 | drbd_remove_interval(&mdev->epoch_entries, &e->i); | 1629 | drbd_remove_epoch_entry_interval(mdev, e); |
1616 | drbd_clear_interval(&e->i); | ||
1617 | spin_unlock_irq(&mdev->tconn->req_lock); | 1630 | spin_unlock_irq(&mdev->tconn->req_lock); |
1618 | 1631 | ||
1619 | dec_unacked(mdev); | 1632 | dec_unacked(mdev); |
@@ -1860,17 +1873,14 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd, | |||
1860 | } | 1873 | } |
1861 | 1874 | ||
1862 | if (signal_pending(current)) { | 1875 | if (signal_pending(current)) { |
1863 | drbd_remove_interval(&mdev->epoch_entries, &e->i); | 1876 | drbd_remove_epoch_entry_interval(mdev, e); |
1864 | drbd_clear_interval(&e->i); | ||
1865 | |||
1866 | spin_unlock_irq(&mdev->tconn->req_lock); | 1877 | spin_unlock_irq(&mdev->tconn->req_lock); |
1867 | |||
1868 | finish_wait(&mdev->misc_wait, &wait); | 1878 | finish_wait(&mdev->misc_wait, &wait); |
1869 | goto out_interrupted; | 1879 | goto out_interrupted; |
1870 | } | 1880 | } |
1871 | 1881 | ||
1872 | /* Indicate to wake up mdev->misc_wait upon completion. */ | 1882 | /* Indicate to wake up mdev->misc_wait upon completion. */ |
1873 | req2->rq_state |= RQ_COLLISION; | 1883 | i->waiting = true; |
1874 | 1884 | ||
1875 | spin_unlock_irq(&mdev->tconn->req_lock); | 1885 | spin_unlock_irq(&mdev->tconn->req_lock); |
1876 | if (first) { | 1886 | if (first) { |
@@ -1922,8 +1932,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd, | |||
1922 | dev_err(DEV, "submit failed, triggering re-connect\n"); | 1932 | dev_err(DEV, "submit failed, triggering re-connect\n"); |
1923 | spin_lock_irq(&mdev->tconn->req_lock); | 1933 | spin_lock_irq(&mdev->tconn->req_lock); |
1924 | list_del(&e->w.list); | 1934 | list_del(&e->w.list); |
1925 | drbd_remove_interval(&mdev->epoch_entries, &e->i); | 1935 | drbd_remove_epoch_entry_interval(mdev, e); |
1926 | drbd_clear_interval(&e->i); | ||
1927 | spin_unlock_irq(&mdev->tconn->req_lock); | 1936 | spin_unlock_irq(&mdev->tconn->req_lock); |
1928 | if (e->flags & EE_CALL_AL_COMPLETE_IO) | 1937 | if (e->flags & EE_CALL_AL_COMPLETE_IO) |
1929 | drbd_al_complete_io(mdev, e->i.sector); | 1938 | drbd_al_complete_io(mdev, e->i.sector); |