aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/drbd/drbd_interval.h1
-rw-r--r--drivers/block/drbd/drbd_receiver.c35
-rw-r--r--drivers/block/drbd/drbd_req.c23
-rw-r--r--drivers/block/drbd/drbd_req.h7
4 files changed, 41 insertions, 25 deletions
diff --git a/drivers/block/drbd/drbd_interval.h b/drivers/block/drbd/drbd_interval.h
index a847b4a07b25..9d1e5eb2d7eb 100644
--- a/drivers/block/drbd/drbd_interval.h
+++ b/drivers/block/drbd/drbd_interval.h
@@ -9,6 +9,7 @@ struct drbd_interval {
9 sector_t sector; /* start sector of the interval */ 9 sector_t sector; /* start sector of the interval */
10 unsigned int size; /* size in bytes */ 10 unsigned int size; /* size in bytes */
11 sector_t end; /* highest interval end in subtree */ 11 sector_t end; /* highest interval end in subtree */
12 int waiting:1;
12}; 13};
13 14
14static inline void drbd_clear_interval(struct drbd_interval *i) 15static inline void drbd_clear_interval(struct drbd_interval *i)
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
1177static 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
1175static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd, 1190static 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);
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 8b4ba94538bd..078f77ba68fb 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -70,9 +70,12 @@ static struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
70 req->mdev = mdev; 70 req->mdev = mdev;
71 req->master_bio = bio_src; 71 req->master_bio = bio_src;
72 req->epoch = 0; 72 req->epoch = 0;
73
73 drbd_clear_interval(&req->i); 74 drbd_clear_interval(&req->i);
74 req->i.sector = bio_src->bi_sector; 75 req->i.sector = bio_src->bi_sector;
75 req->i.size = bio_src->bi_size; 76 req->i.size = bio_src->bi_size;
77 req->i.waiting = false;
78
76 INIT_LIST_HEAD(&req->tl_requests); 79 INIT_LIST_HEAD(&req->tl_requests);
77 INIT_LIST_HEAD(&req->w.list); 80 INIT_LIST_HEAD(&req->w.list);
78 81
@@ -175,10 +178,6 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
175 (s & RQ_NET_SENT) != 0 && 178 (s & RQ_NET_SENT) != 0 &&
176 req->epoch == mdev->tconn->newest_tle->br_number) 179 req->epoch == mdev->tconn->newest_tle->br_number)
177 queue_barrier(mdev); 180 queue_barrier(mdev);
178
179 /* Wake up any processes waiting for this request to complete. */
180 if ((s & RQ_NET_DONE) && (s & RQ_COLLISION))
181 wake_up(&mdev->misc_wait);
182} 181}
183 182
184void complete_master_bio(struct drbd_conf *mdev, 183void complete_master_bio(struct drbd_conf *mdev,
@@ -188,6 +187,20 @@ void complete_master_bio(struct drbd_conf *mdev,
188 dec_ap_bio(mdev); 187 dec_ap_bio(mdev);
189} 188}
190 189
190
191static void drbd_remove_request_interval(struct rb_root *root,
192 struct drbd_request *req)
193{
194 struct drbd_conf *mdev = req->mdev;
195 struct drbd_interval *i = &req->i;
196
197 drbd_remove_interval(root, i);
198
199 /* Wake up any processes waiting for this request to complete. */
200 if (i->waiting)
201 wake_up(&mdev->misc_wait);
202}
203
191/* Helper for __req_mod(). 204/* Helper for __req_mod().
192 * Set m->bio to the master bio, if it is fit to be completed, 205 * Set m->bio to the master bio, if it is fit to be completed,
193 * or leave it alone (it is initialized to NULL in __req_mod), 206 * or leave it alone (it is initialized to NULL in __req_mod),
@@ -251,7 +264,7 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
251 root = &mdev->write_requests; 264 root = &mdev->write_requests;
252 else 265 else
253 root = &mdev->read_requests; 266 root = &mdev->read_requests;
254 drbd_remove_interval(root, &req->i); 267 drbd_remove_request_interval(root, req);
255 } else 268 } else
256 D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0); 269 D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0);
257 270
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 7a7464a2b3a6..431e3f962c3a 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -194,12 +194,6 @@ enum drbd_req_state_bits {
194 194
195 /* Should call drbd_al_complete_io() for this request... */ 195 /* Should call drbd_al_complete_io() for this request... */
196 __RQ_IN_ACT_LOG, 196 __RQ_IN_ACT_LOG,
197
198 /*
199 * Set when a processes puts itself to sleep to wait for this request
200 * to complete.
201 */
202 __RQ_COLLISION,
203}; 197};
204 198
205#define RQ_LOCAL_PENDING (1UL << __RQ_LOCAL_PENDING) 199#define RQ_LOCAL_PENDING (1UL << __RQ_LOCAL_PENDING)
@@ -220,7 +214,6 @@ enum drbd_req_state_bits {
220 214
221#define RQ_WRITE (1UL << __RQ_WRITE) 215#define RQ_WRITE (1UL << __RQ_WRITE)
222#define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG) 216#define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG)
223#define RQ_COLLISION (1UL << __RQ_COLLISION)
224 217
225/* For waking up the frozen transfer log mod_req() has to return if the request 218/* For waking up the frozen transfer log mod_req() has to return if the request
226 should be counted in the epoch object*/ 219 should be counted in the epoch object*/